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 bps,
|
||||||
gushort spp,
|
gushort spp,
|
||||||
gboolean is_bw,
|
gboolean is_bw,
|
||||||
|
gboolean is_signed,
|
||||||
gint extra);
|
gint extra);
|
||||||
static void load_separate (TIFF *tif,
|
static void load_separate (TIFF *tif,
|
||||||
ChannelData *channel,
|
ChannelData *channel,
|
||||||
@ -103,6 +104,7 @@ static void load_separate (TIFF *tif,
|
|||||||
gushort bps,
|
gushort bps,
|
||||||
gushort spp,
|
gushort spp,
|
||||||
gboolean is_bw,
|
gboolean is_bw,
|
||||||
|
gboolean is_signed,
|
||||||
gint extra);
|
gint extra);
|
||||||
static void load_paths (TIFF *tif,
|
static void load_paths (TIFF *tif,
|
||||||
gint image,
|
gint image,
|
||||||
@ -117,6 +119,13 @@ static void convert_bit2byte (const guchar *src,
|
|||||||
gint width,
|
gint width,
|
||||||
gint height);
|
gint height);
|
||||||
|
|
||||||
|
static void convert_int2uint (guchar *buffer,
|
||||||
|
gint bps,
|
||||||
|
gint spp,
|
||||||
|
gint width,
|
||||||
|
gint height,
|
||||||
|
gint stride);
|
||||||
|
|
||||||
static gboolean load_dialog (TIFF *tif,
|
static gboolean load_dialog (TIFF *tif,
|
||||||
const gchar *help_id,
|
const gchar *help_id,
|
||||||
TiffSelectedPages *pages,
|
TiffSelectedPages *pages,
|
||||||
@ -326,6 +335,7 @@ load_image (GFile *file,
|
|||||||
ChannelData *channel = NULL;
|
ChannelData *channel = NULL;
|
||||||
uint16 planar = PLANARCONFIG_CONTIG;
|
uint16 planar = PLANARCONFIG_CONTIG;
|
||||||
gboolean is_bw;
|
gboolean is_bw;
|
||||||
|
gboolean is_signed;
|
||||||
gint i;
|
gint i;
|
||||||
gboolean worst_case = FALSE;
|
gboolean worst_case = FALSE;
|
||||||
TiffSaveVals save_vals;
|
TiffSaveVals save_vals;
|
||||||
@ -553,7 +563,8 @@ load_image (GFile *file,
|
|||||||
else if (photomet != PHOTOMETRIC_RGB && spp > 1 + (alpha ? 1 : 0) + extra)
|
else if (photomet != PHOTOMETRIC_RGB && spp > 1 + (alpha ? 1 : 0) + extra)
|
||||||
extra = spp - 1 - (alpha ? 1 : 0);
|
extra = spp - 1 - (alpha ? 1 : 0);
|
||||||
|
|
||||||
is_bw = FALSE;
|
is_bw = FALSE;
|
||||||
|
is_signed = sampleformat == SAMPLEFORMAT_INT;
|
||||||
|
|
||||||
switch (photomet)
|
switch (photomet)
|
||||||
{
|
{
|
||||||
@ -1083,11 +1094,13 @@ load_image (GFile *file,
|
|||||||
}
|
}
|
||||||
else if (planar == PLANARCONFIG_CONTIG)
|
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
|
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))
|
if (TIFFGetField (tif, TIFFTAG_ORIENTATION, &orientation))
|
||||||
@ -1490,6 +1503,7 @@ load_contiguous (TIFF *tif,
|
|||||||
gushort bps,
|
gushort bps,
|
||||||
gushort spp,
|
gushort spp,
|
||||||
gboolean is_bw,
|
gboolean is_bw,
|
||||||
|
gboolean is_signed,
|
||||||
gint extra)
|
gint extra)
|
||||||
{
|
{
|
||||||
guint32 image_width;
|
guint32 image_width;
|
||||||
@ -1566,7 +1580,14 @@ load_contiguous (TIFF *tif,
|
|||||||
rows = MIN (image_height - y, tile_height);
|
rows = MIN (image_height - y, tile_height);
|
||||||
|
|
||||||
if (is_bw)
|
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_buf = gegl_buffer_linear_new_from_data (is_bw ? bw_buffer : buffer,
|
||||||
src_format,
|
src_format,
|
||||||
@ -1632,6 +1653,7 @@ load_separate (TIFF *tif,
|
|||||||
gushort bps,
|
gushort bps,
|
||||||
gushort spp,
|
gushort spp,
|
||||||
gboolean is_bw,
|
gboolean is_bw,
|
||||||
|
gboolean is_signed,
|
||||||
gint extra)
|
gint extra)
|
||||||
{
|
{
|
||||||
guint32 image_width;
|
guint32 image_width;
|
||||||
@ -1727,7 +1749,14 @@ load_separate (TIFF *tif,
|
|||||||
rows = MIN (image_height - y, tile_height);
|
rows = MIN (image_height - y, tile_height);
|
||||||
|
|
||||||
if (is_bw)
|
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_buf = gegl_buffer_linear_new_from_data (is_bw ? bw_buffer : buffer,
|
||||||
src_format,
|
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
|
static gboolean
|
||||||
load_dialog (TIFF *tif,
|
load_dialog (TIFF *tif,
|
||||||
const gchar *help_id,
|
const gchar *help_id,
|
||||||
|
Reference in New Issue
Block a user