Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

osg::PNGImageFileType Class Reference
[Image]

PNG File Handler. See Image for a detailed description. More...

#include <OSGPNGImageFileType.h>

Inheritance diagram for osg::PNGImageFileType:

osg::ImageFileType List of all members.

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)

Copy Constructor

typedef ImageFileType Inherited
PNGImageFileType (const PNGImageFileType &obj)
static PNGImageFileType _the

Public Member Functions

Destructor
*virtual ~PNGImageFileType (void)
Read/Write
*virtual bool read (ImagePtr &image, const Char8 *fileName)
virtual bool write (const ImagePtr &image, const Char8 *fileName)
virtual bool validateHeader (const Char8 *fileName, bool &implemented)
Buffer
*virtual UInt64 restoreData (ImagePtr &image, const UChar8 *buffer, Int32 memSize=-1)
virtual UInt64 storeData (const ImagePtr &image, UChar8 *buffer, Int32 memSize=-1)

Static Public Member Functions

Get Method
*static PNGImageFileTypethe (void)

Protected Member Functions

Default Constructor
PNGImageFileType (const Char8 *mimeType, const Char8 *suffixArray[], UInt16 suffixByteCount, UInt32 flags)

Detailed Description

Image File Type to read/write and store/restore Image objects as PNG data.

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 55 of file OSGPNGImageFileType.h.


Member Typedef Documentation

typedef ImageFileType osg::PNGImageFileType::Inherited [protected]
 

Definition at line 115 of file OSGPNGImageFileType.h.


Member Enumeration Documentation

anonymous enum [inherited]
 

Enumerator:
OSG_READ_SUPPORTED 
OSG_WRITE_SUPPORTED 

Definition at line 65 of file OSGImageFileType.h.

00066     {
00067         OSG_READ_SUPPORTED = 1,
00068         OSG_WRITE_SUPPORTED = 2
00069     };


Constructor & Destructor Documentation

PNGImageFileType::~PNGImageFileType void   )  [virtual]
 

Destructor

Definition at line 836 of file OSGPNGImageFileType.cpp.

00837 {
00838     return;
00839 }

PNGImageFileType::PNGImageFileType const Char8 mimeType,
const Char8 suffixArray[],
UInt16  suffixByteCount,
UInt32  flags
[protected]
 

Constructor used for the singleton object

Definition at line 812 of file OSGPNGImageFileType.cpp.

00815                                                    :
00816     ImageFileType(mimeType, suffixArray, suffixByteCount, flags)
00817 {
00818     return;
00819 }

PNGImageFileType::PNGImageFileType const PNGImageFileType obj  )  [protected]
 

Dummy Copy Constructor

Definition at line 825 of file OSGPNGImageFileType.cpp.

00825                                                               :
00826     ImageFileType(obj)
00827 {
00828     return;
00829 }


Member Function Documentation

bool PNGImageFileType::read ImagePtr image,
const Char8 fileName
[virtual]
 

Tries to fill the image object with the data read from the given fileName. Returns true on success.

Implements osg::ImageFileType.

Definition at line 139 of file OSGPNGImageFileType.cpp.

References 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, and SWARNING.

