~ubuntu-branches/ubuntu/oneiric/cups/oneiric

« back to all changes in this revision

Viewing changes to .pc/00svn_gif_overflow.patch/filter/image-gif.c

  • Committer: Package Import Robot
  • Author(s): Martin Pitt
  • Date: 2011-09-27 14:46:38 UTC
  • Revision ID: package-import@ubuntu.com-20110927144638-i5ku2zniedcyxzxt
Tags: 1.5.0-8
* Urgency medium due to security fix. The previous version wasn't in testing
  yet, but already matured for half of the usual period, so it will still
  be 10 days in sum.
* Add 00svn_gif_overflow.patch: Fix heap overflow with broken/crafted GIF
  files. Patch taken from upstream svn. [CVE-2011-3170]

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * "$Id: image-gif.c 9840 2011-06-20 20:37:39Z mike $"
 
3
 *
 
4
 *   GIF image routines for CUPS.
 
5
 *
 
6
 *   Copyright 2007-2011 by Apple Inc.
 
7
 *   Copyright 1993-2007 by Easy Software Products.
 
8
 *
 
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/".
 
14
 *
 
15
 *   This file is subject to the Apple OS-Developed Software exception.
 
16
 *
 
17
 * Contents:
 
18
 *
 
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...
 
25
 */
 
26
 
 
27
/*
 
28
 * Include necessary headers...
 
29
 */
 
30
 
 
31
#include "image-private.h"
 
32
 
 
33
 
 
34
/*
 
35
 * GIF definitions...
 
36
 */
 
37
 
 
38
#define GIF_INTERLACE   0x40
 
39
#define GIF_COLORMAP    0x80
 
40
#define GIF_MAX_BITS    12
 
41
 
 
42
typedef cups_ib_t       gif_cmap_t[256][4];
 
43
typedef short           gif_table_t[4096];
 
44
 
 
45
 
 
46
/*
 
47
 * Local globals...
 
48
 */
 
49
 
 
50
static int      gif_eof = 0;            /* Did we hit EOF? */
 
51
 
 
52
 
 
53
/*
 
54
 * Local functions...
 
55
 */
 
56
 
 
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,
 
60
                              int *gray);
 
61
static int      gif_read_image(FILE *fp, cups_image_t *img, gif_cmap_t cmap,
 
62
                               int interlace);
 
63
static int      gif_read_lzw(FILE *fp, int first_time, int input_code_size);
 
64
 
 
65
 
 
66
/*
 
67
 * '_cupsImageReadGIF()' - Read a GIF image file.
 
68
 */
 
69
 
 
70
int                                     /* O - Read status */
 
