1 /* $Id: gif2tiff.c,v 1.12 2010-12-15 00:22:44 faxguy Exp $ */
4 * Copyright (c) 1990-1997 Sam Leffler
5 * Copyright (c) 1991-1997 Silicon Graphics, Inc.
7 * Permission to use, copy, modify, distribute, and sell this software and
8 * its documentation for any purpose is hereby granted without fee, provided
9 * that (i) the above copyright notices and this permission notice appear in
10 * all copies of the software and related documentation, and (ii) the names of
11 * Sam Leffler and Silicon Graphics may not be used in any advertising or
12 * publicity relating to the software without the specific, prior written
13 * permission of Sam Leffler and Silicon Graphics.
15 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
17 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
19 * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
20 * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
21 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
22 * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
23 * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
28 * convert a GIF file into a TIFF file.
29 * based on Paul Haeberli's fromgif program which in turn is
30 * based on a GIF file reader by Marcel J.E. Mol March 23 1989
32 * if input is 320 by 200 pixel aspect is probably 1.2
33 * if input is 640 350 pixel aspect is probably 1.37
36 #include "tif_config.h"
53 #define GIFGAMMA (1.5) /* smaller makes output img brighter */
54 #define IMAX 0xffff /* max intensity value */
55 #define EXTRAFUDGE 128 /* some people write BAD .gif files */
57 #define streq(a,b) (strcmp(a,b) == 0)
58 #define strneq(a,b,n) (strncmp(a,b,n) == 0)
60 unsigned short gamtab[256];
68 gamtab[i] = (unsigned short) (IMAX*pow(i/255.0,gam)+0.5);
72 "usage: gif2tiff [options] input.gif output.tif",
74 " -r # make each strip have no more than # rows",
76 " -c lzw[:opts] compress output with Lempel-Ziv & Welch encoding",
77 " -c zip[:opts] compress output with deflate encoding",
78 " -c packbits compress output with packbits encoding",
79 " -c none use no compression algorithm on output",
81 "LZW and deflate options:",
82 " # set predictor value",
83 "For example, -c lzw:2 to get LZW-encoded data with horizontal differencing",
94 fprintf(stderr, "%s\n\n", TIFFGetVersion());
95 for (i = 0; stuff[i] != NULL; i++)
96 fprintf(stderr, "%s\n", stuff[i]);
102 unsigned char *stackp;
103 unsigned int prefix[4096];
104 unsigned char suffix[4096];
105 unsigned char stack[4096];
106 int datasize,codesize,codemask; /* Decoder working variables */
107 int clear,eoi; /* Special code values */
111 int global; /* Is there a global color map? */
112 int globalbits; /* Number of bits of global colors */
113 unsigned char globalmap[COLSIZE][3];/* RGB values for global color map */
114 unsigned char *raster; /* Decoded image data */
115 unsigned long width, height;
116 unsigned short red[COLSIZE];
117 unsigned short green[COLSIZE];
118 unsigned short blue[COLSIZE];
119 char *filename, *imagename;
121 static uint16 compression = COMPRESSION_PACKBITS;
122 static uint16 predictor = 0;
123 static uint32 rowsperstrip = (uint32) -1;
124 static int processCompressOptions(char*);
127 int checksignature(void);
128 void readscreen(void);
129 int readgifimage(char*);
130 void readextension(void);
131 int readraster(void);
132 int process(int, unsigned char**);
133 void initcolors(unsigned char [COLSIZE][3], int);
134 void rasterize(int, char*);
137 main(int argc, char* argv[])
143 while ((c = getopt(argc, argv, "c:r:")) != -1)
145 case 'c': /* compression scheme */
146 if (!processCompressOptions(optarg))
149 case 'r': /* rows/strip */
150 rowsperstrip = atoi(optarg);
156 if (argc - optind != 2)
159 makegamtab(GIFGAMMA);
160 filename = argv[optind];
161 imagename = argv[optind+1];
162 if ((infile = fopen(imagename, "rb")) != NULL) {
165 printf("overwrite %s? ", imagename); fflush(stdout);
167 if (c != 'y' && c != 'Y')
170 if ((infile = fopen(filename, "rb")) == NULL) {
180 processCompressOptions(char* opt)
182 if (streq(opt, "none"))
183 compression = COMPRESSION_NONE;
184 else if (streq(opt, "packbits"))
185 compression = COMPRESSION_PACKBITS;
186 else if (strneq(opt, "lzw", 3)) {
187 char* cp = strchr(opt, ':');
189 predictor = atoi(cp+1);
190 compression = COMPRESSION_LZW;
191 } else if (strneq(opt, "zip", 3)) {
192 char* cp = strchr(opt, ':');
194 predictor = atoi(cp+1);
195 compression = COMPRESSION_DEFLATE;
207 if (!checksignature())
210 while ((ch = getc(infile)) != ';' && ch != EOF) {
212 case '\0': break; /* this kludge for non-standard files */
213 case ',': if (!readgifimage(mode))
215 mode = "a"; /* subsequent images append */
217 case '!': readextension();
219 default: fprintf(stderr, "illegal GIF block type\n");
231 fread(buf,1,6,infile);
232 if (strncmp(buf,"GIF",3)) {
233 fprintf(stderr, "file is not a GIF file\n");
236 if (strncmp(&buf[3],"87a",3)) {
237 fprintf(stderr, "unknown GIF version number\n");
245 * Get information which is global to all the images stored
251 unsigned char buf[7];
253 fread(buf,1,7,infile);
254 global = buf[4] & 0x80;
256 globalbits = (buf[4] & 0x07) + 1;
257 fread(globalmap,3,((size_t)1)<<globalbits,infile);
262 readgifimage(char* mode)
264 unsigned char buf[9];
265 int local, interleaved;
266 unsigned char localmap[256][3];
270 if (fread(buf, 1, 9, infile) == 0) {
274 width = buf[4] + (buf[5] << 8);
275 height = buf[6] + (buf[7] << 8);
276 local = buf[8] & 0x80;
277 interleaved = buf[8] & 0x40;
279 if (local == 0 && global == 0) {
280 fprintf(stderr, "no colormap present for image\n");
283 if ((raster = (unsigned char*) _TIFFmalloc(width*height+EXTRAFUDGE)) == NULL) {
284 fprintf(stderr, "not enough memory for image\n");
288 localbits = (buf[8] & 0x7) + 1;
290 fprintf(stderr, " local colors: %d\n", 1<<localbits);
292 fread(localmap, 3, ((size_t)1)<<localbits, infile);
293 initcolors(localmap, 1<<localbits);
295 initcolors(globalmap, 1<<globalbits);
297 if ((status = readraster()))
298 rasterize(interleaved, mode);
305 * Read a GIF extension block (and do nothing with it).
315 while ((count = getc(infile)))
316 fread(buf, 1, count, infile);
321 * Decode a raster image
327 unsigned char *fill = raster;
328 unsigned char buf[255];
330 register unsigned long datum=0;
331 register unsigned char *ch;
332 register int count, code;
335 datasize = getc(infile);
336 clear = 1 << datasize;
340 codesize = datasize + 1;
341 codemask = (1 << codesize) - 1;
342 for (code = 0; code < clear; code++) {
347 for (count = getc(infile); count > 0; count = getc(infile)) {
348 fread(buf,1,count,infile);
349 for (ch=buf; count-- > 0; ch++) {
350 datum += (unsigned long) *ch << bits;
352 while (bits >= codesize) {
353 code = datum & codemask;
356 if (code == eoi) { /* This kludge put in */
357 goto exitloop; /* because some GIF files*/
358 } /* aren't standard */
359 if (!process(code, &fill)) {
365 if (fill >= raster + width*height) {
366 fprintf(stderr, "raster full before eoi code\n");
371 if (fill != raster + width*height) {
372 fprintf(stderr, "warning: wrong rastersize: %ld bytes\n",
373 (long) (fill-raster));
374 fprintf(stderr, " instead of %ld bytes\n",
375 (long) width*height);
382 * Process a compression code. "clear" resets the code table.
383 * Otherwise make a new code table entry, and output the bytes
384 * associated with the code.
387 process(register int code, unsigned char** fill)
390 static unsigned char firstchar;
393 codesize = datasize + 1;
394 codemask = (1 << codesize) - 1;
401 *(*fill)++ = suffix[code];
402 firstchar = oldcode = code;
406 fprintf(stderr, "code %d too large for %d\n", code, avail);
411 if (code == avail) { /* the first code is always < avail */
412 *stackp++ = firstchar;
415 while (code > clear) {
416 *stackp++ = suffix[code];
420 *stackp++ = firstchar = suffix[code];
421 prefix[avail] = oldcode;
422 suffix[avail] = firstchar;
425 if (((avail & codemask) == 0) && (avail < 4096)) {
431 *(*fill)++ = *--stackp;
432 } while (stackp > stack);
438 * Convert a color map (local or global) to arrays with R, G and B
443 initcolors(unsigned char colormap[COLSIZE][3], int ncolors)
447 for (i = 0; i < ncolors; i++) {
448 red[i] = gamtab[colormap[i][0]];
449 green[i] = gamtab[colormap[i][1]];
450 blue[i] = gamtab[colormap[i][2]];
455 rasterize(int interleaved, char* mode)
457 register unsigned long row;
458 unsigned char *newras;
464 if ((newras = (unsigned char*) _TIFFmalloc(width*height+EXTRAFUDGE)) == NULL) {
465 fprintf(stderr, "not enough memory for image\n");
468 #define DRAWSEGMENT(offset, step) { \
469 for (row = offset; row < height; row += step) { \
470 _TIFFmemcpy(newras + row*width, ras, width);\
484 tif = TIFFOpen(imagename, mode);
486 TIFFError(imagename,"Can not open output image");
489 TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, (uint32) width);
490 TIFFSetField(tif, TIFFTAG_IMAGELENGTH, (uint32) height);
491 TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_PALETTE);
492 TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
493 TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 1);
494 TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, 8);
495 TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP,
496 rowsperstrip = TIFFDefaultStripSize(tif, rowsperstrip));
497 TIFFSetField(tif, TIFFTAG_COMPRESSION, compression);
498 switch (compression) {
499 case COMPRESSION_LZW:
500 case COMPRESSION_DEFLATE:
502 TIFFSetField(tif, TIFFTAG_PREDICTOR, predictor);
505 TIFFSetField(tif, TIFFTAG_COLORMAP, red, green, blue);
506 TIFFSetField(tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
508 stripsize = TIFFStripSize(tif);
509 for (row=0; row<height; row += rowsperstrip) {
510 if (rowsperstrip > height-row) {
511 rowsperstrip = height-row;
512 stripsize = TIFFVStripSize(tif, rowsperstrip);
514 if (TIFFWriteEncodedStrip(tif, strip, newras+row*width, stripsize) < 0)
523 /* vim: set ts=8 sts=8 sw=8 noet: */