add some wxIMAGE_OPTION_PNG_xxx options to wxImage and wxPNGHandler to allow the user to set the desired compression level (closes #10372)

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@58103 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Francesco Montorsi
2009-01-14 17:54:38 +00:00
parent 09ddabf738
commit d19ce8c491
4 changed files with 97 additions and 15 deletions

View File

@@ -22,6 +22,11 @@
#define wxIMAGE_OPTION_PNG_FORMAT wxT("PngFormat") #define wxIMAGE_OPTION_PNG_FORMAT wxT("PngFormat")
#define wxIMAGE_OPTION_PNG_BITDEPTH wxT("PngBitDepth") #define wxIMAGE_OPTION_PNG_BITDEPTH wxT("PngBitDepth")
#define wxIMAGE_OPTION_PNG_FILTER wxT("PngF")
#define wxIMAGE_OPTION_PNG_COMPRESSION_LEVEL wxT("PngZL")
#define wxIMAGE_OPTION_PNG_COMPRESSION_MEM_LEVEL wxT("PngZM")
#define wxIMAGE_OPTION_PNG_COMPRESSION_STRATEGY wxT("PngZS")
#define wxIMAGE_OPTION_PNG_COMPRESSION_BUFFER_SIZE wxT("PngZB")
enum enum
{ {

View File

@@ -783,16 +783,16 @@ public:
Gets a user-defined string-valued option. Gets a user-defined string-valued option.
Currently the only defined string option is Currently the only defined string option is
@li wxIMAGE_OPTION_FILENAME: The name of the file from which the image @li @c wxIMAGE_OPTION_FILENAME: The name of the file from which the image
was loaded. was loaded.
@see SetOption(), GetOptionInt(), HasOption()
@param name @param name
The name of the option, case-insensitive. The name of the option, case-insensitive.
@return @return
The value of the option or an empty string if not found. Use The value of the option or an empty string if not found. Use
HasOption() if an empty string can be a valid option value. HasOption() if an empty string can be a valid option value.
@see SetOption(), GetOptionInt(), HasOption()
*/ */
wxString GetOption(const wxString& name) const; wxString GetOption(const wxString& name) const;
@@ -804,7 +804,7 @@ public:
Use HasOption() is 0 is a possibly valid value for the option. Use HasOption() is 0 is a possibly valid value for the option.
Generic options: Generic options:
@li wxIMAGE_OPTION_MAX_WIDTH and wxIMAGE_OPTION_MAX_HEIGHT: If either @li @c wxIMAGE_OPTION_MAX_WIDTH and @c wxIMAGE_OPTION_MAX_HEIGHT: If either
of these options is specified, the loaded image will be scaled down of these options is specified, the loaded image will be scaled down
(preserving its aspect ratio) so that its width is less than the (preserving its aspect ratio) so that its width is less than the
max width given if it is not 0 @em and its height is less than the max width given if it is not 0 @em and its height is less than the
@@ -817,18 +817,18 @@ public:
handler, this is still what happens however). These options must be handler, this is still what happens however). These options must be
set before calling LoadFile() to have any effect. set before calling LoadFile() to have any effect.
@li wxIMAGE_OPTION_QUALITY: JPEG quality used when saving. This is an @li @c wxIMAGE_OPTION_QUALITY: JPEG quality used when saving. This is an
integer in 0..100 range with 0 meaning very poor and 100 excellent integer in 0..100 range with 0 meaning very poor and 100 excellent
(but very badly compressed). This option is currently ignored for (but very badly compressed). This option is currently ignored for
the other formats. the other formats.
@li wxIMAGE_OPTION_RESOLUTIONUNIT: The value of this option determines @li @c wxIMAGE_OPTION_RESOLUTIONUNIT: The value of this option determines
whether the resolution of the image is specified in centimetres or whether the resolution of the image is specified in centimetres or
inches, see wxImageResolution enum elements. inches, see wxImageResolution enum elements.
@li wxIMAGE_OPTION_RESOLUTION, wxIMAGE_OPTION_RESOLUTIONX and @li @c wxIMAGE_OPTION_RESOLUTION, @c wxIMAGE_OPTION_RESOLUTIONX and
wxIMAGE_OPTION_RESOLUTIONY: These options define the resolution of @c wxIMAGE_OPTION_RESOLUTIONY: These options define the resolution of
the image in the units corresponding to wxIMAGE_OPTION_RESOLUTIONUNIT the image in the units corresponding to @c wxIMAGE_OPTION_RESOLUTIONUNIT
options value. The first option can be set before saving the image options value. The first option can be set before saving the image
to set both horizontal and vertical resolution to the same value. to set both horizontal and vertical resolution to the same value.
The X and Y options are set by the image handlers if they support The X and Y options are set by the image handlers if they support
@@ -837,17 +837,36 @@ public:
after loading the image. after loading the image.
Options specific to wxPNGHandler: Options specific to wxPNGHandler:
@li wxIMAGE_OPTION_PNG_FORMAT: Format for saving a PNG file, see @li @c wxIMAGE_OPTION_PNG_FORMAT: Format for saving a PNG file, see
wxImagePNGType for the supported values. wxImagePNGType for the supported values.
@li wxIMAGE_OPTION_PNG_BITDEPTH: Bit depth for every channel (R/G/B/A). @li @c wxIMAGE_OPTION_PNG_BITDEPTH: Bit depth for every channel (R/G/B/A).
@li @c wxIMAGE_OPTION_PNG_FILTER: Filter for saving a PNG file, see libpng
@see SetOption(), GetOption() (http://www.libpng.org/pub/png/libpng-1.2.5-manual.html) for possible values
(e.g. PNG_FILTER_NONE, PNG_FILTER_SUB, PNG_FILTER_UP, etc).
@li @c wxIMAGE_OPTION_PNG_COMPRESSION_LEVEL: Compression level (0..9) for
saving a PNG file. An high value creates smaller-but-slower PNG file.
Note that unlike other formats (e.g. JPEG) the PNG format is always
lossless and thus this compression level doesn't tradeoff the image
quality.
@li @c wxIMAGE_OPTION_PNG_COMPRESSION_MEM_LEVEL: Compression memory usage
level (1..9) for saving a PNG file. An high value means the saving
process consumes more memory, but may create smaller PNG file.
@li @c wxIMAGE_OPTION_PNG_COMPRESSION_STRATEGY: Possible values are 0 for
default strategy, 1 for filter, and 2 for Huffman-only.
You can use OptiPNG (http://optipng.sourceforge.net/) to get a suitable
value for your application.
@li @c wxIMAGE_OPTION_PNG_COMPRESSION_BUFFER_SIZE: Internal buffer size
(in bytes) for saving a PNG file. Ideally this should be as big as
the resulting PNG file. Use this option if your application produces
images with small size variation.
@param name @param name
The name of the option, case-insensitive. The name of the option, case-insensitive.
@return @return
The value of the option or 0 if not found. Use HasOption() if 0 The value of the option or 0 if not found.
can be a valid option value. Use HasOption() if 0 can be a valid option value.
@see SetOption(), GetOption()
*/ */
int GetOptionInt(const wxString& name) const; int GetOptionInt(const wxString& name) const;
@@ -923,6 +942,9 @@ public:
Returns @true if the given option is present. Returns @true if the given option is present.
The function is case-insensitive to @a name. The function is case-insensitive to @a name.
The lists of the currently supported options are in GetOption() and
GetOptionInt() function docs.
@see SetOption(), GetOption(), GetOptionInt() @see SetOption(), GetOption(), GetOptionInt()
*/ */
bool HasOption(const wxString& name) const; bool HasOption(const wxString& name) const;
@@ -1373,6 +1395,9 @@ public:
For example, when saving as a JPEG file, the option @b quality is For example, when saving as a JPEG file, the option @b quality is
used, which is a number between 0 and 100 (0 is terrible, 100 is very good). used, which is a number between 0 and 100 (0 is terrible, 100 is very good).
The lists of the currently supported options are in GetOption() and
GetOptionInt() function docs.
@see GetOption(), GetOptionInt(), HasOption() @see GetOption(), GetOptionInt(), HasOption()
*/ */
void SetOption(const wxString& name, const wxString& value); void SetOption(const wxString& name, const wxString& value);

View File

@@ -268,6 +268,43 @@ public:
{ {
image.SetOption(wxIMAGE_OPTION_PNG_FORMAT, pngvalues[sel]); image.SetOption(wxIMAGE_OPTION_PNG_FORMAT, pngvalues[sel]);
image.SetOption(wxIMAGE_OPTION_PNG_BITDEPTH, sel % 2 ? 16 : 8); image.SetOption(wxIMAGE_OPTION_PNG_BITDEPTH, sel % 2 ? 16 : 8);
// these values are taken from OptiPNG with -o3 switch
const wxString compressionChoices[] =
{
_T("compression = 9, memory = 8, strategy = 0, filter = 0"),
_T("compression = 9, memory = 9, strategy = 0, filter = 0"),
_T("compression = 9, memory = 8, strategy = 1, filter = 0"),
_T("compression = 9, memory = 9, strategy = 1, filter = 0"),
_T("compression = 1, memory = 8, strategy = 2, filter = 0"),
_T("compression = 1, memory = 9, strategy = 2, filter = 0"),
_T("compression = 9, memory = 8, strategy = 0, filter = 5"),
_T("compression = 9, memory = 9, strategy = 0, filter = 5"),
_T("compression = 9, memory = 8, strategy = 1, filter = 5"),
_T("compression = 9, memory = 9, strategy = 1, filter = 5"),
_T("compression = 1, memory = 8, strategy = 2, filter = 5"),
_T("compression = 1, memory = 9, strategy = 2, filter = 5"),
};
int sel = wxGetSingleChoiceIndex(_T("Select compression option (Cancel to use default)\n"),
_T("PNG Compression Options"),
WXSIZEOF(compressionChoices),
compressionChoices,
this);
if (sel != -1)
{
const int zc[] = {9, 9, 9, 9, 1, 1, 9, 9, 9, 9, 1, 1};
const int zm[] = {8, 9, 8, 9, 8, 9, 8, 9, 8, 9, 8, 9};
const int zs[] = {0, 0, 1, 1, 2, 2, 0, 0, 1, 1, 2, 2};
const int f[] = {0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8};
image.SetOption(wxIMAGE_OPTION_PNG_COMPRESSION_LEVEL , zc[sel]);
image.SetOption(wxIMAGE_OPTION_PNG_COMPRESSION_MEM_LEVEL , zm[sel]);
image.SetOption(wxIMAGE_OPTION_PNG_COMPRESSION_STRATEGY , zs[sel]);
image.SetOption(wxIMAGE_OPTION_PNG_FILTER , f[sel]);
image.SetOption(wxIMAGE_OPTION_PNG_COMPRESSION_BUFFER_SIZE, 1048576); // 1 MB
}
} }
} }
else if ( extension == _T("cur") ) else if ( extension == _T("cur") )

View File

@@ -710,6 +710,21 @@ bool wxPNGHandler::SaveFile( wxImage *image, wxOutputStream& stream, bool verbos
: PNG_COLOR_TYPE_GRAY; : PNG_COLOR_TYPE_GRAY;
} }
if (image->HasOption(wxIMAGE_OPTION_PNG_FILTER))
png_set_filter( png_ptr, PNG_FILTER_TYPE_BASE, image->GetOptionInt(wxIMAGE_OPTION_PNG_FILTER) );
if (image->HasOption(wxIMAGE_OPTION_PNG_COMPRESSION_LEVEL))
png_set_compression_level( png_ptr, image->GetOptionInt(wxIMAGE_OPTION_PNG_COMPRESSION_LEVEL) );
if (image->HasOption(wxIMAGE_OPTION_PNG_COMPRESSION_MEM_LEVEL))
png_set_compression_mem_level( png_ptr, image->GetOptionInt(wxIMAGE_OPTION_PNG_COMPRESSION_MEM_LEVEL) );
if (image->HasOption(wxIMAGE_OPTION_PNG_COMPRESSION_STRATEGY))
png_set_compression_strategy( png_ptr, image->GetOptionInt(wxIMAGE_OPTION_PNG_COMPRESSION_STRATEGY) );
if (image->HasOption(wxIMAGE_OPTION_PNG_COMPRESSION_BUFFER_SIZE))
png_set_compression_buffer_size( png_ptr, image->GetOptionInt(wxIMAGE_OPTION_PNG_COMPRESSION_BUFFER_SIZE) );
png_set_IHDR( png_ptr, info_ptr, image->GetWidth(), image->GetHeight(), png_set_IHDR( png_ptr, info_ptr, image->GetWidth(), image->GetHeight(),
iBitDepth, iPngColorType, iBitDepth, iPngColorType,
PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE,