# HG changeset patch # User magedrifaat # Date 1662154067 -7200 # Node ID fa50e2c1756873408ecd305cf4103ead38850b65 # Parent be6ccdcd5775782452663aa89c8635d9f919bf5b Tiff: fixed bug RGBA incorrect orientation handling for rotated orientations * libinterp/corefcn/__tiff__.cc (F__tiff_read_rgba_image__, F__tiff_read_rgba_strip__, F__tiff_read_rgba_tile__): fixed bug where orientations that require rotation and flipping were incorrectly handled. diff -r be6ccdcd5775 -r fa50e2c17568 libinterp/corefcn/__tiff__.cc --- a/libinterp/corefcn/__tiff__.cc Fri Sep 02 21:20:56 2022 +0200 +++ b/libinterp/corefcn/__tiff__.cc Fri Sep 02 23:27:47 2022 +0200 @@ -2752,9 +2752,18 @@ if (! TIFFRGBAImageOK (tif, emsg) || ! TIFFRGBAImageBegin (&img_config, tif, 0, emsg)) error ("Failed to read image"); + + if (orientation == ORIENTATION_RIGHTTOP + || orientation == ORIENTATION_LEFTBOT) + // LibTIFF can only do flips and doesn't do rotations, so if we need + // an orientation that requires a rotation before flipping + // (i.e. LeftBottom, RightTop) then the only thing we can do is start + // with an orientation that doesn't require a rotation, then permute at + // the end. + img_config.orientation = ORIENTATION_RIGHTBOT; + else + img_config.orientation = ORIENTATION_TOPLEFT; - // FIXME: rotated orientation don't work correctly (e.g. LeftTop) - img_config.orientation = ORIENTATION_TOPLEFT; img_config.req_orientation = orientation; bool success = TIFFRGBAImageGet (&img_config, img_ptr, img_config.width, @@ -2766,9 +2775,19 @@ // Permute to the correct Octave dimension order Array perm (dim_vector (3, 1)); - perm(0) = 2; - perm(1) = 1; - perm(2) = 0; + if (orientation >= ORIENTATION_LEFTTOP) + { + // Transpose for rotated orientations + perm(0) = 1; + perm(1) = 2; + perm(2) = 0; + } + else + { + perm(0) = 2; + perm(1) = 1; + perm(2) = 0; + } img = img.permute (perm); // Slice the data into RGB and alpha @@ -2844,7 +2863,17 @@ || ! TIFFRGBAImageBegin (&img_config, tif, 0, emsg)) error ("Failed to read strip"); - img_config.orientation = ORIENTATION_TOPLEFT; + if (orientation == ORIENTATION_RIGHTTOP + || orientation == ORIENTATION_LEFTBOT) + // LibTIFF can only do flips and doesn't do rotations, so if we need + // an orientation that requires a rotation before flipping + // (i.e. LeftBottom, RightTop) then the only thing we can do is start + // with an orientation that doesn't require a rotation, then permute at + // the end. + img_config.orientation = ORIENTATION_RIGHTBOT; + else + img_config.orientation = ORIENTATION_TOPLEFT; + img_config.req_orientation = orientation; img_config.row_offset = row; img_config.col_offset = 0; @@ -2858,9 +2887,19 @@ // Permute to the correct order of dimensions for Octave Array perm (dim_vector (3, 1)); - perm(0) = 2; - perm(1) = 1; - perm(2) = 0; + if (orientation >= ORIENTATION_LEFTTOP) + { + // Transpose for rotated orientations + perm(0) = 1; + perm(1) = 2; + perm(2) = 0; + } + else + { + perm(0) = 2; + perm(1) = 1; + perm(2) = 0; + } strip_data = strip_data.permute (perm); // Slice the data into RGB and alpha @@ -2945,7 +2984,17 @@ || ! TIFFRGBAImageBegin (&img_config, tif, 0, emsg)) error ("Failed to read tile"); - img_config.orientation = ORIENTATION_TOPLEFT; + if (orientation == ORIENTATION_RIGHTTOP + || orientation == ORIENTATION_LEFTBOT) + // LibTIFF can only do flips and doesn't do rotations, so if we need + // an orientation that requires a rotation before flipping + // (i.e. LeftBottom, RightTop) then the only thing we can do is start + // with an orientation that doesn't require a rotation, then permute at + // the end. + img_config.orientation = ORIENTATION_RIGHTBOT; + else + img_config.orientation = ORIENTATION_TOPLEFT; + img_config.req_orientation = orientation; img_config.row_offset = row; img_config.col_offset = col; @@ -2959,9 +3008,19 @@ // Permute to the correct order of dimensions for Octave Array perm (dim_vector (3, 1)); - perm(0) = 2; - perm(1) = 1; - perm(2) = 0; + if (orientation >= ORIENTATION_LEFTTOP) + { + // Transpose for rotated orientations + perm(0) = 1; + perm(1) = 2; + perm(2) = 0; + } + else + { + perm(0) = 2; + perm(1) = 1; + perm(2) = 0; + } tile_data = tile_data.permute (perm); // Slice the data into RGB and alpha