summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/mupdf/fitz/filter.h5
-rw-r--r--platform/win32/libmupdf.vcproj4
-rw-r--r--source/fitz/filter-sgi.c683
-rw-r--r--source/fitz/load-tiff.c42
4 files changed, 734 insertions, 0 deletions
diff --git a/include/mupdf/fitz/filter.h b/include/mupdf/fitz/filter.h
index 3d6a21bd..5192540e 100644
--- a/include/mupdf/fitz/filter.h
+++ b/include/mupdf/fitz/filter.h
@@ -30,4 +30,9 @@ fz_stream *fz_open_jbig2d(fz_context *ctx, fz_stream *chain, fz_jbig2_globals *g
fz_jbig2_globals *fz_load_jbig2_globals(fz_context *ctx, fz_buffer *buf);
void fz_drop_jbig2_globals_imp(fz_context *ctx, fz_storable *globals);
+/* Extra filters for tiff */
+fz_stream *fz_open_sgilog16(fz_context *ctx, fz_stream *chain, int w);
+fz_stream *fz_open_sgilog24(fz_context *ctx, fz_stream *chain, int w);
+fz_stream *fz_open_sgilog32(fz_context *ctx, fz_stream *chain, int w);
+
#endif
diff --git a/platform/win32/libmupdf.vcproj b/platform/win32/libmupdf.vcproj
index 14656640..96214121 100644
--- a/platform/win32/libmupdf.vcproj
+++ b/platform/win32/libmupdf.vcproj
@@ -883,6 +883,10 @@
>
</File>
<File
+ RelativePath="..\..\source\fitz\filter-sgi.c"
+ >
+ </File>
+ <File
RelativePath="..\..\source\fitz\font.c"
>
</File>
diff --git a/source/fitz/filter-sgi.c b/source/fitz/filter-sgi.c
new file mode 100644
index 00000000..c0fd9a74
--- /dev/null
+++ b/source/fitz/filter-sgi.c
@@ -0,0 +1,683 @@
+#include "mupdf/fitz/system.h"
+#include "mupdf/fitz/context.h"
+#include "mupdf/fitz/stream.h"
+
+/* Table stolen from LibTiff */
+#define UV_SQSIZ 0.003500f
+#define UV_NDIVS 16289
+#define UV_VSTART 0.016940f
+#define UV_NVS 163
+#define U_NEU 0.210526316f
+#define V_NEU 0.473684211f
+#define UVSCALE 410
+static struct {
+ float ustart;
+ short nus, ncum;
+} uv_row[UV_NVS] = {
+ { 0.247663f, 4, 0 },
+ { 0.243779f, 6, 4 },
+ { 0.241684f, 7, 10 },
+ { 0.237874f, 9, 17 },
+ { 0.235906f, 10, 26 },
+ { 0.232153f, 12, 36 },
+ { 0.228352f, 14, 48 },
+ { 0.226259f, 15, 62 },
+ { 0.222371f, 17, 77 },
+ { 0.220410f, 18, 94 },
+ { 0.214710f, 21, 112 },
+ { 0.212714f, 22, 133 },
+ { 0.210721f, 23, 155 },
+ { 0.204976f, 26, 178 },
+ { 0.202986f, 27, 204 },
+ { 0.199245f, 29, 231 },
+ { 0.195525f, 31, 260 },
+ { 0.193560f, 32, 291 },
+ { 0.189878f, 34, 323 },
+ { 0.186216f, 36, 357 },
+ { 0.186216f, 36, 393 },
+ { 0.182592f, 38, 429 },
+ { 0.179003f, 40, 467 },
+ { 0.175466f, 42, 507 },
+ { 0.172001f, 44, 549 },
+ { 0.172001f, 44, 593 },
+ { 0.168612f, 46, 637 },
+ { 0.168612f, 46, 683 },
+ { 0.163575f, 49, 729 },
+ { 0.158642f, 52, 778 },
+ { 0.158642f, 52, 830 },
+ { 0.158642f, 52, 882 },
+ { 0.153815f, 55, 934 },
+ { 0.153815f, 55, 989 },
+ { 0.149097f, 58, 1044 },
+ { 0.149097f, 58, 1102 },
+ { 0.142746f, 62, 1160 },
+ { 0.142746f, 62, 1222 },
+ { 0.142746f, 62, 1284 },
+ { 0.138270f, 65, 1346 },
+ { 0.138270f, 65, 1411 },
+ { 0.138270f, 65, 1476 },
+ { 0.132166f, 69, 1541 },
+ { 0.132166f, 69, 1610 },
+ { 0.126204f, 73, 1679 },
+ { 0.126204f, 73, 1752 },
+ { 0.126204f, 73, 1825 },
+ { 0.120381f, 77, 1898 },
+ { 0.120381f, 77, 1975 },
+ { 0.120381f, 77, 2052 },
+ { 0.120381f, 77, 2129 },
+ { 0.112962f, 82, 2206 },
+ { 0.112962f, 82, 2288 },
+ { 0.112962f, 82, 2370 },
+ { 0.107450f, 86, 2452 },
+ { 0.107450f, 86, 2538 },
+ { 0.107450f, 86, 2624 },
+ { 0.107450f, 86, 2710 },
+ { 0.100343f, 91, 2796 },
+ { 0.100343f, 91, 2887 },
+ { 0.100343f, 91, 2978 },
+ { 0.095126f, 95, 3069 },
+ { 0.095126f, 95, 3164 },
+ { 0.095126f, 95, 3259 },
+ { 0.095126f, 95, 3354 },
+ { 0.088276f, 100, 3449 },
+ { 0.088276f, 100, 3549 },
+ { 0.088276f, 100, 3649 },
+ { 0.088276f, 100, 3749 },
+ { 0.081523f, 105, 3849 },
+ { 0.081523f, 105, 3954 },
+ { 0.081523f, 105, 4059 },
+ { 0.081523f, 105, 4164 },
+ { 0.074861f, 110, 4269 },
+ { 0.074861f, 110, 4379 },
+ { 0.074861f, 110, 4489 },
+ { 0.074861f, 110, 4599 },
+ { 0.068290f, 115, 4709 },
+ { 0.068290f, 115, 4824 },
+ { 0.068290f, 115, 4939 },
+ { 0.068290f, 115, 5054 },
+ { 0.063573f, 119, 5169 },
+ { 0.063573f, 119, 5288 },
+ { 0.063573f, 119, 5407 },
+ { 0.063573f, 119, 5526 },
+ { 0.057219f, 124, 5645 },
+ { 0.057219f, 124, 5769 },
+ { 0.057219f, 124, 5893 },
+ { 0.057219f, 124, 6017 },
+ { 0.050985f, 129, 6141 },
+ { 0.050985f, 129, 6270 },
+ { 0.050985f, 129, 6399 },
+ { 0.050985f, 129, 6528 },
+ { 0.050985f, 129, 6657 },
+ { 0.044859f, 134, 6786 },
+ { 0.044859f, 134, 6920 },
+ { 0.044859f, 134, 7054 },
+ { 0.044859f, 134, 7188 },
+ { 0.040571f, 138, 7322 },
+ { 0.040571f, 138, 7460 },
+ { 0.040571f, 138, 7598 },
+ { 0.040571f, 138, 7736 },
+ { 0.036339f, 142, 7874 },
+ { 0.036339f, 142, 8016 },
+ { 0.036339f, 142, 8158 },
+ { 0.036339f, 142, 8300 },
+ { 0.032139f, 146, 8442 },
+ { 0.032139f, 146, 8588 },
+ { 0.032139f, 146, 8734 },
+ { 0.032139f, 146, 8880 },
+ { 0.027947f, 150, 9026 },
+ { 0.027947f, 150, 9176 },
+ { 0.027947f, 150, 9326 },
+ { 0.023739f, 154, 9476 },
+ { 0.023739f, 154, 9630 },
+ { 0.023739f, 154, 9784 },
+ { 0.023739f, 154, 9938 },
+ { 0.019504f, 158, 10092 },
+ { 0.019504f, 158, 10250 },
+ { 0.019504f, 158, 10408 },
+ { 0.016976f, 161, 10566 },
+ { 0.016976f, 161, 10727 },
+ { 0.016976f, 161, 10888 },
+ { 0.016976f, 161, 11049 },
+ { 0.012639f, 165, 11210 },
+ { 0.012639f, 165, 11375 },
+ { 0.012639f, 165, 11540 },
+ { 0.009991f, 168, 11705 },
+ { 0.009991f, 168, 11873 },
+ { 0.009991f, 168, 12041 },
+ { 0.009016f, 170, 12209 },
+ { 0.009016f, 170, 12379 },
+ { 0.009016f, 170, 12549 },
+ { 0.006217f, 173, 12719 },
+ { 0.006217f, 173, 12892 },
+ { 0.005097f, 175, 13065 },
+ { 0.005097f, 175, 13240 },
+ { 0.005097f, 175, 13415 },
+ { 0.003909f, 177, 13590 },
+ { 0.003909f, 177, 13767 },
+ { 0.002340f, 177, 13944 },
+ { 0.002389f, 170, 14121 },
+ { 0.001068f, 164, 14291 },
+ { 0.001653f, 157, 14455 },
+ { 0.000717f, 150, 14612 },
+ { 0.001614f, 143, 14762 },
+ { 0.000270f, 136, 14905 },
+ { 0.000484f, 129, 15041 },
+ { 0.001103f, 123, 15170 },
+ { 0.001242f, 115, 15293 },
+ { 0.001188f, 109, 15408 },
+ { 0.001011f, 103, 15517 },
+ { 0.000709f, 97, 15620 },
+ { 0.000301f, 89, 15717 },
+ { 0.002416f, 82, 15806 },
+ { 0.003251f, 76, 15888 },
+ { 0.003246f, 69, 15964 },
+ { 0.004141f, 62, 16033 },
+ { 0.005963f, 55, 16095 },
+ { 0.008839f, 47, 16150 },
+ { 0.010490f, 40, 16197 },
+ { 0.016994f, 31, 16237 },
+ { 0.023659f, 21, 16268 },
+};
+
+#ifndef M_LN2
+#define M_LN2 0.69314718055994530942
+#endif
+
+/* SGI Log 16bit (greyscale) */
+
+typedef struct fz_sgilog16_s fz_sgilog16;
+
+struct fz_sgilog16_s
+{
+ fz_stream *chain;
+ int run, n, c, w;
+ uint16_t *temp;
+};
+
+static inline int
+sgilog16val(fz_context *ctx, uint16_t v)
+{
+ int Le;
+ float Y;
+
+ Le = v & 0x7fff;
+ if (!Le)
+ Y = 0;
+ else
+ {
+ Y = expf(M_LN2/256 * (Le + .5f) - M_LN2*64);
+ if (v & 0x8000)
+ Y = -Y;
+ }
+
+ return ((Y <= 0) ? 0 : (Y >= 1) ? 255 : (int)(256*sqrtf(Y)));
+}
+
+static int
+next_sgilog16(fz_context *ctx, fz_stream *stm, int max)
+{
+ fz_sgilog16 *state = stm->state;
+ uint16_t *p;
+ uint16_t *ep;
+ uint8_t *q;
+ int shift;
+
+ (void)max;
+
+ if (state->run < 0)
+ return EOF;
+
+ memset(state->temp, 0, state->w * sizeof(uint16_t));
+
+ for (shift = 8; shift >= 0; shift -= 8)
+ {
+ p = state->temp;
+ ep = p + state->w;
+ while (p < ep)
+ {
+ if (state->n == 0)
+ {
+ state->run = fz_read_byte(ctx, state->chain);
+ if (state->run < 0)
+ {
+ state->run = -1;
+ fz_throw(ctx, FZ_ERROR_GENERIC, "premature end of data in run length decode");
+ }
+ if (state->run < 128)
+ state->n = state->run;
+ else
+ {
+ state->n = state->run - 126;
+ state->c = fz_read_byte(ctx, state->chain);
+ if (state->c < 0)
+ {
+ state->run = -1;
+ fz_throw(ctx, FZ_ERROR_GENERIC, "premature end of data in run length decode");
+ }
+ }
+ }
+
+ if (state->run < 128)
+ {
+ while (p < ep && state->n)
+ {
+ int c = fz_read_byte(ctx, state->chain);
+ if (c < 0)
+ {
+ state->run = -1;
+ fz_throw(ctx, FZ_ERROR_GENERIC, "premature end of data in run length decode");
+ }
+ *p++ |= c<<shift;
+ state->n--;
+ }
+ }
+ else
+ {
+ while (p < ep && state->n)
+ {
+ *p++ |= state->c<<shift;
+ state->n--;
+ }
+ }
+ }
+ }
+
+ p = state->temp;
+ q = (uint8_t *)p;
+ ep = p + state->w;
+ while (p < ep)
+ {
+ *q++ = sgilog16val(ctx, *p++);
+ }
+
+ stm->rp = (uint8_t *)(state->temp);
+ stm->wp = q;
+ stm->pos += q - stm->rp;
+
+ if (q == stm->rp)
+ return EOF;
+
+ return *stm->rp++;
+}
+
+static void
+close_sgilog16(fz_context *ctx, void *state_)
+{
+ fz_sgilog16 *state = (fz_sgilog16 *)state_;
+ fz_stream *chain = state->chain;
+
+ fz_free(ctx, state->temp);
+ fz_free(ctx, state);
+ fz_drop_stream(ctx, chain);
+}
+
+fz_stream *
+fz_open_sgilog16(fz_context *ctx, fz_stream *chain, int w)
+{
+ fz_sgilog16 *state = NULL;
+
+ fz_var(state);
+
+ fz_try(ctx)
+ {
+ state = fz_malloc_struct(ctx, fz_sgilog16);
+ state->chain = chain;
+ state->run = 0;
+ state->n = 0;
+ state->c = 0;
+ state->w = w;
+ state->temp = fz_malloc(ctx, w * sizeof(uint16_t));
+ }
+ fz_catch(ctx)
+ {
+ fz_free(ctx, state);
+ fz_drop_stream(ctx, chain);
+ fz_rethrow(ctx);
+ }
+
+ return fz_new_stream(ctx, state, next_sgilog16, close_sgilog16);
+}
+
+/* SGI Log 24bit (LUV) */
+
+typedef struct fz_sgilog24_s fz_sgilog24;
+
+struct fz_sgilog24_s
+{
+ fz_stream *chain;
+ int err, w;
+ uint8_t *temp;
+};
+
+static int
+uv_decode(float *up, float *vp, int c) /* decode (u',v') index */
+{
+ int upper, lower;
+ register int ui, vi;
+
+ if (c < 0 || c >= UV_NDIVS)
+ return (-1);
+ lower = 0; /* binary search */
+ upper = UV_NVS;
+ while (upper - lower > 1) {
+ vi = (lower + upper) >> 1;
+ ui = c - uv_row[vi].ncum;
+ if (ui > 0)
+ lower = vi;
+ else if (ui < 0)
+ upper = vi;
+ else {
+ lower = vi;
+ break;
+ }
+ }
+ vi = lower;
+ ui = c - uv_row[vi].ncum;
+ *up = uv_row[vi].ustart + (ui+.5f)*UV_SQSIZ;
+ *vp = UV_VSTART + (vi+.5f)*UV_SQSIZ;
+ return (0);
+}
+
+static inline int
+sgilog24val(fz_context *ctx, fz_stream *chain, uint8_t *rgb)
+{
+ int b0, b1, b2;
+ int luv, p;
+ float u, v, s, x, y, X, Y, Z;
+ float r, g, b;
+
+ b0 = fz_read_byte(ctx, chain);
+ if (b0 < 0)
+ return b0;
+ b1 = fz_read_byte(ctx, chain);
+ if (b1 < 0)
+ return b1;
+ b2 = fz_read_byte(ctx, chain);
+ if (b2 < 0)
+ return b2;
+
+ luv = (b0<<16) | (b1<<8) | b2;
+
+ /* decode luminance */
+ p = (luv>>14) & 0x3ff;
+ Y = (p == 0 ? 0 : expf(M_LN2/64*(p+.5f) - M_LN2*12));
+ if (Y <= 0)
+ {
+ X = Y = Z = 0;
+ }
+ else
+ {
+ /* decode color */
+ if (uv_decode(&u, &v, luv & 0x3fff) < 0) {
+ u = U_NEU; v = V_NEU;
+ }
+ s = 6*u - 16*v + 12;
+ x = 9*u;
+ y = 4*v;
+ /* convert to XYZ */
+ X = x/y * Y;
+ Z = (s-x-y)/y * Y;
+ }
+
+ /* assume CCIR-709 primaries */
+ r = 2.690f*X + -1.276f*Y + -0.414f*Z;
+ g = -1.022f*X + 1.978f*Y + 0.044f*Z;
+ b = 0.061f*X + -0.224f*Y + 1.163f*Z;
+
+ /* assume 2.0 gamma for speed */
+ /* could use integer sqrt approx., but this is probably faster */
+ rgb[0] = (uint8_t)((r<=0) ? 0 : (r >= 1) ? 255 : (int)(256*sqrtf(r)));
+ rgb[1] = (uint8_t)((g<=0) ? 0 : (g >= 1) ? 255 : (int)(256*sqrtf(g)));
+ rgb[2] = (uint8_t)((b<=0) ? 0 : (b >= 1) ? 255 : (int)(256*sqrtf(b)));
+
+ return 0;
+}
+
+static int
+next_sgilog24(fz_context *ctx, fz_stream *stm, int max)
+{
+ fz_sgilog24 *state = stm->state;
+ uint8_t *p;
+ uint8_t *ep;
+
+ (void)max;
+
+ if (state->err)
+ return EOF;
+
+ memset(state->temp, 0, state->w * 3);
+
+ p = state->temp;
+ ep = p + state->w * 3;
+ while (p < ep)
+ {
+ int c = sgilog24val(ctx, state->chain, p);
+ if (c < 0)
+ {
+ state->err = 1;
+ fz_throw(ctx, FZ_ERROR_GENERIC, "premature end of data in run length decode");
+ }
+ p += 3;
+ }
+
+ stm->rp = state->temp;
+ stm->wp = p;
+ stm->pos += p - stm->rp;
+
+ if (p == stm->rp)
+ return EOF;
+
+ return *stm->rp++;
+}
+
+static void
+close_sgilog24(fz_context *ctx, void *state_)
+{
+ fz_sgilog24 *state = (fz_sgilog24 *)state_;
+ fz_stream *chain = state->chain;
+
+ fz_free(ctx, state->temp);
+ fz_free(ctx, state);
+ fz_drop_stream(ctx, chain);
+}
+
+fz_stream *
+fz_open_sgilog24(fz_context *ctx, fz_stream *chain, int w)
+{
+ fz_sgilog24 *state = NULL;
+
+ fz_var(state);
+
+ fz_try(ctx)
+ {
+ state = fz_malloc_struct(ctx, fz_sgilog24);
+ state->chain = chain;
+ state->err = 0;
+ state->w = w;
+ state->temp = fz_malloc(ctx, w * 3);
+ }
+ fz_catch(ctx)
+ {
+ fz_free(ctx, state);
+ fz_drop_stream(ctx, chain);
+ fz_rethrow(ctx);
+ }
+
+ return fz_new_stream(ctx, state, next_sgilog24, close_sgilog24);
+}
+
+/* SGI Log 32bit */
+
+typedef struct fz_sgilog32_s fz_sgilog32;
+
+struct fz_sgilog32_s
+{
+ fz_stream *chain;
+ int run, n, c, w;
+ uint32_t *temp;
+};
+
+static inline void
+sgilog32val(fz_context *ctx, uint32_t p, uint8_t *rgb)
+{
+ float r, g, b;
+ float u, v, s, x, y;
+ float X, Y, Z;
+
+ if (p>>31)
+ {
+ X = Y = Z = 0;
+ }
+ else
+ {
+ int Le = (p>>16) & 0x7fff;
+ Y = !Le ? 0 : expf(M_LN2/256*(Le+.5f) - M_LN2*64);
+ /* decode color */
+ u = (1.f/UVSCALE) * ((p>>8 & 0xff) + .5f);
+ v = (1.f/UVSCALE) * ((p & 0xff) + .5f);
+ s = 6*u - 16*v + 12;
+ x = 9 * u;
+ y = 4 * v;
+
+ /* convert to XYZ */
+ X = x/y * Y;
+ Z = (s-x-y)/y * Y;
+ }
+
+ /* assume CCIR-709 primaries */
+ r = 2.690f*X + -1.276f*Y + -0.414f*Z;
+ g = -1.022f*X + 1.978f*Y + 0.044f*Z;
+ b = 0.061f*X + -0.224f*Y + 1.163f*Z;
+
+ /* assume 2.0 gamma for speed */
+ /* could use integer sqrt approx., but this is probably faster */
+ rgb[0] = (uint8_t)((r<=0) ? 0 : (r >= 1) ? 255 : (int)(256*sqrtf(r)));
+ rgb[1] = (uint8_t)((g<=0) ? 0 : (g >= 1) ? 255 : (int)(256*sqrtf(g)));
+ rgb[2] = (uint8_t)((b<=0) ? 0 : (b >= 1) ? 255 : (int)(256*sqrtf(b)));
+}
+
+static int
+next_sgilog32(fz_context *ctx, fz_stream *stm, int max)
+{
+ fz_sgilog32 *state = stm->state;
+ uint32_t *p;
+ uint32_t *ep;
+ uint8_t *q;
+ int shift;
+
+ (void)max;
+
+ if (state->run < 0)
+ return EOF;
+
+ memset(state->temp, 0, state->w * sizeof(uint32_t));
+
+ for (shift = 24; shift >= 0; shift -= 8)
+ {
+ p = state->temp;
+ ep = p + state->w;
+ while (p < ep)
+ {
+ if (state->n == 0)
+ {
+ state->run = fz_read_byte(ctx, state->chain);
+ if (state->run < 0)
+ {
+ state->run = -1;
+ fz_throw(ctx, FZ_ERROR_GENERIC, "premature end of data in run length decode");
+ }
+ if (state->run < 128)
+ state->n = state->run;
+ else
+ {
+ state->n = state->run - 126;
+ state->c = fz_read_byte(ctx, state->chain);
+ if (state->c < 0)
+ {
+ state->run = -1;
+ fz_throw(ctx, FZ_ERROR_GENERIC, "premature end of data in run length decode");
+ }
+ }
+ }
+
+ if (state->run < 128)
+ {
+ while (p < ep && state->n)
+ {
+ int c = fz_read_byte(ctx, state->chain);
+ if (c < 0)
+ {
+ state->run = -1;
+ fz_throw(ctx, FZ_ERROR_GENERIC, "premature end of data in run length decode");
+ }
+ *p++ |= c<<shift;
+ state->n--;
+ }
+ }
+ else
+ {
+ while (p < ep && state->n)
+ {
+ *p++ |= state->c<<shift;
+ state->n--;
+ }
+ }
+ }
+ }
+
+ p = state->temp;
+ q = (uint8_t *)p;
+ ep = p + state->w;
+ while (p < ep)
+ {
+ sgilog32val(ctx, *p++, q);
+ q += 3;
+ }
+
+ stm->rp = (uint8_t *)(state->temp);
+ stm->wp = q;
+ stm->pos += q - stm->rp;
+
+ if (q == stm->rp)
+ return EOF;
+
+ return *stm->rp++;
+}
+
+static void
+close_sgilog32(fz_context *ctx, void *state_)
+{
+ fz_sgilog32 *state = (fz_sgilog32 *)state_;
+ fz_stream *chain = state->chain;
+
+ fz_free(ctx, state->temp);
+ fz_free(ctx, state);
+ fz_drop_stream(ctx, chain);
+}
+
+fz_stream *
+fz_open_sgilog32(fz_context *ctx, fz_stream *chain, int w)
+{
+ fz_sgilog32 *state = NULL;
+
+ fz_var(state);
+
+ fz_try(ctx)
+ {
+ state = fz_malloc_struct(ctx, fz_sgilog32);
+ state->chain = chain;
+ state->run = 0;
+ state->n = 0;
+ state->c = 0;
+ state->w = w;
+ state->temp = fz_malloc(ctx, w * sizeof(uint32_t));
+ }
+ fz_catch(ctx)
+ {
+ fz_free(ctx, state);
+ fz_drop_stream(ctx, chain);
+ fz_rethrow(ctx);
+ }
+
+ return fz_new_stream(ctx, state, next_sgilog32, close_sgilog32);
+}
diff --git a/source/fitz/load-tiff.c b/source/fitz/load-tiff.c
index 3df9f7c8..297d71dc 100644
--- a/source/fitz/load-tiff.c
+++ b/source/fitz/load-tiff.c
@@ -154,6 +154,29 @@ fz_decode_tiff_packbits(fz_context *ctx, struct tiff *tiff, fz_stream *chain, un
fz_drop_stream(ctx, stm);
}
+fz_decode_tiff_sgilog16(fz_context *ctx, struct tiff *tiff, fz_stream *chain, unsigned char *wp, int wlen, int w)
+{
+ fz_stream *stm = fz_open_sgilog16(ctx, chain, w);
+ fz_read(ctx, stm, wp, wlen);
+ fz_drop_stream(ctx, stm);
+}
+
+static void
+fz_decode_tiff_sgilog24(fz_context *ctx, struct tiff *tiff, fz_stream *chain, unsigned char *wp, int wlen, int w)
+{
+ fz_stream *stm = fz_open_sgilog24(ctx, chain, w);
+ fz_read(ctx, stm, wp, wlen);
+ fz_drop_stream(ctx, stm);
+}
+
+static void
+fz_decode_tiff_sgilog32(fz_context *ctx, struct tiff *tiff, fz_stream *chain, unsigned char *wp, int wlen, int w)
+{
+ fz_stream *stm = fz_open_sgilog32(ctx, chain, w);
+ fz_read(ctx, stm, wp, wlen);
+ fz_drop_stream(ctx, stm);
+}
+
static void
fz_decode_tiff_lzw(fz_context *ctx, struct tiff *tiff, fz_stream *chain, unsigned char *wp, int wlen, int old_tiff)
{
@@ -390,6 +413,16 @@ fz_decode_tiff_strips(fz_context *ctx, struct tiff *tiff)
/* it's probably a jpeg ... we let jpeg convert to rgb */
tiff->colorspace = fz_device_rgb(ctx);
break;
+ case 32844: /* SGI CIE Log 2 L (16bpp Greyscale) */
+ tiff->colorspace = fz_device_gray(ctx);
+ tiff->bitspersample = 8;
+ tiff->stride >>= 1;
+ break;
+ case 32845: /* SGI CIE Log 2 L, u, v (24bpp or 32bpp) */
+ tiff->colorspace = fz_device_rgb(ctx);
+ tiff->bitspersample = 8;
+ tiff->stride >>= 1;
+ break;
default:
fz_throw(ctx, FZ_ERROR_GENERIC, "unknown photometric: %d", tiff->photometric);
}
@@ -471,6 +504,15 @@ fz_decode_tiff_strips(fz_context *ctx, struct tiff *tiff)
case 32773:
fz_decode_tiff_packbits(ctx, tiff, stm, wp, wlen);
break;
+ case 34676:
+ if (tiff->photometric == 32845)
+ fz_decode_tiff_sgilog32(ctx, tiff, stm, wp, wlen, tiff->imagewidth);
+ else
+ fz_decode_tiff_sgilog16(ctx, tiff, stm, wp, wlen, tiff->imagewidth);
+ break;
+ case 34677:
+ fz_decode_tiff_sgilog24(ctx, tiff, stm, wp, wlen, tiff->imagewidth);
+ break;
default:
fz_throw(ctx, FZ_ERROR_GENERIC, "unknown TIFF compression: %d", tiff->compression);
}