00141 {
00142 
00143 #ifdef OSG_WITH_PNG
00144 
00145     bool                retCode;
00146     Image::PixelFormat  pixelFormat = osg::Image::OSG_INVALID_PF;
00147     png_structp         png_ptr;
00148     png_infop           info_ptr;
00149     png_uint_32         width, wc, height, h, i;
00150     png_byte            bit_depth, channels, color_type;
00151     png_bytep           *row_pointers, base;
00152     FILE                *fd;
00153 
00154     if((fd = fopen(fileName, "rb")) == NULL)
00155         return false;
00156 
00157     png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
00158     if(!png_ptr)
00159     {
00160         fclose(fd);
00161         return false;
00162     }
00163 
00164     png_set_error_fn(png_ptr, 0, &errorOutput, &warningOutput);
00165 
00166     info_ptr = png_create_info_struct(png_ptr);
00167     if(!info_ptr)
00168     {
00169         fclose(fd);
00170         png_destroy_read_struct(&png_ptr, 0, 0);
00171         return false;
00172     }
00173 
00174     if(setjmp(png_ptr->jmpbuf))
00175     {
00176         png_destroy_read_struct(&png_ptr, &info_ptr, 0);
00177         fclose(fd);
00178         return false;
00179     }
00180 
00181     png_init_io(png_ptr, fd);
00182 
00183     png_read_info(png_ptr, info_ptr);
00184 
00185     width = png_get_image_width(png_ptr, info_ptr);
00186     height = png_get_image_height(png_ptr, info_ptr);
00187     bit_depth = png_get_bit_depth(png_ptr, info_ptr);
00188     channels = png_get_channels(png_ptr, info_ptr);
00189     color_type = png_get_color_type(png_ptr, info_ptr);
00190 
00191     // Convert paletted images to RGB
00192     if (color_type == PNG_COLOR_TYPE_PALETTE)
00193     {
00194       png_set_palette_to_rgb(png_ptr);
00195       channels = 3;
00196     }
00197 
00198     // Convert < 8 bit to 8 bit
00199     if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
00200       png_set_gray_1_2_4_to_8(png_ptr);
00201     
00202     // Add a full alpha channel if there is transparency
00203     // information in a tRNS chunk
00204     if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
00205     {
00206       png_set_tRNS_to_alpha(png_ptr);
00207       ++channels;
00208     }                                                                                
00209     // Convert 16 bit to 8 bit
00210     if (bit_depth == 16)
00211       png_set_strip_16(png_ptr);
00212 
00213     switch(channels)
00214     {
00215     case 1:
00216         pixelFormat = Image::OSG_L_PF;
00217         break;
00218     case 2:
00219         pixelFormat = Image::OSG_LA_PF;
00220         break;
00221     case 3:
00222         pixelFormat = Image::OSG_RGB_PF;
00223         break;
00224     case 4:
00225         pixelFormat = Image::OSG_RGBA_PF;
00226         break;
00227     };
00228 
00229     if(image->set(pixelFormat, width, height))
00230     {
00231         // Calculate the row pointers
00232         row_pointers = new png_bytep[height];
00233         wc = width * channels;
00234         h = height - 1;
00235         base = image->getData();
00236         for(i = 0; i < height; ++i)
00237             row_pointers[i] = base + (h - i) * wc;
00238 
00239         // Read the image data
00240         png_read_image(png_ptr, row_pointers);
00241 
00242         delete[] row_pointers;
00243 
00244         retCode = true;
00245     }
00246     else
00247         retCode = false;
00248 
00249     png_destroy_read_struct(&png_ptr, &info_ptr, 0);
00250 
00251     fclose(fd);
00252 
00253     return retCode;
00254 
00255 #else
00256 
00257     SWARNING <<
00258         getMimeType() <<
00259         " read is not compiled into the current binary " <<
00260         std::endl;
00261     return false;
00262 
00263 #endif
00264 
00265 }

bool PNGImageFileType::write const ImagePtr img,
const Char8 fileName
[virtual]
 

Tries to write the image object to the given fileName. Returns true on success. Based on the public domain example.c from the PNG dist.

Implements osg::ImageFileType.

Definition at line 273 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_RGB_PF, osg::Image::OSG_RGBA_PF, and SWARNING.

