Added option wxIMAGE_OPTION_TIFF_PHOTOMETRIC for reading and writing TIFF images. This is mostly for being able to distinguish between PHOTOMETRIC_MINISBLACK (chocolate flavour) and PHOTOMETRIC_MINISWHITE (vanilla) as currently the flavour used was fixed. It applies to greyscale as well as black and white images. Added unit tests to verify the written photometric value.
Also see #13194.
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@68785
c3d73ce0-8a6f-49c7-b76d-
6d57e0e08775
#define wxIMAGE_OPTION_TIFF_BITSPERSAMPLE wxString(wxT("BitsPerSample"))
#define wxIMAGE_OPTION_TIFF_SAMPLESPERPIXEL wxString(wxT("SamplesPerPixel"))
#define wxIMAGE_OPTION_TIFF_COMPRESSION wxString(wxT("Compression"))
#define wxIMAGE_OPTION_TIFF_BITSPERSAMPLE wxString(wxT("BitsPerSample"))
#define wxIMAGE_OPTION_TIFF_SAMPLESPERPIXEL wxString(wxT("SamplesPerPixel"))
#define wxIMAGE_OPTION_TIFF_COMPRESSION wxString(wxT("Compression"))
+#define wxIMAGE_OPTION_TIFF_PHOTOMETRIC wxString(wxT("Photometric"))
#define wxIMAGE_OPTION_TIFF_IMAGEDESCRIPTOR wxString(wxT("ImageDescriptor"))
// for backwards compatibility
#define wxIMAGE_OPTION_TIFF_IMAGEDESCRIPTOR wxString(wxT("ImageDescriptor"))
// for backwards compatibility
+ image->SetOption(wxIMAGE_OPTION_TIFF_PHOTOMETRIC, photometric);
+
uint16 spp, bps, compression;
/*
Read some baseline TIFF tags which helps when re-saving a TIFF
uint16 spp, bps, compression;
/*
Read some baseline TIFF tags which helps when re-saving a TIFF
+ int photometric = PHOTOMETRIC_RGB;
+
+ if ( image->HasOption(wxIMAGE_OPTION_TIFF_PHOTOMETRIC) )
+ {
+ photometric = image->GetOptionInt(wxIMAGE_OPTION_TIFF_PHOTOMETRIC);
+ if (photometric == PHOTOMETRIC_MINISWHITE
+ || photometric == PHOTOMETRIC_MINISBLACK)
+ {
+ // either b/w or greyscale
+ spp = 1;
+ }
+ }
+ else if (spp == 1)
+ {
+ photometric = PHOTOMETRIC_MINISBLACK;
+ }
+
+ const bool isColouredImage = (spp > 1)
+ && (photometric != PHOTOMETRIC_MINISWHITE)
+ && (photometric != PHOTOMETRIC_MINISBLACK);
+
int compression = image->GetOptionInt(wxIMAGE_OPTION_TIFF_COMPRESSION);
if ( !compression )
{
int compression = image->GetOptionInt(wxIMAGE_OPTION_TIFF_COMPRESSION);
if ( !compression )
{
TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, spp);
TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, bps);
TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, spp);
TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, bps);
- TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, spp*bps == 1 ? PHOTOMETRIC_MINISBLACK
- : PHOTOMETRIC_RGB);
+ TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, photometric);
TIFFSetField(tif, TIFFTAG_COMPRESSION, compression);
// scanlinesize if determined by spp and bps
TIFFSetField(tif, TIFFTAG_COMPRESSION, compression);
// scanlinesize if determined by spp and bps
- if (TIFFScanlineSize(tif) > linebytes || (spp * bps < 24))
+ if (TIFFScanlineSize(tif) > linebytes || !isColouredImage)
{
buf = (unsigned char *)_TIFFmalloc(TIFFScanlineSize(tif));
if (!buf)
{
buf = (unsigned char *)_TIFFmalloc(TIFFScanlineSize(tif));
if (!buf)
TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP,TIFFDefaultStripSize(tif, (uint32) -1));
TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP,TIFFDefaultStripSize(tif, (uint32) -1));
+ const bool minIsWhite = (photometric == PHOTOMETRIC_MINISWHITE);
unsigned char *ptr = image->GetData();
for ( int row = 0; row < image->GetHeight(); row++ )
{
if ( buf )
{
unsigned char *ptr = image->GetData();
for ( int row = 0; row < image->GetHeight(); row++ )
{
if ( buf )
{
{
// color image
memcpy(buf, ptr, image->GetWidth());
{
// color image
memcpy(buf, ptr, image->GetWidth());
{
for ( int column = 0; column < linebytes; column++ )
{
{
for ( int column = 0; column < linebytes; column++ )
{
- buf[column] = ptr[column*3 + 1];
+ uint8 value = ptr[column*3 + 1];
+ if (minIsWhite)
+ {
+ value = 255 - value;
+ }
+
+ buf[column] = value;
}
}
else // black and white image
}
}
else // black and white image
uint8 reverse = 0;
for ( int bp = 0; bp < 8; bp++ )
{
uint8 reverse = 0;
for ( int bp = 0; bp < 8; bp++ )
{
- if ( ptr[column*24 + bp*3 + 1] > 127 )
+ if ( (ptr[column*24 + bp*3 + 1] <=127) == minIsWhite )
{
// check only green as this is sufficient
reverse = (uint8)(reverse | 128 >> bp);
{
// check only green as this is sufficient
reverse = (uint8)(reverse | 128 >> bp);
{
TestTIFFImage(wxIMAGE_OPTION_TIFF_BITSPERSAMPLE, 1);
TestTIFFImage(wxIMAGE_OPTION_TIFF_SAMPLESPERPIXEL, 1);
{
TestTIFFImage(wxIMAGE_OPTION_TIFF_BITSPERSAMPLE, 1);
TestTIFFImage(wxIMAGE_OPTION_TIFF_SAMPLESPERPIXEL, 1);
+ TestTIFFImage(wxIMAGE_OPTION_TIFF_PHOTOMETRIC, 0/*PHOTOMETRIC_MINISWHITE*/);
+ TestTIFFImage(wxIMAGE_OPTION_TIFF_PHOTOMETRIC, 1/*PHOTOMETRIC_MINISBLACK*/);
}
void ImageTestCase::SaveAnimatedGIF()
}
void ImageTestCase::SaveAnimatedGIF()