~ubuntu-branches/ubuntu/maverick/webkit/maverick

« back to all changes in this revision

Viewing changes to WebCore/platform/image-decoders/gif/GIFImageReader.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Mike Hommey
  • Date: 2007-08-19 15:54:12 UTC
  • Revision ID: james.westby@ubuntu.com-20070819155412-uxxg1h9plpghmtbi
Tags: upstream-0~svn25144
ImportĀ upstreamĀ versionĀ 0~svn25144

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 
2
/* ***** BEGIN LICENSE BLOCK *****
 
3
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 
4
 *
 
5
 * The contents of this file are subject to the Mozilla Public License Version
 
6
 * 1.1 (the "License"); you may not use this file except in compliance with
 
7
 * the License. You may obtain a copy of the License at
 
8
 * http://www.mozilla.org/MPL/
 
9
 *
 
10
 * Software distributed under the License is distributed on an "AS IS" basis,
 
11
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 
12
 * for the specific language governing rights and limitations under the
 
13
 * License.
 
14
 *
 
15
 * The Original Code is mozilla.org code.
 
16
 *
 
17
 * The Initial Developer of the Original Code is
 
18
 * Netscape Communications Corporation.
 
19
 * Portions created by the Initial Developer are Copyright (C) 1998
 
20
 * the Initial Developer. All Rights Reserved.
 
21
 *
 
22
 * Contributor(s):
 
23
 *   Chris Saari <saari@netscape.com>
 
24
 *   Apple Computer
 
25
 *
 
26
 * Alternatively, the contents of this file may be used under the terms of
 
27
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 
28
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 
29
 * in which case the provisions of the GPL or the LGPL are applicable instead
 
30
 * of those above. If you wish to allow use of your version of this file only
 
31
 * under the terms of either the GPL or the LGPL, and not to allow others to
 
32
 * use your version of this file under the terms of the MPL, indicate your
 
33
 * decision by deleting the provisions above and replace them with the notice
 
34
 * and other provisions required by the GPL or the LGPL. If you do not delete
 
35
 * the provisions above, a recipient may use your version of this file under
 
36
 * the terms of any one of the MPL, the GPL or the LGPL.
 
37
 *
 
38
 * ***** END LICENSE BLOCK ***** */
 
39
 
 
40
/*
 
41
The Graphics Interchange Format(c) is the copyright property of CompuServe
 
42
Incorporated. Only CompuServe Incorporated is authorized to define, redefine,
 
43
enhance, alter, modify or change in any way the definition of the format.
 
44
 
 
45
CompuServe Incorporated hereby grants a limited, non-exclusive, royalty-free
 
46
license for the use of the Graphics Interchange Format(sm) in computer
 
47
software; computer software utilizing GIF(sm) must acknowledge ownership of the
 
48
Graphics Interchange Format and its Service Mark by CompuServe Incorporated, in
 
49
User and Technical Documentation. Computer software utilizing GIF, which is
 
50
distributed or may be distributed without User or Technical Documentation must
 
51
display to the screen or printer a message acknowledging ownership of the
 
52
Graphics Interchange Format and the Service Mark by CompuServe Incorporated; in
 
53
this case, the acknowledgement may be displayed in an opening screen or leading
 
54
banner, or a closing screen or trailing banner. A message such as the following
 
55
may be used:
 
56
 
 
57
    "The Graphics Interchange Format(c) is the Copyright property of
 
58
    CompuServe Incorporated. GIF(sm) is a Service Mark property of
 
59
    CompuServe Incorporated."
 
60
 
 
61
For further information, please contact :
 
62
 
 
63
    CompuServe Incorporated
 
64
    Graphics Technology Department
 
65
    5000 Arlington Center Boulevard
 
66
    Columbus, Ohio  43220
 
67
    U. S. A.
 
68
 
 
69
CompuServe Incorporated maintains a mailing list with all those individuals and
 
70
organizations who wish to receive copies of this document when it is corrected
 
71
or revised. This service is offered free of charge; please provide us with your
 
72
mailing address.
 
73
*/
 
74
 
 
75
#include "config.h"
 
76
#include "GIFImageReader.h"
 
77
 
 
78
#include <string.h>
 
79
#include "GIFImageDecoder.h"
 
80
 
 
81
#if PLATFORM(CAIRO) || PLATFORM(QT)
 
82
 
 
83
using WebCore::GIFImageDecoder;
 
84
 
 
85
// Define the Mozilla macro setup so that we can leave the macros alone.
 
86
#define PR_BEGIN_MACRO  do {
 
87
#define PR_END_MACRO    } while (0)
 