00275 {
00276 #ifdef OSG_WITH_PNG
00277 
00278     FILE *fp;
00279     png_structp png_ptr;
00280     png_infop info_ptr;
00281 
00282     if(img->getDimension() < 1 || img->getDimension() > 2)
00283     {
00284         FWARNING(("PNGImageFileType::write: invalid dimension %d!\n",
00285             img->getDimension()));
00286         return false;
00287     }
00288     
00289     /* open the file */
00290     fp = fopen(fileName, "wb");
00291     if (fp == NULL)
00292     {
00293         FWARNING(("PNGImageFileType::write: couldn't open %s for writing!\n",
00294             fileName));
00295         return false;
00296     }
00297 
00298     /* Create and initialize the png_struct with the desired error handler
00299     * functions.  If you want to use the default stderr and longjump method,
00300     * you can supply NULL for the last three parameters.  We also check that
00301     * the library version is compatible with the one used at compile time,
00302     * in case we are using dynamically linked libraries.  REQUIRED.
00303     */
00304     png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
00305                                 0, &errorOutput, &warningOutput);
00306 
00307     if (png_ptr == NULL)
00308     {
00309       fclose(fp);
00310       return false;
00311     }
00312 
00313     /* Allocate/initialize the image information data.  REQUIRED */
00314     info_ptr = png_create_info_struct(png_ptr);
00315     if (info_ptr == NULL)
00316     {
00317       fclose(fp);
00318       png_destroy_write_struct(&png_ptr,  NULL);
00319       return false;
00320     }
00321 
00322     /* set up the output control if you are using standard C streams */
00323     png_init_io(png_ptr, fp);
00324 
00325     /* This is the hard way */
00326 
00327     /* Set the image information here.  Width and height are up to 2^31,
00328     * bit_depth is one of 1, 2, 4, 8, or 16, but valid values also depend on
00329     * the color_type selected. color_type is one of PNG_COLOR_TYPE_GRAY,
00330     * PNG_COLOR_TYPE_GRAY_ALPHA, PNG_COLOR_TYPE_PALETTE, PNG_COLOR_TYPE_RGB,
00331     * or PNG_COLOR_TYPE_RGB_ALPHA.  interlace is either PNG_INTERLACE_NONE or
00332     * PNG_INTERLACE_ADAM7, and the compression_type and filter_type MUST
00333     * currently be PNG_COMPRESSION_TYPE_BASE and PNG_FILTER_TYPE_BASE. REQUIRED
00334     */
00335     Int32 ctype;
00336     switch(img->getPixelFormat())
00337     {
00338     case Image::OSG_L_PF:       ctype = PNG_COLOR_TYPE_GRAY;        
00339                                 break;
00340                                 
00341     case Image::OSG_LA_PF:      ctype = PNG_COLOR_TYPE_GRAY_ALPHA;          
00342                                 break;
00343                                 
00344 #if defined(GL_BGR) || defined(GL_BGR_EXT)
00345     case Image::OSG_BGR_PF:
00346 #endif
00347     case Image::OSG_RGB_PF:     ctype = PNG_COLOR_TYPE_RGB;                 
00348                                 break;
00349                                 
00350 #if defined(GL_BGRA) || defined(GL_BGRA_EXT)
00351     case Image::OSG_BGRA_PF:
00352 #endif
00353     case Image::OSG_RGBA_PF:    ctype = PNG_COLOR_TYPE_RGB_ALPHA;           
00354                                 break;
00355 
00356     default:
00357         FWARNING(("PNGImageFileType::write: unknown pixel format %d!\n",
00358             img->getPixelFormat()));
00359         png_destroy_write_struct(&png_ptr,  NULL);
00360         return false;
00361         
00362     }
00363     
00364     png_set_IHDR(png_ptr, info_ptr, img->getWidth(), img->getHeight(),
00365         8, ctype,      
00366         PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
00367 
00368 #if 0
00369     /* optional significant bit chunk */
00370     /* if we are dealing with a grayscale image then */
00371     sig_bit.gray = true_bit_depth;
00372     /* otherwise, if we are dealing with a color image then */
00373     sig_bit.red = true_red_bit_depth;
00374     sig_bit.green = true_green_bit_depth;
00375     sig_bit.blue = true_blue_bit_depth;
00376     /* if the image has an alpha channel then */
00377     sig_bit.alpha = true_alpha_bit_depth;
00378     png_set_sBIT(png_ptr, info_ptr, sig_bit);
00379 
00380 
00381     /* Optional gamma chunk is strongly suggested if you have any guess
00382     * as to the correct gamma of the image.
00383     */
00384     png_set_gAMA(png_ptr, info_ptr, gamma);
00385 
00386     /* Optionally write comments into the image */
00387     text_ptr[0].key = "Title";
00388     text_ptr[0].text = "Mona Lisa";
00389     text_ptr[0].compression = PNG_TEXT_COMPRESSION_NONE;
00390     text_ptr[1].key = "Author";
00391     text_ptr[1].text = "Leonardo DaVinci";
00392     text_ptr[1].compression = PNG_TEXT_COMPRESSION_NONE;
00393     text_ptr[2].key = "Description";
00394     text_ptr[2].text = "<long text>";
00395     text_ptr[2].compression = PNG_TEXT_COMPRESSION_zTXt;
00396 #ifdef PNG_iTXt_SUPPORTED
00397     text_ptr[0].lang = NULL;
00398     text_ptr[1].lang = NULL;
00399     text_ptr[2].lang = NULL;
00400 #endif
00401     png_set_text(png_ptr, info_ptr, text_ptr, 3);
00402 #endif
00403     /* other optional chunks like cHRM, bKGD, tRNS, tIME, oFFs, pHYs, */
00404     /* note that if sRGB is present the gAMA and cHRM chunks must be ignored
00405     * on read and must be written in accordance with the sRGB profile */
00406 
00407     /* Write the file header information.  REQUIRED */
00408     png_write_info(png_ptr, info_ptr);
00409 
00410 #if 0
00411     /* invert monochrome pixels */
00412     png_set_invert_mono(png_ptr);
00413 
00414     /* Shift the pixels up to a legal bit depth and fill in
00415     * as appropriate to correctly scale the image.
00416     */
00417     png_set_shift(png_ptr, &sig_bit);
00418 
00419     /* pack pixels into bytes */
00420     png_set_packing(png_ptr);
00421 
00422     /* Get rid of filler (OR ALPHA) bytes, pack XRGB/RGBX/ARGB/RGBA into
00423     * RGB (4 channels -> 3 channels). The second parameter is not used.
00424     */
00425     png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE);
00426 
00427     /* swap bytes of 16-bit files to most significant byte first */
00428     png_set_swap(png_ptr);
00429 
00430     /* swap bits of 1, 2, 4 bit packed pixel formats */
00431     png_set_packswap(png_ptr);
00432 #endif
00433 
00434     if(img->getPixelFormat() == Image::OSG_BGR_PF ||
00435        img->getPixelFormat() == Image::OSG_BGRA_PF
00436       )
00437     {
00438         /* flip BGR pixels to RGB */
00439         png_set_bgr(png_ptr);
00440 
00441         /* swap location of alpha bytes from ARGB to RGBA */
00442         png_set_swap_alpha(png_ptr);
00443     }
00444     
00445     /* The easiest way to write the image (you may have a different memory
00446     * layout, however, so choose what fits your needs best).  You need to
00447     * use the first method if you aren't handling interlacing yourself.
00448     */
00449     png_bytep *row_pointers = new png_bytep [img->getHeight()];
00450     
00451     for(Int32 k = 0; k < img->getHeight(); k++)
00452     {
00453         row_pointers[k] = img->getData() + 
00454                           (img->getHeight() - 1 - k) * 
00455                             img->getWidth() * img->getBpp();
00456     }
00457     
00458     /* write out the entire image data in one call */
00459     png_write_image(png_ptr, row_pointers);
00460 
00461     /* It is REQUIRED to call this to finish writing the rest of the file */
00462     png_write_end(png_ptr, info_ptr);
00463     
00464     /* clean up after the write, and free any memory allocated */
00465     png_destroy_write_struct(&png_ptr, &info_ptr);
00466 
00467     delete [] row_pointers;
00468 
00469     /* close the file */
00470     fclose(fp);
00471 
00472     /* that's it */
00473     return true;
00474 
00475 #else
00476     SWARNING <<
00477         getMimeType() <<
00478         " write is not compiled into the current binary " <<
00479         endLog;
00480     return false;
00481 #endif
00482 }

