ReactOS 0.4.15-dev-7842-g558ab78
rdgif.c
Go to the documentation of this file.
1/*
2 * rdgif.c
3 *
4 * Copyright (C) 1991-1996, Thomas G. Lane.
5 * Modified 2019 by Guido Vollbeding.
6 * This file is part of the Independent JPEG Group's software.
7 * For conditions of distribution and use, see the accompanying README file.
8 *
9 * This file contains routines to read input images in GIF format.
10 *
11 * These routines may need modification for non-Unix environments or
12 * specialized applications. As they stand, they assume input from
13 * an ordinary stdio stream. They further assume that reading begins
14 * at the start of the file; start_input may need work if the
15 * user interface has already read some data (e.g., to determine that
16 * the file is indeed GIF format).
17 */
18
19/*
20 * This code is loosely based on giftoppm from the PBMPLUS distribution
21 * of Feb. 1991. That file contains the following copyright notice:
22 * +-------------------------------------------------------------------+
23 * | Copyright 1990, David Koblas. |
24 * | Permission to use, copy, modify, and distribute this software |
25 * | and its documentation for any purpose and without fee is hereby |
26 * | granted, provided that the above copyright notice appear in all |
27 * | copies and that both that copyright notice and this permission |
28 * | notice appear in supporting documentation. This software is |
29 * | provided "as is" without express or implied warranty. |
30 * +-------------------------------------------------------------------+
31 */
32
33#include "cdjpeg.h" /* Common decls for cjpeg/djpeg applications */
34
35#ifdef GIF_SUPPORTED
36
37
38/* Macros to deal with unsigned chars as efficiently as compiler allows */
39
40#ifdef HAVE_UNSIGNED_CHAR
41typedef unsigned char U_CHAR;
42#define UCH(x) ((int) (x))
43#else /* !HAVE_UNSIGNED_CHAR */
44typedef char U_CHAR;
45#ifdef CHAR_IS_UNSIGNED
46#define UCH(x) ((int) (x))
47#else
48#define UCH(x) ((int) (x) & 0xFF)
49#endif
50#endif /* HAVE_UNSIGNED_CHAR */
51
52
53#define ReadOK(file,buffer,len) (JFREAD(file,buffer,len) == ((size_t) (len)))
54
55
56#define MAXCOLORMAPSIZE 256 /* max # of colors in a GIF colormap */
57#define NUMCOLORS 3 /* # of colors */
58#define CM_RED 0 /* color component numbers */
59#define CM_GREEN 1
60#define CM_BLUE 2
61
62#define MAX_LZW_BITS 12 /* maximum LZW code size */
63#define LZW_TABLE_SIZE (1<<MAX_LZW_BITS) /* # of possible LZW symbols */
64
65/* Macros for extracting header data --- note we assume chars may be signed */
66
67#define LM_to_uint(array, offset) ((unsigned int) UCH(array[offset]) + \
68 (((unsigned int) UCH(array[offset+1])) << 8))
69
70#define BitSet(byte, bit) ((byte) & (bit))
71#define INTERLACE 0x40 /* mask for bit signifying interlaced image */
72#define COLORMAPFLAG 0x80 /* mask for bit signifying colormap presence */
73
74
75/*
76 * LZW decompression tables look like this:
77 * symbol_head[K] = prefix symbol of any LZW symbol K (0..LZW_TABLE_SIZE-1)
78 * symbol_tail[K] = suffix byte of any LZW symbol K (0..LZW_TABLE_SIZE-1)
79 * Note that entries 0..end_code of the above tables are not used,
80 * since those symbols represent raw bytes or special codes.
81 *
82 * The stack represents the not-yet-used expansion of the last LZW symbol.
83 * In the worst case, a symbol could expand to as many bytes as there are
84 * LZW symbols, so we allocate LZW_TABLE_SIZE bytes for the stack.
85 * (This is conservative since that number includes the raw-byte symbols.)
86 *
87 * The tables are allocated from FAR heap space since they would use up
88 * rather a lot of the near data space in a PC.
89 */
90
91
92/* Private version of data source object */
93
94typedef struct {
95 struct cjpeg_source_struct pub; /* public fields */
96
97 j_compress_ptr cinfo; /* back link saves passing separate parm */
98
99 JSAMPARRAY colormap; /* GIF colormap (converted to my format) */
100
101 /* State for GetCode and LZWReadByte */
102 U_CHAR code_buf[256+4]; /* current input data block */
103 int last_byte; /* # of bytes in code_buf */
104 int last_bit; /* # of bits in code_buf */
105 int cur_bit; /* next bit index to read */
106 boolean first_time; /* flags first call to GetCode */
107 boolean out_of_blocks; /* TRUE if hit terminator data block */
108
109 int input_code_size; /* codesize given in GIF file */
110 int clear_code, end_code; /* values for Clear and End codes */
111
112 int code_size; /* current actual code size */
113 int limit_code; /* 2^code_size */
114 int max_code; /* first unused code value */
115
116 /* Private state for LZWReadByte */
117 int oldcode; /* previous LZW symbol */
118 int firstcode; /* first byte of oldcode's expansion */
119
120 /* LZW symbol table and expansion stack */
121 UINT16 FAR *symbol_head; /* => table of prefix symbols */
122 UINT8 FAR *symbol_tail; /* => table of suffix bytes */
123 UINT8 FAR *symbol_stack; /* => stack for symbol expansions */
124 UINT8 FAR *sp; /* stack pointer */
125
126 /* State for interlaced image processing */
127 boolean is_interlaced; /* TRUE if have interlaced image */
128 jvirt_sarray_ptr interlaced_image; /* full image in interlaced order */
129 JDIMENSION cur_row_number; /* need to know actual row number */
130 JDIMENSION pass2_offset; /* # of pixel rows in pass 1 */
131 JDIMENSION pass3_offset; /* # of pixel rows in passes 1&2 */
132 JDIMENSION pass4_offset; /* # of pixel rows in passes 1,2,3 */
133} gif_source_struct;
134
135typedef gif_source_struct * gif_source_ptr;
136
137
138/* Forward declarations */
139METHODDEF(JDIMENSION) get_pixel_rows
141METHODDEF(JDIMENSION) load_interlaced_image
143METHODDEF(JDIMENSION) get_interlaced_row
145
146
147LOCAL(int)
148ReadByte (gif_source_ptr sinfo)
149/* Read next byte from GIF file */
150{
151 register FILE *infile = sinfo->pub.input_file;
152 register int c;
153
154 if ((c = getc(infile)) == EOF)
155 ERREXIT(sinfo->cinfo, JERR_INPUT_EOF);
156 return c;
157}
158
159
160LOCAL(int)
161GetDataBlock (gif_source_ptr sinfo, U_CHAR *buf)
162/* Read a GIF data block, which has a leading count byte */
163/* A zero-length block marks the end of a data block sequence */
164{
165 int count;
166
168 if (count > 0) {
169 if (! ReadOK(sinfo->pub.input_file, buf, count))
170 ERREXIT(sinfo->cinfo, JERR_INPUT_EOF);
171 }
172 return count;
173}
174
175
176LOCAL(void)
177SkipDataBlocks (gif_source_ptr sinfo)
178/* Skip a series of data blocks, until a block terminator is found */
179{
180 U_CHAR buf[256];
181
182 while (GetDataBlock(sinfo, buf) > 0)
183 /* skip */;
184}
185
186
187LOCAL(void)
188ReInitLZW (gif_source_ptr sinfo)
189/* (Re)initialize LZW state; shared code for startup and Clear processing */
190{
191 sinfo->code_size = sinfo->input_code_size + 1;
192 sinfo->limit_code = sinfo->clear_code << 1; /* 2^code_size */
193 sinfo->max_code = sinfo->clear_code + 2; /* first unused code value */
194 sinfo->sp = sinfo->symbol_stack; /* init stack to empty */
195}
196
197
198LOCAL(void)
199InitLZWCode (gif_source_ptr sinfo)
200/* Initialize for a series of LZWReadByte (and hence GetCode) calls */
201{
202 /* GetCode initialization */
203 sinfo->last_byte = 2; /* make safe to "recopy last two bytes" */
204 sinfo->code_buf[0] = 0;
205 sinfo->code_buf[1] = 0;
206 sinfo->last_bit = 0; /* nothing in the buffer */
207 sinfo->cur_bit = 0; /* force buffer load on first call */
208 sinfo->first_time = TRUE;
209 sinfo->out_of_blocks = FALSE;
210
211 /* LZWReadByte initialization: */
212 /* compute special code values (note that these do not change later) */
213 sinfo->clear_code = 1 << sinfo->input_code_size;
214 sinfo->end_code = sinfo->clear_code + 1;
215 ReInitLZW(sinfo);
216}
217
218
219LOCAL(int)
220GetCode (gif_source_ptr sinfo)
221/* Fetch the next code_size bits from the GIF data */
222/* We assume code_size is less than 16 */
223{
224 register INT32 accum;
225 int offs, count;
226
227 while (sinfo->cur_bit + sinfo->code_size > sinfo->last_bit) {
228 /* Time to reload the buffer */
229 /* First time, share code with Clear case */
230 if (sinfo->first_time) {
231 sinfo->first_time = FALSE;
232 return sinfo->clear_code;
233 }
234 if (sinfo->out_of_blocks) {
235 WARNMS(sinfo->cinfo, JWRN_GIF_NOMOREDATA);
236 return sinfo->end_code; /* fake something useful */
237 }
238 /* preserve last two bytes of what we have -- assume code_size <= 16 */
239 sinfo->code_buf[0] = sinfo->code_buf[sinfo->last_byte-2];
240 sinfo->code_buf[1] = sinfo->code_buf[sinfo->last_byte-1];
241 /* Load more bytes; set flag if we reach the terminator block */
242 if ((count = GetDataBlock(sinfo, &sinfo->code_buf[2])) == 0) {
243 sinfo->out_of_blocks = TRUE;
244 WARNMS(sinfo->cinfo, JWRN_GIF_NOMOREDATA);
245 return sinfo->end_code; /* fake something useful */
246 }
247 /* Reset counters */
248 sinfo->cur_bit = (sinfo->cur_bit - sinfo->last_bit) + 16;
249 sinfo->last_byte = 2 + count;
250 sinfo->last_bit = sinfo->last_byte * 8;
251 }
252
253 /* Form up next 24 bits in accum */
254 offs = sinfo->cur_bit >> 3; /* byte containing cur_bit */
255 accum = (INT32) UCH(sinfo->code_buf[offs+2]);
256 accum <<= 8;
257 accum |= (INT32) UCH(sinfo->code_buf[offs+1]);
258 accum <<= 8;
259 accum |= (INT32) UCH(sinfo->code_buf[offs]);
260
261 /* Right-align cur_bit in accum, then mask off desired number of bits */
262 accum >>= (sinfo->cur_bit & 7);
263 sinfo->cur_bit += sinfo->code_size;
264 return ((int) accum) & ((1 << sinfo->code_size) - 1);
265}
266
267
268LOCAL(int)
269LZWReadByte (gif_source_ptr sinfo)
270/* Read an LZW-compressed byte */
271{
272 register int code; /* current working code */
273 int incode; /* saves actual input code */
274
275 /* If any codes are stacked from a previously read symbol, return them */
276 if (sinfo->sp > sinfo->symbol_stack)
277 return (int) *(-- sinfo->sp);
278
279 /* Time to read a new symbol */
280 code = GetCode(sinfo);
281
282 if (code == sinfo->clear_code) {
283 /* Reinit state, swallow any extra Clear codes, and */
284 /* return next code, which is expected to be a raw byte. */
285 ReInitLZW(sinfo);
286 do {
287 code = GetCode(sinfo);
288 } while (code == sinfo->clear_code);
289 if (code > sinfo->clear_code) { /* make sure it is a raw byte */
290 WARNMS(sinfo->cinfo, JWRN_GIF_BADDATA);
291 code = 0; /* use something valid */
292 }
293 /* make firstcode, oldcode valid! */
294 sinfo->firstcode = sinfo->oldcode = code;
295 return code;
296 }
297
298 if (code == sinfo->end_code) {
299 /* Skip the rest of the image, unless GetCode already read terminator */
300 if (! sinfo->out_of_blocks) {
301 SkipDataBlocks(sinfo);
302 sinfo->out_of_blocks = TRUE;
303 }
304 /* Complain that there's not enough data */
305 WARNMS(sinfo->cinfo, JWRN_GIF_ENDCODE);
306 /* Pad data with 0's */
307 return 0; /* fake something usable */
308 }
309
310 /* Got normal raw byte or LZW symbol */
311 incode = code; /* save for a moment */
312
313 if (code >= sinfo->max_code) { /* special case for not-yet-defined symbol */
314 /* code == max_code is OK; anything bigger is bad data */
315 if (code > sinfo->max_code) {
316 WARNMS(sinfo->cinfo, JWRN_GIF_BADDATA);
317 incode = 0; /* prevent creation of loops in symbol table */
318 }
319 /* this symbol will be defined as oldcode/firstcode */
320 *(sinfo->sp++) = (UINT8) sinfo->firstcode;
321 code = sinfo->oldcode;
322 }
323
324 /* If it's a symbol, expand it into the stack */
325 while (code >= sinfo->clear_code) {
326 *(sinfo->sp++) = sinfo->symbol_tail[code]; /* tail is a byte value */
327 code = sinfo->symbol_head[code]; /* head is another LZW symbol */
328 }
329 /* At this point code just represents a raw byte */
330 sinfo->firstcode = code; /* save for possible future use */
331
332 /* If there's room in table... */
333 if ((code = sinfo->max_code) < LZW_TABLE_SIZE) {
334 /* Define a new symbol = prev sym + head of this sym's expansion */
335 sinfo->symbol_head[code] = (UINT16) sinfo->oldcode;
336 sinfo->symbol_tail[code] = (UINT8) sinfo->firstcode;
337 sinfo->max_code++;
338 /* Is it time to increase code_size? */
339 if (sinfo->max_code >= sinfo->limit_code &&
340 sinfo->code_size < MAX_LZW_BITS) {
341 sinfo->code_size++;
342 sinfo->limit_code <<= 1; /* keep equal to 2^code_size */
343 }
344 }
345
346 sinfo->oldcode = incode; /* save last input symbol for future use */
347 return sinfo->firstcode; /* return first byte of symbol's expansion */
348}
349
350
351LOCAL(void)
352ReadColorMap (gif_source_ptr sinfo, int cmaplen, JSAMPARRAY cmap)
353/* Read a GIF colormap */
354{
355 int i;
356
357 for (i = 0; i < cmaplen; i++) {
358#if BITS_IN_JSAMPLE == 8
359#define UPSCALE(x) (x)
360#else
361#define UPSCALE(x) ((x) << (BITS_IN_JSAMPLE-8))
362#endif
363 cmap[CM_RED ][i] = (JSAMPLE) UPSCALE(ReadByte(sinfo));
364 cmap[CM_GREEN][i] = (JSAMPLE) UPSCALE(ReadByte(sinfo));
365 cmap[CM_BLUE ][i] = (JSAMPLE) UPSCALE(ReadByte(sinfo));
366 }
367}
368
369
370LOCAL(void)
371DoExtension (gif_source_ptr sinfo)
372/* Process an extension block */
373/* Currently we ignore 'em all */
374{
375 int extlabel;
376
377 /* Read extension label byte */
378 extlabel = ReadByte(sinfo);
379 TRACEMS1(sinfo->cinfo, 1, JTRC_GIF_EXTENSION, extlabel);
380 /* Skip the data block(s) associated with the extension */
381 SkipDataBlocks(sinfo);
382}
383
384
385/*
386 * Read the file header; return image size and component count.
387 */
388
389METHODDEF(void)
390start_input_gif (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
391{
392 gif_source_ptr source = (gif_source_ptr) sinfo;
393 U_CHAR hdrbuf[10]; /* workspace for reading control blocks */
394 unsigned int width, height; /* image dimensions */
395 int colormaplen, aspectRatio;
396 int c;
397
398 /* Read and verify GIF Header */
399 if (! ReadOK(source->pub.input_file, hdrbuf, 6))
400 ERREXIT(cinfo, JERR_GIF_NOT);
401 if (hdrbuf[0] != 'G' || hdrbuf[1] != 'I' || hdrbuf[2] != 'F')
402 ERREXIT(cinfo, JERR_GIF_NOT);
403 /* Check for expected version numbers.
404 * If unknown version, give warning and try to process anyway;
405 * this is per recommendation in GIF89a standard.
406 */
407 if ((hdrbuf[3] != '8' || hdrbuf[4] != '7' || hdrbuf[5] != 'a') &&
408 (hdrbuf[3] != '8' || hdrbuf[4] != '9' || hdrbuf[5] != 'a'))
409 TRACEMS3(cinfo, 1, JTRC_GIF_BADVERSION, hdrbuf[3], hdrbuf[4], hdrbuf[5]);
410
411 /* Read and decipher Logical Screen Descriptor */
412 if (! ReadOK(source->pub.input_file, hdrbuf, 7))
413 ERREXIT(cinfo, JERR_INPUT_EOF);
414 width = LM_to_uint(hdrbuf, 0);
415 height = LM_to_uint(hdrbuf, 2);
416 /* we ignore the color resolution, sort flag, and background color index */
417 aspectRatio = UCH(hdrbuf[6]);
418 if (aspectRatio != 0 && aspectRatio != 49)
419 TRACEMS(cinfo, 1, JTRC_GIF_NONSQUARE);
420
421 /* Allocate space to store the colormap */
422 source->colormap = (*cinfo->mem->alloc_sarray) ((j_common_ptr) cinfo,
423 JPOOL_IMAGE, (JDIMENSION) MAXCOLORMAPSIZE, (JDIMENSION) NUMCOLORS);
424 colormaplen = 0; /* indicate initialization */
425
426 /* Read global colormap if header indicates it is present */
427 if (BitSet(hdrbuf[4], COLORMAPFLAG)) {
428 colormaplen = 2 << (hdrbuf[4] & 0x07);
429 ReadColorMap(source, colormaplen, source->colormap);
430 }
431
432 /* Scan until we reach start of desired image.
433 * We don't currently support skipping images, but could add it easily.
434 */
435 for (;;) {
436 c = ReadByte(source);
437
438 if (c == ';') /* GIF terminator?? */
439 ERREXIT(cinfo, JERR_GIF_IMAGENOTFOUND);
440
441 if (c == '!') { /* Extension */
442 DoExtension(source);
443 continue;
444 }
445
446 if (c != ',') { /* Not an image separator? */
447 WARNMS1(cinfo, JWRN_GIF_CHAR, c);
448 continue;
449 }
450
451 /* Read and decipher Local Image Descriptor */
452 if (! ReadOK(source->pub.input_file, hdrbuf, 9))
453 ERREXIT(cinfo, JERR_INPUT_EOF);
454 /* we ignore top/left position info, also sort flag */
455 width = LM_to_uint(hdrbuf, 4);
456 height = LM_to_uint(hdrbuf, 6);
457 source->is_interlaced = (BitSet(hdrbuf[8], INTERLACE) != 0);
458
459 /* Read local colormap if header indicates it is present */
460 /* Note: if we wanted to support skipping images, */
461 /* we'd need to skip rather than read colormap for ignored images */
462 if (BitSet(hdrbuf[8], COLORMAPFLAG)) {
463 colormaplen = 2 << (hdrbuf[8] & 0x07);
464 ReadColorMap(source, colormaplen, source->colormap);
465 }
466
467 source->input_code_size = ReadByte(source); /* get min-code-size byte */
468 if (source->input_code_size < 2 || source->input_code_size > 8)
469 ERREXIT1(cinfo, JERR_GIF_CODESIZE, source->input_code_size);
470
471 /* Reached desired image, so break out of loop */
472 /* If we wanted to skip this image, */
473 /* we'd call SkipDataBlocks and then continue the loop */
474 break;
475 }
476
477 /* Prepare to read selected image: first initialize LZW decompressor */
478 source->symbol_head = (UINT16 FAR *) (*cinfo->mem->alloc_large)
479 ((j_common_ptr) cinfo, JPOOL_IMAGE, LZW_TABLE_SIZE * SIZEOF(UINT16));
480 source->symbol_tail = (UINT8 FAR *) (*cinfo->mem->alloc_large)
481 ((j_common_ptr) cinfo, JPOOL_IMAGE, LZW_TABLE_SIZE * SIZEOF(UINT8));
482 source->symbol_stack = (UINT8 FAR *) (*cinfo->mem->alloc_large)
483 ((j_common_ptr) cinfo, JPOOL_IMAGE, LZW_TABLE_SIZE * SIZEOF(UINT8));
484 InitLZWCode(source);
485
486 /*
487 * If image is interlaced, we read it into a full-size sample array,
488 * decompressing as we go; then get_interlaced_row selects rows from the
489 * sample array in the proper order.
490 */
491 if (source->is_interlaced) {
492 /* We request the virtual array now, but can't access it until virtual
493 * arrays have been allocated. Hence, the actual work of reading the
494 * image is postponed until the first call to get_pixel_rows.
495 */
496 source->interlaced_image = (*cinfo->mem->request_virt_sarray)
497 ((j_common_ptr) cinfo, JPOOL_IMAGE, FALSE,
499 if (cinfo->progress != NULL) {
500 cd_progress_ptr progress = (cd_progress_ptr) cinfo->progress;
501 progress->total_extra_passes++; /* count file input as separate pass */
502 }
503 source->pub.get_pixel_rows = load_interlaced_image;
504 } else {
505 source->pub.get_pixel_rows = get_pixel_rows;
506 }
507
508 /* Create compressor input buffer. */
509 source->pub.buffer = (*cinfo->mem->alloc_sarray) ((j_common_ptr) cinfo,
511 source->pub.buffer_height = 1;
512
513 /* Pad colormap for safety. */
514 for (c = colormaplen; c < source->clear_code; c++) {
515 source->colormap[CM_RED ][c] =
516 source->colormap[CM_GREEN][c] =
517 source->colormap[CM_BLUE ][c] = CENTERJSAMPLE;
518 }
519
520 /* Return info about the image. */
521 cinfo->in_color_space = JCS_RGB;
523 cinfo->data_precision = BITS_IN_JSAMPLE; /* we always rescale data to this */
524 cinfo->image_width = width;
525 cinfo->image_height = height;
526
527 TRACEMS3(cinfo, 1, JTRC_GIF, width, height, colormaplen);
528}
529
530
531/*
532 * Read one row of pixels.
533 * This version is used for noninterlaced GIF images:
534 * we read directly from the GIF file.
535 */
536
538get_pixel_rows (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
539{
540 gif_source_ptr source = (gif_source_ptr) sinfo;
541 register int c;
542 register JSAMPROW ptr;
543 register JDIMENSION col;
544 register JSAMPARRAY colormap = source->colormap;
545
546 ptr = source->pub.buffer[0];
547 for (col = cinfo->image_width; col > 0; col--) {
548 c = LZWReadByte(source);
549 *ptr++ = colormap[CM_RED ][c];
550 *ptr++ = colormap[CM_GREEN][c];
551 *ptr++ = colormap[CM_BLUE ][c];
552 }
553 return 1;
554}
555
556
557/*
558 * Read one row of pixels.
559 * This version is used for the first call on get_pixel_rows when
560 * reading an interlaced GIF file: we read the whole image into memory.
561 */
562
564load_interlaced_image (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
565{
566 gif_source_ptr source = (gif_source_ptr) sinfo;
567 register JSAMPROW sptr;
568 register JDIMENSION col;
570 cd_progress_ptr progress = (cd_progress_ptr) cinfo->progress;
571
572 /* Read the interlaced image into the virtual array we've created. */
573 for (row = 0; row < cinfo->image_height; row++) {
574 if (progress != NULL) {
575 progress->pub.pass_counter = (long) row;
576 progress->pub.pass_limit = (long) cinfo->image_height;
577 (*progress->pub.progress_monitor) ((j_common_ptr) cinfo);
578 }
579 sptr = * (*cinfo->mem->access_virt_sarray) ((j_common_ptr) cinfo,
580 source->interlaced_image, row, (JDIMENSION) 1, TRUE);
581 for (col = cinfo->image_width; col > 0; col--) {
582 *sptr++ = (JSAMPLE) LZWReadByte(source);
583 }
584 }
585 if (progress != NULL)
587
588 /* Replace method pointer so subsequent calls don't come here. */
589 source->pub.get_pixel_rows = get_interlaced_row;
590 /* Initialize for get_interlaced_row, and perform first call on it. */
591 source->cur_row_number = 0;
592 source->pass2_offset = (cinfo->image_height + 7) / 8;
593 source->pass3_offset = source->pass2_offset + (cinfo->image_height + 3) / 8;
594 source->pass4_offset = source->pass3_offset + (cinfo->image_height + 1) / 4;
595
596 return get_interlaced_row(cinfo, sinfo);
597}
598
599
600/*
601 * Read one row of pixels.
602 * This version is used for interlaced GIF images:
603 * we read from the virtual array.
604 */
605
607get_interlaced_row (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
608{
609 gif_source_ptr source = (gif_source_ptr) sinfo;
610 register int c;
611 register JSAMPROW sptr, ptr;
612 register JDIMENSION col;
613 register JSAMPARRAY colormap = source->colormap;
614 JDIMENSION irow;
615
616 /* Figure out which row of interlaced image is needed, and access it. */
617 switch ((int) (source->cur_row_number & 7)) {
618 case 0: /* first-pass row */
619 irow = source->cur_row_number >> 3;
620 break;
621 case 4: /* second-pass row */
622 irow = (source->cur_row_number >> 3) + source->pass2_offset;
623 break;
624 case 2: /* third-pass row */
625 case 6:
626 irow = (source->cur_row_number >> 2) + source->pass3_offset;
627 break;
628 default: /* fourth-pass row */
629 irow = (source->cur_row_number >> 1) + source->pass4_offset;
630 }
631 sptr = * (*cinfo->mem->access_virt_sarray) ((j_common_ptr) cinfo,
632 source->interlaced_image, irow, (JDIMENSION) 1, FALSE);
633 /* Scan the row, expand colormap, and output */
634 ptr = source->pub.buffer[0];
635 for (col = cinfo->image_width; col > 0; col--) {
636 c = GETJSAMPLE(*sptr++);
637 *ptr++ = colormap[CM_RED ][c];
638 *ptr++ = colormap[CM_GREEN][c];
639 *ptr++ = colormap[CM_BLUE ][c];
640 }
641 source->cur_row_number++; /* for next time */
642 return 1;
643}
644
645
646/*
647 * Finish up at the end of the file.
648 */
649
650METHODDEF(void)
651finish_input_gif (j_compress_ptr cinfo, cjpeg_source_ptr sinfo)
652{
653 /* no work */
654}
655
656
657/*
658 * The module selection routine for GIF format input.
659 */
660
662jinit_read_gif (j_compress_ptr cinfo)
663{
664 gif_source_ptr source;
665
666 /* Create module interface object */
667 source = (gif_source_ptr) (*cinfo->mem->alloc_small)
668 ((j_common_ptr) cinfo, JPOOL_IMAGE, SIZEOF(gif_source_struct));
669 source->cinfo = cinfo; /* make back link for subroutines */
670 /* Fill in method ptrs, except get_pixel_rows which start_input sets */
671 source->pub.start_input = start_input_gif;
672 source->pub.finish_input = finish_input_gif;
673
674 return &source->pub;
675}
676
677#endif /* GIF_SUPPORTED */
unsigned short UINT16
signed int INT32
unsigned char UINT8
#define SIZEOF(_ar)
Definition: calc.h:97
cd_progress_ptr progress
Definition: cdjpeg.h:152
struct cdjpeg_progress_mgr * cd_progress_ptr
Definition: cdjpeg.h:90
#define GetCode(X)
Definition: debug.cpp:2
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define FAR
Definition: zlib.h:34
struct png_info_def *typedef unsigned char **typedef struct png_info_def *typedef struct png_info_def *typedef struct png_info_def *typedef unsigned char ** row
Definition: typeof.h:78
#define UPSCALE(x)
Definition: ftgrays.c:345
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLint GLint GLsizei GLsizei height
Definition: gl.h:1546
GLint GLint GLsizei width
Definition: gl.h:1546
const GLubyte * c
Definition: glext.h:8905
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
_Check_return_ _CRTIMP int __cdecl getc(_Inout_ FILE *_File)
#define EOF
Definition: stdio.h:24
#define TRACEMS1(cinfo, lvl, code, p1)
Definition: jerror.h:268
#define TRACEMS(cinfo, lvl, code)
Definition: jerror.h:265
#define WARNMS1(cinfo, code, p1)
Definition: jerror.h:254
#define ERREXIT1(cinfo, code, p1)
Definition: jerror.h:212
#define WARNMS(cinfo, code)
Definition: jerror.h:251
#define TRACEMS3(cinfo, lvl, code, p1, p2, p3)
Definition: jerror.h:277
unsigned int JDIMENSION
Definition: jmorecfg.h:229
char JSAMPLE
Definition: jmorecfg.h:74
#define LOCAL(type)
Definition: jmorecfg.h:289
#define BITS_IN_JSAMPLE
Definition: jmorecfg.h:33
#define METHODDEF(type)
Definition: jmorecfg.h:287
#define CENTERJSAMPLE
Definition: jmorecfg.h:84
#define GLOBAL(type)
Definition: jmorecfg.h:291
#define GETJSAMPLE(value)
Definition: jmorecfg.h:78
struct jpeg_common_struct * j_common_ptr
Definition: jpeglib.h:284
#define JPP(arglist)
Definition: jpeglib.h:877
@ JCS_RGB
Definition: jpeglib.h:223
JSAMPROW * JSAMPARRAY
Definition: jpeglib.h:76
JSAMPLE FAR * JSAMPROW
Definition: jpeglib.h:75
#define JPOOL_IMAGE
Definition: jpeglib.h:808
#define c
Definition: ke_i.h:80
#define for
Definition: utility.h:88
static PVOID ptr
Definition: dispmode.c:27
static const WCHAR sp[]
Definition: suminfo.c:287
BYTE ReadByte(PSAFE_READ pRead)
Definition: mspatcha_main.c:57
#define long
Definition: qsort.c:33
#define ERREXIT(msg)
Definition: rdjpgcom.c:72
static FILE * infile
Definition: rdjpgcom.c:65
int total_extra_passes
Definition: cdjpeg.h:85
struct jpeg_progress_mgr pub
Definition: cdjpeg.h:83
int completed_extra_passes
Definition: cdjpeg.h:84
Definition: inflate.c:139
JDIMENSION image_height
Definition: jpeglib.h:303
J_COLOR_SPACE in_color_space
Definition: jpeglib.h:305
JDIMENSION image_width
Definition: jpeglib.h:302
Definition: general.c:220
#define ReadOK(tif, buf, size)
Definition: tiffiop.h:252
#define NUMCOLORS
Definition: wingdi.h:725