[gimp] 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] Issue #5275 - TIFF files with signed-int samples are misinterpreted as unsigned
- Date: Wed, 24 Jun 2020 12:37:03 +0000 (UTC)
commit 8b9819339d86f56087c220194bf8ce16d7ba39d7
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.
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 b88f6f7e7d..7f985bd7b8 100644
--- a/plug-ins/file-tiff/file-tiff-load.c
+++ b/plug-ins/file-tiff/file-tiff-load.c
@@ -90,6 +90,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,
@@ -97,6 +98,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,
GimpImage *image,
@@ -111,6 +113,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,
@@ -314,6 +323,7 @@ load_image (GFile *file,
ChannelData *channel = NULL;
uint16 planar = PLANARCONFIG_CONTIG;
gboolean is_bw;
+ gboolean is_signed;
gint i;
gboolean worst_case = FALSE;
gint gimp_compression = GIMP_COMPRESSION_NONE;
@@ -541,7 +551,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)
{
@@ -1110,11 +1121,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))
@@ -1517,6 +1530,7 @@ load_contiguous (TIFF *tif,
gushort bps,
gushort spp,
gboolean is_bw,
+ gboolean is_signed,
gint extra)
{
guint32 image_width;
@@ -1593,7 +1607,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,
@@ -1659,6 +1680,7 @@ load_separate (TIFF *tif,
gushort bps,
gushort spp,
gboolean is_bw,
+ gboolean is_signed,
gint extra)
{
guint32 image_width;
@@ -1754,7 +1776,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,
@@ -1856,6 +1885,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]