bool PNGImageFileType::validateHeader const Char8 fileName,
bool &  implemented
[virtual]
 

Tries to fill the image object with the data read from the given fileName. Returns true on success.

Reimplemented from osg::ImageFileType.

Definition at line 484 of file OSGPNGImageFileType.cpp.

00485 {
00486     implemented = true;
00487 
00488     if(fileName == NULL)
00489         return false;
00490 
00491     FILE *file = fopen(fileName, "rb");
00492     if(file == NULL)
00493         return false;
00494 
00495     std::string magic;
00496     magic.resize(4);
00497     fread((void *) &magic[0], 4, 1, file);
00498     fclose(file);
00499 
00500     if(magic == "\x89PNG")
00501     {
00502         return true;
00503     }
00504 
00505     return false;
00506 }

UInt64 PNGImageFileType::restoreData ImagePtr image,
const UChar8 buffer,
Int32  memSize = -1
[virtual]
 

Abstract restore method. Should be overwriten by a concrete derived class. Tries to restore the image data from the given memblock.

Reimplemented from osg::ImageFileType.

Definition at line 527 of file OSGPNGImageFileType.cpp.

References 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, and SWARNING.

00530 {
00531 #ifdef OSG_WITH_PNG
00532 
00533     UInt64              retCode;
00534     Image::PixelFormat  pixelFormat = osg::Image::OSG_INVALID_PF;
00535     png_structp         png_ptr;
00536     png_infop           info_ptr;
00537     png_uint_32         width, wc, height, h, i;
00538     png_byte            bit_depth, channels, color_type;
00539     png_bytep           *row_pointers, base;
00540 
00541     png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0);
00542     if(!png_ptr)
00543     {
00544         return 0;
00545     }
00546 
00547     png_set_error_fn(png_ptr, 0, &errorOutput, &warningOutput);
00548 
00549     info_ptr = png_create_info_struct(png_ptr);
00550     if(!info_ptr)
00551     {
00552         png_destroy_read_struct(&png_ptr, 0, 0);
00553         return 0;
00554     }
00555 
00556     if(setjmp(png_ptr->jmpbuf))
00557     {
00558         png_destroy_read_struct(&png_ptr, &info_ptr, 0);
00559         return 0;
00560     }
00561 
00562     BufferInfo bufferInfo;
00563     bufferInfo.buffer = (UChar8 *) buffer;
00564     bufferInfo.length = 0;
00565     png_set_read_fn(png_ptr, (void *) &bufferInfo, user_read_data);
00566 
00567     png_read_info(png_ptr, info_ptr);
00568 
00569     width = png_get_image_width(png_ptr, info_ptr);
00570     height = png_get_image_height(png_ptr, info_ptr);
00571     bit_depth = png_get_bit_depth(png_ptr, info_ptr);
00572     channels = png_get_channels(png_ptr, info_ptr);
00573     color_type = png_get_color_type(png_ptr, info_ptr);
00574 
00575     // Convert paletted images to RGB
00576     if (color_type == PNG_COLOR_TYPE_PALETTE)
00577     {
00578         png_set_palette_to_rgb(png_ptr);
00579         channels = 3;
00580     }
00581 
00582     // Convert < 8 bit to 8 bit
00583     if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
00584         png_set_gray_1_2_4_to_8(png_ptr);
00585     
00586     // Add a full alpha channel if there is transparency
00587     // information in a tRNS chunk
00588     if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
00589     {
00590         png_set_tRNS_to_alpha(png_ptr);
00591         ++channels;
00592     }                                                                                
00593     // Convert 16 bit to 8 bit
00594     if (bit_depth == 16)
00595         png_set_strip_16(png_ptr);
00596 
00597     switch(channels)
00598     {
00599     case 1:
00600         pixelFormat = Image::OSG_L_PF;
00601         break;
00602     case 2:
00603         pixelFormat = Image::OSG_LA_PF;
00604         break;
00605     case 3:
00606         pixelFormat = Image::OSG_RGB_PF;
00607         break;
00608     case 4:
00609         pixelFormat = Image::OSG_RGBA_PF;
00610         break;
00611     };
00612 
00613     if(image->set(pixelFormat, width, height))
00614     {
00615         // Calculate the row pointers
00616         row_pointers = new png_bytep[height];
00617         wc = width * channels;
00618         h = height - 1;
00619         base = image->getData();
00620         for(i = 0; i < height; ++i)
00621             row_pointers[i] = base + (h - i) * wc;
00622 
00623         // Read the image data
00624         png_read_image(png_ptr, row_pointers);
00625 
00626         delete[] row_pointers;
00627 
00628         retCode = bufferInfo.length;
00629     }
00630     else
00631         retCode = 0;
00632 
00633     png_destroy_read_struct(&png_ptr, &info_ptr, 0);
00634 
00635     return retCode;
00636 
00637 #else
00638     SWARNING <<
00639         getMimeType() <<
00640         " restoreData is not compiled into the current binary " <<
00641         std::endl;
00642     return 0;
00643 #endif
00644 }

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 668 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, and SWARNING.

