X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/8529b0b909e478f0cf43aaafb262d1913d87c824..4a2d030adfa836f6ada1830c9057170d053bcc64:/src/common/imagpng.cpp diff --git a/src/common/imagpng.cpp b/src/common/imagpng.cpp index 3472c5a1fc..5a27ca92f7 100644 --- a/src/common/imagpng.cpp +++ b/src/common/imagpng.cpp @@ -2,7 +2,6 @@ // Name: src/common/imagpng.cpp // Purpose: wxImage PNG handler // Author: Robert Roebling -// RCS-ID: $Id$ // Copyright: (c) Robert Roebling // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// @@ -43,7 +42,7 @@ // constants // ---------------------------------------------------------------------------- -// image can not have any transparent pixels at all, have only 100% opaque +// image cannot have any transparent pixels at all, have only 100% opaque // and/or 100% transparent pixels in which case a simple mask is enough to // store this information in wxImage or have a real alpha channel in which case // we need to have it in wxImage as well @@ -116,11 +115,9 @@ IMPLEMENT_DYNAMIC_CLASS(wxPNGHandler,wxImageHandler) // First, let me describe what's the problem: libpng uses jmp_buf in // its png_struct structure. Unfortunately, this structure is // compiler-specific and may vary in size, so if you use libpng compiled -// as DLL with another compiler than the main executable, it may not work -// (this is for example the case with wxMGL port and SciTech MGL library -// that provides custom runtime-loadable libpng implementation with jmpbuf -// disabled altogether). Luckily, it is still possible to use setjmp() & -// longjmp() as long as the structure is not part of png_struct. +// as DLL with another compiler than the main executable, it may not work. +// Luckily, it is still possible to use setjmp() & longjmp() as long as the +// structure is not part of png_struct. // // Sadly, there's no clean way to attach user-defined data to png_struct. // There is only one customizable place, png_struct.io_ptr, which is meant @@ -162,7 +159,7 @@ static void PNGLINKAGEMODE wx_PNG_stream_writer( png_structp png_ptr, png_bytep } static void -PNGLINKAGEMODE wx_png_warning(png_structp png_ptr, png_const_charp message) +PNGLINKAGEMODE wx_PNG_warning(png_structp png_ptr, png_const_charp message) { wxPNGInfoStruct *info = png_ptr ? WX_PNG_INFO(png_ptr) : NULL; if ( !info || info->verbose ) @@ -174,9 +171,9 @@ PNGLINKAGEMODE wx_png_warning(png_structp png_ptr, png_const_charp message) // from pngerror.c // so that the libpng doesn't send anything on stderr static void -PNGLINKAGEMODE wx_png_error(png_structp png_ptr, png_const_charp message) +PNGLINKAGEMODE wx_PNG_error(png_structp png_ptr, png_const_charp message) { - wx_png_warning(NULL, message); + wx_PNG_warning(NULL, message); // we're not using libpng built-in jump buffer (see comment before // wxPNGInfoStruct above) so we have to return ourselves, otherwise libpng @@ -523,8 +520,8 @@ wxPNGHandler::LoadFile(wxImage *image, ( PNG_LIBPNG_VER_STRING, NULL, - wx_png_error, - wx_png_warning + wx_PNG_error, + wx_PNG_warning ); if (!png_ptr) goto error; @@ -558,7 +555,7 @@ wxPNGHandler::LoadFile(wxImage *image, image->Create((int)width, (int)height, (bool) false /* no need to init pixels */); - if (!image->Ok()) + if (!image->IsOk()) goto error; // initialize all line pointers to NULL to ensure that they can be safely @@ -569,7 +566,7 @@ wxPNGHandler::LoadFile(wxImage *image, for (i = 0; i < height; i++) { - if ((lines[i] = (unsigned char *)malloc( (size_t)(width * (sizeof(unsigned char) * 4)))) == NULL) + if ((lines[i] = (unsigned char *)malloc( (size_t)(width * 4))) == NULL) goto error; } @@ -602,6 +599,47 @@ wxPNGHandler::LoadFile(wxImage *image, } #endif // wxUSE_PALETTE + + // set the image resolution if it's available + png_uint_32 resX, resY; + int unitType; + if (png_get_pHYs(png_ptr, info_ptr, &resX, &resY, &unitType) + == PNG_INFO_pHYs) + { + wxImageResolution res = wxIMAGE_RESOLUTION_CM; + + switch (unitType) + { + default: + wxLogWarning(_("Unknown PNG resolution unit %d"), unitType); + // fall through + + case PNG_RESOLUTION_UNKNOWN: + image->SetOption(wxIMAGE_OPTION_RESOLUTIONX, resX); + image->SetOption(wxIMAGE_OPTION_RESOLUTIONY, resY); + + res = wxIMAGE_RESOLUTION_NONE; + break; + + case PNG_RESOLUTION_METER: + /* + Convert meters to centimeters. + Use a string to not lose precision (converting to cm and then + to inch would result in integer rounding error). + If an app wants an int, GetOptionInt will convert and round + down for them. + */ + image->SetOption(wxIMAGE_OPTION_RESOLUTIONX, + wxString::FromCDouble((double) resX / 100.0, 2)); + image->SetOption(wxIMAGE_OPTION_RESOLUTIONY, + wxString::FromCDouble((double) resY / 100.0, 2)); + break; + } + + image->SetOption(wxIMAGE_OPTION_RESOLUTIONUNIT, res); + } + + png_destroy_read_struct( &png_ptr, &info_ptr, (png_infopp) NULL ); // loaded successfully, now init wxImage with this data @@ -619,7 +657,7 @@ error: wxLogError(_("Couldn't load a PNG image - file is corrupted or not enough memory.")); } - if ( image->Ok() ) + if ( image->IsOk() ) { image->Destroy(); } @@ -698,8 +736,8 @@ bool wxPNGHandler::SaveFile( wxImage *image, wxOutputStream& stream, bool verbos ( PNG_LIBPNG_VER_STRING, NULL, - wx_png_error, - wx_png_warning + wx_PNG_error, + wx_PNG_warning ); if (!png_ptr) { @@ -754,15 +792,13 @@ bool wxPNGHandler::SaveFile( wxImage *image, wxOutputStream& stream, bool verbos #endif ; - png_color_8 mask; + png_color_8 mask = { 0, 0, 0, 0, 0 }; if (bHasMask) { mask.red = image->GetMaskRed(); mask.green = image->GetMaskGreen(); mask.blue = image->GetMaskBlue(); - mask.alpha = 0; - mask.gray = 0; } PaletteMap palette;