[gimp/gimp-2-10] Issue #5275 - TIFF files with signed-int samples are misinterpreted as unsigned
- From: Ell <ell src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp/gimp-2-10] Issue #5275 - TIFF files with signed-int samples are misinterpreted as unsigned
- Date: Wed, 24 Jun 2020 12:36:58 +0000 (UTC)
commit 7d5188db490e8a0234095a0df23a6ba3e96ad4be
Author: Ell <ell_se yahoo com>
Date: Wed Jun 24 15:16:50 2020 +0300
Issue #5275 - TIFF files with signed-int samples are misinterpreted as unsigned
When loading a TIFF file with signed-int samples, convert the
samples to unsigned-int by offsetting them to the unsigned range,
instead of misinterpreting them as unsigned values.
(cherry picked from commit 8b9819339d86f56087c220194bf8ce16d7ba39d7)
plug-ins/file-tiff/file-tiff-load.c | 68 ++++++++++++++++++++++++++++++++++---
1 file changed, 63 insertions(+), 5 deletions(-)
---
diff --git a/plug-ins/file-tiff/file-tiff-load.c b/plug-ins/file-tiff/file-tiff-load.c
index 2817633aa7..07338d9bb7 100644
--- a/plug-ins/file-tiff/file-tiff-load.c
+++ b/plug-ins/file-tiff/file-tiff-load.c
@@ -96,6 +96,7 @@ static void load_contiguous (TIFF *tif,
gushort bps,
gushort spp,
gboolean is_bw,
+ gboolean is_signed,
gint extra);
static void load_separate (TIFF *tif,
ChannelData *channel,
@@ -103,6 +104,7 @@ static void load_separate (TIFF *tif,
gushort bps,
gushort spp,
gboolean is_bw,
+ gboolean is_signed,
gint extra);
static void load_paths (TIFF *tif,
gint image,
@@ -117,6 +119,13 @@ static void convert_bit2byte (const guchar *src,
gint width,
gint height);
+static void convert_int2uint (guchar *buffer,
+ gint bps,
+ gint spp,
+ gint width,
+ gint height,
+ gint stride);
+
static gboolean load_dialog (TIFF *tif,
const gchar *help_id,
TiffSelectedPages *pages,
@@ -326,6 +335,7 @@ load_image (GFile *file,
ChannelData *channel = NULL;
uint16 planar = PLANARCONFIG_CONTIG;
gboolean is_bw;
+ gboolean is_signed;
gint i;
gboolean worst_case = FALSE;
TiffSaveVals save_vals;
@@ -553,7 +563,8 @@ load_image (GFile *file,
else if (photomet != PHOTOMETRIC_RGB && spp > 1 + (alpha ? 1 : 0) + extra)
extra = spp - 1 - (alpha ? 1 : 0);
- is_bw = FALSE;
+ is_bw = FALSE;
+ is_signed = sampleformat == SAMPLEFORMAT_INT;
switch (photomet)
{
@@ -1083,11 +1094,13 @@ load_image (GFile *file,
}
else if (planar == PLANARCONFIG_CONTIG)
{
- load_contiguous (tif, channel, type, bps, spp, is_bw, extra);
+ load_contiguous (tif, channel, type, bps, spp,
+ is_bw, is_signed, extra);
}
else
{
- load_separate (tif, channel, type, bps, spp, is_bw, extra);
+ load_separate (tif, channel, type, bps, spp,
+ is_bw, is_signed, extra);
}
if (TIFFGetField (tif, TIFFTAG_ORIENTATION, &orientation))
@@ -1490,6 +1503,7 @@ load_contiguous (TIFF *tif,
gushort bps,
gushort spp,
gboolean is_bw,
+ gboolean is_signed,
gint extra)
{
guint32 image_width;
@@ -1566,7 +1580,14 @@ load_contiguous (TIFF *tif,
rows = MIN (image_height - y, tile_height);
if (is_bw)
- convert_bit2byte (buffer, bw_buffer, cols, rows);
+ {
+ convert_bit2byte (buffer, bw_buffer, cols, rows);
+ }
+ else if (is_signed)
+ {
+ convert_int2uint (buffer, bps, spp, cols, rows,
+ tile_width * bytes_per_pixel);
+ }
src_buf = gegl_buffer_linear_new_from_data (is_bw ? bw_buffer : buffer,
src_format,
@@ -1632,6 +1653,7 @@ load_separate (TIFF *tif,
gushort bps,
gushort spp,
gboolean is_bw,
+ gboolean is_signed,
gint extra)
{
guint32 image_width;
@@ -1727,7 +1749,14 @@ load_separate (TIFF *tif,
rows = MIN (image_height - y, tile_height);
if (is_bw)
- convert_bit2byte (buffer, bw_buffer, cols, rows);
+ {
+ convert_bit2byte (buffer, bw_buffer, cols, rows);
+ }
+ else if (is_signed)
+ {
+ convert_int2uint (buffer, bps, spp, cols, rows,
+ tile_width * bytes_per_pixel);
+ }
src_buf = gegl_buffer_linear_new_from_data (is_bw ? bw_buffer : buffer,
src_format,
@@ -1829,6 +1858,35 @@ convert_bit2byte (const guchar *src,
}
}
+static void
+convert_int2uint (guchar *buffer,
+ gint bps,
+ gint spp,
+ gint width,
+ gint height,
+ gint stride)
+{
+ gint bytes_per_pixel = bps / 8;
+ gint y;
+
+ for (y = 0; y < height; y++)
+ {
+ guchar *d = buffer + stride * y;
+ gint x;
+
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
+ d += bytes_per_pixel - 1;
+#endif
+
+ for (x = 0; x < width * spp; x++)
+ {
+ *d ^= 0x80;
+
+ d += bytes_per_pixel;
+ }
+ }
+}
+
static gboolean
load_dialog (TIFF *tif,
const gchar *help_id,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]