00671 {
00672 #ifdef OSG_WITH_PNG
00673 
00674     png_structp png_ptr;
00675     png_infop info_ptr;
00676 
00677     if(image->getDimension() < 1 || image->getDimension() > 2)
00678     {
00679         FWARNING(("PNGImageFileType::write: invalid dimension %d!\n",
00680             image->getDimension()));
00681         return 0;
00682     }
00683 
00684     /* Create and initialize the png_struct with the desired error handler
00685     * functions.  If you want to use the default stderr and longjump method,
00686     * you can supply NULL for the last three parameters.  We also check that
00687     * the library version is compatible with the one used at compile time,
00688     * in case we are using dynamically linked libraries.  REQUIRED.
00689     */
00690     png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
00691                                 0, &errorOutput, &warningOutput);
00692 
00693     if (png_ptr == NULL)
00694     {
00695         return 0;
00696     }
00697 
00698     /* Allocate/initialize the image information data.  REQUIRED */
00699     info_ptr = png_create_info_struct(png_ptr);
00700     if (info_ptr == NULL)
00701     {
00702         png_destroy_write_struct(&png_ptr,  NULL);
00703         return 0;
00704     }
00705 
00706     BufferInfo bufferInfo;
00707     bufferInfo.buffer = buffer;
00708     bufferInfo.length = 0;
00709     png_set_write_fn(png_ptr, (void *) &bufferInfo, user_write_data, user_flush_data);
00710 
00711     /* This is the hard way */
00712 
00713     /* Set the image information here.  Width and height are up to 2^31,
00714     * bit_depth is one of 1, 2, 4, 8, or 16, but valid values also depend on
00715     * the color_type selected. color_type is one of PNG_COLOR_TYPE_GRAY,
00716     * PNG_COLOR_TYPE_GRAY_ALPHA, PNG_COLOR_TYPE_PALETTE, PNG_COLOR_TYPE_RGB,
00717     * or PNG_COLOR_TYPE_RGB_ALPHA.  interlace is either PNG_INTERLACE_NONE or
00718     * PNG_INTERLACE_ADAM7, and the compression_type and filter_type MUST
00719     * currently be PNG_COMPRESSION_TYPE_BASE and PNG_FILTER_TYPE_BASE. REQUIRED
00720     */
00721     Int32 ctype;
00722     switch(image->getPixelFormat())
00723     {
00724     case Image::OSG_L_PF:       ctype = PNG_COLOR_TYPE_GRAY;        
00725                                 break;
00726                                 
00727     case Image::OSG_LA_PF:      ctype = PNG_COLOR_TYPE_GRAY_ALPHA;          
00728                                 break;
00729                                 
00730 #if defined(GL_BGR) || defined(GL_BGR_EXT)
00731     case Image::OSG_BGR_PF:
00732 #endif
00733     case Image::OSG_RGB_PF:     ctype = PNG_COLOR_TYPE_RGB;                 
00734                                 break;
00735                                 
00736 #if defined(GL_BGRA) || defined(GL_BGRA_EXT)
00737     case Image::OSG_BGRA_PF:
00738 #endif
00739     case Image::OSG_RGBA_PF:    ctype = PNG_COLOR_TYPE_RGB_ALPHA;           
00740                                 break;
00741 
00742     default:
00743         FWARNING(("PNGImageFileType::write: unknown pixel format %d!\n",
00744             image->getPixelFormat()));
00745         png_destroy_write_struct(&png_ptr,  NULL);
00746         return false;
00747         
00748     }
00749     
00750     png_set_IHDR(png_ptr, info_ptr, image->getWidth(), image->getHeight(),
00751         8, ctype,      
00752         PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
00753 
00754     /* other optional chunks like cHRM, bKGD, tRNS, tIME, oFFs, pHYs, */
00755     /* note that if sRGB is present the gAMA and cHRM chunks must be ignored
00756     * on read and must be written in accordance with the sRGB profile */
00757 
00758     /* Write the file header information.  REQUIRED */
00759     png_write_info(png_ptr, info_ptr);
00760 
00761     if(image->getPixelFormat() == Image::OSG_BGR_PF ||
00762        image->getPixelFormat() == Image::OSG_BGRA_PF
00763       )
00764     {
00765         /* flip BGR pixels to RGB */
00766         png_set_bgr(png_ptr);
00767 
00768         /* swap location of alpha bytes from ARGB to RGBA */
00769         png_set_swap_alpha(png_ptr);
00770     }
00771     
00772     /* The easiest way to write the image (you may have a different memory
00773     * layout, however, so choose what fits your needs best).  You need to
00774     * use the first method if you aren't handling interlacing yourself.
00775     */
00776     png_bytep *row_pointers = new png_bytep [image->getHeight()];
00777     
00778     for(Int32 k = 0; k < image->getHeight(); k++)
00779     {
00780         row_pointers[k] = image->getData() + 
00781                           (image->getHeight() - 1 - k) * 
00782                             image->getWidth() * image->getBpp();
00783     }
00784     
00785     /* write out the entire image data in one call */
00786     png_write_image(png_ptr, row_pointers);
00787 
00788     /* It is REQUIRED to call this to finish writing the rest of the file */
00789     png_write_end(png_ptr, info_ptr);
00790     
00791     /* clean up after the write, and free any memory allocated */
00792     png_destroy_write_struct(&png_ptr, &info_ptr);
00793 
00794     delete [] row_pointers;
00795 
00796     /* that's it */
00797     return bufferInfo.length;
00798 
00799 #else
00800     SWARNING <<
00801         getMimeType() <<
00802         " storeData is not compiled into the current binary " <<
00803         std::endl;
00804     return 0;
00805 #endif
00806 }

