added support for image resolution options to PNG handler (heavily modified patch 1704128)

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@45567 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2007-04-21 19:29:01 +00:00
parent defde6bc66
commit 361f4288eb
4 changed files with 84 additions and 28 deletions

View File

@@ -37,9 +37,17 @@
#define wxIMAGE_OPTION_RESOLUTIONUNIT wxString(_T("ResolutionUnit")) #define wxIMAGE_OPTION_RESOLUTIONUNIT wxString(_T("ResolutionUnit"))
// constants used with wxIMAGE_OPTION_RESOLUTIONUNIT // constants used with wxIMAGE_OPTION_RESOLUTIONUNIT
enum //
// NB: don't change these values, they correspond to libjpeg constants
enum wxImageResolution
{ {
// Resolution not specified
wxIMAGE_RESOLUTION_NONE = 0,
// Resolution specified in inches
wxIMAGE_RESOLUTION_INCHES = 1, wxIMAGE_RESOLUTION_INCHES = 1,
// Resolution specified in centimeters
wxIMAGE_RESOLUTION_CM = 2 wxIMAGE_RESOLUTION_CM = 2
}; };
@@ -112,6 +120,13 @@ protected:
bool CallDoCanRead(wxInputStream& stream); bool CallDoCanRead(wxInputStream& stream);
#endif // wxUSE_STREAMS #endif // wxUSE_STREAMS
// helper for the derived classes SaveFile() implementations: returns the
// values of x- and y-resolution options specified as the image options if
// any
static wxImageResolution
GetResolutionFromOptions(const wxImage& image, int *x, int *y);
wxString m_name; wxString m_name;
wxString m_extension; wxString m_extension;
wxString m_mime; wxString m_mime;

View File

@@ -2645,6 +2645,42 @@ bool wxImageHandler::CallDoCanRead(wxInputStream& stream)
#endif // wxUSE_STREAMS #endif // wxUSE_STREAMS
/* static */
wxImageResolution
wxImageHandler::GetResolutionFromOptions(const wxImage& image, int *x, int *y)
{
wxCHECK_MSG( x && y, wxIMAGE_RESOLUTION_NONE, _T("NULL pointer") );
if ( image.HasOption(wxIMAGE_OPTION_RESOLUTIONX) &&
image.HasOption(wxIMAGE_OPTION_RESOLUTIONY) )
{
*x = image.GetOptionInt(wxIMAGE_OPTION_RESOLUTIONX);
*y = image.GetOptionInt(wxIMAGE_OPTION_RESOLUTIONY);
}
else if ( image.HasOption(wxIMAGE_OPTION_RESOLUTION) )
{
*x =
*y = image.GetOptionInt(wxIMAGE_OPTION_RESOLUTION);
}
else // no resolution options specified
{
*x =
*y = 0;
return wxIMAGE_RESOLUTION_NONE;
}
// get the resolution unit too
int resUnit = image.GetOptionInt(wxIMAGE_OPTION_RESOLUTIONUNIT);
if ( !resUnit )
{
// this is the default
resUnit = wxIMAGE_RESOLUTION_INCHES;
}
return (wxImageResolution)resUnit;
}
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// image histogram stuff // image histogram stuff
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------

View File

@@ -414,37 +414,16 @@ bool wxJPEGHandler::SaveFile( wxImage *image, wxOutputStream& stream, bool verbo
jpeg_set_quality(&cinfo, image->GetOptionInt(wxIMAGE_OPTION_QUALITY), TRUE); jpeg_set_quality(&cinfo, image->GetOptionInt(wxIMAGE_OPTION_QUALITY), TRUE);
// set the resolution fields in the output file // set the resolution fields in the output file
UINT16 resX, int resX, resY;
resY; wxImageResolution res = GetResolutionFromOptions(*image, &resX, &resY);
if ( image->HasOption(wxIMAGE_OPTION_RESOLUTIONX) && if ( res != wxIMAGE_RESOLUTION_NONE )
image->HasOption(wxIMAGE_OPTION_RESOLUTIONY) )
{
resX = (UINT16)image->GetOptionInt(wxIMAGE_OPTION_RESOLUTIONX);
resY = (UINT16)image->GetOptionInt(wxIMAGE_OPTION_RESOLUTIONY);
}
else if ( image->HasOption(wxIMAGE_OPTION_RESOLUTION) )
{
resX =
resY = (UINT16)image->GetOptionInt(wxIMAGE_OPTION_RESOLUTION);
}
else
{
resX =
resY = 0;
}
if ( resX && resY )
{ {
cinfo.X_density = resX; cinfo.X_density = resX;
cinfo.Y_density = resY; cinfo.Y_density = resY;
}
// sets the resolution unit field in the output file // it so happens that wxIMAGE_RESOLUTION_INCHES/CM values are the same
// wxIMAGE_RESOLUTION_INCHES for inches // ones as used by libjpeg, so we can assign them directly
// wxIMAGE_RESOLUTION_CM for centimeters cinfo.density_unit = res;
if ( image->HasOption(wxIMAGE_OPTION_RESOLUTIONUNIT) )
{
cinfo.density_unit = (UINT8)image->GetOptionInt(wxIMAGE_OPTION_RESOLUTIONUNIT);
} }
jpeg_start_compress(&cinfo, TRUE); jpeg_start_compress(&cinfo, TRUE);

View File

@@ -63,6 +63,8 @@ enum Transparency
Transparency_Alpha Transparency_Alpha
}; };
static const double INCHES_IN_METER = 39.3700787;
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// local functions // local functions
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@@ -748,6 +750,30 @@ bool wxPNGHandler::SaveFile( wxImage *image, wxOutputStream& stream, bool verbos
if ( iBitDepth == 16 ) if ( iBitDepth == 16 )
iElements *= 2; iElements *= 2;
// save the image resolution if we have it
int resX, resY;
switch ( GetResolutionFromOptions(*image, &resX, &resY) )
{
case wxIMAGE_RESOLUTION_INCHES:
resX *= INCHES_IN_METER;
resY *= INCHES_IN_METER;
break;
case wxIMAGE_RESOLUTION_CM:
resX *= 100;
resY *= 100;
break;
case wxIMAGE_RESOLUTION_NONE:
break;
default:
wxFAIL_MSG( _T("unsupported image resolution units") );
}
if ( resX && resY )
png_set_pHYs( png_ptr, info_ptr, resX, resY, PNG_RESOLUTION_METER );
png_set_sBIT( png_ptr, info_ptr, &sig_bit ); png_set_sBIT( png_ptr, info_ptr, &sig_bit );
png_write_info( png_ptr, info_ptr ); png_write_info( png_ptr, info_ptr );
png_set_shift( png_ptr, &sig_bit ); png_set_shift( png_ptr, &sig_bit );