71
_cupsImageReadGIF(
 
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 */
 
79
{
 
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 */
 
87
 
 
88
 
 
89
 /*
 
90
  * GIF files are either grayscale or RGB - no CMYK...
 
91
  */
 
92
 
 
93
  if (primary == CUPS_IMAGE_RGB_CMYK)
 
94
    primary = CUPS_IMAGE_RGB;
 
95
 
 
96
 /*
 
97
  * Read the header; we already know it is a GIF file...
 
98
  */
 
99
 
 
100
  fread(buf, 13, 1, fp);
 
101
 
 
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;
 
106
 
 
107
  if (buf[10] & GIF_COLORMAP)
 
108
    if (gif_read_cmap(fp, ncolors, cmap, &gray))
 
109
    {
 
110
      fclose(fp);
 
111
      return (-1);
 
112
    }
 
113
 
 
114
  transparent = -1;
 
115
 
 
116
  for (;;)
 
117
  {
 
118
    switch (getc(fp))
 
119
    {
 
120
      case ';' :        /* End of image */
 
121
          fclose(fp);
 
122
          return (-1);          /* Early end of file */
 
123
 
 
124
      case '!' :        /* Extension record */
 
125
          buf[0] = getc(fp);
 
126
          if (buf[0] == 0xf9)   /* Graphic Control Extension */
 
127
          {
 
128
            gif_get_block(fp, buf);
 
129
            if (buf[0] & 1)     /* Get transparent color index */
 
130
              transparent = buf[3];
 
131
          }
 
132
 
 
133
          while (gif_get_block(fp, buf) != 0);
 
134
          break;
 
135
 
 
136
      case ',' :        /* cupsImage data */
 
137
          fread(buf, 9, 1, fp);
 
138
 
 
139
          if (buf[8] & GIF_COLORMAP)
 
140
          {
 
141
            ncolors = 2 << (buf[8] & 0x07);
 
142
            gray = primary == CUPS_IMAGE_BLACK || primary == CUPS_IMAGE_WHITE;
 
143
 
 
144
            if (gif_read_cmap(fp, ncolors, cmap, &gray))
 
145
            {
 
146
              fclose(fp);
 
147
              return (-1);
 
148
            }
 
149
          }
 
150
 
 
151
          if (transparent >= 0)
 
152
          {
 
153
           /*
 
154
            * Make transparent color white...
 
155
            */
 
156
 
 
157
            cmap[transparent][0] = 255;
 
158
            cmap[transparent][1] = 255;
 
159
            cmap[transparent][2] = 255;
 
160
          }
 
161
 
 
162
          if (gray)
 
163
          {
 
164
            switch (secondary)
 
165
            {
 
166
              case CUPS_IMAGE_CMYK :
 
167
                  for (i = ncolors - 1; i >= 0; i --)
 
168
                    cupsImageWhiteToCMYK(cmap[i], cmap[i], 1);
 
169
                  break;
 
170
              case CUPS_IMAGE_CMY :
 
171
                  for (i = ncolors - 1; i >= 0; i --)
 
172
                    cupsImageWhiteToCMY(cmap[i], cmap[i], 1);
 
173
                  break;
 
174
              case CUPS_IMAGE_BLACK :
 
175
                  for (i = ncolors - 1; i >= 0; i --)
 
176
                    cupsImageWhiteToBlack(cmap[i], cmap[i], 1);
 
177
                  break;
 
178
              case CUPS_IMAGE_WHITE :
 
179
                  break;
 
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);
 
184
                  break;
 
185
            }
 
186
 
 
187
            img->colorspace = secondary;
 
188
          }
 
189
          else
 
190
          {
 
191
            if (hue != 0 || saturation != 100)
 
192
              for (i = ncolors - 1; i >= 0; i --)
 
193
                cupsImageRGBAdjust(cmap[i], 1, saturation, hue);
 
194
 
 
195
            switch (primary)
 
196
            {
 
197
              case CUPS_IMAGE_CMYK :
 
198
                  for (i = ncolors - 1; i >= 0; i --)
 
199
                    cupsImageRGBToCMYK(cmap[i], cmap[i], 1);
 
200
                  break;
 
201
              case CUPS_IMAGE_CMY :
 
202
                  for (i = ncolors - 1; i >= 0; i --)
 
203
                    cupsImageRGBToCMY(cmap[i], cmap[i], 1);
 
204
                  break;
 
205
              case CUPS_IMAGE_BLACK :
 
206
                  for (i = ncolors - 1; i >= 0; i --)
 
207
                    cupsImageRGBToBlack(cmap[i], cmap[i], 1);
 
208
                  break;
 
209
              case CUPS_IMAGE_WHITE :
 
210
                  for (i = ncolors - 1; i >= 0; i --)
 
211
                    cupsImageRGBToWhite(cmap[i], cmap[i], 1);
 
212
                  break;
 
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);
 
217
                  break;
 
218
            }
 
219
 
 
220
            img->colorspace = primary;
 
221
          }
 
222
 
 
223
          if (lut)
 
224
          {
 
225
            bpp = cupsImageGetDepth(img);
 
226
 
 
227
            for (i = ncolors - 1; i >= 0; i --)
 
228
              cupsImageLut(cmap[i], bpp, lut);
 
229
          }
 
230
 
 
231
          img->xsize = (buf[5] << 8) | buf[4];
 
232
          img->ysize = (buf[7] << 8) | buf[6];
 
233
 
 
234
         /*
 
235
          * Check the dimensions of the image; since the dimensions are
 
236
          * a 16-bit integer we just need to check for 0...
 
237
          */
 
238
 
 
239
          if (img->xsize == 0 || img->ysize == 0)
 
240
          {
 
241
            fprintf(stderr, "DEBUG: Bad GIF image dimensions: %dx%d\n",
 
242
                    img->xsize, img->ysize);
 
243
            fclose(fp);
 
244
            return (1);
 
245
          }
 
246
 
 
247
          i = gif_read_image(fp, img, cmap, buf[8] & GIF_INTERLACE);
 
248
          fclose(fp);
 
249
          return (i);
 
250
    }
 
251
  }
 