88
 
 
89
/*
 
90
 * GETN(n, s) requests at least 'n' bytes available from 'q', at start of state 's'
 
91
 *
 
92
 * Note, the hold will never need to be bigger than 256 bytes to gather up in the hold,
 
93
 * as each GIF block (except colormaps) can never be bigger than 256 bytes.
 
94
 * Colormaps are directly copied in the resp. global_colormap or dynamically allocated local_colormap.
 
95
 * So a fixed buffer in GIFImageReader is good enough.
 
96
 * This buffer is only needed to copy left-over data from one GifWrite call to the next
 
97
 */
 
98
#define GETN(n,s)                    \
 
99
  PR_BEGIN_MACRO                     \
 
100
    bytes_to_consume = (n);      \
 
101
    state = (s);                 \
 
102
  PR_END_MACRO
 
103
 
 
104
/* Get a 16-bit value stored in little-endian format */
 
105
#define GETINT16(p)   ((p)[1]<<8|(p)[0])
 
106
 
 
107
//******************************************************************************
 
108
// Send the data to the display front-end.
 
109
void GIFImageReader::output_row()
 
110
{
 
111
  GIFFrameReader* gs = frame_reader;
 
112
 
 
113
  int width, drow_start, drow_end;
 
114
 
 
115
  drow_start = drow_end = gs->irow;
 
116
 
 
117
  /*
 
118
   * Haeberli-inspired hack for interlaced GIFs: Replicate lines while
 
119
   * displaying to diminish the "venetian-blind" effect as the image is
 
120
   * loaded. Adjust pixel vertical positions to avoid the appearance of the
 
121
   * image crawling up the screen as successive passes are drawn.
 
122
   */
 
123
  if (gs->progressive_display && gs->interlaced && gs->ipass < 4) {
 
124
    unsigned row_dup = 0, row_shift = 0;
 
125
 
 
126
    switch (gs->ipass) {
 
127
    case 1:
 
128
      row_dup = 7;
 
129
      row_shift = 3;
 
130
      break;
 
131
    case 2:
 
132
      row_dup = 3;
 
133
      row_shift = 1;
 
134
      break;
 
135
    case 3:
 
136
      row_dup = 1;
 
137
      row_shift = 0;
 
138
      break;
 
139
    default:
 
140
      break;
 
141
    }
 
142
 
 
143
    drow_start -= row_shift;
 
144
    drow_end = drow_start + row_dup;
 
145
 
 
146
    /* Extend if bottom edge isn't covered because of the shift upward. */
 
147
    if (((gs->height - 1) - drow_end) <= row_shift)
 
148
      drow_end = gs->height - 1;
 
149
 
 
150
    /* Clamp first and last rows to upper and lower edge of image. */
 
151
    if (drow_start < 0)
 
152
      drow_start = 0;
 
153
    if ((unsigned)drow_end >= gs->height)
 
154
      drow_end = gs->height - 1;
 
155
  }
 
156
 
 
157
  /* Protect against too much image data */
 
158
  if ((unsigned)drow_start >= gs->height)
 
159
    return;
 
160
 
 
161
  /* Check for scanline below edge of logical screen */
 
162
  if ((gs->y_offset + gs->irow) < screen_height) {
 
163
    /* Clip if right edge of image exceeds limits */
 
164
    if ((gs->x_offset + gs->width) > screen_width)
 
165
      width = screen_width - gs->x_offset;
 
166
    else
 
167
      width = gs->width;
 
168
 
 
169
    // CALLBACK: Let the client know we have decoded a row.
 
170
    if (width > 0 && clientptr && frame_reader)
 
171
      clientptr->haveDecodedRow(images_count - 1, frame_reader->rowbuf, frame_reader->rowend,
 
172
                                drow_start, drow_end - drow_start + 1);
 
173
  }
 
174
 
 
175
  gs->rowp = gs->rowbuf;
 
176
 
 
177
  if (!gs->interlaced)
 
178
    gs->irow++;
 
179
  else {
 
180
    do {
 
181
      switch (gs->ipass)
 
182
      {
 
183
        case 1:
 
184
          gs->irow += 8;
 
185
          if (gs->irow >= gs->height) {
 
186
            gs->ipass++;
 
187
            gs->irow = 4;
 
188
          }
 
189
          break;
 
190
 
 
191
        case 2:
 
192
          gs->irow += 8;
 
193
          if (gs->irow >= gs->height) {
 
194
            gs->ipass++;
 
195
            gs->irow = 2;
 
196
          }
 
197
          break;
 
198
 
 
199
        case 3:
 
200
          gs->irow += 4;
 
201
          if (gs->irow >= gs->height) {
 
202
            gs->ipass++;
 
203
            gs->irow = 1;
 
204
          }
 
205
          break;
 
206
 
 
207
        case 4:
 
208
          gs->irow += 2;
 
209
          if (gs->irow >= gs->height){
 
210
            gs->ipass++;
 
211
            gs->irow = 0;
 
212
          }
 
213
          break;
 
214
 
 
215
        default:
 
216
          break;
 
217
      }
 
218
    } while (gs->irow > (gs->height - 1));
 
219
  }
 
220
}
 
