#include <OSGPNGImageFileType.h>

Safe Store/Restore | |
| UInt64 | store (const ImagePtr &image, UChar8 *buffer, Int32 memSize=-1) |
| virtual UInt64 | maxBufferSize (const ImagePtr &image) |
| static UInt64 | restore (ImagePtr &image, const UChar8 *buffer, Int32 memSize=-1) |
| static UInt64 | store (const ImagePtr &image, const char *mimeType, UChar8 *buffer, Int32 memSize=-1) |
Public Types | |
Flags | |
| enum | { OSG_READ_SUPPORTED = 1, OSG_WRITE_SUPPORTED = 2 } |
Public Member Functions | |
Destructor | |
| virtual | ~PNGImageFileType (void) |
Read/Write | |
| virtual bool | validateHeader (const Char8 *fileName, bool &implemented) |
| virtual bool | read (ImagePtr &image, std::istream &is, const std::string &mimetype) |
| virtual bool | write (const ImagePtr &image, std::ostream &os, const std::string &mimetype) |
| virtual std::string | determineMimetypeFromStream (std::istream &is) |
Buffer | |
| virtual UInt64 | restoreData (ImagePtr &image, const UChar8 *buffer, Int32 memSize=-1) |
| virtual UInt64 | storeData (const ImagePtr &image, UChar8 *buffer, Int32 memSize=-1) |
Set | |
| void | setOptions (const Char8 *options) |
Get Methods | |
| const Char8 * | getMimeType (void) const |
| const std::list< IDString > & | getSuffixList (void) const |
| virtual UInt32 | getFlags (void) const |
| const Char8 * | getOptions (void) |
Read/Write | |
| virtual bool | read (ImagePtr &image, const Char8 *fileName) |
| virtual bool | write (const ImagePtr &image, const Char8 *fileName) |
dump | |
| void | dump (void) |
Static Public Member Functions | |
Get Method | |
| static PNGImageFileType & | the (void) |
Protected Member Functions | |
Default Constructor | |
| PNGImageFileType (const Char8 *mimeType, const Char8 *suffixArray[], UInt16 suffixByteCount, UInt32 flags) | |
Protected Attributes | |
MTD Header | |
| std::string | _options |
Private Member Functions | |
Copy Constructor | |
| PNGImageFileType (const PNGImageFileType &obj) | |
Copy Operator | |
| const PNGImageFileType & | operator= (const PNGImageFileType &obj) |
Static Private Attributes | |
| static PNGImageFileType | _the |
To be able to load PNG images you need the PNG library, (check the Prerequisites page on www.opensg.org). The lib comes with all Linux distributions.
You have to --enable-png in the configure line to enable the singleton object.
Definition at line 56 of file OSGPNGImageFileType.h.
anonymous enum [inherited] |
Definition at line 66 of file OSGImageFileType.h.
00067 { 00068 OSG_READ_SUPPORTED = 1, 00069 OSG_WRITE_SUPPORTED = 2 00070 };
| PNGImageFileType::~PNGImageFileType | ( | void | ) | [virtual] |
| PNGImageFileType::PNGImageFileType | ( | const Char8 * | mimeType, | |
| const Char8 * | suffixArray[], | |||
| UInt16 | suffixByteCount, | |||
| UInt32 | flags | |||
| ) | [protected] |
Constructor used for the singleton object
Definition at line 937 of file OSGPNGImageFileType.cpp.
00940 : 00941 ImageFileType(mimeType, suffixArray, suffixByteCount, flags) 00942 {}
| osg::PNGImageFileType::PNGImageFileType | ( | const PNGImageFileType & | obj | ) | [private] |
| bool PNGImageFileType::validateHeader | ( | const Char8 * | fileName, | |
| bool & | implemented | |||
| ) | [virtual] |
Reimplemented from osg::ImageFileType.
Definition at line 571 of file OSGPNGImageFileType.cpp.
00572 { 00573 implemented = true; 00574 00575 if(fileName == NULL) 00576 return false; 00577 00578 FILE *file = fopen(fileName, "rb"); 00579 if(file == NULL) 00580 return false; 00581 00582 std::string magic; 00583 magic.resize(4); 00584 fread((void *) &magic[0], 4, 1, file); 00585 fclose(file); 00586 00587 if(magic == "\x89PNG") 00588 { 00589 return true; 00590 } 00591 00592 return false; 00593 }
| bool PNGImageFileType::read | ( | ImagePtr & | image, | |
| std::istream & | is, | |||
| const std::string & | mimetype | |||
| ) | [virtual] |
Tries to fill the image object with the data read from the given input stream. Returns true on success.
Reimplemented from osg::ImageFileType.
Definition at line 165 of file OSGPNGImageFileType.cpp.
References FWARNING, osg::ImageFileType::getMimeType(), osg::Image::OSG_INVALID_PF, osg::Image::OSG_L_PF, osg::Image::OSG_LA_PF, osg::Image::OSG_RESUNIT_INCH, osg::Image::OSG_RGB_PF, osg::Image::OSG_RGBA_PF, osg::Image::OSG_UINT16_IMAGEDATA, osg::Image::OSG_UINT8_IMAGEDATA, and SWARNING.
00167 { 00168 #ifdef OSG_WITH_PNG 00169 00170 bool retCode; 00171 Image::PixelFormat pixelFormat = osg::Image::OSG_INVALID_PF; 00172 png_structp png_ptr; 00173 png_infop info_ptr; 00174 png_uint_32 width, wc, height, h, i, res_x, res_y; 00175 png_byte bit_depth, channels, color_type; 00176 png_bytep *row_pointers, base; 00177 00178 png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0); 00179 if(!png_ptr) 00180 return false; 00181 00182 png_set_error_fn(png_ptr, 0, &errorOutput, &warningOutput); 00183 00184 info_ptr = png_create_info_struct(png_ptr); 00185 if(!info_ptr) 00186 { 00187 png_destroy_read_struct(&png_ptr, 0, 0); 00188 return false; 00189 } 00190 00191 if(setjmp(png_ptr->jmpbuf)) 00192 { 00193 png_destroy_read_struct(&png_ptr, &info_ptr, 0); 00194 return false; 00195 } 00196 00197 png_set_read_fn(png_ptr, &is, &isReadFunc); 00198 00199 png_read_info(png_ptr, info_ptr); 00200 00201 width = png_get_image_width(png_ptr, info_ptr); 00202 height = png_get_image_height(png_ptr, info_ptr); 00203 bit_depth = png_get_bit_depth(png_ptr, info_ptr); 00204 res_x = png_get_x_pixels_per_meter(png_ptr, info_ptr); 00205 res_y = png_get_y_pixels_per_meter(png_ptr, info_ptr); 00206 channels = png_get_channels(png_ptr, info_ptr); 00207 color_type = png_get_color_type(png_ptr, info_ptr); 00208 00209 // Convert paletted images to RGB 00210 if (color_type == PNG_COLOR_TYPE_PALETTE) 00211 { 00212 png_set_palette_to_rgb(png_ptr); 00213 channels = 3; 00214 bit_depth = 8; 00215 } 00216 00217 // Convert < 8 bit to 8 bit 00218 if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) { 00219 png_set_gray_1_2_4_to_8(png_ptr); 00220 bit_depth = 8; 00221 } 00222 00223 #if BYTE_ORDER == LITTLE_ENDIAN 00224 if (bit_depth == 16) 00225 png_set_swap(png_ptr); 00226 #endif 00227 00228 // Add a full alpha channel if there is transparency 00229 // information in a tRNS chunk 00230 if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) 00231 { 00232 png_set_tRNS_to_alpha(png_ptr); 00233 ++channels; 00234 } 00235 Int32 dataType; 00236 switch (bit_depth) { 00237 case 8: 00238 dataType = Image::OSG_UINT8_IMAGEDATA; 00239 break; 00240 case 16: 00241 dataType = Image::OSG_UINT16_IMAGEDATA; 00242 break; 00243 default: 00244 FWARNING (( "Invalid bit_depth: %d, can not read png-data\n", 00245 bit_depth )); 00246 return false; 00247 } 00248 00249 switch(channels) 00250 { 00251 case 1: 00252 pixelFormat = Image::OSG_L_PF; 00253 break; 00254 case 2: 00255 pixelFormat = Image::OSG_LA_PF; 00256 break; 00257 case 3: 00258 pixelFormat = Image::OSG_RGB_PF; 00259 break; 00260 case 4: 00261 pixelFormat = Image::OSG_RGBA_PF; 00262 break; 00263 }; 00264 00265 if(image->set( pixelFormat, width, height, 00266 1, 1, 1, 0.0, 0, 00267 dataType )) 00268 { 00269 // set resolution png supports only pixel per meter, 00270 // so we do a conversion to dpi with some rounding. 00271 res_x = png_uint_32((Real32(res_x) / 39.37007874f) < 0.0f ? 00272 (Real32(res_x) / 39.37007874f) - 0.5f : 00273 (Real32(res_x) / 39.37007874f) + 0.5f); 00274 res_y = png_uint_32((Real32(res_y) / 39.37007874f) < 0.0f ? 00275 (Real32(res_y) / 39.37007874f) - 0.5f : 00276 (Real32(res_y) / 39.37007874f) + 0.5f); 00277 00278 image->setResX(Real32(res_x)); 00279 image->setResY(Real32(res_y)); 00280 image->setResUnit(Image::OSG_RESUNIT_INCH); 00281 00282 // Calculate the row pointers 00283 row_pointers = new png_bytep[height]; 00284 wc = width * channels * (bit_depth / 8); 00285 h = height - 1; 00286 base = image->getData(); 00287 for(i = 0; i < height; ++i) 00288 row_pointers[i] = base + (h - i) * wc; 00289 00290 // Read the image data 00291 png_read_image(png_ptr, row_pointers); 00292 00293 delete[] row_pointers; 00294 00295 retCode = true; 00296 } 00297 else 00298 retCode = false; 00299 00300 png_destroy_read_struct(&png_ptr, &info_ptr, 0); 00301 00302 return retCode; 00303 00304 #else 00305 00306 SWARNING << 00307 getMimeType() << 00308 " read is not compiled into the current binary " << 00309 std::endl; 00310 return false; 00311 00312 #endif 00313 00314 }
| bool PNGImageFileType::write | ( | const ImagePtr & | img, | |
| std::ostream & | os, | |||
| const std::string & | mimetype | |||
| ) | [virtual] |
Tries to write the image object to the given output stream. Returns true on success. Based on the public domain example.c from the PNG dist.
Reimplemented from osg::ImageFileType.
Definition at line 322 of file OSGPNGImageFileType.cpp.
References osg::endLog(), FWARNING, osg::ImageFileType::getMimeType(), osg::Image::OSG_BGR_PF, osg::Image::OSG_BGRA_PF, osg::Image::OSG_L_PF, osg::Image::OSG_LA_PF, osg::Image::OSG_RESUNIT_INCH, osg::Image::OSG_RGB_PF, osg::Image::OSG_RGBA_PF, osg::Image::OSG_UINT16_IMAGEDATA, osg::Image::OSG_UINT8_IMAGEDATA, and SWARNING.
00324 { 00325 #ifdef OSG_WITH_PNG 00326 00327 png_structp png_ptr; 00328 png_infop info_ptr; 00329 00330 if(img->getDimension() < 1 || img->getDimension() > 2) 00331 { 00332 FWARNING(("PNGImageFileType::write: invalid dimension %d!\n", 00333 img->getDimension())); 00334 return false; 00335 } 00336 00337 /* Create and initialize the png_struct with the desired error handler 00338 * functions. If you want to use the default stderr and longjump method, 00339 * you can supply NULL for the last three parameters. We also check that 00340 * the library version is compatible with the one used at compile time, 00341 * in case we are using dynamically linked libraries. REQUIRED. 00342 */ 00343 png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, 00344 0, &errorOutput, &warningOutput); 00345 00346 if (png_ptr == NULL) 00347 return false; 00348 00349 /* Allocate/initialize the image information data. REQUIRED */ 00350 info_ptr = png_create_info_struct(png_ptr); 00351 if (info_ptr == NULL) 00352 { 00353 png_destroy_write_struct(&png_ptr, NULL); 00354 return false; 00355 } 00356 00357 /* set up the output handlers */ 00358 png_set_write_fn(png_ptr, &os, &osWriteFunc, &osFlushFunc); 00359 00360 /* This is the hard way */ 00361 00362 /* Set the image information here. Width and height are up to 2^31, 00363 * bit_depth is one of 1, 2, 4, 8, or 16, but valid values also depend on 00364 * the color_type selected. color_type is one of PNG_COLOR_TYPE_GRAY, 00365 * PNG_COLOR_TYPE_GRAY_ALPHA, PNG_COLOR_TYPE_PALETTE, PNG_COLOR_TYPE_RGB, 00366 * or PNG_COLOR_TYPE_RGB_ALPHA. interlace is either PNG_INTERLACE_NONE or 00367 * PNG_INTERLACE_ADAM7, and the compression_type and filter_type MUST 00368 * currently be PNG_COMPRESSION_TYPE_BASE and PNG_FILTER_TYPE_BASE. REQUIRED 00369 */ 00370 Int32 ctype; 00371 switch(img->getPixelFormat()) 00372 { 00373 case Image::OSG_L_PF: ctype = PNG_COLOR_TYPE_GRAY; 00374 break; 00375 00376 case Image::OSG_LA_PF: ctype = PNG_COLOR_TYPE_GRAY_ALPHA; 00377 break; 00378 00379 #if defined(GL_BGR) || defined(GL_BGR_EXT) 00380 case Image::OSG_BGR_PF: 00381 #endif 00382 case Image::OSG_RGB_PF: ctype = PNG_COLOR_TYPE_RGB; 00383 break; 00384 00385 #if defined(GL_BGRA) || defined(GL_BGRA_EXT) 00386 case Image::OSG_BGRA_PF: 00387 #endif 00388 case Image::OSG_RGBA_PF: ctype = PNG_COLOR_TYPE_RGB_ALPHA; 00389 break; 00390 00391 default: 00392 FWARNING(("PNGImageFileType::write: unknown pixel format %d!\n", 00393 img->getPixelFormat())); 00394 png_destroy_write_struct(&png_ptr, NULL); 00395 return false; 00396 00397 } 00398 00399 Int32 bit_depth; 00400 switch (img->getDataType()) { 00401 case Image::OSG_UINT8_IMAGEDATA: 00402 bit_depth = 8; 00403 break; 00404 case Image::OSG_UINT16_IMAGEDATA: 00405 bit_depth = 16; 00406 break; 00407 default: 00408 FWARNING (("Invalid pixeldepth, cannot store data\n")); 00409 return false; 00410 }; 00411 00412 png_set_IHDR(png_ptr, info_ptr, img->getWidth(), img->getHeight(), 00413 bit_depth, ctype, 00414 PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); 00415 00416 // set resolution png supports only meter per pixel, 00417 // so we do a conversion from dpi with some rounding. 00418 png_uint_32 res_x = img->getResX(); 00419 png_uint_32 res_y = img->getResY(); 00420 if(img->getResUnit() == Image::OSG_RESUNIT_INCH) 00421 { 00422 res_x = png_uint_32((img->getResX() * 39.37007874f) < 0.0f ? 00423 (img->getResX() * 39.37007874f) - 0.5f : 00424 (img->getResX() * 39.37007874f) + 0.5f); 00425 res_y = png_uint_32((img->getResY() * 39.37007874f) < 0.0f ? 00426 (img->getResY() * 39.37007874f) - 0.5f : 00427 (img->getResY() * 39.37007874f) + 0.5f); 00428 } 00429 00430 png_set_pHYs(png_ptr, info_ptr, res_x, res_y, 00431 PNG_RESOLUTION_METER); 00432 00433 #if 0 00434 /* optional significant bit chunk */ 00435 /* if we are dealing with a grayscale image then */ 00436 sig_bit.gray = true_bit_depth; 00437 /* otherwise, if we are dealing with a color image then */ 00438 sig_bit.red = true_red_bit_depth; 00439 sig_bit.green = true_green_bit_depth; 00440 sig_bit.blue = true_blue_bit_depth; 00441 /* if the image has an alpha channel then */ 00442 sig_bit.alpha = true_alpha_bit_depth; 00443 png_set_sBIT(png_ptr, info_ptr, sig_bit); 00444 00445 00446 /* Optional gamma chunk is strongly suggested if you have any guess 00447 * as to the correct gamma of the image. 00448 */ 00449 png_set_gAMA(png_ptr, info_ptr, gamma); 00450 00451 /* Optionally write comments into the image */ 00452 text_ptr[0].key = "Title"; 00453 text_ptr[0].text = "Mona Lisa"; 00454 text_ptr[0].compression = PNG_TEXT_COMPRESSION_NONE; 00455 text_ptr[1].key = "Author"; 00456 text_ptr[1].text = "Leonardo DaVinci"; 00457 text_ptr[1].compression = PNG_TEXT_COMPRESSION_NONE; 00458 text_ptr[2].key = "Description"; 00459 text_ptr[2].text = "<long text>"; 00460 text_ptr[2].compression = PNG_TEXT_COMPRESSION_zTXt; 00461 #ifdef PNG_iTXt_SUPPORTED 00462 text_ptr[0].lang = NULL; 00463 text_ptr[1].lang = NULL; 00464 text_ptr[2].lang = NULL; 00465 #endif 00466 png_set_text(png_ptr, info_ptr, text_ptr, 3); 00467 #endif 00468 /* other optional chunks like cHRM, bKGD, tRNS, tIME, oFFs, pHYs, */ 00469 /* note that if sRGB is present the gAMA and cHRM chunks must be ignored 00470 * on read and must be written in accordance with the sRGB profile */ 00471 00472 /* Write the file header information. REQUIRED */ 00473 png_write_info(png_ptr, info_ptr); 00474 00475 #if BYTE_ORDER == LITTLE_ENDIAN 00476 00477 if (bit_depth == 16) 00478 png_set_swap(png_ptr); 00479 00480 #endif 00481 00482 00483 #if 0 00484 /* invert monochrome pixels */ 00485 png_set_invert_mono(png_ptr); 00486 00487 /* Shift the pixels up to a legal bit depth and fill in 00488 * as appropriate to correctly scale the image. 00489 */ 00490 png_set_shift(png_ptr, &sig_bit); 00491 00492 /* pack pixels into bytes */ 00493 png_set_packing(png_ptr); 00494 00495 /* Get rid of filler (OR ALPHA) bytes, pack XRGB/RGBX/ARGB/RGBA into 00496 * RGB (4 channels -> 3 channels). The second parameter is not used. 00497 */ 00498 png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE); 00499 00500 /* swap bytes of 16-bit files to most significant byte first */ 00501 png_set_swap(png_ptr); 00502 00503 /* swap bits of 1, 2, 4 bit packed pixel formats */ 00504 png_set_packswap(png_ptr); 00505 #endif 00506 00507 if(img->getPixelFormat() == Image::OSG_BGR_PF || 00508 img->getPixelFormat() == Image::OSG_BGRA_PF 00509 ) 00510 { 00511 /* flip BGR pixels to RGB */ 00512 png_set_bgr(png_ptr); 00513 00514 /* swap location of alpha bytes from ARGB to RGBA */ 00515 png_set_swap_alpha(png_ptr); 00516 } 00517 00518 /* The easiest way to write the image (you may have a different memory 00519 * layout, however, so choose what fits your needs best). You need to 00520 * use the first method if you aren't handling interlacing yourself. 00521 */ 00522 png_bytep *row_pointers = new png_bytep [img->getHeight()]; 00523 00524 for(Int32 k = 0; k < img->getHeight(); k++) 00525 { 00526 row_pointers[k] = img->getData() + 00527 (img->getHeight() - 1 - k) * 00528 img->getWidth() * img->getBpp(); 00529 } 00530 00531 /* write out the entire image data in one call */ 00532 png_write_image(png_ptr, row_pointers); 00533 00534 /* It is REQUIRED to call this to finish writing the rest of the file */ 00535 png_write_end(png_ptr, info_ptr); 00536 00537 /* clean up after the write, and free any memory allocated */ 00538 png_destroy_write_struct(&png_ptr, &info_ptr); 00539 00540 delete [] row_pointers; 00541 00542 /* that's it */ 00543 return true; 00544 00545 #else 00546 SWARNING << 00547 getMimeType() << 00548 " write is not compiled into the current binary " << 00549 endLog; 00550 return false; 00551 #endif 00552 }
| std::string PNGImageFileType::determineMimetypeFromStream | ( | std::istream & | is | ) | [virtual] |
Tries to determine the mime type of the data provided by an input stream by searching for magic bytes. Returns the mime type or an empty string when the function could not determine the mime type.
Reimplemented from osg::ImageFileType.
Definition at line 560 of file OSGPNGImageFileType.cpp.
References osg::ImageFileType::getMimeType().
00561 { 00562 char filecode[4]; 00563 is.read(filecode, 4); 00564 is.seekg(-4, std::ios::cur); 00565 return strncmp(filecode, "\x89PNG", 4) == 0 ? 00566 std::string(getMimeType()) : std::string(); 00567 }
| UInt64 PNGImageFileType::restoreData | ( | ImagePtr & | image, | |
| const UChar8 * | buffer, | |||
| Int32 | memSize = -1 | |||
| ) | [virtual] |
Reimplemented from osg::ImageFileType.
Definition at line 614 of file OSGPNGImageFileType.cpp.
References FWARNING, osg::ImageFileType::getMimeType(), osg::Image::OSG_INVALID_PF, osg::Image::OSG_L_PF, osg::Image::OSG_LA_PF, osg::Image::OSG_RGB_PF, osg::Image::OSG_RGBA_PF, osg::Image::OSG_UINT16_IMAGEDATA, osg::Image::OSG_UINT8_IMAGEDATA, and SWARNING.
00617 { 00618 #ifdef OSG_WITH_PNG 00619 00620 UInt64 retCode; 00621 Image::PixelFormat pixelFormat = osg::Image::OSG_INVALID_PF; 00622 png_structp png_ptr; 00623 png_infop info_ptr; 00624 png_uint_32 width, wc, height, h, i; 00625 png_byte bit_depth, channels, color_type; 00626 png_bytep *row_pointers, base; 00627 00628 png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0); 00629 if(!png_ptr) 00630 { 00631 return 0; 00632 } 00633 00634 png_set_error_fn(png_ptr, 0, &errorOutput, &warningOutput); 00635 00636 info_ptr = png_create_info_struct(png_ptr); 00637 if(!info_ptr) 00638 { 00639 png_destroy_read_struct(&png_ptr, 0, 0); 00640 return 0; 00641 } 00642 00643 if(setjmp(png_ptr->jmpbuf)) 00644 { 00645 png_destroy_read_struct(&png_ptr, &info_ptr, 0); 00646 return 0; 00647 } 00648 00649 BufferInfo bufferInfo; 00650 bufferInfo.buffer = (UChar8 *) buffer; 00651 bufferInfo.length = 0; 00652 png_set_read_fn(png_ptr, (void *) &bufferInfo, user_read_data); 00653 00654 png_read_info(png_ptr, info_ptr); 00655 00656 width = png_get_image_width(png_ptr, info_ptr); 00657 height = png_get_image_height(png_ptr, info_ptr); 00658 bit_depth = png_get_bit_depth(png_ptr, info_ptr); 00659 channels = png_get_channels(png_ptr, info_ptr); 00660 color_type = png_get_color_type(png_ptr, info_ptr); 00661 00662 // Convert paletted images to RGB 00663 if (color_type == PNG_COLOR_TYPE_PALETTE) 00664 { 00665 png_set_palette_to_rgb(png_ptr); 00666 channels = 3; 00667 bit_depth = 8; 00668 } 00669 00670 // Convert < 8 bit to 8 bit 00671 if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) { 00672 png_set_gray_1_2_4_to_8(png_ptr); 00673 bit_depth = 8; 00674 } 00675 00676 #if BYTE_ORDER == LITTLE_ENDIAN 00677 if (bit_depth == 16) 00678 png_set_swap(png_ptr); 00679 #endif 00680 00681 // Add a full alpha channel if there is transparency 00682 // information in a tRNS chunk 00683 if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) 00684 { 00685 png_set_tRNS_to_alpha(png_ptr); 00686 ++channels; 00687 } 00688 Int32 dataType; 00689 switch (bit_depth) { 00690 case 8: 00691 dataType = Image::OSG_UINT8_IMAGEDATA; 00692 break; 00693 case 16: 00694 dataType = Image::OSG_UINT16_IMAGEDATA; 00695 break; 00696 default: 00697 FWARNING (( "Invalid bit_depth: %d, can not read png-data\n", 00698 bit_depth )); 00699 return false; 00700 } 00701 00702 switch(channels) 00703 { 00704 case 1: 00705 pixelFormat = Image::OSG_L_PF; 00706 break; 00707 case 2: 00708 pixelFormat = Image::OSG_LA_PF; 00709 break; 00710 case 3: 00711 pixelFormat = Image::OSG_RGB_PF; 00712 break; 00713 case 4: 00714 pixelFormat = Image::OSG_RGBA_PF; 00715 break; 00716 }; 00717 00718 if(image->set( pixelFormat, width, height, 00719 1, 1, 1, 0.0, 0, 00720 dataType )) 00721 { 00722 // Calculate the row pointers 00723 row_pointers = new png_bytep[height]; 00724 wc = width * channels * (bit_depth / 8); 00725 h = height - 1; 00726 base = image->getData(); 00727 for(i = 0; i < height; ++i) 00728 row_pointers[i] = base + (h - i) * wc; 00729 00730 // Read the image data 00731 png_read_image(png_ptr, row_pointers); 00732 00733 delete[] row_pointers; 00734 00735 retCode = bufferInfo.length; 00736 } 00737 else 00738 retCode = 0; 00739 00740 png_destroy_read_struct(&png_ptr, &info_ptr, 0); 00741 00742 return retCode; 00743 00744 #else 00745 SWARNING << 00746 getMimeType() << 00747 " restoreData is not compiled into the current binary " << 00748 std::endl; 00749 return 0; 00750 #endif 00751 }
| UInt64 PNGImageFileType::storeData | ( | const ImagePtr & | image, | |
| UChar8 * | buffer, | |||
| Int32 | memSize = -1 | |||
| ) | [virtual] |
Tries to restore the image data from the given memblock. Returns the amount of data read.
Reimplemented from osg::ImageFileType.
Definition at line 775 of file OSGPNGImageFileType.cpp.
References FWARNING, osg::ImageFileType::getMimeType(), osg::Image::OSG_BGR_PF, osg::Image::OSG_BGRA_PF, osg::Image::OSG_L_PF, osg::Image::OSG_LA_PF, osg::Image::OSG_RGB_PF, osg::Image::OSG_RGBA_PF, osg::Image::OSG_UINT16_IMAGEDATA, osg::Image::OSG_UINT8_IMAGEDATA, and SWARNING.
00778 { 00779 #ifdef OSG_WITH_PNG 00780 00781 png_structp png_ptr; 00782 png_infop info_ptr; 00783 00784 if(image->getDimension() < 1 || image->getDimension() > 2) 00785 { 00786 FWARNING(("PNGImageFileType::write: invalid dimension %d!\n", 00787 image->getDimension())); 00788 return 0; 00789 } 00790 00791 /* Create and initialize the png_struct with the desired error handler 00792 * functions. If you want to use the default stderr and longjump method, 00793 * you can supply NULL for the last three parameters. We also check that 00794 * the library version is compatible with the one used at compile time, 00795 * in case we are using dynamically linked libraries. REQUIRED. 00796 */ 00797 png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, 00798 0, &errorOutput, &warningOutput); 00799 00800 if (png_ptr == NULL) 00801 { 00802 return 0; 00803 } 00804 00805 /* Allocate/initialize the image information data. REQUIRED */ 00806 info_ptr = png_create_info_struct(png_ptr); 00807 if (info_ptr == NULL) 00808 { 00809 png_destroy_write_struct(&png_ptr, NULL); 00810 return 0; 00811 } 00812 00813 BufferInfo bufferInfo; 00814 bufferInfo.buffer = buffer; 00815 bufferInfo.length = 0; 00816 png_set_write_fn(png_ptr, (void *) &bufferInfo, user_write_data, user_flush_data); 00817 00818 /* This is the hard way */ 00819 00820 /* Set the image information here. Width and height are up to 2^31, 00821 * bit_depth is one of 1, 2, 4, 8, or 16, but valid values also depend on 00822 * the color_type selected. color_type is one of PNG_COLOR_TYPE_GRAY, 00823 * PNG_COLOR_TYPE_GRAY_ALPHA, PNG_COLOR_TYPE_PALETTE, PNG_COLOR_TYPE_RGB, 00824 * or PNG_COLOR_TYPE_RGB_ALPHA. interlace is either PNG_INTERLACE_NONE or 00825 * PNG_INTERLACE_ADAM7, and the compression_type and filter_type MUST 00826 * currently be PNG_COMPRESSION_TYPE_BASE and PNG_FILTER_TYPE_BASE. REQUIRED 00827 */ 00828 Int32 ctype; 00829 switch(image->getPixelFormat()) 00830 { 00831 case Image::OSG_L_PF: ctype = PNG_COLOR_TYPE_GRAY; 00832 break; 00833 00834 case Image::OSG_LA_PF: ctype = PNG_COLOR_TYPE_GRAY_ALPHA; 00835 break; 00836 00837 #if defined(GL_BGR) || defined(GL_BGR_EXT) 00838 case Image::OSG_BGR_PF: 00839 #endif 00840 case Image::OSG_RGB_PF: ctype = PNG_COLOR_TYPE_RGB; 00841 break; 00842 00843 #if defined(GL_BGRA) || defined(GL_BGRA_EXT) 00844 case Image::OSG_BGRA_PF: 00845 #endif 00846 case Image::OSG_RGBA_PF: ctype = PNG_COLOR_TYPE_RGB_ALPHA; 00847 break; 00848 00849 default: 00850 FWARNING(("PNGImageFileType::write: unknown pixel format %d!\n", 00851 image->getPixelFormat())); 00852 png_destroy_write_struct(&png_ptr, NULL); 00853 return 0; 00854 00855 } 00856 00857 Int32 bit_depth; 00858 switch (image->getDataType()) { 00859 case Image::OSG_UINT8_IMAGEDATA: 00860 bit_depth = 8; 00861 break; 00862 case Image::OSG_UINT16_IMAGEDATA: 00863 bit_depth = 16; 00864 break; 00865 default: 00866 FWARNING (("Invalid pixeldepth, cannot store data\n")); 00867 return 0; 00868 }; 00869 00870 png_set_IHDR(png_ptr, info_ptr, image->getWidth(), image->getHeight(), 00871 bit_depth, ctype, 00872 PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); 00873 00874 /* other optional chunks like cHRM, bKGD, tRNS, tIME, oFFs, pHYs, */ 00875 /* note that if sRGB is present the gAMA and cHRM chunks must be ignored 00876 * on read and must be written in accordance with the sRGB profile */ 00877 00878 /* Write the file header information. REQUIRED */ 00879 png_write_info(png_ptr, info_ptr); 00880 00881 #if BYTE_ORDER == LITTLE_ENDIAN 00882 if (bit_depth == 16) 00883 png_set_swap(png_ptr); 00884 #endif 00885 00886 if(image->getPixelFormat() == Image::OSG_BGR_PF || 00887 image->getPixelFormat() == Image::OSG_BGRA_PF 00888 ) 00889 { 00890 /* flip BGR pixels to RGB */ 00891 png_set_bgr(png_ptr); 00892 00893 /* swap location of alpha bytes from ARGB to RGBA */ 00894 png_set_swap_alpha(png_ptr); 00895 } 00896 00897 /* The easiest way to write the image (you may have a different memory 00898 * layout, however, so choose what fits your needs best). You need to 00899 * use the first method if you aren't handling interlacing yourself. 00900 */ 00901 png_bytep *row_pointers = new png_bytep [image->getHeight()]; 00902 00903 for(Int32 k = 0; k < image->getHeight(); k++) 00904 { 00905 row_pointers[k] = image->getData() + 00906 (image->getHeight() - 1 - k) * 00907 image->getWidth() * image->getBpp(); 00908 } 00909 00910 /* write out the entire image data in one call */ 00911 png_write_image(png_ptr, row_pointers); 00912 00913 /* It is REQUIRED to call this to finish writing the rest of the file */ 00914 png_write_end(png_ptr, info_ptr); 00915 00916 /* clean up after the write, and free any memory allocated */ 00917 png_destroy_write_struct(&png_ptr, &info_ptr); 00918 00919 delete [] row_pointers; 00920 00921 /* that's it */ 00922 return bufferInfo.length; 00923 00924 #else 00925 SWARNING << 00926 getMimeType() << 00927 " storeData is not compiled into the current binary " << 00928 std::endl; 00929 return 0; 00930 #endif 00931 }
| PNGImageFileType & PNGImageFileType::the | ( | void | ) | [static] |
Definition at line 151 of file OSGPNGImageFileType.cpp.
References _the.
00152 { 00153 return _the; 00154 }
| const PNGImageFileType& osg::PNGImageFileType::operator= | ( | const PNGImageFileType & | obj | ) | [private] |
| void ImageFileType::setOptions | ( | const Char8 * | options | ) | [inherited] |
Definition at line 243 of file OSGImageFileType.cpp.
References osg::ImageFileType::_options.
Referenced by osg::ImageFileHandler::setOptions().
00244 { 00245 _options = options; 00246 }
| const Char8 * ImageFileType::getMimeType | ( | void | ) | const [inherited] |
Get method for the mime type
Definition at line 107 of file OSGImageFileType.cpp.
References osg::ImageFileType::_mimeType, and osg::IDString::str().
Referenced by osg::ImageFileHandler::addImageFileType(), osg::TIFImageFileType::determineMimetypeFromStream(), osg::SGIImageFileType::determineMimetypeFromStream(), osg::PSDImageFileType::determineMimetypeFromStream(), osg::PNMImageFileType::determineMimetypeFromStream(), determineMimetypeFromStream(), osg::MNGImageFileType::determineMimetypeFromStream(), osg::JPGImageFileType::determineMimetypeFromStream(), osg::JP2ImageFileType::determineMimetypeFromStream(), osg::GIFImageFileType::determineMimetypeFromStream(), osg::DDSImageFileType::determineMimetypeFromStream(), osg::BMPImageFileType::determineMimetypeFromStream(), osg::ImageFileType::dump(), osg::TIFImageFileType::read(), read(), osg::JPGImageFileType::read(), osg::JP2ImageFileType::read(), osg::ImageFileType::read(), osg::ImageFileHandler::read(), osg::EXRImageFileType::read(), restoreData(), osg::JPGImageFileType::restoreData(), osg::ImageFileType::restoreData(), osg::ImageFileHandler::store(), storeData(), osg::JPGImageFileType::storeData(), osg::ImageFileType::storeData(), osg::TIFImageFileType::write(), write(), osg::JPGImageFileType::write(), osg::ImageFileType::write(), osg::ImageFileHandler::write(), and osg::EXRImageFileType::write().
| const std::list< IDString > & ImageFileType::getSuffixList | ( | void | ) | const [inherited] |
Get method for the suffix list container
Definition at line 134 of file OSGImageFileType.cpp.
References osg::ImageFileType::_suffixList.
Referenced by osg::ImageFileHandler::addImageFileType().
00135 { 00136 return _suffixList; 00137 }
| UInt32 ImageFileType::getFlags | ( | void | ) | const [virtual, inherited] |
Get method for the flags indicating read/write support. Most image types only support reading.
Definition at line 117 of file OSGImageFileType.cpp.
References osg::ImageFileType::_flags.
Referenced by osg::ImageFileHandler::getSuffixList().
00118 { 00119 return _flags; 00120 }
| const Char8 * ImageFileType::getOptions | ( | void | ) | [inherited] |
Get method for the mime type
Definition at line 124 of file OSGImageFileType.cpp.
References osg::ImageFileType::_options.
Referenced by osg::ImageFileHandler::getOptions().
00125 { 00126 return _options.c_str(); 00127 }
Reimplemented in osg::DATImageFileType, and osg::HDRImageFileType.
Definition at line 141 of file OSGImageFileType.cpp.
Referenced by osg::ImageFileHandler::read().
00142 { 00143 std::ifstream is(fileName, std::ios::binary); 00144 if (is.good() == false) 00145 return false; 00146 return read(image, is, std::string()); 00147 }
Reimplemented in osg::DATImageFileType, and osg::HDRImageFileType.
Definition at line 151 of file OSGImageFileType.cpp.
Referenced by osg::ImageFileHandler::write().
00152 { 00153 std::ofstream os(fileName, std::ios::binary); 00154 if (os.good() == false) 00155 return false; 00156 return write(image, os, std::string()); 00157 }
| UInt64 ImageFileType::restore | ( | ImagePtr & | image, | |
| const UChar8 * | buffer, | |||
| Int32 | memSize = -1 | |||
| ) | [static, inherited] |
Tries to restore the Imagedata from the given memblock. The buffer must include a ImageFileType::Head data block.
Definition at line 283 of file OSGImageFileType.cpp.
References osg::ImageFileType::Head::dataType, osg::ImageFileType::Head::depth, osg::ImageFileHandler::determineMimetypeFromSuffix(), FDEBUG, osg::ImageFileType::Head::frameCount, osg::ImageFileType::Head::frameDelay, FWARNING, osg::ImageFileType::Head::height, osg::ImageFileType::Head::mipmapCount, osg::ImageFileType::Head::netToHost(), osg::NullFC, osg::Image::OSG_UINT8_IMAGEDATA, osg::ImageFileType::Head::pixelFormat, osg::ImageFileType::Head::sideCount, osg::ImageFileType::Head::suffix, osg::ImageFileHandler::the(), and osg::ImageFileType::Head::width.
Referenced by osg::ClusterViewBuffer::recv(), osg::ImageFileHandler::restore(), and osg::SimpleSceneManager::useOpenSGLogo().
00285 { 00286 unsigned long imageSize, headSize = sizeof(Head); 00287 unsigned long size = 0, attachmentSize; 00288 Head head; 00289 const UChar8 *data = buffer ? (buffer + headSize) : 0; 00290 ImageFileType *type; 00291 std::string mimeType; 00292 Image::Type dataType; 00293 00294 if ((image != osg::NullFC) && buffer && (memSize >= headSize)) { 00295 00296 // Copy header. Otherwise netToHost would change the original 00297 // data structur. 00298 memcpy(&head,buffer,sizeof(Head)); 00299 head.netToHost(); 00300 mimeType = ImageFileHandler::the().determineMimetypeFromSuffix(head.suffix); 00301 00302 if((type = ImageFileHandler::the().getFileType(mimeType.c_str(), 0))) 00303 { 00304 if (head.dataType) 00305 dataType = Image::Type(head.dataType); 00306 else 00307 dataType = Image::OSG_UINT8_IMAGEDATA; 00308 00309 image->set(Image::PixelFormat(head.pixelFormat), head.width, 00310 head.height, head.depth, head.mipmapCount, 00311 head.frameCount, float(head.frameDelay) / 1000.0, 0, 00312 dataType,true,head.sideCount ); 00313 imageSize = static_cast<unsigned long>( 00314 type->restoreData(image, data, memSize - headSize)); 00315 attachmentSize = 0; // head->attachmentSize; 00316 00317 /* 00318 if ((attachmentSize = head->attachmentSize)) 00319 { 00320 attData = (char*)(buffer + headSize + imageSize); 00321 attKey = attData; 00322 attValue = 0; 00323 for (i = 0; i < (attachmentSize-1); i++) { 00324 if (attData[i] == 0) 00325 if (attKey) { 00326 attValue = &(attData[i+1]); 00327 image->setAttachmentField (attKey,attValue); 00328 attKey = attValue = 0; 00329 } 00330 else 00331 attKey = &(attData[i+1]); 00332 } 00333 if (attKey || attValue) { 00334 FFATAL (("Attachment restore error\n")); 00335 } 00336 } 00337 */ 00338 00339 size = headSize + imageSize + attachmentSize; 00340 00341 FDEBUG (( "Restore image data: %lu (%lu/%lu/%lu)\n", 00342 size, headSize, imageSize, attachmentSize )); 00343 00344 } 00345 else 00346 { 00347 imageSize = 0; 00348 FWARNING(("Can not restore image data, invalid mimeType: %s\n", 00349 mimeType.empty() == false ? mimeType.c_str() : "Unknown")); 00350 } 00351 00352 00353 } 00354 00355 return size; 00356 }
| UInt64 ImageFileType::store | ( | const ImagePtr & | image, | |
| const char * | mimeType, | |||
| UChar8 * | buffer, | |||
| Int32 | memSize = -1 | |||
| ) | [static, inherited] |
Tries to store the raster data to the given mem block. Will include a ImageFileType::Head description and the data encoded as 'mimeType'
Definition at line 364 of file OSGImageFileType.cpp.
References osg::ImageFileHandler::getFileType(), osg::ImageFileType::store(), and osg::ImageFileHandler::the().
Referenced by osg::ClusterViewBuffer::send(), osg::ImageFileType::store(), and osg::ImageFileHandler::store().
00366 { 00367 ImageFileType *type = ImageFileHandler::the().getFileType(mimeType); 00368 00369 return type ? type->store(image, buffer, memSize) : 0; 00370 }
| UInt64 ImageFileType::store | ( | const ImagePtr & | image, | |
| UChar8 * | buffer, | |||
| Int32 | memSize = -1 | |||
| ) | [inherited] |
Tries to store the raster data to the given mem block. Will include a ImageFileType::Head description for the derived concreate mimeType.
Definition at line 378 of file OSGImageFileType.cpp.
References osg::ImageFileType::_suffixList, osg::ImageFileType::Head::attachmentSize, osg::ImageFileType::Head::dataType, osg::ImageFileType::Head::depth, FDEBUG, FFATAL, osg::ImageFileType::Head::frameCount, osg::ImageFileType::Head::frameDelay, osg::ImageFileType::Head::height, osg::ImageFileType::Head::hostToNet(), osg::ImageFileType::Head::mipmapCount, osg::ImageFileType::Head::pixelFormat, osg::ImageFileType::Head::sideCount, osg::ImageFileType::storeData(), osg::ImageFileType::Head::suffix, and osg::ImageFileType::Head::width.
00380 { 00381 Head *head; 00382 unsigned long dataSize = 0, headSize = sizeof(Head); 00383 unsigned long attachmentSize; 00384 UChar8 *dest; 00385 const UChar8 *src = image->getData(); 00386 std::map<std::string, std::string>::const_iterator aI; 00387 std::string value; 00388 00389 attachmentSize = 0; 00390 00391 // get attachment size 00392 /* 00393 ImageGenericAttPtr att=ImageGenericAttPtr::dcast( 00394 const_cast<Image*>(image.getCPtr())->findAttachment( 00395 ImageGenericAtt::getClassType().getGroupId())); 00396 if(att != NullFC) 00397 { 00398 for(i = 0; i < (att->getType().getNumFieldDescs()-1); ++i) 00399 { 00400 FieldDescription *fieldDesc=att->getType().getFieldDescription(i); 00401 Field *field=att->getField(i); 00402 if (fieldDesc && field) 00403 { 00404 field->getValueByStr(value); 00405 attachmentSize += strlen( fieldDesc->getName().str() ) + 1; 00406 attachmentSize += value.length() + 1; 00407 00408 std::cout << fieldDesc->getName().str() << std::endl; 00409 std::cout << value << std::endl; 00410 } 00411 else 00412 { 00413 FFATAL (("Invalid Attachment in ImageFileType::store()\n")); 00414 } 00415 } 00416 } 00417 */ 00418 00419 if (buffer) 00420 { 00421 head = (Head *)buffer; 00422 00423 head->pixelFormat = image->getPixelFormat(); 00424 head->width = image->getWidth(); 00425 head->height = image->getHeight(); 00426 head->depth = image->getDepth(); 00427 head->mipmapCount = image->getMipMapCount(); 00428 head->frameCount = image->getFrameCount(); 00429 head->frameDelay = short(image->getFrameDelay() * 1000.0); 00430 head->sideCount = image->getSideCount(); 00431 head->dataType = image->getDataType(); 00432 head->attachmentSize = static_cast<unsigned short>(attachmentSize); 00433 head->hostToNet(); 00434 00435 strcpy(head->suffix, _suffixList.front().str()); 00436 00437 dest = (UChar8 *) (buffer + headSize); 00438 00439 if (src) 00440 dataSize = static_cast<unsigned long>( 00441 storeData(image, dest, memSize - headSize)); 00442 00443 dest = (UChar8 *) (buffer + headSize + dataSize); 00444 00445 /* 00446 if(att != NullFC) 00447 { 00448 for(i = 0; i < (att->getType().getNumFieldDescs()-1); ++i) 00449 { 00450 FieldDescription *fieldDesc=att->getType().getFieldDescription(i); 00451 Field *field=att->getField(i); 00452 if (field && fieldDesc) 00453 { 00454 field->getValueByStr(value); 00455 00456 l = strlen( fieldDesc->getName().str() ); 00457 for (i = 0; i < l; i++) 00458 *dest++ = fieldDesc->getName().str()[i]; 00459 *dest++ = 0; 00460 l = value.length(); 00461 for (i = 0; i < l; i++) 00462 *dest++ = value[i]; 00463 *dest++ = 0; 00464 } 00465 else 00466 { 00467 FFATAL (("Invalid Attachment in ImageFileType::store()\n")); 00468 } 00469 } 00470 } 00471 */ 00472 00473 FDEBUG (( "Store image data: %lu (%lu/%lu/%lu)\n", 00474 headSize + dataSize + attachmentSize, headSize, dataSize, 00475 attachmentSize )); 00476 } 00477 else { 00478 FFATAL (("Invalid buffer in ImageFileType::store()\n")); 00479 } 00480 00481 return (headSize + dataSize + attachmentSize); 00482 00483 }
Returns the max buffer size needed to store the Image (Head + mimeType specific data block)
Definition at line 490 of file OSGImageFileType.cpp.
References FINFO.
Referenced by osg::ClusterViewBuffer::send(), and osg::ImageFileHandler::store().
00491 { 00492 std::string value; 00493 unsigned long size, attachmentSize; 00494 unsigned long imageSize = image->getSize(), headSize = sizeof(Head); 00495 00496 std::map<std::string, std::string>::const_iterator aI; 00497 00498 attachmentSize = 0; 00499 00500 // get attachment size 00501 /* 00502 ImageGenericAttPtr att=ImageGenericAttPtr::dcast( 00503 const_cast<Image*>(image.getCPtr())->findAttachment( 00504 ImageGenericAtt::getClassType().getGroupId())); 00505 if(att != NullFC) 00506 { 00507 for(i = 0; i < (att->getType().getNumFieldDescs()-1); ++i) 00508 { 00509 FieldDescription *fieldDesc=att->getType().getFieldDescription(i); 00510 Field *field=att->getField(i); 00511 if (field && fieldDesc) 00512 { 00513 field->getValueByStr(value); 00514 attachmentSize += strlen( fieldDesc->getName().str() ) + 1; 00515 attachmentSize += value.length() + 1; 00516 } 00517 else 00518 { 00519 FFATAL (("Invalid Attachment in ImageFileType::maxBufferSize()\n")); 00520 } 00521 } 00522 } 00523 */ 00524 00525 size = headSize + imageSize + attachmentSize; 00526 00527 FINFO (( "ImageFileType::maxBufferSize(): %lu (%lu/%lu/%lu)\n", 00528 size, headSize, imageSize, attachmentSize )); 00529 00530 return size; 00531 }
| void ImageFileType::dump | ( | void | ) | [inherited] |
The dump method just writes some object debugging info to the LOG stream
Definition at line 537 of file OSGImageFileType.cpp.
References osg::ImageFileType::_suffixList, osg::ImageFileType::getMimeType(), osg::LOG_DEBUG, and SLOG.
00538 { 00539 std::list<IDString>::iterator sI; 00540 00541 SLOG << getMimeType(); 00542 00543 if(_suffixList.empty()) 00544 { 00545 SLOG << ": Suffix: "; 00546 for(sI = _suffixList.begin(); sI != _suffixList.end(); sI++) 00547 { 00548 Log().stream(OSG::LOG_DEBUG) << sI->str() << " "; 00549 } 00550 } 00551 00552 std::cerr << std::endl; 00553 }
PNGImageFileType PNGImageFileType::_the [static, private] |
std::string osg::ImageFileType::_options [protected, inherited] |
Definition at line 182 of file OSGImageFileType.h.
Referenced by osg::ImageFileType::getOptions(), osg::ImageFileType::setOptions(), and osg::TIFImageFileType::write().
1.5.5