Unreviewed, rolling out r143936.
[WebKit-https.git] / Source / WebCore / platform / image-decoders / gif / GIFImageReader.h
1 /* -*- Mode: C; tab-width: 4; 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 Communicator client 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  *
24  * Alternatively, the contents of this file may be used under the terms of
25  * either the GNU General Public License Version 2 or later (the "GPL"), or
26  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27  * in which case the provisions of the GPL or the LGPL are applicable instead
28  * of those above. If you wish to allow use of your version of this file only
29  * under the terms of either the GPL or the LGPL, and not to allow others to
30  * use your version of this file under the terms of the MPL, indicate your
31  * decision by deleting the provisions above and replace them with the notice
32  * and other provisions required by the GPL or the LGPL. If you do not delete
33  * the provisions above, a recipient may use your version of this file under
34  * the terms of any one of the MPL, the GPL or the LGPL.
35  *
36  * ***** END LICENSE BLOCK ***** */
37
38 #ifndef GIFImageReader_h
39 #define GIFImageReader_h
40
41 // Define ourselves as the clientPtr.  Mozilla just hacked their C++ callback class into this old C decoder,
42 // so we will too.
43 #include "GIFImageDecoder.h"
44
45 #define MAX_LZW_BITS          12
46 #define MAX_BITS            4097 /* 2^MAX_LZW_BITS+1 */
47 #define MAX_COLORS           256
48 #define MAX_HOLD_SIZE        256
49
50 const int cLoopCountNotSeen = -2;
51
52 // List of possible parsing states.
53 enum GIFState {
54     GIFType,
55     GIFGlobalHeader,
56     GIFGlobalColormap,
57     GIFImageStart,            
58     GIFImageHeader,
59     GIFImageColormap,
60     GIFImageBody,
61     GIFLZWStart,
62     GIFLZW,
63     GIFSubBlock,
64     GIFExtension,
65     GIFControlExtension,
66     GIFConsumeBlock,
67     GIFSkipBlock,
68     GIFDone,
69     GIFCommentExtension,
70     GIFApplicationExtension,
71     GIFNetscapeExtensionBlock,
72     GIFConsumeNetscapeExtension,
73     GIFConsumeComment
74 };
75
76 struct GIFFrameContext {
77     WTF_MAKE_FAST_ALLOCATED;
78 public:
79     // LZW decoder state machine.
80     unsigned char *stackp; // Current stack pointer.
81     int datasize;
82     int codesize;
83     int codemask;
84     int clearCode; // Codeword used to trigger dictionary reset.
85     int avail; // Index of next available slot in dictionary.
86     int oldcode;
87     unsigned char firstchar;
88     int bits; // Number of unread bits in "datum".
89     int datum; // 32-bit input buffer.
90
91     // Output state machine.
92     int ipass; // Interlace pass; Ranges 1-4 if interlaced.
93     unsigned rowsRemaining; // Rows remaining to be output.
94     unsigned irow; // Current output row, starting at zero.
95     unsigned char *rowbuf; // Single scanline temporary buffer.
96     unsigned char *rowend; // Pointer to end of rowbuf.
97     unsigned char *rowp; // Current output pointer.
98
99     // Parameters for image frame currently being decoded.
100     unsigned xOffset;
101     unsigned yOffset; // With respect to "screen" origin.
102     unsigned width;
103     unsigned height;
104     int tpixel; // Index of transparent pixel.
105     WebCore::ImageFrame::FrameDisposalMethod disposalMethod; // Restore to background, leave in place, etc.
106     unsigned char *localColormap; // Per-image colormap.
107     int localColormapSize; // Size of local colormap array.
108     
109     bool isLocalColormapDefined : 1;
110     bool progressiveDisplay : 1; // If true, do Haeberli interlace hack.
111     bool interlaced : 1; // True, if scanlines arrive interlaced order.
112     bool isTransparent : 1; // TRUE, if tpixel is valid.
113
114     unsigned delayTime; // Display time, in milliseconds, for this image in a multi-image GIF.
115
116     unsigned short* prefix; // LZW decoding tables.
117     unsigned char* suffix; // LZW decoding tables.
118     unsigned char* stack; // Base of LZW decoder stack.
119
120     GIFFrameContext()
121         : stackp(0)
122         , datasize(0)
123         , codesize(0)
124         , codemask(0)
125         , clearCode(0)
126         , avail(0)
127         , oldcode(0)
128         , firstchar(0)
129         , bits(0)
130         , datum(0)
131         , ipass(0)
132         , rowsRemaining(0)
133         , irow(0)
134         , rowbuf(0)
135         , rowend(0)
136         , rowp(0)
137         , xOffset(0)
138         , yOffset(0)
139         , width(0)
140         , height(0)
141         , tpixel(0)
142         , disposalMethod(WebCore::ImageFrame::DisposeNotSpecified)
143         , localColormap(0)
144         , localColormapSize(0)
145         , isLocalColormapDefined(false)
146         , progressiveDisplay(false)
147         , interlaced(false)
148         , isTransparent(false)
149         , delayTime(0)
150         , prefix(0)
151         , suffix(0)
152         , stack(0)
153     {
154     }
155     
156     ~GIFFrameContext()
157     {
158         delete [] rowbuf;
159         delete [] localColormap;
160         delete [] prefix;
161         delete [] suffix;
162         delete [] stack;
163     }
164 };
165
166 class GIFImageReader {
167     WTF_MAKE_FAST_ALLOCATED;
168 public:
169     GIFImageReader(WebCore::GIFImageDecoder* client = 0)
170         : m_client(client)
171         , m_state(GIFType)
172         , m_bytesToConsume(6)
173         , m_bytesInHold(0)
174         , m_globalColormap(0)
175         , m_screenBgcolor(0)
176         , m_version(0)
177         , m_screenWidth(0)
178         , m_screenHeight(0)
179         , m_globalColormapSize(0)
180         , m_imagesDecoded(0)
181         , m_imagesCount(0)
182         , m_loopCount(cLoopCountNotSeen)
183         , m_count(0)
184         , m_frameContext(0)
185     {
186     }
187
188     ~GIFImageReader()
189     {
190         delete [] m_globalColormap;
191         m_globalColormap = 0;
192
193         delete m_frameContext;
194         m_frameContext = 0;
195     }
196
197     bool read(const unsigned char* buf, unsigned numbytes, WebCore::GIFImageDecoder::GIFQuery = WebCore::GIFImageDecoder::GIFFullQuery, unsigned haltAtFrame = -1);
198
199     int imagesCount() const { return m_imagesCount; }
200     int loopCount() const { return m_loopCount; }
201     unsigned char* globalColormap() const { return m_globalColormap; }
202     int globalColormapSize() const { return m_globalColormapSize; }
203     const GIFFrameContext* frameContext() const { return m_frameContext; }
204
205 private:
206     bool outputRow();
207     bool doLZW(const unsigned char *q);
208
209     WebCore::GIFImageDecoder* m_client;
210
211     // Parsing state machine.
212     GIFState m_state; // Current decoder master state.
213     unsigned m_bytesToConsume; // Number of bytes to accumulate.
214     unsigned m_bytesInHold; // bytes accumulated so far.
215     unsigned char m_hold[MAX_HOLD_SIZE]; // Accumulation buffer.
216     unsigned char* m_globalColormap; // (3* MAX_COLORS in size) Default colormap if local not supplied, 3 bytes for each color.
217     
218     // Global (multi-image) state.
219     int m_screenBgcolor; // Logical screen background color.
220     int m_version; // Either 89 for GIF89 or 87 for GIF87.
221     unsigned m_screenWidth; // Logical screen width & height.
222     unsigned m_screenHeight;
223     int m_globalColormapSize; // Size of global colormap array.
224     unsigned m_imagesDecoded; // Counts completed frames for animated GIFs.
225     int m_imagesCount; // Counted all frames seen so far (including incomplete frames).
226     int m_loopCount; // Netscape specific extension block to control the number of animation loops a GIF renders.
227     
228     // Not really global, but convenient to locate here.
229     int m_count; // Remaining # bytes in sub-block.
230     
231     GIFFrameContext* m_frameContext;
232 };
233
234 #endif