221
 
 
222
//******************************************************************************
 
223
/* Perform Lempel-Ziv-Welch decoding */
 
224
int GIFImageReader::do_lzw(const unsigned char *q)
 
225
{
 
226
  GIFFrameReader* gs = frame_reader;
 
227
  if (!gs)
 
228
    return 0;
 
229
 
 
230
  int code;
 
231
  int incode;
 
232
  const unsigned char *ch;
 
233
  
 
234
  /* Copy all the decoder state variables into locals so the compiler
 
235
   * won't worry about them being aliased.  The locals will be homed
 
236
   * back into the GIF decoder structure when we exit.
 
237
   */
 
238
  int avail       = gs->avail;
 
239
  int bits        = gs->bits;
 
240
  int cnt         = count;
 
241
  int codesize    = gs->codesize;
 
242
  int codemask    = gs->codemask;
 
243
  int oldcode     = gs->oldcode;
 
244
  int clear_code  = gs->clear_code;
 
245
  unsigned char firstchar = gs->firstchar;
 
246
  int datum     = gs->datum;
 
247
 
 
248
  if (!gs->prefix) {
 
249
    gs->prefix = new unsigned short[MAX_BITS];
 
250
    memset(gs->prefix, 0, MAX_BITS * sizeof(short));
 
251
  }
 
252
 
 
253
  unsigned short *prefix  = gs->prefix;
 
254
  unsigned char *stackp   = gs->stackp;
 
255
  unsigned char *suffix   = gs->suffix;
 
256
  unsigned char *stack    = gs->stack;
 
257
  unsigned char *rowp     = gs->rowp;
 
258
  unsigned char *rowend   = gs->rowend;
 
259
  unsigned rows_remaining = gs->rows_remaining;
 
260
 
 
261
  if (rowp == rowend)
 
262
    return 0;
 
263
 
 
264
#define OUTPUT_ROW                                                  \
 
265
  PR_BEGIN_MACRO                                                        \
 
266
    output_row();                                                     \
 
267
    rows_remaining--;                                                   \
 
268
    rowp = frame_reader->rowp;                                                    \
 
269
    if (!rows_remaining)                                                \
 
270
      goto END;                                                         \
 
271
  PR_END_MACRO
 
272
 
 
273
  for (ch = q; cnt-- > 0; ch++)
 
274
  {
 
275
    /* Feed the next byte into the decoder's 32-bit input buffer. */
 
276
    datum += ((int) *ch) << bits;
 
277
    bits += 8;
 
278
 
 
279
    /* Check for underflow of decoder's 32-bit input buffer. */
 
280
    while (bits >= codesize)
 
281
    {
 
282
      /* Get the leading variable-length symbol from the data stream */
 
283
      code = datum & codemask;
 
284
      datum >>= codesize;
 
285
      bits -= codesize;
 
286
 
 
287
      /* Reset the dictionary to its original state, if requested */
 
288
      if (code == clear_code) {
 
289
        codesize = gs->datasize + 1;
 
290
        codemask = (1 << codesize) - 1;
 
291
        avail = clear_code + 2;
 
292
        oldcode = -1;
 
293
        continue;
 
294
      }
 
295
 
 
296
      /* Check for explicit end-of-stream code */
 
297
      if (code == (clear_code + 1)) {
 
298
        /* end-of-stream should only appear after all image data */
 
299
        if (rows_remaining != 0)
 
300
          return -1;
 
301
        return 0;
 
302
      }
 
303
 
 
304
      if (oldcode == -1) {
 
305
        *rowp++ = suffix[code];
 
306
        if (rowp == rowend)
 
307
          OUTPUT_ROW;
 
308
 
 
309
        firstchar = oldcode = code;
 
310
        continue;
 
311
      }
 
312
 
 
313
      incode = code;
 
314
      if (code >= avail) {
 
315
        *stackp++ = firstchar;
 
316
        code = oldcode;
 
317
 
 
318
        if (stackp == stack + MAX_BITS)
 
319
          return -1;
 
320
      }
 
321
 
 
322
      while (code >= clear_code)
 
323
      {
 
324
        if (code == prefix[code])
 
325
          return -1;
 
326
 
 
327
        *stackp++ = suffix[code];
 
328
        code = prefix[code];
 
329
 
 
330
        if (stackp == stack + MAX_BITS)
 
331
          return -1;
 
332
      }
 
333
 
 
334
      *stackp++ = firstchar = suffix[code];
 
335
 
 
336
      /* Define a new codeword in the dictionary. */
 
337
      if (avail < 4096) {
 
338
        prefix[avail] = oldcode;
 
339
        suffix[avail] = firstchar;
 
340
        avail++;
 
341
 
 
342
        /* If we've used up all the codewords of a given length
 
343
         * increase the length of codewords by one bit, but don't
 
344
         * exceed the specified maximum codeword size of 12 bits.
 
345
         */
 
346
        if (((avail & codemask) == 0) && (avail < 4096)) {
 
347
          codesize++;
 
348
          codemask += avail;
 
349
        }
 
350
      }
 
351
      oldcode = incode;
 
352
 
 
353
        /* Copy the decoded data out to the scanline buffer. */
 
354
      do {
 
355
        *rowp++ = *--stackp;
 
356
        if (rowp == rowend) {
 
357
          OUTPUT_ROW;
 
358
        }
 
359
      } while (stackp > stack);
 
360
    }
 
361
  }
 
362
 
 
363
  END:
 
364
 
 
365
  /* Home the local copies of the GIF decoder state variables */
 
366
  gs->avail = avail;
 
367
  gs->bits = bits;
 
368
  gs->codesize = codesize;
 
369
  gs->codemask = codemask;
 
370
  count = cnt;
 
371
  gs->oldcode = oldcode;
 
372
  gs->firstchar = firstchar;
 
373
  gs->datum = datum;
 
374
  gs->stackp = stackp;
 
375
  gs->rowp = rowp;
 
376
  gs->rows_remaining = rows_remaining;
 
377
 
 
378
  return 0;
 
379
}
 