252
}
 
253
 
 
254
 
 
255
/*
 
256
 * 'gif_get_block()' - Read a GIF data block...
 
257
 */
 
258
 
 
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 */
 
262
{
 
263
  int   count;                          /* Number of character to read */
 
264
 
 
265
 
 
266
 /*
 
267
  * Read the count byte followed by the data from the file...
 
268
  */
 
269
 
 
270
  if ((count = getc(fp)) == EOF)
 
271
  {
 
272
    gif_eof = 1;
 
273
    return (-1);
 
274
  }
 
275
  else if (count == 0)
 
276
    gif_eof = 1;
 
277
  else if (fread(buf, 1, count, fp) < count)
 
278
  {
 
279
    gif_eof = 1;
 
280
    return (-1);
 
281
  }
 
282
  else
 
283
    gif_eof = 0;
 
284
 
 
285
  return (count);
 
286
}
 
287
 
 
288
 
 
289
/*
 
290
 * 'gif_get_code()' - Get a LZW code from the file...
 
291
 */
 
292
 
 
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 */
 
297
{
 
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 */
 
307
                        {
 
308
                          0x01, 0x02, 0x04, 0x08,
 
309
                          0x10, 0x20, 0x40, 0x80
 
310
                        };
 
311
 
 
312
 
 
313
  if (first_time)
 
314
  {
 
315
   /*
 
316
    * Just initialize the input buffer...
 
317
    */
 
318
 
 
319
    curbit    = 0;
 
320
    lastbit   = 0;
 
321
    last_byte = 0;
 
322
    done      = 0;
 
323
 
 
324
    return (0);
 
325
  }
 
326
 
 
327
  if ((curbit + code_size) >= lastbit)
 
328
  {
 
329
   /*
 
330
    * Don't have enough bits to hold the code...
 
331
    */
 
332
 
 
333
    if (done)
 
334
      return (-1);      /* Sorry, no more... */
 
335
 
 
336
   /*
 
337
    * Move last two bytes to front of buffer...
 
338
    */
 
339
 
 
340
    if (last_byte > 1)
 
341
    {
 
342
      buf[0]    = buf[last_byte - 2];
 
343
      buf[1]    = buf[last_byte - 1];
 
344
      last_byte = 2;
 
345
    }
 
346
    else if (last_byte == 1)
 
347
    {
 
348
      buf[0]    = buf[last_byte - 1];
 
349
      last_byte = 1;
 
350
    }
 
351
 
 
352
   /*
 
353
    * Read in another buffer...
 
354
    */
 
355
 
 
356
    if ((count = gif_get_block(fp, buf + last_byte)) <= 0)
 
357
    {
 
358
     /*
 
359
      * Whoops, no more data!
 
360
      */
 
361
 
 
362
      done = 1;
 
363
      return (-1);
 
364
    }
 
365
 
 
366
   /*
 
367
    * Update buffer state...
 
368
    */
 
369
 
 
370
    curbit    = (curbit - lastbit) + 8 * last_byte;
 
371
    last_byte += count;
 
372
    lastbit   = last_byte * 8;
 
373
  }
 
374
 
 
375
  for (ret = 0, i = curbit + code_size - 1, j = code_size;
 
376
       j > 0;
 
377
       i --, j --)
 
378
    ret = (ret << 1) | ((buf[i / 8] & bits[i & 7]) != 0);
 
379
 
 
380
  curbit += code_size;
 
381
 
 
382
  return ret;
 
383
}
 
384
 
 
385
 
 
386
/*
 
387
 * 'gif_read_cmap()' - Read the colormap from a GIF file...
 
388
 */
 
