2009-01-23 Darin Fisher <darin@chromium.org>
[WebKit-https.git] / WebCore / platform / image-decoders / skia / GIFImageReader.cpp
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) || PLATFORM(WX)
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 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   // CALLBACK: Let the client know we have decoded a row.
162   if (clientptr && frame_reader)
163     clientptr->haveDecodedRow(images_count - 1, frame_reader->rowbuf, frame_reader->rowend,
164                               drow_start, drow_end - drow_start + 1,
165                               gs->progressive_display && gs->interlaced && gs->ipass > 1);
166
167   gs->rowp = gs->rowbuf;
168
169   if (!gs->interlaced)
170     gs->irow++;
171   else {
172     do {
173       switch (gs->ipass)
174       {
175         case 1:
176           gs->irow += 8;
177           if (gs->irow >= gs->height) {
178             gs->ipass++;
179             gs->irow = 4;
180           }
181           break;
182
183         case 2:
184           gs->irow += 8;
185           if (gs->irow >= gs->height) {
186             gs->ipass++;
187             gs->irow = 2;
188           }
189           break;
190
191         case 3:
192           gs->irow += 4;
193           if (gs->irow >= gs->height) {
194             gs->ipass++;
195             gs->irow = 1;
196           }
197           break;
198
199         case 4:
200           gs->irow += 2;
201           if (gs->irow >= gs->height){
202             gs->ipass++;
203             gs->irow = 0;
204           }
205           break;
206
207         default:
208           break;
209       }
210     } while (gs->irow > (gs->height - 1));
211   }
212 }
213
214 //******************************************************************************
215 /* Perform Lempel-Ziv-Welch decoding */
216 int GIFImageReader::do_lzw(const unsigned char *q)
217 {
218   GIFFrameReader* gs = frame_reader;
219   if (!gs)
220     return 0;
221
222   int code;
223   int incode;
224   const unsigned char *ch;
225   
226   /* Copy all the decoder state variables into locals so the compiler
227    * won't worry about them being aliased.  The locals will be homed
228    * back into the GIF decoder structure when we exit.
229    */
230   int avail       = gs->avail;
231   int bits        = gs->bits;
232   int cnt         = count;
233   int codesize    = gs->codesize;
234   int codemask    = gs->codemask;
235   int oldcode     = gs->oldcode;
236   int clear_code  = gs->clear_code;
237   unsigned char firstchar = gs->firstchar;
238   int datum     = gs->datum;
239
240   if (!gs->prefix) {
241     gs->prefix = new unsigned short[MAX_BITS];
242     memset(gs->prefix, 0, MAX_BITS * sizeof(short));
243   }
244
245   unsigned short *prefix  = gs->prefix;
246   unsigned char *stackp   = gs->stackp;
247   unsigned char *suffix   = gs->suffix;
248   unsigned char *stack    = gs->stack;
249   unsigned char *rowp     = gs->rowp;
250   unsigned char *rowend   = gs->rowend;
251   unsigned rows_remaining = gs->rows_remaining;
252
253   if (rowp == rowend)
254     return 0;
255
256 #define OUTPUT_ROW                                                  \
257   PR_BEGIN_MACRO                                                        \
258     output_row();                                                     \
259     rows_remaining--;                                                   \
260     rowp = frame_reader->rowp;                                                    \
261     if (!rows_remaining)                                                \
262       goto END;                                                         \
263   PR_END_MACRO
264
265   for (ch = q; cnt-- > 0; ch++)
266   {
267     /* Feed the next byte into the decoder's 32-bit input buffer. */
268     datum += ((int) *ch) << bits;
269     bits += 8;
270
271     /* Check for underflow of decoder's 32-bit input buffer. */
272     while (bits >= codesize)
273     {
274       /* Get the leading variable-length symbol from the data stream */
275       code = datum & codemask;
276       datum >>= codesize;
277       bits -= codesize;
278
279       /* Reset the dictionary to its original state, if requested */
280       if (code == clear_code) {
281         codesize = gs->datasize + 1;
282         codemask = (1 << codesize) - 1;
283         avail = clear_code + 2;
284         oldcode = -1;
285         continue;
286       }
287
288       /* Check for explicit end-of-stream code */
289       if (code == (clear_code + 1)) {
290         /* end-of-stream should only appear after all image data */
291         if (rows_remaining != 0)
292           return -1;
293         return 0;
294       }
295
296       if (oldcode == -1) {
297         *rowp++ = suffix[code];
298         if (rowp == rowend)
299           OUTPUT_ROW;
300
301         firstchar = oldcode = code;
302         continue;
303       }
304
305       incode = code;
306       if (code >= avail) {
307         *stackp++ = firstchar;
308         code = oldcode;
309
310         if (stackp == stack + MAX_BITS)
311           return -1;
312       }
313
314       while (code >= clear_code)
315       {
316         if (code == prefix[code])
317           return -1;
318
319         *stackp++ = suffix[code];
320         code = prefix[code];
321
322         if (stackp == stack + MAX_BITS)
323           return -1;
324       }
325
326       *stackp++ = firstchar = suffix[code];
327
328       /* Define a new codeword in the dictionary. */
329       if (avail < 4096) {
330         prefix[avail] = oldcode;
331         suffix[avail] = firstchar;
332         avail++;
333
334         /* If we've used up all the codewords of a given length
335          * increase the length of codewords by one bit, but don't
336          * exceed the specified maximum codeword size of 12 bits.
337          */
338         if (((avail & codemask) == 0) && (avail < 4096)) {
339           codesize++;
340           codemask += avail;
341         }
342       }
343       oldcode = incode;
344
345         /* Copy the decoded data out to the scanline buffer. */
346       do {
347         *rowp++ = *--stackp;
348         if (rowp == rowend) {
349           OUTPUT_ROW;
350         }
351       } while (stackp > stack);
352     }
353   }
354
355   END:
356
357   /* Home the local copies of the GIF decoder state variables */
358   gs->avail = avail;
359   gs->bits = bits;
360   gs->codesize = codesize;
361   gs->codemask = codemask;
362   count = cnt;
363   gs->oldcode = oldcode;
364   gs->firstchar = firstchar;
365   gs->datum = datum;
366   gs->stackp = stackp;
367   gs->rowp = rowp;
368   gs->rows_remaining = rows_remaining;
369
370   return 0;
371 }
372
373
374 /******************************************************************************/
375 /*
376  * process data arriving from the stream for the gif decoder
377  */
378
379 bool GIFImageReader::read(const unsigned char *buf, unsigned len, 
380                      GIFImageDecoder::GIFQuery query, unsigned haltAtFrame)
381 {
382   if (!len) {
383     // No new data has come in since the last call, just ignore this call.
384     return true;
385   }
386
387   const unsigned char *q = buf;
388
389   // Add what we have so far to the block
390   // If previous call to me left something in the hold first complete current block
391   // Or if we are filling the colormaps, first complete the colormap
392   unsigned char* p = 0;
393   if (state == gif_global_colormap)
394     p = global_colormap;
395   else if (state == gif_image_colormap)
396     p = frame_reader ? frame_reader->local_colormap : 0;
397   else if (bytes_in_hold)
398     p = hold;
399   else
400     p = 0;
401
402   if (p || (state == gif_global_colormap) || (state == gif_image_colormap)) {
403     // Add what we have sofar to the block
404     unsigned l = len < bytes_to_consume ? len : bytes_to_consume;
405     if (p)
406         memcpy(p + bytes_in_hold, buf, l);
407
408     if (l < bytes_to_consume) {
409       // Not enough in 'buf' to complete current block, get more
410       bytes_in_hold += l;
411       bytes_to_consume -= l;
412       if (clientptr)
413         clientptr->decodingHalted(0);
414       return true;
415     }
416     // Reset hold buffer count
417     bytes_in_hold = 0;
418     // Point 'q' to complete block in hold (or in colormap)
419     q = p;
420   }
421
422   // Invariant:
423   //    'q' is start of current to be processed block (hold, colormap or buf)
424   //    'bytes_to_consume' is number of bytes to consume from 'buf'
425   //    'buf' points to the bytes to be consumed from the input buffer
426   //    'len' is number of bytes left in input buffer from position 'buf'.
427   //    At entrance of the for loop will 'buf' will be moved 'bytes_to_consume'
428   //    to point to next buffer, 'len' is adjusted accordingly.
429   //    So that next round in for loop, q gets pointed to the next buffer.
430
431   for (;len >= bytes_to_consume; q=buf) {
432     // Eat the current block from the buffer, q keeps pointed at current block
433     buf += bytes_to_consume;
434     len -= bytes_to_consume;
435
436     switch (state)
437     {
438     case gif_lzw:
439       if (do_lzw(q) < 0) {
440         state = gif_error;
441         break;
442       }
443       GETN(1, gif_sub_block);
444       break;
445
446     case gif_lzw_start:
447     {
448       /* Initialize LZW parser/decoder */
449       int datasize = *q;
450       if (datasize > MAX_LZW_BITS) {
451         state = gif_error;
452         break;
453       }
454       int clear_code = 1 << datasize;
455       if (clear_code >= MAX_BITS) {
456         state = gif_error;
457         break;
458       }
459
460       if (frame_reader) {
461         frame_reader->datasize = datasize;
462         frame_reader->clear_code = clear_code;
463         frame_reader->avail = frame_reader->clear_code + 2;
464         frame_reader->oldcode = -1;
465         frame_reader->codesize = frame_reader->datasize + 1;
466         frame_reader->codemask = (1 << frame_reader->codesize) - 1;
467
468         frame_reader->datum = frame_reader->bits = 0;
469
470         /* init the tables */
471         if (!frame_reader->suffix)
472           frame_reader->suffix = new unsigned char[MAX_BITS];
473         for (int i = 0; i < frame_reader->clear_code; i++)
474           frame_reader->suffix[i] = i;
475
476         if (!frame_reader->stack)
477           frame_reader->stack = new unsigned char[MAX_BITS];
478         frame_reader->stackp = frame_reader->stack;
479       }
480
481       GETN(1, gif_sub_block);
482     }
483     break;
484
485     /* All GIF files begin with "GIF87a" or "GIF89a" */
486     case gif_type:
487     {
488       if (!strncmp((char*)q, "GIF89a", 6)) {
489         version = 89;
490       } else if (!strncmp((char*)q, "GIF87a", 6)) {
491         version = 87;
492       } else {
493         state = gif_error;
494         break;
495       }
496       GETN(7, gif_global_header);
497     }
498     break;
499
500     case gif_global_header:
501     {
502       /* This is the height and width of the "screen" or
503        * frame into which images are rendered.  The
504        * individual images can be smaller than the
505        * screen size and located with an origin anywhere
506        * within the screen.
507        */
508
509       screen_width = GETINT16(q);
510       screen_height = GETINT16(q + 2);
511
512       // CALLBACK: Inform the decoderplugin of our size.
513       if (clientptr)
514         clientptr->sizeNowAvailable(screen_width, screen_height);
515       
516       screen_bgcolor = q[5];
517       global_colormap_size = 2<<(q[4]&0x07);
518
519       if ((q[4] & 0x80) && global_colormap_size > 0) { /* global map */
520         // Get the global colormap
521         const unsigned size = 3*global_colormap_size;
522         
523         // Malloc the color map, but only if we're not just counting frames.
524         if (query != GIFImageDecoder::GIFFrameCountQuery)
525           global_colormap = new unsigned char[size];
526
527         if (len < size) {
528           // Use 'hold' pattern to get the global colormap
529           GETN(size, gif_global_colormap);
530           break;
531         }
532         
533         // Copy everything and go directly to gif_image_start.
534         if (global_colormap)
535             memcpy(global_colormap, buf, size);
536         buf += size;
537         len -= size;
538       }
539
540       GETN(1, gif_image_start);
541
542       // q[6] = Pixel Aspect Ratio
543       //   Not used
544       //   float aspect = (float)((q[6] + 15) / 64.0);
545     }
546     break;
547
548     case gif_global_colormap:
549       // Everything is already copied into global_colormap
550       GETN(1, gif_image_start);
551     break;
552
553     case gif_image_start:
554     {
555       if (*q == ';') { /* terminator */
556         state = gif_done;
557         break;
558       }
559
560       if (*q == '!') { /* extension */
561         GETN(2, gif_extension);
562         break;
563       }
564
565       /* If we get anything other than ',' (image separator), '!'
566        * (extension), or ';' (trailer), there is extraneous data
567        * between blocks. The GIF87a spec tells us to keep reading
568        * until we find an image separator, but GIF89a says such
569        * a file is corrupt. We follow GIF89a and bail out. */
570       if (*q != ',') {
571         if (images_decoded > 0) {
572           /* The file is corrupt, but one or more images have
573            * been decoded correctly. In this case, we proceed
574            * as if the file were correctly terminated and set
575            * the state to gif_done, so the GIF will display.
576            */
577           state = gif_done;
578         } else {
579           /* No images decoded, there is nothing to display. */
580           state = gif_error;
581         }
582         break;
583       } else
584         GETN(9, gif_image_header);
585     }
586     break;
587
588     case gif_extension:
589     {
590       int len = count = q[1];
591       gstate es = gif_skip_block;
592
593       switch (*q)
594       {
595       case 0xf9:
596         es = gif_control_extension;
597         break;
598
599       case 0x01:
600         // ignoring plain text extension
601         break;
602
603       case 0xff:
604         es = gif_application_extension;
605         break;
606
607       case 0xfe:
608         es = gif_consume_comment;
609         break;
610       }
611
612       if (len)
613         GETN(len, es);
614       else
615         GETN(1, gif_image_start);
616     }
617     break;
618
619     case gif_consume_block:
620       if (!*q)
621         GETN(1, gif_image_start);
622       else
623         GETN(*q, gif_skip_block);
624     break;
625
626     case gif_skip_block:
627       GETN(1, gif_consume_block);
628       break;
629
630     case gif_control_extension:
631     {
632       if (query != GIFImageDecoder::GIFFrameCountQuery) {
633           if (!frame_reader)
634             frame_reader = new GIFFrameReader();
635       }
636
637       if (frame_reader) {
638         if (*q & 0x1) {
639           frame_reader->tpixel = q[3];
640           frame_reader->is_transparent = true;
641         } else {
642           frame_reader->is_transparent = false;
643           // ignoring gfx control extension
644         }
645         // NOTE: This relies on the values in the FrameDisposalMethod enum
646         // matching those in the GIF spec!
647         frame_reader->disposal_method = (WebCore::RGBA32Buffer::FrameDisposalMethod)(((*q) >> 2) & 0x7);
648         // Some specs say 3rd bit (value 4), other specs say value 3
649         // Let's choose 3 (the more popular)
650         if (frame_reader->disposal_method == 4)
651           frame_reader->disposal_method = WebCore::RGBA32Buffer::DisposeOverwritePrevious;
652         frame_reader->delay_time = GETINT16(q + 1) * 10;
653       }
654       GETN(1, gif_consume_block);
655     }
656     break;
657
658     case gif_comment_extension:
659     {
660       if (*q)
661         GETN(*q, gif_consume_comment);
662       else
663         GETN(1, gif_image_start);
664     }
665     break;
666
667     case gif_consume_comment:
668       GETN(1, gif_comment_extension);
669     break;
670
671     case gif_application_extension:
672       /* Check for netscape application extension */
673       if (!strncmp((char*)q, "NETSCAPE2.0", 11) ||
674         !strncmp((char*)q, "ANIMEXTS1.0", 11))
675         GETN(1, gif_netscape_extension_block);
676       else
677         GETN(1, gif_consume_block);
678     break;
679
680     /* Netscape-specific GIF extension: animation looping */
681     case gif_netscape_extension_block:
682       if (*q)
683         GETN(*q, gif_consume_netscape_extension);
684       else
685         GETN(1, gif_image_start);
686     break;
687
688     /* Parse netscape-specific application extensions */
689     case gif_consume_netscape_extension:
690     {
691       int netscape_extension = q[0] & 7;
692
693       /* Loop entire animation specified # of times.  Only read the
694          loop count during the first iteration. */
695       if (netscape_extension == 1) {
696         loop_count = GETINT16(q + 1);
697
698         GETN(1, gif_netscape_extension_block);
699       }
700       /* Wait for specified # of bytes to enter buffer */
701       else if (netscape_extension == 2) {
702         // Don't do this, this extension doesn't exist (isn't used at all) 
703         // and doesn't do anything, as our streaming/buffering takes care of it all...
704         // See: http://semmix.pl/color/exgraf/eeg24.htm
705         GETN(1, gif_netscape_extension_block);
706       } else
707         state = gif_error; // 0,3-7 are yet to be defined netscape
708                                // extension codes
709
710       break;
711     }
712
713     case gif_image_header:
714     {
715       unsigned height, width, x_offset, y_offset;
716       
717       /* Get image offsets, with respect to the screen origin */
718       x_offset = GETINT16(q);
719       y_offset = GETINT16(q + 2);
720
721       /* Get image width and height. */
722       width  = GETINT16(q + 4);
723       height = GETINT16(q + 6);
724
725       /* Work around broken GIF files where the logical screen
726        * size has weird width or height.  We assume that GIF87a
727        * files don't contain animations.
728        */
729       if ((images_decoded == 0) &&
730           ((screen_height < height) || (screen_width < width) ||
731            (version == 87)))
732       {
733         screen_height = height;
734         screen_width = width;
735         x_offset = 0;
736         y_offset = 0;
737
738         // CALLBACK: Inform the decoderplugin of our size.
739         if (clientptr)
740           clientptr->sizeNowAvailable(screen_width, screen_height);
741       }
742
743       /* Work around more broken GIF files that have zero image
744          width or height */
745       if (!height || !width) {
746         height = screen_height;
747         width = screen_width;
748         if (!height || !width) {
749           state = gif_error;
750           break;
751         }
752       }
753
754       if (query == GIFImageDecoder::GIFSizeQuery || haltAtFrame == images_decoded) {
755         // The decoder needs to stop.  Hand back the number of bytes we consumed from
756         // buffer minus 9 (the amount we consumed to read the header).
757         if (clientptr)
758             clientptr->decodingHalted(len + 9);
759         GETN(9, gif_image_header);
760         return true;
761       }
762       
763       images_count = images_decoded + 1;
764
765       if (query == GIFImageDecoder::GIFFullQuery && !frame_reader)
766         frame_reader = new GIFFrameReader();
767
768       if (frame_reader) {
769         frame_reader->x_offset = x_offset;
770         frame_reader->y_offset = y_offset;
771         frame_reader->height = height;
772         frame_reader->width = width;
773
774         /* This case will never be taken if this is the first image */
775         /* being decoded. If any of the later images are larger     */
776         /* than the screen size, we need to reallocate buffers.     */
777         if (screen_width < width) {
778           /* XXX Deviant! */
779
780           delete []frame_reader->rowbuf;
781           screen_width = width;
782           frame_reader->rowbuf = new unsigned char[screen_width];
783         } else if (!frame_reader->rowbuf) {
784           frame_reader->rowbuf = new unsigned char[screen_width];
785         }
786
787         if (!frame_reader->rowbuf) {
788           state = gif_oom;
789           break;
790         }
791         if (screen_height < height)
792           screen_height = height;
793
794         if (q[8] & 0x40) {
795           frame_reader->interlaced = true;
796           frame_reader->ipass = 1;
797         } else {
798           frame_reader->interlaced = false;
799           frame_reader->ipass = 0;
800         }
801
802         if (images_decoded == 0) {
803           frame_reader->progressive_display = true;
804         } else {
805           /* Overlaying interlaced, transparent GIFs over
806              existing image data using the Haeberli display hack
807              requires saving the underlying image in order to
808              avoid jaggies at the transparency edges.  We are
809              unprepared to deal with that, so don't display such
810              images progressively */
811           frame_reader->progressive_display = false;
812         }
813
814         /* Clear state from last image */
815         frame_reader->irow = 0;
816         frame_reader->rows_remaining = frame_reader->height;
817         frame_reader->rowend = frame_reader->rowbuf + frame_reader->width;
818         frame_reader->rowp = frame_reader->rowbuf;
819
820         /* bits per pixel is q[8]&0x07 */
821       }
822       
823       if (q[8] & 0x80) /* has a local colormap? */
824       {
825         int num_colors = 2 << (q[8] & 0x7);
826         const unsigned size = 3*num_colors;
827         unsigned char *map = frame_reader ? frame_reader->local_colormap : 0;
828         if (frame_reader && (!map || (num_colors > frame_reader->local_colormap_size))) {
829           delete []map;
830           map = new unsigned char[size];
831           if (!map) {
832             state = gif_oom;
833             break;
834           }
835         }
836
837         /* Switch to the new local palette after it loads */
838         if (frame_reader) {
839           frame_reader->local_colormap = map;
840           frame_reader->local_colormap_size = num_colors;
841           frame_reader->is_local_colormap_defined = true;
842         }
843
844         if (len < size) {
845           // Use 'hold' pattern to get the image colormap
846           GETN(size, gif_image_colormap);
847           break;
848         }
849         // Copy everything and directly go to gif_lzw_start
850         if (frame_reader)
851           memcpy(frame_reader->local_colormap, buf, size);
852         buf += size;
853         len -= size;
854       } else if (frame_reader) {
855         /* Switch back to the global palette */
856         frame_reader->is_local_colormap_defined = false;
857       }
858       GETN(1, gif_lzw_start);
859     }
860     break;
861
862     case gif_image_colormap:
863       // Everything is already copied into local_colormap
864       GETN(1, gif_lzw_start);
865     break;
866
867     case gif_sub_block:
868     {
869       if ((count = *q) != 0)
870       /* Still working on the same image: Process next LZW data block */
871       {
872         /* Make sure there are still rows left. If the GIF data */
873         /* is corrupt, we may not get an explicit terminator.   */
874         if (frame_reader && frame_reader->rows_remaining == 0) {
875           /* This is an illegal GIF, but we remain tolerant. */
876           GETN(1, gif_sub_block);
877         }
878         GETN(count, gif_lzw);
879       }
880       else
881       /* See if there are any more images in this sequence. */
882       {
883         images_decoded++;
884
885         // CALLBACK: The frame is now complete.
886         if (clientptr && frame_reader)
887           clientptr->frameComplete(images_decoded - 1, frame_reader->delay_time, 
888                                    frame_reader->disposal_method);
889
890         /* Clear state from this image */
891         if (frame_reader) {
892             frame_reader->is_local_colormap_defined = false;
893             frame_reader->is_transparent = false;
894         }
895
896         GETN(1, gif_image_start);
897       }
898     }
899     break;
900
901     case gif_done:
902       // When the GIF is done, we can stop.
903       if (clientptr)
904         clientptr->gifComplete();
905       return true;
906
907     // Handle out of memory errors
908     case gif_oom:
909       return false;
910
911     // Handle general errors
912     case gif_error:
913       // nsGIFDecoder2::EndGIF(gs->clientptr, gs->loop_count);
914       return false;
915
916     // We shouldn't ever get here.
917     default:
918       break;
919     }
920   }
921
922   // Copy the leftover into gs->hold
923   bytes_in_hold = len;
924   if (len) {
925     // Add what we have sofar to the block
926     unsigned char* p;
927     if (state == gif_global_colormap)
928       p = global_colormap;
929     else if (state == gif_image_colormap)
930       p = frame_reader ? frame_reader->local_colormap : 0;
931     else
932       p = hold;
933     if (p)
934       memcpy(p, buf, len);
935     bytes_to_consume -= len;
936   }
937
938   if (clientptr)
939     clientptr->decodingHalted(0);
940   return true;
941 }
942
943 #endif // PLATFORM(CAIRO)