PNGImageFileType & PNGImageFileType::the void   )  [static]
 

Definition at line 125 of file OSGPNGImageFileType.cpp.

References _the.

00126 {
00127   return _the;
00128 }

const Char8 * ImageFileType::getMimeType void   )  const [inherited]
 

Get method for the mime type

Definition at line 106 of file OSGImageFileType.cpp.

References osg::ImageFileType::_mimeType, and osg::IDString::str().

Referenced by osg::ImageFileType::dump(), osg::TIFImageFileType::read(), read(), osg::MNGImageFileType::read(), osg::JPGImageFileType::read(), osg::ImageFileHandler::read(), restoreData(), osg::JPGImageFileType::restoreData(), osg::ImageFileType::restoreData(), osg::ImageFileType::store(), osg::ImageFileHandler::store(), storeData(), osg::JPGImageFileType::storeData(), osg::ImageFileType::storeData(), osg::TIFImageFileType::write(), osg::TGAImageFileType::write(), write(), osg::MNGImageFileType::write(), osg::JPGImageFileType::write(), osg::ImageFileHandler::write(), osg::GIFImageFileType::write(), and osg::DDSImageFileType::write().

00107 {
00108     return _mimeType.str();
00109 }

const std::list< IDString > & ImageFileType::getSuffixList void   )  const [inherited]
 

Get method for the suffix list container

Definition at line 125 of file OSGImageFileType.cpp.

References osg::ImageFileType::_suffixList.

Referenced by osg::ImageFileHandler::addImageFileType().

00126 {
00127     return _suffixList; 
00128 }

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 116 of file OSGImageFileType.cpp.

References osg::ImageFileType::_flags.

Referenced by osg::ImageFileHandler::getSuffixList().

00117 {
00118     return _flags;
00119 }

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 223 of file OSGImageFileType.cpp.

References FDEBUG, FWARNING, osg::ImageFileHandler::getFileType(), osg::NullFC, osg::Image::OSG_UINT8_IMAGEDATA, osg::ImageFileType::restoreData(), and osg::ImageFileHandler::the().

Referenced by osg::ClusterViewBuffer::recv(), osg::ImageFileHandler::restore(), and osg::SimpleSceneManager::useOpenSGLogo().