380
 
 
381
 
 
382
/******************************************************************************/
 
383
/*
 
384
 * process data arriving from the stream for the gif decoder
 
385
 */
 
386
 
 
387
bool GIFImageReader::read(const unsigned char *buf, unsigned len, 
 
388
                     GIFImageDecoder::GIFQuery query, unsigned haltAtFrame)
 
389
{
 
390
  if (!len)
 
391
    return false;
 
392
 
 
393
  const unsigned char *q = buf;
 
394
 
 
395
  // Add what we have so far to the block
 
396
  // If previous call to me left something in the hold first complete current block
 
397
  // Or if we are filling the colormaps, first complete the colormap
 
398
  unsigned char* p = 0;
 
399
  if (state == gif_global_colormap)
 
400
    p = global_colormap;
 
401
  else if (state == gif_image_colormap)
 
402
    p = frame_reader ? frame_reader->local_colormap : 0;
 
403
  else if (bytes_in_hold)
 
404
    p = hold;
 
405
  else
 
406
    p = 0;
 
407
 
 
408
  if (p || (state == gif_global_colormap) || (state == gif_image_colormap)) {
 
409
    // Add what we have sofar to the block
 
410
    unsigned l = len < bytes_to_consume ? len : bytes_to_consume;
 
411
    if (p)
 
412
        memcpy(p + bytes_in_hold, buf, l);
 
413
 
 
414
    if (l < bytes_to_consume) {
 
415
      // Not enough in 'buf' to complete current block, get more
 
416
      bytes_in_hold += l;
 
417
      bytes_to_consume -= l;
 
418
      return true;
 
419
    }
 
420
    // Reset hold buffer count
 
421
    bytes_in_hold = 0;
 
422
    // Point 'q' to complete block in hold (or in colormap)
 
423
    q = p;
 
424
  }
 
425
 
 
426
  // Invariant:
 
427
  //    'q' is start of current to be processed block (hold, colormap or buf)
 
428
  //    'bytes_to_consume' is number of bytes to consume from 'buf'
 
429
  //    'buf' points to the bytes to be consumed from the input buffer
 
430
  //    'len' is number of bytes left in input buffer from position 'buf'.
 
431
  //    At entrance of the for loop will 'buf' will be moved 'bytes_to_consume'
 
432
  //    to point to next buffer, 'len' is adjusted accordingly.
 
433
  //    So that next round in for loop, q gets pointed to the next buffer.
 
434
 
 
435
  for (;len >= bytes_to_consume; q=buf) {
 
436
    // Eat the current block from the buffer, q keeps pointed at current block
 
437
    buf += bytes_to_consume;
 
438
    len -= bytes_to_consume;
 
439
 
 
440
    switch (state)
 
441
    {
 
442
    case gif_lzw:
 
443
      if (do_lzw(q) < 0) {
 
444
        state = gif_error;
 
445
        break;
 
446
      }
 
447
      GETN(1, gif_sub_block);
 
448
      break;
 
449
 
 
450
    case gif_lzw_start:
 
451
    {
 
452
      /* Initialize LZW parser/decoder */
 
453
      int datasize = *q;
 
454
      if (datasize > MAX_LZW_BITS) {
 
455
        state = gif_error;
 
456
        break;
 
457
      }
 
458
      int clear_code = 1 << datasize;
 
459
      if (clear_code >= MAX_BITS) {
 
460
        state = gif_error;
 
461
        break;
 
462
      }
 
463
 
 
464
      if (frame_reader) {
 
465
        frame_reader->datasize = datasize;
 
466
        frame_reader->clear_code = clear_code;
 
467
        frame_reader->avail = frame_reader->clear_code + 2;
 
468
        frame_reader->oldcode = -1;
 
469
        frame_reader->codesize = frame_reader->datasize + 1;
 
470
        frame_reader->codemask = (1 << frame_reader->codesize) - 1;
 
471
 
 
472
        frame_reader->datum = frame_reader->bits = 0;
 
473
 
 
474
        /* init the tables */
 
475
        if (!frame_reader->suffix)
 
476
          frame_reader->suffix = new unsigned char[MAX_BITS];
 
477
        for (int i = 0; i < frame_reader->clear_code; i++)
 
478
          frame_reader->suffix[i] = i;
 
479
 
 
480
        if (!frame_reader->stack)
 
481
          frame_reader->stack = new unsigned char[MAX_BITS];
 
482
        frame_reader->stackp = frame_reader->stack;
 
483
      }
 
484
 
 
485
      GETN(1, gif_sub_block);
 
486
    }
 
487
    break;
 
488
 
 
489
    /* All GIF files begin with "GIF87a" or "GIF89a" */
 
490
    case gif_type:
 
491
    {
 
492
      if (!strncmp((char*)q, "GIF89a", 6)) {
 
493
        version = 89;
 
494
      } else if (!strncmp((char*)q, "GIF87a", 6)) {
 
495
        version = 87;
 
496
      } else {
 
497
        state = gif_error;
 
498
        break;
 
499
      }
 
500
      GETN(7, gif_global_header);
 
501
    }
 
502
    break;
 
503
 
 
504
    case gif_global_header:
 
505
    {
 
506
      /* This is the height and width of the "screen" or
 
507
       * frame into which images are rendered.  The
 
508
       * individual images can be smaller than the
 
509
       * screen size and located with an origin anywhere
 
510
       * within the screen.
 
511
       */
 
512
 
 
513
      screen_width = GETINT16(q);
 
514
      screen_height = GETINT16(q + 2);
 
515
 
 
516
      // CALLBACK: Inform the decoderplugin of our size.
 
517
      if (clientptr)
 
518
        clientptr->sizeNowAvailable(screen_width, screen_height);
 
519
      
 
520
      screen_bgcolor = q[5];
 
521
      global_colormap_size = 2<<(q[4]&0x07);
 
522
 
 
523
      if ((q[4] & 0x80) && global_colormap_size > 0) { /* global map */
 
524
        // Get the global colormap
 
525
        const unsigned size = 3*global_colormap_size;
 
526
        
 
527
        // Malloc the color map, but only if we're not just counting frames.
 
528
        if (query != GIFImageDecoder::GIFFrameCountQuery)
 
529
          global_colormap = new unsigned char[size];
 
530
 
 
531
        if (len < size) {
 
532
          // Use 'hold' pattern to get the global colormap
 
533
          GETN(size, gif_global_colormap);
 
534
          break;
 
535
        }
 
536
        
 
537
        // Copy everything and go directly to gif_image_start.
 
538
        if (global_colormap)
 
539
            memcpy(global_colormap, buf, size);
 
540
        buf += size;
 
541
        len -= size;
 
542
      }
 
543
 
 
544
      GETN(1, gif_image_start);
 
545
 
 
546
      // q[6] = Pixel Aspect Ratio
 
547
      //   Not used
 
548
      //   float aspect = (float)((q[6] + 15) / 64.0);
 
549
    }
 
550
    break;
 
551
 
 
552
    case gif_global_colormap:
 
553
      // Everything is already copied into global_colormap
 
554
      GETN(1, gif_image_start);
 
555
    break;
 
556
 
 
557
    case gif_image_start:
 
558
    {
 
559
      if (*q == ';') { /* terminator */
 
560
        state = gif_done;
 
561
        break;
 
562
      }
 
563
 
 
564
      if (*q == '!') { /* extension */
 
565
        GETN(2, gif_extension);
 
566
        break;
 
567
      }
 
568
 
 
569
      /* If we get anything other than ',' (image separator), '!'
 
570
       * (extension), or ';' (trailer), there is extraneous data
 
571
       * between blocks. The GIF87a spec tells us to keep reading
 
572
       * until we find an image separator, but GIF89a says such
 
573
       * a file is corrupt. We follow GIF89a and bail out. */
 
574
      if (*q != ',') {
 
575
        if (images_decoded > 0) {
 
576
          /* The file is corrupt, but one or more images have
 
577
           * been decoded correctly. In this case, we proceed
 
578
           * as if the file were correctly terminated and set
 
579
           * the state to gif_done, so the GIF will display.
 
580
           */
 
581
          state = gif_done;
 
582
        } else {
 
583
          /* No images decoded, there is nothing to display. */
 
584
          state = gif_error;
 
585
        }
 
586
        break;
 
587
      } else
 
588
        GETN(9, gif_image_header);
 
589
    }
 
590
    break;
 
591
 
 
592
    case gif_extension:
 
593
    {
 
594
      int len = count = q[1];
 
595
      gstate es = gif_skip_block;
 
596
 
 
597
      switch (*q)
 
598
      {
 
599
      case 0xf9:
 
600
        es = gif_control_extension;
 
601
        break;
 
602
 
 
603
      case 0x01:
 
604
        // ignoring plain text extension
 
605
        break;
 
606
 
 
607
      case 0xff:
 
608
        es = gif_application_extension;
 
609
        break;
 
610
 
 
611
      case 0xfe:
 
612
        es = gif_consume_comment;
 
613
        break;
 
614
      }
 
615
 
 
616
      if (len)
 
617
        GETN(len, es);
 
618
      else
 
619
        GETN(1, gif_image_start);
 
620
    }
 
621
    break;
 
622
 
 
623
    case gif_consume_block:
 
624
      if (!*q)
 
625
        GETN(1, gif_image_start);
 
626
      else
 
627
        GETN(*q, gif_skip_block);
 
628
    break;
 
629
 
 
630
    case gif_skip_block:
 
631
      GETN(1, gif_consume_block);
 
632
      break;
 
633
 
 
634
    case gif_control_extension:
 
635
    {
 
636
      if (query != GIFImageDecoder::GIFFrameCountQuery) {
 
637
          if (!frame_reader)
 
638
            frame_reader = new GIFFrameReader();
 
639
      }
 
640
 
 
641
      if (frame_reader) {
 
642
        if (*q & 0x1) {
 
643
          frame_reader->tpixel = q[3];
 
644
          frame_reader->is_transparent = true;
 
645
        } else {
 
646
          frame_reader->is_transparent = false;
 
647
          // ignoring gfx control extension
 
648
        }
 
649
        frame_reader->disposal_method = (gdispose)(((*q) >> 2) & 0x7);
 
650
        // Some specs say 3rd bit (value 4), other specs say value 3
 
651
        // Let's choose 3 (the more popular)
 
652
        if (frame_reader->disposal_method == 4)
 
653
          frame_reader->disposal_method = (gdispose)3;
 
654
        unsigned short n = GETINT16(q + 1);
 
655
        // Many annoying ads specify a 0 duration to make an image flash as quickly as possible.
 
656
        // We follow Firefox's behavior and use a duration of 100 ms for any frames that specify
 
657
        // a duration of <= 10 ms. See gfxImageFrame::GetTimeout in Gecko or Radar 4051389 for more.
 
658
        frame_reader->delay_time = n <= 1 ? 100 : n * 10;
 
659
      }
 
660
      GETN(1, gif_consume_block);
 
661
    }
 
662
    break;
 
663
 
 
664
    case gif_comment_extension:
 
665
    {
 
666
      if (*q)
 
667
        GETN(*q, gif_consume_comment);
 
668
      else
 
669
        GETN(1, gif_image_start);
 
670
    }
 
671
    break;
 
672
 
 
673
    case gif_consume_comment:
 
674
      GETN(1, gif_comment_extension);
 
675
    break;
 
676
 
 
677
    case gif_application_extension:
 
678
      /* Check for netscape application extension */
 
679
      if (!strncmp((char*)q, "NETSCAPE2.0", 11) ||
 
680
        !strncmp((char*)q, "ANIMEXTS1.0", 11))
 
681
        GETN(1, gif_netscape_extension_block);
 
682
      else
 
683
        GETN(1, gif_consume_block);
 
684
    break;
 
685
 
 
686
    /* Netscape-specific GIF extension: animation looping */
 
687
    case gif_netscape_extension_block:
 
688
      if (*q)
 
689
        GETN(*q, gif_consume_netscape_extension);
 
690
      else
 
691
        GETN(1, gif_image_start);
 
692
    break;
 
693
 
 
694
    /* Parse netscape-specific application extensions */
 
695
    case gif_consume_netscape_extension:
 
696
    {
 
697
      int netscape_extension = q[0] & 7;
 
698
 
 
699
      /* Loop entire animation specified # of times.  Only read the
 
700
         loop count during the first iteration. */
 
701
      if (netscape_extension == 1) {
 
702
        loop_count = GETINT16(q + 1);
 
703
 
 
704
        GETN(1, gif_netscape_extension_block);
 
705
      }
 
706
      /* Wait for specified # of bytes to enter buffer */
 
707
      else if (netscape_extension == 2) {
 
708
        // Don't do this, this extension doesn't exist (isn't used at all) 
 
709
        // and doesn't do anything, as our streaming/buffering takes care of it all...
 
710
        // See: http://semmix.pl/color/exgraf/eeg24.htm
 
711
        GETN(1, gif_netscape_extension_block);
 
712
      } else
 
713
        state = gif_error; // 0,3-7 are yet to be defined netscape
 
714
                               // extension codes
 
715
 
 
716
      break;
 
717
    }
 
718
 
 
719
    case gif_image_header:
 
720
    {
 
721
      unsigned height, width, x_offset, y_offset;
 
722
      
 
723
      /* Get image offsets, with respect to the screen origin */
 
724
      x_offset = GETINT16(q);
 
725
      y_offset = GETINT16(q + 2);
 
726
 
 
727
      /* Get image width and height. */
 
728
      width  = GETINT16(q + 4);
 
729
      height = GETINT16(q + 6);
 
730
 
 
731
      /* Work around broken GIF files where the logical screen
 
732
       * size has weird width or height.  We assume that GIF87a
 
733
       * files don't contain animations.
 
734
       */
 
735
      if ((images_decoded == 0) &&
 
736
          ((screen_height < height) || (screen_width < width) ||
 
737
           (version == 87)))
 
738
      {
 
739
        screen_height = height;
 
740
        screen_width = width;
 
741
        x_offset = 0;
 
742
        y_offset = 0;
 
743
 
 
744
        // CALLBACK: Inform the decoderplugin of our size.
 
745
        if (clientptr)
 
746
          clientptr->sizeNowAvailable(screen_width, screen_height);
 
747
      }
 
748
 
 
749
      /* Work around more broken GIF files that have zero image
 
750
         width or height */
 
751
      if (!height || !width) {
 
752
        height = screen_height;
 
753
        width = screen_width;
 
754
        if (!height || !width) {
 
755
          state = gif_error;
 
756
          break;
 
757
        }
 
758
      }
 
759
 
 
760
      if (query == GIFImageDecoder::GIFSizeQuery || haltAtFrame == images_decoded) {
 
761
        // The decoder needs to stop.  Hand back the number of bytes we consumed from
 
762
        // buffer minus 9 (the amount we consumed to read the header).
 
763
        if (clientptr)
 
764
            clientptr->decodingHalted(len + 9);
 
765
        GETN(9, gif_image_header);
 
766
        return true;
 
767
      }
 
768
      
 
769
      images_count = images_decoded + 1;
 
770
 
 
771
      if (query == GIFImageDecoder::GIFFullQuery && !frame_reader)
 
772
        frame_reader = new GIFFrameReader();
 
773
 
 
774
      if (frame_reader) {
 
775
        frame_reader->x_offset = x_offset;
 
776
        frame_reader->y_offset = y_offset;
 
777
        frame_reader->height = height;
 
778
        frame_reader->width = width;
 
779
 
 
780
        /* This case will never be taken if this is the first image */
 
781
        /* being decoded. If any of the later images are larger     */
 
782
        /* than the screen size, we need to reallocate buffers.     */
 
783
        if (screen_width < width) {
 
784
          /* XXX Deviant! */
 
785
 
 
786
          delete []frame_reader->rowbuf;
 
787
          frame_reader->rowbuf = new unsigned char[width];
 
788
 
 
789
          if (!frame_reader->rowbuf) {
 
790
            state = gif_oom;
 
791
            break;
 
792
          }
 
793
 
 
794
          screen_width = width;
 
795
          if (screen_height < frame_reader->height)
 
796
            screen_height = frame_reader->height;
 
797
        }
 
798
        else {
 
799
          if (!frame_reader->rowbuf)
 
800
            frame_reader->rowbuf = new unsigned char[screen_width];
 
801
        }
 
802
 
 
803
        if (!frame_reader->rowbuf) {
 
804
          state = gif_oom;
 
805
          break;
 
806
        }
 
807
 
 
808
        if (q[8] & 0x40) {
 
809
          frame_reader->interlaced = true;
 
810
          frame_reader->ipass = 1;
 
811
        } else {
 
812
          frame_reader->interlaced = false;
 
813
          frame_reader->ipass = 0;
 
814
        }
 
815
 
 
816
        if (images_decoded == 0) {
 
817
          frame_reader->progressive_display = true;
 
818
        } else {
 
819
          /* Overlaying interlaced, transparent GIFs over
 
820
             existing image data using the Haeberli display hack
 
821
             requires saving the underlying image in order to
 
822
             avoid jaggies at the transparency edges.  We are
 
823
             unprepared to deal with that, so don't display such
 
824
             images progressively */
 
825
          frame_reader->progressive_display = false;
 
826
        }
 
827
 
 
828
        /* Clear state from last image */
 
829
        frame_reader->irow = 0;
 
830
        frame_reader->rows_remaining = frame_reader->height;
 
831
        frame_reader->rowend = frame_reader->rowbuf + frame_reader->width;
 
832
        frame_reader->rowp = frame_reader->rowbuf;
 
833
 
 
834
        /* bits per pixel is q[8]&0x07 */
 
835
      }
 
836
      
 
837
      if (q[8] & 0x80) /* has a local colormap? */
 
838
      {
 
839
        int num_colors = 2 << (q[8] & 0x7);
 
840
        const unsigned size = 3*num_colors;
 
841
        unsigned char *map = frame_reader ? frame_reader->local_colormap : 0;
 
842
        if (frame_reader && (!map || (num_colors > frame_reader->local_colormap_size))) {
 
843
          delete []map;
 
844
          map = new unsigned char[size];
 
845
          if (!map) {
 
846
            state = gif_oom;
 
847
            break;
 
848
          }
 
849
        }
 
850
 
 
851
        /* Switch to the new local palette after it loads */
 
852
        if (frame_reader) {
 
853
          frame_reader->local_colormap = map;
 
854
          frame_reader->local_colormap_size = num_colors;
 
855
          frame_reader->is_local_colormap_defined = true;
 
856
        }
 
857
 
 
858
        if (len < size) {
 
859
          // Use 'hold' pattern to get the image colormap
 
860
          GETN(size, gif_image_colormap);
 
861
          break;
 
862
        }
 
863
        // Copy everything and directly go to gif_lzw_start
 
864
        if (frame_reader)
 
865
          memcpy(frame_reader->local_colormap, buf, size);
 
866
        buf += size;
 
867
        len -= size;
 
868
      } else if (frame_reader) {
 
869
        /* Switch back to the global palette */
 
870
        frame_reader->is_local_colormap_defined = false;
 
871
      }
 
872
      GETN(1, gif_lzw_start);
 
873
    }
 
874
    break;
 
875
 
 
876
    case gif_image_colormap:
 
877
      // Everything is already copied into local_colormap
 
878
      GETN(1, gif_lzw_start);
 
879
    break;
 
880
 
 
881
    case gif_sub_block:
 
882
    {
 
883
      if ((count = *q) != 0)
 
884
      /* Still working on the same image: Process next LZW data block */
 
885
      {
 
886
        /* Make sure there are still rows left. If the GIF data */
 
887
        /* is corrupt, we may not get an explicit terminator.   */
 
888
        if (frame_reader && frame_reader->rows_remaining == 0) {
 
889
          /* This is an illegal GIF, but we remain tolerant. */
 
890
          GETN(1, gif_sub_block);
 
891
        }
 
892
        GETN(count, gif_lzw);
 
893
      }
 
894
      else
 
895
      /* See if there are any more images in this sequence. */
 
896
      {
 
897
        images_decoded++;
 
898
 
 
899
        // CALLBACK: The frame is now complete.
 
900
        if (clientptr && frame_reader)
 
901
          clientptr->frameComplete(images_decoded - 1, frame_reader->delay_time, 
 
902
                                   frame_reader->disposal_method == DISPOSE_KEEP);
 
903
 
 
904
        /* Clear state from this image */
 
905
        if (frame_reader) {
 
906
            frame_reader->is_local_colormap_defined = false;
 
907
            frame_reader->is_transparent = false;
 
908
        }
 
909
 
 
910
        GETN(1, gif_image_start);
 
911
      }
 
912
    }
 
913
    break;
 
914
 
 
915
    case gif_done:
 
916
      // When the GIF is done, we can stop.
 
917
      if (clientptr)
 
918
        clientptr->gifComplete();
 
919
      return true;
 
920
 
 
921
    // Handle out of memory errors
 
922
    case gif_oom:
 
923
      return false;
 
924
 
 
925
    // Handle general errors
 
926
    case gif_error:
 
927
      // nsGIFDecoder2::EndGIF(gs->clientptr, gs->loop_count);
 
928
      return true;
 
929
 
 
930
    // We shouldn't ever get here.
 
931
    default:
 
932
      break;
 
933
    }
 
934
  }
 
935
 
 
936
  // Copy the leftover into gs->hold
 
937
  bytes_in_hold = len;
 
938
  if (len) {
 
939
    // Add what we have sofar to the block
 
940
    unsigned char* p;
 
941
    if (state == gif_global_colormap)
 
942
      p = global_colormap;
 
943
    else if (state == gif_image_colormap)
 
944
      p = frame_reader ? frame_reader->local_colormap : 0;
 
945
    else
 
946
      p = hold;
 
947
    if (p)
 
948
      memcpy(p, buf, len);
 
949
    bytes_to_consume -= len;
 
950
  }
 
951
 
 
952
  return true;
 
953
}
 
954
 
 
955
#endif // PLATFORM(CAIRO)