[gimp] plug-ins: fix loading 2 and 4 bit tiff images. This fixes issue #6065 and part of #2680.
- From: Jacob Boerema <jboerema src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] plug-ins: fix loading 2 and 4 bit tiff images. This fixes issue #6065 and part of #2680.
- Date: Thu, 10 Dec 2020 23:53:43 +0000 (UTC)
commit 991e99f08ad0562be4a035c869c2b4f246ed37e4
Author: Jacob Boerema <jgboerema gmail com>
Date: Thu Dec 10 18:46:35 2020 -0500
plug-ins: fix loading 2 and 4 bit tiff images.
This fixes issue #6065 and part of #2680.
Sometime after GIMP 2.8 loading of 2 and 4 bit tif images,
both grayscale and indexed, got broken.
I added routines for handling 2 and 4 bit tifs based on
the handling of 1 bit images.
plug-ins/file-tiff/file-tiff-load.c | 223 ++++++++++++++++++++++++++++++++++--
1 file changed, 212 insertions(+), 11 deletions(-)
---
diff --git a/plug-ins/file-tiff/file-tiff-load.c b/plug-ins/file-tiff/file-tiff-load.c
index 011b551d2b..ab1520bd6f 100644
--- a/plug-ins/file-tiff/file-tiff-load.c
+++ b/plug-ins/file-tiff/file-tiff-load.c
@@ -108,10 +108,20 @@ static void load_paths (TIFF *tif,
gint offset_y);
static void fill_bit2byte (void);
+static void fill_2bit2byte (void);
+static void fill_4bit2byte (void);
static void convert_bit2byte (const guchar *src,
guchar *dest,
gint width,
gint height);
+static void convert_2bit2byte (const guchar *src,
+ guchar *dest,
+ gint width,
+ gint height);
+static void convert_4bit2byte (const guchar *src,
+ guchar *dest,
+ gint width,
+ gint height);
static void convert_int2uint (guchar *buffer,
gint bps,
@@ -349,7 +359,7 @@ load_image (GFile *file,
gushort *extra_types;
ChannelData *channel = NULL;
uint16 planar = PLANARCONFIG_CONTIG;
- gboolean is_bw;
+ gboolean is_bw; /* FIXME Might need to change the name since we use it for palette too now */
gboolean is_signed;
gint i;
gboolean worst_case = FALSE;
@@ -385,6 +395,8 @@ load_image (GFile *file,
switch (bps)
{
case 1:
+ case 2:
+ case 4:
case 8:
if (profile_linear)
image_precision = GIMP_PRECISION_U8_LINEAR;
@@ -590,13 +602,18 @@ load_image (GFile *file,
{
case PHOTOMETRIC_MINISBLACK:
case PHOTOMETRIC_MINISWHITE:
- if (bps == 1 && ! alpha && spp == 1)
+ if ((bps == 1 || bps == 2 || bps == 4) && ! alpha && spp == 1)
{
image_type = GIMP_INDEXED;
layer_type = GIMP_INDEXED_IMAGE;
is_bw = TRUE;
- fill_bit2byte ();
+ if (bps == 1)
+ fill_bit2byte ();
+ else if (bps == 2)
+ fill_2bit2byte ();
+ else if (bps == 4)
+ fill_4bit2byte ();
}
else
{
@@ -743,6 +760,14 @@ load_image (GFile *file,
case PHOTOMETRIC_PALETTE:
image_type = GIMP_INDEXED;
layer_type = alpha ? GIMP_INDEXEDA_IMAGE : GIMP_INDEXED_IMAGE;
+
+ is_bw = TRUE;
+ if (bps == 1)
+ fill_bit2byte ();
+ else if (bps == 2)
+ fill_2bit2byte ();
+ else if (bps == 4)
+ fill_4bit2byte ();
break;
default:
@@ -1082,17 +1107,75 @@ load_image (GFile *file,
{
guchar cmap[768];
- if (is_bw)
+ if (is_bw && photomet != PHOTOMETRIC_PALETTE)
{
if (photomet == PHOTOMETRIC_MINISWHITE)
{
- cmap[0] = cmap[1] = cmap[2] = 255;
- cmap[3] = cmap[4] = cmap[5] = 0;
+ if (bps == 1)
+ {
+ cmap[0] = cmap[1] = cmap[2] = 255;
+ cmap[3] = cmap[4] = cmap[5] = 0;
+ }
+ else if (bps == 2)
+ {
+ cmap[0] = cmap[1] = cmap[2] = 255;
+ cmap[3] = cmap[4] = cmap[5] = 170;
+ cmap[6] = cmap[7] = cmap[8] = 85;
+ cmap[9] = cmap[10] = cmap[11] = 0;
+ }
+ else if (bps == 4)
+ {
+ cmap[0] = cmap[1] = cmap[2] = 255;
+ cmap[3] = cmap[4] = cmap[5] = 238;
+ cmap[6] = cmap[7] = cmap[8] = 221;
+ cmap[9] = cmap[10] = cmap[11] = 204;
+ cmap[12] = cmap[13] = cmap[14] = 187;
+ cmap[15] = cmap[16] = cmap[17] = 170;
+ cmap[18] = cmap[19] = cmap[20] = 153;
+ cmap[21] = cmap[22] = cmap[23] = 136;
+ cmap[24] = cmap[25] = cmap[26] = 119;
+ cmap[27] = cmap[28] = cmap[29] = 102;
+ cmap[30] = cmap[31] = cmap[32] = 85;
+ cmap[33] = cmap[34] = cmap[35] = 68;
+ cmap[36] = cmap[37] = cmap[38] = 51;
+ cmap[39] = cmap[40] = cmap[41] = 34;
+ cmap[42] = cmap[43] = cmap[44] = 17;
+ cmap[45] = cmap[46] = cmap[47] = 0;
+ }
}
else
{
- cmap[0] = cmap[1] = cmap[2] = 0;
- cmap[3] = cmap[4] = cmap[5] = 255;
+ if (bps == 1)
+ {
+ cmap[0] = cmap[1] = cmap[2] = 0;
+ cmap[3] = cmap[4] = cmap[5] = 255;
+ }
+ else if (bps == 2)
+ {
+ cmap[0] = cmap[1] = cmap[2] = 0;
+ cmap[3] = cmap[4] = cmap[5] = 85;
+ cmap[6] = cmap[7] = cmap[8] = 170;
+ cmap[9] = cmap[10] = cmap[11] = 255;
+ }
+ else if (bps == 4)
+ {
+ cmap[0] = cmap[1] = cmap[2] = 0;
+ cmap[3] = cmap[4] = cmap[5] = 17;
+ cmap[6] = cmap[7] = cmap[8] = 34;
+ cmap[9] = cmap[10] = cmap[11] = 51;
+ cmap[12] = cmap[13] = cmap[14] = 68;
+ cmap[15] = cmap[16] = cmap[17] = 85;
+ cmap[18] = cmap[19] = cmap[20] = 102;
+ cmap[21] = cmap[22] = cmap[23] = 119;
+ cmap[24] = cmap[25] = cmap[26] = 136;
+ cmap[27] = cmap[28] = cmap[29] = 153;
+ cmap[30] = cmap[31] = cmap[32] = 170;
+ cmap[33] = cmap[34] = cmap[35] = 187;
+ cmap[36] = cmap[37] = cmap[38] = 204;
+ cmap[39] = cmap[40] = cmap[41] = 221;
+ cmap[42] = cmap[43] = cmap[44] = 238;
+ cmap[45] = cmap[46] = cmap[47] = 255;
+ }
}
}
else
@@ -1724,7 +1807,12 @@ load_contiguous (TIFF *tif,
if (is_bw)
{
- convert_bit2byte (buffer, bw_buffer, cols, rows);
+ if (bps == 1)
+ convert_bit2byte (buffer, bw_buffer, cols, rows);
+ else if (bps == 2)
+ convert_2bit2byte (buffer, bw_buffer, cols, rows);
+ else if (bps == 4)
+ convert_4bit2byte (buffer, bw_buffer, cols, rows);
}
else if (is_signed)
{
@@ -1899,7 +1987,12 @@ load_separate (TIFF *tif,
if (is_bw)
{
- convert_bit2byte (buffer, bw_buffer, cols, rows);
+ if (bps == 1)
+ convert_bit2byte (buffer, bw_buffer, cols, rows);
+ else if (bps == 2)
+ convert_2bit2byte (buffer, bw_buffer, cols, rows);
+ else if (bps == 4)
+ convert_4bit2byte (buffer, bw_buffer, cols, rows);
}
else if (is_signed)
{
@@ -1956,7 +2049,9 @@ load_separate (TIFF *tif,
}
-static guchar bit2byte[256 * 8];
+static guchar bit2byte[256 * 8];
+static guchar _2bit2byte[256 * 4];
+static guchar _4bit2byte[256 * 2];
static void
fill_bit2byte (void)
@@ -1978,6 +2073,54 @@ fill_bit2byte (void)
filled = TRUE;
}
+static void
+fill_2bit2byte (void)
+{
+ static gboolean filled2 = FALSE;
+
+ guchar *dest;
+ gint i, j;
+
+ if (filled2)
+ return;
+
+ dest = _2bit2byte;
+
+ for (j = 0; j < 256; j++)
+ {
+ for (i = 3; i >= 0; i--)
+ {
+ *(dest++) = ((j & (3 << (2*i))) >> (2*i));
+ }
+ }
+
+ filled2 = TRUE;
+}
+
+static void
+fill_4bit2byte (void)
+{
+ static gboolean filled4 = FALSE;
+
+ guchar *dest;
+ gint i, j;
+
+ if (filled4)
+ return;
+
+ dest = _4bit2byte;
+
+ for (j = 0; j < 256; j++)
+ {
+ for (i = 1; i >= 0; i--)
+ {
+ *(dest++) = ((j & (15 << (4*i))) >> (4*i));
+ }
+ }
+
+ filled4 = TRUE;
+}
+
static void
convert_bit2byte (const guchar *src,
guchar *dest,
@@ -2007,6 +2150,64 @@ convert_bit2byte (const guchar *src,
}
}
+static void
+convert_2bit2byte (const guchar *src,
+ guchar *dest,
+ gint width,
+ gint height)
+{
+ gint y;
+
+ for (y = 0; y < height; y++)
+ {
+ gint x = width;
+
+ while (x >= 4)
+ {
+ memcpy (dest, _2bit2byte + *src * 4, 4);
+ dest += 4;
+ x -= 4;
+ src++;
+ }
+
+ if (x > 0)
+ {
+ memcpy (dest, _2bit2byte + *src * 4, x);
+ dest += x;
+ src++;
+ }
+ }
+}
+
+static void
+convert_4bit2byte (const guchar *src,
+ guchar *dest,
+ gint width,
+ gint height)
+{
+ gint y;
+
+ for (y = 0; y < height; y++)
+ {
+ gint x = width;
+
+ while (x >= 2)
+ {
+ memcpy (dest, _4bit2byte + *src * 2, 2);
+ dest += 2;
+ x -= 2;
+ src++;
+ }
+
+ if (x > 0)
+ {
+ memcpy (dest, _4bit2byte + *src * 2, x);
+ dest += x;
+ src++;
+ }
+ }
+}
+
static void
convert_int2uint (guchar *buffer,
gint bps,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]