2
* "$Id: image-gif.c 9840 2011-06-20 20:37:39Z mike $"
4
* GIF image routines for CUPS.
6
* Copyright 2007-2011 by Apple Inc.
7
* Copyright 1993-2007 by Easy Software Products.
9
* These coded instructions, statements, and computer programs are the
10
* property of Apple Inc. and are protected by Federal copyright
11
* law. Distribution and use rights are outlined in the file "LICENSE.txt"
12
* which should have been included with this file. If this file is
13
* file is missing or damaged, see the license at "http://www.cups.org/".
15
* This file is subject to the Apple OS-Developed Software exception.
19
* _cupsImageReadGIF() - Read a GIF image file.
20
* gif_get_block() - Read a GIF data block...
21
* gif_get_code() - Get a LZW code from the file...
22
* gif_read_cmap() - Read the colormap from a GIF file...
23
* gif_read_image() - Read a GIF image stream...
24
* gif_read_lzw() - Read a byte from the LZW stream...
28
* Include necessary headers...
31
#include "image-private.h"
38
#define GIF_INTERLACE 0x40
39
#define GIF_COLORMAP 0x80
40
#define GIF_MAX_BITS 12
42
typedef cups_ib_t gif_cmap_t[256][4];
43
typedef short gif_table_t[4096];
50
static int gif_eof = 0; /* Did we hit EOF? */
57
static int gif_get_block(FILE *fp, unsigned char *buffer);
58
static int gif_get_code (FILE *fp, int code_size, int first_time);
59
static int gif_read_cmap(FILE *fp, int ncolors, gif_cmap_t cmap,
61
static int gif_read_image(FILE *fp, cups_image_t *img, gif_cmap_t cmap,
63
static int gif_read_lzw(FILE *fp, int first_time, int input_code_size);
67
* '_cupsImageReadGIF()' - Read a GIF image file.
70
int /* O - Read status */
72
cups_image_t *img, /* IO - cupsImage */
73
FILE *fp, /* I - cupsImage file */
74
cups_icspace_t primary, /* I - Primary choice for colorspace */
75
cups_icspace_t secondary, /* I - Secondary choice for colorspace */
76
int saturation, /* I - Color saturation (%) */
77
int hue, /* I - Color hue (degrees) */
78
const cups_ib_t *lut) /* I - Lookup table for gamma/brightness */
80
unsigned char buf[1024]; /* Input buffer */
81
gif_cmap_t cmap; /* Colormap */
82
int i, /* Looping var */
83
bpp, /* Bytes per pixel */
84
gray, /* Grayscale image? */
85
ncolors, /* Bits per pixel */
86
transparent; /* Transparent color index */
90
* GIF files are either grayscale or RGB - no CMYK...
93
if (primary == CUPS_IMAGE_RGB_CMYK)
94
primary = CUPS_IMAGE_RGB;
97
* Read the header; we already know it is a GIF file...
100
fread(buf, 13, 1, fp);
102
img->xsize = (buf[7] << 8) | buf[6];
103
img->ysize = (buf[9] << 8) | buf[8];
104
ncolors = 2 << (buf[10] & 0x07);
105
gray = primary == CUPS_IMAGE_BLACK || primary == CUPS_IMAGE_WHITE;
107
if (buf[10] & GIF_COLORMAP)
108
if (gif_read_cmap(fp, ncolors, cmap, &gray))
120
case ';' : /* End of image */
122
return (-1); /* Early end of file */
124
case '!' : /* Extension record */
126
if (buf[0] == 0xf9) /* Graphic Control Extension */
128
gif_get_block(fp, buf);
129
if (buf[0] & 1) /* Get transparent color index */
130
transparent = buf[3];
133
while (gif_get_block(fp, buf) != 0);
136
case ',' : /* cupsImage data */
137
fread(buf, 9, 1, fp);
139
if (buf[8] & GIF_COLORMAP)
141
ncolors = 2 << (buf[8] & 0x07);
142
gray = primary == CUPS_IMAGE_BLACK || primary == CUPS_IMAGE_WHITE;
144
if (gif_read_cmap(fp, ncolors, cmap, &gray))
151
if (transparent >= 0)
154
* Make transparent color white...
157
cmap[transparent][0] = 255;
158
cmap[transparent][1] = 255;
159
cmap[transparent][2] = 255;
166
case CUPS_IMAGE_CMYK :
167
for (i = ncolors - 1; i >= 0; i --)
168
cupsImageWhiteToCMYK(cmap[i], cmap[i], 1);
170
case CUPS_IMAGE_CMY :
171
for (i = ncolors - 1; i >= 0; i --)
172
cupsImageWhiteToCMY(cmap[i], cmap[i], 1);
174
case CUPS_IMAGE_BLACK :
175
for (i = ncolors - 1; i >= 0; i --)
176
cupsImageWhiteToBlack(cmap[i], cmap[i], 1);
178
case CUPS_IMAGE_WHITE :
180
case CUPS_IMAGE_RGB :
181
case CUPS_IMAGE_RGB_CMYK :
182
for (i = ncolors - 1; i >= 0; i --)
183
cupsImageWhiteToRGB(cmap[i], cmap[i], 1);
187
img->colorspace = secondary;
191
if (hue != 0 || saturation != 100)
192
for (i = ncolors - 1; i >= 0; i --)
193
cupsImageRGBAdjust(cmap[i], 1, saturation, hue);
197
case CUPS_IMAGE_CMYK :
198
for (i = ncolors - 1; i >= 0; i --)
199
cupsImageRGBToCMYK(cmap[i], cmap[i], 1);
201
case CUPS_IMAGE_CMY :
202
for (i = ncolors - 1; i >= 0; i --)
203
cupsImageRGBToCMY(cmap[i], cmap[i], 1);
205
case CUPS_IMAGE_BLACK :
206
for (i = ncolors - 1; i >= 0; i --)
207
cupsImageRGBToBlack(cmap[i], cmap[i], 1);
209
case CUPS_IMAGE_WHITE :
210
for (i = ncolors - 1; i >= 0; i --)
211
cupsImageRGBToWhite(cmap[i], cmap[i], 1);
213
case CUPS_IMAGE_RGB :
214
case CUPS_IMAGE_RGB_CMYK :
215
for (i = ncolors - 1; i >= 0; i --)
216
cupsImageRGBToRGB(cmap[i], cmap[i], 1);
220
img->colorspace = primary;
225
bpp = cupsImageGetDepth(img);
227
for (i = ncolors - 1; i >= 0; i --)
228
cupsImageLut(cmap[i], bpp, lut);
231
img->xsize = (buf[5] << 8) | buf[4];
232
img->ysize = (buf[7] << 8) | buf[6];
235
* Check the dimensions of the image; since the dimensions are
236
* a 16-bit integer we just need to check for 0...
239
if (img->xsize == 0 || img->ysize == 0)
241
fprintf(stderr, "DEBUG: Bad GIF image dimensions: %dx%d\n",
242
img->xsize, img->ysize);
247
i = gif_read_image(fp, img, cmap, buf[8] & GIF_INTERLACE);
256
* 'gif_get_block()' - Read a GIF data block...
259
static int /* O - Number characters read */
260
gif_get_block(FILE *fp, /* I - File to read from */
261
unsigned char *buf) /* I - Input buffer */
263
int count; /* Number of character to read */
267
* Read the count byte followed by the data from the file...
270
if ((count = getc(fp)) == EOF)
277
else if (fread(buf, 1, count, fp) < count)
290
* 'gif_get_code()' - Get a LZW code from the file...
293
static int /* O - LZW code */
294
gif_get_code(FILE *fp, /* I - File to read from */
295
int code_size, /* I - Size of code in bits */
296
int first_time) /* I - 1 = first time, 0 = not first time */
298
unsigned i, j, /* Looping vars */
299
ret; /* Return value */
300
int count; /* Number of bytes read */
301
static unsigned char buf[280]; /* Input buffer */
302
static unsigned curbit, /* Current bit */
303
lastbit, /* Last bit in buffer */
304
done, /* Done with this buffer? */
305
last_byte; /* Last byte in buffer */
306
static const unsigned char bits[8] = /* Bit masks for codes */
308
0x01, 0x02, 0x04, 0x08,
309
0x10, 0x20, 0x40, 0x80
316
* Just initialize the input buffer...
327
if ((curbit + code_size) >= lastbit)
330
* Don't have enough bits to hold the code...
334
return (-1); /* Sorry, no more... */
337
* Move last two bytes to front of buffer...
342
buf[0] = buf[last_byte - 2];
343
buf[1] = buf[last_byte - 1];
346
else if (last_byte == 1)
348
buf[0] = buf[last_byte - 1];
353
* Read in another buffer...
356
if ((count = gif_get_block(fp, buf + last_byte)) <= 0)
359
* Whoops, no more data!
367
* Update buffer state...
370
curbit = (curbit - lastbit) + 8 * last_byte;
372
lastbit = last_byte * 8;
375
for (ret = 0, i = curbit + code_size - 1, j = code_size;
378
ret = (ret << 1) | ((buf[i / 8] & bits[i & 7]) != 0);
387
* 'gif_read_cmap()' - Read the colormap from a GIF file...
390
static int /* O - -1 on error, 0 on success */
391
gif_read_cmap(FILE *fp, /* I - File to read from */
392
int ncolors, /* I - Number of colors in file */
393
gif_cmap_t cmap, /* O - Colormap information */
394
int *gray) /* IO - Is the image grayscale? */
396
int i; /* Looping var */
400
* Read the colormap...
403
for (i = 0; i < ncolors; i ++)
404
if (fread(cmap[i], 3, 1, fp) < 1)
408
* Check to see if the colormap is a grayscale ramp...
411
for (i = 0; i < ncolors; i ++)
412
if (cmap[i][0] != cmap[i][1] || cmap[i][1] != cmap[i][2])
422
* If this needs to be a grayscale image, convert the RGB values to
423
* luminance values...
427
for (i = 0; i < ncolors; i ++)
428
cmap[i][0] = (cmap[i][0] * 31 + cmap[i][1] * 61 + cmap[i][2] * 8) / 100;
435
* 'gif_read_image()' - Read a GIF image stream...
438
static int /* I - 0 = success, -1 = failure */
439
gif_read_image(FILE *fp, /* I - Input file */
440
cups_image_t *img, /* I - cupsImage pointer */
441
gif_cmap_t cmap, /* I - Colormap */
442
int interlace) /* I - Non-zero = interlaced image */
444
unsigned char code_size; /* Code size */
445
cups_ib_t *pixels, /* Pixel buffer */
446
*temp; /* Current pixel */
447
int xpos, /* Current X position */
448
ypos, /* Current Y position */
449
pass; /* Current pass */
450
int pixel; /* Current pixel */
451
int bpp; /* Bytes per pixel */
452
static const int xpasses[4] = /* X interleaving */
454
ypasses[5] = /* Y interleaving */
455
{ 0, 4, 2, 1, 999999 };
458
bpp = cupsImageGetDepth(img);
459
pixels = calloc(bpp, img->xsize);
463
code_size = getc(fp);
468
if (code_size > GIF_MAX_BITS || gif_read_lzw(fp, 1, code_size) < 0)
475
while ((pixel = gif_read_lzw(fp, 0, code_size)) >= 0)
480
temp[3] = cmap[pixel][3];
482
temp[2] = cmap[pixel][2];
484
temp[1] = cmap[pixel][1];
486
temp[0] = cmap[pixel][0];
491
if (xpos == img->xsize)
493
_cupsImagePutRow(img, 0, ypos, img->xsize, pixels);
500
ypos += xpasses[pass];
502
if (ypos >= img->ysize)
506
ypos = ypasses[pass];
513
if (ypos >= img->ysize)
524
* 'gif_read_lzw()' - Read a byte from the LZW stream...
527
static int /* I - Byte from stream */
528
gif_read_lzw(FILE *fp, /* I - File to read from */
529
int first_time, /* I - 1 = first time, 0 = not first time */
530
int input_code_size) /* I - Code size in bits */
532
int i, /* Looping var */
533
code, /* Current code */
534
incode; /* Input code */
535
static short fresh = 0, /* 1 = empty buffers */
536
code_size, /* Current code size */
537
set_code_size, /* Initial code size set */
538
max_code, /* Maximum code used */
539
max_code_size, /* Maximum code size */
540
firstcode, /* First code read */
541
oldcode, /* Last code read */
542
clear_code, /* Clear code for LZW input */
543
end_code, /* End code for LZW input */
544
*stack = NULL, /* Output stack */
545
*sp; /* Current stack pointer */
546
static gif_table_t *table = NULL; /* String table */
555
set_code_size = input_code_size;
556
code_size = set_code_size + 1;
557
clear_code = 1 << set_code_size;
558
end_code = clear_code + 1;
559
max_code_size = 2 * clear_code;
560
max_code = clear_code + 2;
563
* Allocate memory for buffers...
567
table = calloc(2, sizeof(gif_table_t));
573
stack = calloc(8192, sizeof(short));
579
* Initialize input buffers...
582
gif_get_code(fp, 0, 1);
585
* Wipe the decompressor table (already mostly 0 due to the calloc above...)
590
for (i = 1; i < clear_code; i ++)
603
firstcode = oldcode = gif_get_code(fp, code_size, 0);
605
while (firstcode == clear_code);
607
return (firstcode & 255);
613
return ((*--sp) & 255);
615
while ((code = gif_get_code(fp, code_size, 0)) >= 0)
617
if (code == clear_code)
620
* Clear/reset the compression table...
623
memset(table, 0, 2 * sizeof(gif_table_t));
624
for (i = 1; i < clear_code; i ++)
627
code_size = set_code_size + 1;
628
max_code_size = 2 * clear_code;
629
max_code = clear_code + 2;
633
firstcode = oldcode = gif_get_code(fp, code_size, 0);
635
return (firstcode & 255);
637
else if (code == end_code || code > max_code)
639
unsigned char buf[260]; /* Block buffer */
642
while (gif_get_block(fp, buf) > 0);
649
if (code == max_code)
655
while (code >= clear_code)
657
*sp++ = table[1][code];
658
if (code == table[0][code])
661
code = table[0][code];
664
*sp++ = firstcode = table[1][code];
669
table[0][code] = oldcode;
670
table[1][code] = firstcode;
673
if (max_code >= max_code_size && max_code_size < 4096)
683
return ((*--sp) & 255);
691
* End of "$Id: image-gif.c 9840 2011-06-20 20:37:39Z mike $".