389
 
 
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? */
 
395
{
 
396
  int   i;                              /* Looping var */
 
397
 
 
398
 
 
399
 /*
 
400
  * Read the colormap...
 
401
  */
 
402
 
 
403
  for (i = 0; i < ncolors; i ++)
 
404
    if (fread(cmap[i], 3, 1, fp) < 1)
 
405
      return (-1);
 
406
 
 
407
 /*
 
408
  * Check to see if the colormap is a grayscale ramp...
 
409
  */
 
410
 
 
411
  for (i = 0; i < ncolors; i ++)
 
412
    if (cmap[i][0] != cmap[i][1] || cmap[i][1] != cmap[i][2])
 
413
      break;
 
414
 
 
415
  if (i == ncolors)
 
416
  {
 
417
    *gray = 1;
 
418
    return (0);
 
419
  }
 
420
 
 
421
 /*
 
422
  * If this needs to be a grayscale image, convert the RGB values to
 
423
  * luminance values...
 
424
  */
 
425
 
 
426
  if (*gray)
 
427
    for (i = 0; i < ncolors; i ++)
 
428
      cmap[i][0] = (cmap[i][0] * 31 + cmap[i][1] * 61 + cmap[i][2] * 8) / 100;
 
429
 
 
430
  return (0);
 
431
}
 
432
 
 
433
 
 
434
/*
 
435
 * 'gif_read_image()' - Read a GIF image stream...
 
436
 */
 
437
 
 
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 */
 
443
{
 
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 */
 
453
                        { 8, 8, 4, 2 },
 
454
                        ypasses[5] =    /* Y interleaving */
 
455
                        { 0, 4, 2, 1, 999999 };
 
456
 
 
457
 
 
458
  bpp       = cupsImageGetDepth(img);
 
459
  pixels    = calloc(bpp, img->xsize);
 
460
  xpos      = 0;
 
461
  ypos      = 0;
 
462
  pass      = 0;
 
463
  code_size = getc(fp);
 
464
 
 
465
  if (!pixels)
 
466
    return (-1);
 
467
 
 
468
  if (code_size > GIF_MAX_BITS || gif_read_lzw(fp, 1, code_size) < 0)
 
469
  {
 
470
    free(pixels);
 
471
    return (-1);
 
472
  }
 
473
 
 
474
  temp = pixels;
 
475
  while ((pixel = gif_read_lzw(fp, 0, code_size)) >= 0)
 
476
  {
 
477
    switch (bpp)
 
478
    {
 
479
      case 4 :
 
480
          temp[3] = cmap[pixel][3];
 
481
      case 3 :
 
482
          temp[2] = cmap[pixel][2];
 
483
      case 2 :
 
484
          temp[1] = cmap[pixel][1];
 
485
      default :
 
486
          temp[0] = cmap[pixel][0];
 
487
    }
 
488
 
 
489
    xpos ++;
 
490
    temp += bpp;
 
491
    if (xpos == img->xsize)
 
492
    {
 
493
      _cupsImagePutRow(img, 0, ypos, img->xsize, pixels);
 
494
 
 
495
      xpos = 0;
 
496
      temp = pixels;
 
497
 
 
498
      if (interlace)
 
499
      {
 
500
        ypos += xpasses[pass];
 
501
 
 
502
        if (ypos >= img->ysize)
 
503
        {
 
504
          pass ++;
 
505
 
 
506
          ypos = ypasses[pass];
 
507
        }
 
508
      }
 
509
      else
 
510
        ypos ++;
 
511
    }
 
512
 
 
513
    if (ypos >= img->ysize)
 
514
      break;
 
515
  }
 
516
 
 
517
  free(pixels);
 
518
 
 
519
  return (0);
 
520
}
 
521
 
 
522
 
 
523
/*
 
524
 * 'gif_read_lzw()' - Read a byte from the LZW stream...
 
525
 */
 
526
 
 
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 */
 
