Merge pull request #2323 from stuart8c:issue2601_2.4_fix_16bit_tiff_reading_on_big_endian_host
This commit is contained in:
commit
fa272c43c2
12
3rdparty/libtiff/tif_config.h.cmakein
vendored
12
3rdparty/libtiff/tif_config.h.cmakein
vendored
@ -54,7 +54,7 @@
|
|||||||
|
|
||||||
/* Native cpu byte order: 1 if big-endian (Motorola) or 0 if little-endian
|
/* Native cpu byte order: 1 if big-endian (Motorola) or 0 if little-endian
|
||||||
(Intel) */
|
(Intel) */
|
||||||
#define HOST_BIGENDIAN 0
|
#define HOST_BIGENDIAN @WORDS_BIGENDIAN@
|
||||||
|
|
||||||
/* Set the native cpu bit order (FILLORDER_LSB2MSB or FILLORDER_MSB2LSB) */
|
/* Set the native cpu bit order (FILLORDER_LSB2MSB or FILLORDER_MSB2LSB) */
|
||||||
#define HOST_FILLORDER FILLORDER_LSB2MSB
|
#define HOST_FILLORDER FILLORDER_LSB2MSB
|
||||||
@ -156,15 +156,7 @@
|
|||||||
|
|
||||||
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
|
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
|
||||||
significant byte first (like Motorola and SPARC, unlike Intel). */
|
significant byte first (like Motorola and SPARC, unlike Intel). */
|
||||||
#if defined AC_APPLE_UNIVERSAL_BUILD
|
#cmakedefine WORDS_BIGENDIAN 1
|
||||||
# if defined __BIG_ENDIAN__
|
|
||||||
# define WORDS_BIGENDIAN 1
|
|
||||||
# endif
|
|
||||||
#else
|
|
||||||
# ifndef WORDS_BIGENDIAN
|
|
||||||
/* # undef WORDS_BIGENDIAN */
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Support Deflate compression */
|
/* Support Deflate compression */
|
||||||
#define ZIP_SUPPORT 1
|
#define ZIP_SUPPORT 1
|
||||||
|
@ -444,6 +444,12 @@ endif()
|
|||||||
include(cmake/OpenCVPCHSupport.cmake)
|
include(cmake/OpenCVPCHSupport.cmake)
|
||||||
include(cmake/OpenCVModule.cmake)
|
include(cmake/OpenCVModule.cmake)
|
||||||
|
|
||||||
|
# ----------------------------------------------------------------------------
|
||||||
|
# Detect endianness of build platform
|
||||||
|
# ----------------------------------------------------------------------------
|
||||||
|
include(TestBigEndian)
|
||||||
|
test_big_endian(WORDS_BIGENDIAN)
|
||||||
|
|
||||||
# ----------------------------------------------------------------------------
|
# ----------------------------------------------------------------------------
|
||||||
# Detect 3rd-party libraries
|
# Detect 3rd-party libraries
|
||||||
# ----------------------------------------------------------------------------
|
# ----------------------------------------------------------------------------
|
||||||
|
@ -161,6 +161,6 @@
|
|||||||
/* Xine video library */
|
/* Xine video library */
|
||||||
#cmakedefine HAVE_XINE
|
#cmakedefine HAVE_XINE
|
||||||
|
|
||||||
/* Define to 1 if your processor stores words with the most significant byte
|
/* Define if your processor stores words with the most significant byte
|
||||||
first (like Motorola and SPARC, unlike Intel and VAX). */
|
first (like Motorola and SPARC, unlike Intel and VAX). */
|
||||||
#cmakedefine WORDS_BIGENDIAN
|
#cmakedefine WORDS_BIGENDIAN
|
||||||
|
@ -111,18 +111,21 @@ bool TiffDecoder::readHeader()
|
|||||||
bool result = false;
|
bool result = false;
|
||||||
|
|
||||||
close();
|
close();
|
||||||
TIFF* tif = TIFFOpen( m_filename.c_str(), "rb" );
|
// TIFFOpen() mode flags are different to fopen(). A 'b' in mode "rb" has no effect when reading.
|
||||||
|
// http://www.remotesensing.org/libtiff/man/TIFFOpen.3tiff.html
|
||||||
|
TIFF* tif = TIFFOpen( m_filename.c_str(), "r" );
|
||||||
|
|
||||||
if( tif )
|
if( tif )
|
||||||
{
|
{
|
||||||
int wdth = 0, hght = 0, photometric = 0;
|
uint32 wdth = 0, hght = 0;
|
||||||
|
uint16 photometric = 0;
|
||||||
m_tif = tif;
|
m_tif = tif;
|
||||||
|
|
||||||
if( TIFFGetField( tif, TIFFTAG_IMAGEWIDTH, &wdth ) &&
|
if( TIFFGetField( tif, TIFFTAG_IMAGEWIDTH, &wdth ) &&
|
||||||
TIFFGetField( tif, TIFFTAG_IMAGELENGTH, &hght ) &&
|
TIFFGetField( tif, TIFFTAG_IMAGELENGTH, &hght ) &&
|
||||||
TIFFGetField( tif, TIFFTAG_PHOTOMETRIC, &photometric ))
|
TIFFGetField( tif, TIFFTAG_PHOTOMETRIC, &photometric ))
|
||||||
{
|
{
|
||||||
int bpp=8, ncn = photometric > 1 ? 3 : 1;
|
uint16 bpp=8, ncn = photometric > 1 ? 3 : 1;
|
||||||
TIFFGetField( tif, TIFFTAG_BITSPERSAMPLE, &bpp );
|
TIFFGetField( tif, TIFFTAG_BITSPERSAMPLE, &bpp );
|
||||||
TIFFGetField( tif, TIFFTAG_SAMPLESPERPIXEL, &ncn );
|
TIFFGetField( tif, TIFFTAG_SAMPLESPERPIXEL, &ncn );
|
||||||
|
|
||||||
@ -175,12 +178,12 @@ bool TiffDecoder::readData( Mat& img )
|
|||||||
if( m_tif && m_width && m_height )
|
if( m_tif && m_width && m_height )
|
||||||
{
|
{
|
||||||
TIFF* tif = (TIFF*)m_tif;
|
TIFF* tif = (TIFF*)m_tif;
|
||||||
int tile_width0 = m_width, tile_height0 = 0;
|
uint32 tile_width0 = m_width, tile_height0 = 0;
|
||||||
int x, y, i;
|
int x, y, i;
|
||||||
int is_tiled = TIFFIsTiled(tif);
|
int is_tiled = TIFFIsTiled(tif);
|
||||||
int photometric;
|
uint16 photometric;
|
||||||
TIFFGetField( tif, TIFFTAG_PHOTOMETRIC, &photometric );
|
TIFFGetField( tif, TIFFTAG_PHOTOMETRIC, &photometric );
|
||||||
int bpp = 8, ncn = photometric > 1 ? 3 : 1;
|
uint16 bpp = 8, ncn = photometric > 1 ? 3 : 1;
|
||||||
TIFFGetField( tif, TIFFTAG_BITSPERSAMPLE, &bpp );
|
TIFFGetField( tif, TIFFTAG_BITSPERSAMPLE, &bpp );
|
||||||
TIFFGetField( tif, TIFFTAG_SAMPLESPERPIXEL, &ncn );
|
TIFFGetField( tif, TIFFTAG_SAMPLESPERPIXEL, &ncn );
|
||||||
const int bitsPerByte = 8;
|
const int bitsPerByte = 8;
|
||||||
|
@ -408,8 +408,8 @@ TEST(Highgui_Tiff, decode_tile16384x16384)
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
cv::imread(file3);
|
cv::imread(file3, CV_LOAD_IMAGE_UNCHANGED);
|
||||||
EXPECT_NO_THROW(cv::imread(file4));
|
EXPECT_NO_THROW(cv::imread(file4, CV_LOAD_IMAGE_UNCHANGED));
|
||||||
}
|
}
|
||||||
catch(const std::bad_alloc&)
|
catch(const std::bad_alloc&)
|
||||||
{
|
{
|
||||||
@ -419,4 +419,52 @@ TEST(Highgui_Tiff, decode_tile16384x16384)
|
|||||||
remove(file3.c_str());
|
remove(file3.c_str());
|
||||||
remove(file4.c_str());
|
remove(file4.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(Highgui_Tiff, write_read_16bit_big_little_endian)
|
||||||
|
{
|
||||||
|
// see issue #2601 "16-bit Grayscale TIFF Load Failures Due to Buffer Underflow and Endianness"
|
||||||
|
|
||||||
|
// Setup data for two minimal 16-bit grayscale TIFF files in both endian formats
|
||||||
|
uchar tiff_sample_data[2][86] = { {
|
||||||
|
// Little endian
|
||||||
|
0x49, 0x49, 0x2a, 0x00, 0x0c, 0x00, 0x00, 0x00, 0xad, 0xde, 0xef, 0xbe, 0x06, 0x00, 0x00, 0x01,
|
||||||
|
0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x01, 0x03, 0x00, 0x01, 0x00,
|
||||||
|
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x10, 0x00,
|
||||||
|
0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x11, 0x01,
|
||||||
|
0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x17, 0x01, 0x04, 0x00, 0x01, 0x00,
|
||||||
|
0x00, 0x00, 0x04, 0x00, 0x00, 0x00 }, {
|
||||||
|
// Big endian
|
||||||
|
0x4d, 0x4d, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x0c, 0xde, 0xad, 0xbe, 0xef, 0x00, 0x06, 0x01, 0x00,
|
||||||
|
0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x01, 0x01, 0x00, 0x03, 0x00, 0x00,
|
||||||
|
0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, 0x02, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x10,
|
||||||
|
0x00, 0x00, 0x01, 0x06, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, 0x11,
|
||||||
|
0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x01, 0x17, 0x00, 0x04, 0x00, 0x00,
|
||||||
|
0x00, 0x01, 0x00, 0x00, 0x00, 0x04 }
|
||||||
|
};
|
||||||
|
|
||||||
|
// Test imread() for both a little endian TIFF and big endian TIFF
|
||||||
|
for (int i = 0; i < 2; i++)
|
||||||
|
{
|
||||||
|
string filename = cv::tempfile(".tiff");
|
||||||
|
|
||||||
|
// Write sample TIFF file
|
||||||
|
FILE* fp = fopen(filename.c_str(), "wb");
|
||||||
|
ASSERT_TRUE(fp != NULL);
|
||||||
|
ASSERT_EQ((size_t)1, fwrite(tiff_sample_data, 86, 1, fp));
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
|
Mat img = imread(filename, CV_LOAD_IMAGE_UNCHANGED);
|
||||||
|
|
||||||
|
EXPECT_EQ(1, img.rows);
|
||||||
|
EXPECT_EQ(2, img.cols);
|
||||||
|
EXPECT_EQ(CV_16U, img.type());
|
||||||
|
EXPECT_EQ(sizeof(ushort), img.elemSize());
|
||||||
|
EXPECT_EQ(1, img.channels());
|
||||||
|
EXPECT_EQ(0xDEAD, img.at<ushort>(0,0));
|
||||||
|
EXPECT_EQ(0xBEEF, img.at<ushort>(0,1));
|
||||||
|
|
||||||
|
remove(filename.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user