00225 {
00226     unsigned long   imageSize, headSize = sizeof(Head);
00227     unsigned long   size = 0, attachmentSize;
00228     Head            head;
00229     const UChar8    *data = buffer ? (buffer + headSize) : 0;
00230     ImageFileType   *type;
00231     const char      *mimeType;
00232     Image::Type     dataType;
00233 
00234     if ((image != osg::NullFC) && buffer && (memSize >= headSize)) {
00235 
00236         // Copy header. Otherwise netToHost would change the original
00237         // data structur.
00238         memcpy(&head,buffer,sizeof(Head));
00239         head.netToHost();
00240         mimeType = head.mimeType;
00241         
00242         if((type = ImageFileHandler::the().getFileType(mimeType, 0)))
00243         {
00244             if (head.dataType)
00245               dataType = Image::Type(head.dataType);
00246             else
00247               dataType = Image::OSG_UINT8_IMAGEDATA;
00248 
00249             image->set(Image::PixelFormat(head.pixelFormat), head.width,
00250                        head.height, head.depth, head.mipmapCount,
00251                        head.frameCount, float(head.frameDelay) / 1000.0, 0,
00252                        dataType,true,head.sideCount );
00253             imageSize = static_cast<unsigned long>(
00254                 type->restoreData(image, data, memSize - headSize));
00255             attachmentSize = 0; // head->attachmentSize;
00256 
00257             /*
00258             if ((attachmentSize = head->attachmentSize))
00259             {
00260                 attData = (char*)(buffer + headSize + imageSize);
00261                 attKey = attData;
00262                 attValue = 0;
00263                 for (i = 0; i < (attachmentSize-1); i++) {
00264                     if (attData[i] == 0) 
00265                         if (attKey) {
00266                             attValue = &(attData[i+1]);
00267                             image->setAttachmentField (attKey,attValue);
00268                             attKey = attValue = 0;
00269                         }
00270                         else
00271                             attKey = &(attData[i+1]);
00272                 }
00273                 if (attKey || attValue) {
00274                     FFATAL (("Attachment restore error\n"));
00275                 }
00276             }
00277             */
00278 
00279             size = headSize + imageSize + attachmentSize;
00280       
00281             FDEBUG (( "Restore image data: %lu (%lu/%lu/%lu)\n",
00282                       size, headSize, imageSize, attachmentSize ));
00283 
00284         }
00285         else
00286         {
00287             imageSize = 0;
00288             FWARNING(("Can not restore image data, invalid mimeType: %s\n",
00289                       mimeType ? mimeType : "Unknown"));
00290         }
00291 
00292       
00293     }
00294 
00295     return size;
00296 }

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 304 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().

00306 {
00307   ImageFileType   *type = ImageFileHandler::the().getFileType(mimeType);
00308   
00309   return type ? type->store(image, buffer, memSize) : 0;
00310 }

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 318 of file OSGImageFileType.cpp.

References osg::ImageFileType::Head::attachmentSize, osg::ImageFileType::Head::dataType, osg::ImageFileType::Head::depth, FDEBUG, FFATAL, osg::ImageFileType::Head::frameCount, osg::ImageFileType::Head::frameDelay, osg::ImageFileType::getMimeType(), osg::ImageFileType::Head::height, osg::ImageFileType::Head::hostToNet(), osg::ImageFileType::Head::mimeType, osg::ImageFileType::Head::mipmapCount, osg::ImageFileType::Head::pixelFormat, osg::ImageFileType::Head::sideCount, osg::ImageFileType::storeData(), and osg::ImageFileType::Head::width.

