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 8b9819339d
)
This commit is contained in:
@ -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,
|
||||
|
Reference in New Issue
Block a user