Added option to TIFF handler for specifying the photometric interpretation.
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
This commit is contained in:
@@ -25,6 +25,7 @@
|
|||||||
#define wxIMAGE_OPTION_TIFF_BITSPERSAMPLE wxString(wxT("BitsPerSample"))
|
#define wxIMAGE_OPTION_TIFF_BITSPERSAMPLE wxString(wxT("BitsPerSample"))
|
||||||
#define wxIMAGE_OPTION_TIFF_SAMPLESPERPIXEL wxString(wxT("SamplesPerPixel"))
|
#define wxIMAGE_OPTION_TIFF_SAMPLESPERPIXEL wxString(wxT("SamplesPerPixel"))
|
||||||
#define wxIMAGE_OPTION_TIFF_COMPRESSION wxString(wxT("Compression"))
|
#define wxIMAGE_OPTION_TIFF_COMPRESSION wxString(wxT("Compression"))
|
||||||
|
#define wxIMAGE_OPTION_TIFF_PHOTOMETRIC wxString(wxT("Photometric"))
|
||||||
#define wxIMAGE_OPTION_TIFF_IMAGEDESCRIPTOR wxString(wxT("ImageDescriptor"))
|
#define wxIMAGE_OPTION_TIFF_IMAGEDESCRIPTOR wxString(wxT("ImageDescriptor"))
|
||||||
|
|
||||||
// for backwards compatibility
|
// for backwards compatibility
|
||||||
|
@@ -437,6 +437,8 @@ bool wxTIFFHandler::LoadFile( wxImage *image, wxInputStream& stream, bool verbos
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
image->SetOption(wxIMAGE_OPTION_TIFF_PHOTOMETRIC, photometric);
|
||||||
|
|
||||||
uint16 spp, bps, compression;
|
uint16 spp, bps, compression;
|
||||||
/*
|
/*
|
||||||
Read some baseline TIFF tags which helps when re-saving a TIFF
|
Read some baseline TIFF tags which helps when re-saving a TIFF
|
||||||
@@ -603,6 +605,27 @@ bool wxTIFFHandler::SaveFile( wxImage *image, wxOutputStream& stream, bool verbo
|
|||||||
spp = 1;
|
spp = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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);
|
int compression = image->GetOptionInt(wxIMAGE_OPTION_TIFF_COMPRESSION);
|
||||||
if ( !compression )
|
if ( !compression )
|
||||||
{
|
{
|
||||||
@@ -615,8 +638,7 @@ bool wxTIFFHandler::SaveFile( wxImage *image, wxOutputStream& stream, bool verbo
|
|||||||
|
|
||||||
TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, spp);
|
TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, spp);
|
||||||
TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, bps);
|
TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, bps);
|
||||||
TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, spp*bps == 1 ? PHOTOMETRIC_MINISBLACK
|
TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, photometric);
|
||||||
: PHOTOMETRIC_RGB);
|
|
||||||
TIFFSetField(tif, TIFFTAG_COMPRESSION, compression);
|
TIFFSetField(tif, TIFFTAG_COMPRESSION, compression);
|
||||||
|
|
||||||
// scanlinesize if determined by spp and bps
|
// scanlinesize if determined by spp and bps
|
||||||
@@ -627,7 +649,7 @@ bool wxTIFFHandler::SaveFile( wxImage *image, wxOutputStream& stream, bool verbo
|
|||||||
|
|
||||||
unsigned char *buf;
|
unsigned char *buf;
|
||||||
|
|
||||||
if (TIFFScanlineSize(tif) > linebytes || (spp * bps < 24))
|
if (TIFFScanlineSize(tif) > linebytes || !isColouredImage)
|
||||||
{
|
{
|
||||||
buf = (unsigned char *)_TIFFmalloc(TIFFScanlineSize(tif));
|
buf = (unsigned char *)_TIFFmalloc(TIFFScanlineSize(tif));
|
||||||
if (!buf)
|
if (!buf)
|
||||||
@@ -649,12 +671,13 @@ bool wxTIFFHandler::SaveFile( wxImage *image, wxOutputStream& stream, bool verbo
|
|||||||
|
|
||||||
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();
|
unsigned char *ptr = image->GetData();
|
||||||
for ( int row = 0; row < image->GetHeight(); row++ )
|
for ( int row = 0; row < image->GetHeight(); row++ )
|
||||||
{
|
{
|
||||||
if ( buf )
|
if ( buf )
|
||||||
{
|
{
|
||||||
if ( spp * bps > 1 )
|
if (isColouredImage)
|
||||||
{
|
{
|
||||||
// color image
|
// color image
|
||||||
memcpy(buf, ptr, image->GetWidth());
|
memcpy(buf, ptr, image->GetWidth());
|
||||||
@@ -663,7 +686,13 @@ bool wxTIFFHandler::SaveFile( wxImage *image, wxOutputStream& stream, bool verbo
|
|||||||
{
|
{
|
||||||
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
|
||||||
@@ -673,7 +702,7 @@ bool wxTIFFHandler::SaveFile( wxImage *image, wxOutputStream& stream, bool verbo
|
|||||||
uint8 reverse = 0;
|
uint8 reverse = 0;
|
||||||
for ( int bp = 0; bp < 8; bp++ )
|
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
|
// check only green as this is sufficient
|
||||||
reverse = (uint8)(reverse | 128 >> bp);
|
reverse = (uint8)(reverse | 128 >> bp);
|
||||||
|
@@ -1116,6 +1116,8 @@ void ImageTestCase::SaveTIFF()
|
|||||||
{
|
{
|
||||||
TestTIFFImage(wxIMAGE_OPTION_TIFF_BITSPERSAMPLE, 1);
|
TestTIFFImage(wxIMAGE_OPTION_TIFF_BITSPERSAMPLE, 1);
|
||||||
TestTIFFImage(wxIMAGE_OPTION_TIFF_SAMPLESPERPIXEL, 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()
|
||||||
|
Reference in New Issue
Block a user