diff --git a/modules/imgcodecs/src/grfmt_tiff.cpp b/modules/imgcodecs/src/grfmt_tiff.cpp index a604423c62..1ab0b1d242 100644 --- a/modules/imgcodecs/src/grfmt_tiff.cpp +++ b/modules/imgcodecs/src/grfmt_tiff.cpp @@ -334,6 +334,77 @@ bool TiffDecoder::nextPage() readHeader(); } +static void fixOrientationPartial(Mat &img, uint16 orientation) +{ + switch(orientation) { + case ORIENTATION_RIGHTTOP: + case ORIENTATION_LEFTBOT: + flip(img, img, -1); + /* fall through */ + + case ORIENTATION_LEFTTOP: + case ORIENTATION_RIGHTBOT: + transpose(img, img); + break; + } +} + +static void fixOrientationFull(Mat &img, int orientation) +{ + switch(orientation) { + case ORIENTATION_TOPRIGHT: + flip(img, img, 1); + break; + + case ORIENTATION_BOTRIGHT: + flip(img, img, -1); + break; + + case ORIENTATION_BOTLEFT: + flip(img, img, 0); + break; + + case ORIENTATION_LEFTTOP: + transpose(img, img); + break; + + case ORIENTATION_RIGHTTOP: + transpose(img, img); + flip(img, img, 1); + break; + + case ORIENTATION_RIGHTBOT: + transpose(img, img); + flip(img, img, -1); + break; + + case ORIENTATION_LEFTBOT: + transpose(img, img); + flip(img, img, 0); + break; + } +} + +/** + * Fix orientation defined in tag 274. + * For 8 bit some corrections are done by TIFFReadRGBAStrip/Tile already. + * Not so for 16/32/64 bit. + */ +static void fixOrientation(Mat &img, uint16 orientation, int dst_bpp) +{ + switch(dst_bpp) { + case 8: + fixOrientationPartial(img, orientation); + break; + + case 16: + case 32: + case 64: + fixOrientationFull(img, orientation); + break; + } +} + bool TiffDecoder::readData( Mat& img ) { int type_ = img.type(); @@ -363,10 +434,11 @@ bool TiffDecoder::readData( Mat& img ) CV_TIFF_CHECK_CALL_DEBUG(TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &ncn)); uint16 img_orientation = ORIENTATION_TOPLEFT; CV_TIFF_CHECK_CALL_DEBUG(TIFFGetField(tif, TIFFTAG_ORIENTATION, &img_orientation)); - bool vert_flip = (img_orientation == ORIENTATION_BOTRIGHT) || (img_orientation == ORIENTATION_RIGHTBOT) || - (img_orientation == ORIENTATION_BOTLEFT) || (img_orientation == ORIENTATION_LEFTBOT); const int bitsPerByte = 8; int dst_bpp = (int)(img.elemSize1() * bitsPerByte); + bool vert_flip = dst_bpp == 8 && + (img_orientation == ORIENTATION_BOTRIGHT || img_orientation == ORIENTATION_RIGHTBOT || + img_orientation == ORIENTATION_BOTLEFT || img_orientation == ORIENTATION_LEFTBOT); int wanted_channels = normalizeChannelsNumber(img.channels()); if (dst_bpp == 8) @@ -579,6 +651,7 @@ bool TiffDecoder::readData( Mat& img ) } // for x } // for y } + fixOrientation(img, img_orientation, dst_bpp); } if (m_hdr && depth >= CV_32F)