00320 {
00321     Head            *head;
00322     unsigned long   dataSize = 0, headSize = sizeof(Head);
00323     unsigned long   attachmentSize;
00324     UChar8          *dest;
00325     const UChar8    *src = image->getData();
00326     std::map<std::string, std::string>::const_iterator aI;
00327     std::string     value;
00328 
00329     attachmentSize = 0;
00330 
00331     // get attachment size
00332     /*
00333     ImageGenericAttPtr att=ImageGenericAttPtr::dcast(
00334         const_cast<Image*>(image.getCPtr())->findAttachment(
00335             ImageGenericAtt::getClassType().getGroupId()));
00336     if(att != NullFC)
00337     {
00338         for(i = 0; i < (att->getType().getNumFieldDescs()-1); ++i)
00339         {
00340             FieldDescription *fieldDesc=att->getType().getFieldDescription(i);
00341             Field *field=att->getField(i);
00342             if (fieldDesc && field) 
00343             {
00344                 field->getValueByStr(value);
00345                 attachmentSize += strlen( fieldDesc->getName().str() ) + 1;
00346                 attachmentSize += value.length() + 1;
00347               
00348                 std::cout << fieldDesc->getName().str() << std::endl; 
00349                 std::cout << value << std::endl; 
00350             }
00351             else 
00352             {
00353                 FFATAL (("Invalid Attachment in ImageFileType::store()\n"));
00354             }
00355         }
00356     }
00357     */
00358 
00359     if (buffer) 
00360     {
00361         head = (Head *)buffer;
00362 
00363         head->pixelFormat    = image->getPixelFormat();
00364         head->width          = image->getWidth();
00365         head->height         = image->getHeight();
00366         head->depth          = image->getDepth();
00367         head->mipmapCount    = image->getMipMapCount();
00368         head->frameCount     = image->getFrameCount();
00369         head->frameDelay     = short(image->getFrameDelay() * 1000.0);
00370         head->sideCount      = image->getSideCount();
00371         head->dataType       = image->getDataType();
00372         head->attachmentSize = static_cast<unsigned short>(attachmentSize);
00373         head->hostToNet();
00374       
00375         strcpy(head->mimeType, getMimeType());
00376       
00377         dest = (UChar8 *) (buffer + headSize);
00378 
00379         if (src) 
00380             dataSize = static_cast<unsigned long>(
00381                 storeData(image, dest, memSize - headSize));
00382 
00383         dest = (UChar8 *) (buffer + headSize + dataSize);
00384 
00385         /*
00386         if(att != NullFC)
00387         {
00388             for(i = 0; i < (att->getType().getNumFieldDescs()-1); ++i)
00389             {
00390                 FieldDescription *fieldDesc=att->getType().getFieldDescription(i);
00391                 Field *field=att->getField(i);
00392                 if (field && fieldDesc) 
00393                 {
00394                     field->getValueByStr(value);
00395 
00396                     l = strlen( fieldDesc->getName().str() );
00397                     for (i = 0; i < l; i++)
00398                       *dest++ = fieldDesc->getName().str()[i];
00399                     *dest++ = 0;
00400                     l = value.length();
00401                     for (i = 0; i < l; i++)
00402                       *dest++ = value[i];
00403                     *dest++ = 0;
00404                 }
00405                 else
00406                 {
00407                     FFATAL (("Invalid Attachment in ImageFileType::store()\n"));
00408                 }
00409             }
00410         }
00411         */
00412 
00413         FDEBUG (( "Store image data: %lu (%lu/%lu/%lu)\n",
00414                   headSize + dataSize + attachmentSize, headSize, dataSize, 
00415                   attachmentSize ));
00416     }
00417     else {
00418         FFATAL (("Invalid buffer in ImageFileType::store()\n"));
00419     }
00420   
00421     return (headSize + dataSize + attachmentSize);
00422 
00423 }

UInt64 ImageFileType::maxBufferSize const ImagePtr image  )  [virtual, inherited]
 

Returns the max buffer size needed to store the Image (Head + mimeType specific data block)

Definition at line 430 of file OSGImageFileType.cpp.

References FINFO.

Referenced by osg::ClusterViewBuffer::send(), and osg::ImageFileHandler::store().

00431 {
00432     std::string value;
00433     unsigned long size, attachmentSize;
00434     unsigned long imageSize = image->getSize(), headSize = sizeof(Head);
00435 
00436     std::map<std::string, std::string>::const_iterator aI;
00437 
00438     attachmentSize = 0;
00439 
00440     // get attachment size
00441         /*
00442     ImageGenericAttPtr att=ImageGenericAttPtr::dcast(
00443         const_cast<Image*>(image.getCPtr())->findAttachment(
00444             ImageGenericAtt::getClassType().getGroupId()));
00445     if(att != NullFC)
00446     {
00447         for(i = 0; i < (att->getType().getNumFieldDescs()-1); ++i)
00448         {
00449             FieldDescription *fieldDesc=att->getType().getFieldDescription(i);
00450             Field *field=att->getField(i);
00451             if (field && fieldDesc) 
00452             {
00453                 field->getValueByStr(value);
00454                 attachmentSize += strlen( fieldDesc->getName().str() ) + 1;
00455                 attachmentSize += value.length() + 1;
00456             }
00457             else 
00458             {
00459                 FFATAL (("Invalid Attachment in ImageFileType::maxBufferSize()\n"));
00460             }
00461         }
00462     }
00463         */
00464 
00465     size = headSize + imageSize + attachmentSize;
00466   
00467     FINFO (( "ImageFileType::maxBufferSize(): %lu (%lu/%lu/%lu)\n", 
00468              size, headSize, imageSize, attachmentSize ));
00469   
00470     return size;
00471 }

void ImageFileType::dump void   )  [inherited]
 

The dump method just writes some object debugging info to the LOG stream

Definition at line 477 of file OSGImageFileType.cpp.

References osg::ImageFileType::_suffixList, osg::ImageFileType::getMimeType(), osg::LOG_DEBUG, and SLOG.

00478 {
00479     std::list<IDString>::iterator    sI;
00480 
00481     SLOG << getMimeType();
00482 
00483     if(_suffixList.empty())
00484     {
00485         SLOG << ": Suffix: ";
00486         for(sI = _suffixList.begin(); sI != _suffixList.end(); sI++)
00487         {
00488             Log().stream(OSG::LOG_DEBUG) << sI->str() << " ";
00489         }
00490     }
00491 
00492     std::cerr << std::endl;
00493 }


Member Data Documentation

PNGImageFileType PNGImageFileType::_the [static, protected]
 

Referenced by the().


The documentation for this class was generated from the following files:
Generated on Thu Aug 25 04:14:23 2005 for OpenSG by  doxygen 1.4.3