531
{
 
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 */
 
547
 
 
548
 
 
549
  if (first_time)
 
550
  {
 
551
   /*
 
552
    * Setup LZW state...
 
553
    */
 
554
 
 
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;
 
561
 
 
562
   /*
 
563
    * Allocate memory for buffers...
 
564
    */
 
565
 
 
566
    if (table == NULL)
 
567
      table = calloc(2, sizeof(gif_table_t));
 
568
 
 
569
    if (table == NULL)
 
570
      return (-1);
 
571
 
 
572
    if (stack == NULL)
 
573
      stack = calloc(8192, sizeof(short));
 
574
 
 
575
    if (stack == NULL)
 
576
      return (-1);
 
577
 
 
578
   /*
 
579
    * Initialize input buffers...
 
580
    */
 
581
 
 
582
    gif_get_code(fp, 0, 1);
 
583
 
 
584
   /*
 
585
    * Wipe the decompressor table (already mostly 0 due to the calloc above...)
 
586
    */
 
587
 
 
588
    fresh = 1;
 
589
 
 
590
    for (i = 1; i < clear_code; i ++)
 
591
      table[1][i] = i;
 
592
 
 
593
    sp = stack;
 
594
 
 
595
    return (0);
 
596
  }
 
597
  else if (fresh)
 
598
  {
 
599
    fresh = 0;
 
600
 
 
601
    do
 
602
    {
 
603
      firstcode = oldcode = gif_get_code(fp, code_size, 0);
 
604
    }
 
605
    while (firstcode == clear_code);
 
606
 
 
607
    return (firstcode & 255);
 
608
  }
 
609
  else if (!table)
 
610
    return (0);
 
611
 
 
612
  if (sp > stack)
 
613
    return ((*--sp) & 255);
 
614
 
 
615
  while ((code = gif_get_code(fp, code_size, 0)) >= 0)
 
616
  {
 
617
    if (code == clear_code)
 
618
    {
 
619
     /*
 
620
      * Clear/reset the compression table...
 
621
      */
 
622
 
 
623
      memset(table, 0, 2 * sizeof(gif_table_t));
 
624
      for (i = 1; i < clear_code; i ++)
 
625
        table[1][i] = i;
 
626
 
 
627
      code_size     = set_code_size + 1;
 
628
      max_code_size = 2 * clear_code;
 
629
      max_code      = clear_code + 2;
 
630
 
 
631
      sp = stack;
 
632
 
 
633
      firstcode = oldcode = gif_get_code(fp, code_size, 0);
 
634
 
 
635
      return (firstcode & 255);
 
636
    }
 
637
    else if (code == end_code || code > max_code)
 
638
    {
 
639
      unsigned char     buf[260];       /* Block buffer */
 
640
 
 
641
      if (!gif_eof)
 
642
        while (gif_get_block(fp, buf) > 0);
 
643
 
 
644
      return (-2);
 
645
    }
 
646
 
 
647
    incode = code;
 
648
 
 
649
    if (code == max_code)
 
650
    {
 
651
      *sp++ = firstcode;
 
652
      code  = oldcode;
 
653
    }
 
654
 
 
655
    while (code >= clear_code)
 
656
    {
 
657
      *sp++ = table[1][code];
 
658
      if (code == table[0][code])
 
659
        return (255);
 
660
 
 
661
      code = table[0][code];
 
662
    }
 
663
 
 
664
    *sp++ = firstcode = table[1][code];
 
665
    code  = max_code;
 
666
 
 
667
    if (code < 4096)
 
668
    {
 
669
      table[0][code] = oldcode;
 
670
      table[1][code] = firstcode;
 
671
      max_code ++;
 
672
 
 
673
      if (max_code >= max_code_size && max_code_size < 4096)
 
674
      {
 
675
        max_code_size *= 2;
 
676
        code_size ++;
 
677
      }
 
678
    }
 
679
 
 
680
    oldcode = incode;
 
681
 
 
682
    if (sp > stack)
 
683
      return ((*--sp) & 255);
 
684
  }
 
685
 
 
686
  return (code & 255);
 
687
}
 
688
 
 
689
 
 
690
/*
 
691
 * End of "$Id: image-gif.c 9840 2011-06-20 20:37:39Z mike $".
 
692
 */