Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(817)

Side by Side Diff: Source/core/platform/image-decoders/gif/GIFImageReader.h

Issue 15350006: Decode GIF image frames on demand. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* ***** BEGIN LICENSE BLOCK ***** 2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1 3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 * 4 *
5 * The contents of this file are subject to the Mozilla Public License Version 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 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 7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/ 8 * http://www.mozilla.org/MPL/
9 * 9 *
10 * Software distributed under the License is distributed on an "AS IS" basis, 10 * Software distributed under the License is distributed on an "AS IS" basis,
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after
206 bool isComplete() const { return m_isComplete; } 206 bool isComplete() const { return m_isComplete; }
207 void setComplete() { m_isComplete = true; } 207 void setComplete() { m_isComplete = true; }
208 bool isHeaderDefined() const { return m_isHeaderDefined; } 208 bool isHeaderDefined() const { return m_isHeaderDefined; }
209 void setHeaderDefined() { m_isHeaderDefined = true; } 209 void setHeaderDefined() { m_isHeaderDefined = true; }
210 bool isDataSizeDefined() const { return m_isDataSizeDefined; } 210 bool isDataSizeDefined() const { return m_isDataSizeDefined; }
211 void setDataSize(int size) 211 void setDataSize(int size)
212 { 212 {
213 datasize = size; 213 datasize = size;
214 m_isDataSizeDefined = true; 214 m_isDataSizeDefined = true;
215 } 215 }
216 216 void clearDecodeState() { m_lzwContext.clear(); }
217 private: 217 private:
218 OwnPtr<GIFLZWContext> m_lzwContext; 218 OwnPtr<GIFLZWContext> m_lzwContext;
219 Vector<GIFLZWBlock> m_lzwBlocks; // LZW blocks for this frame. 219 Vector<GIFLZWBlock> m_lzwBlocks; // LZW blocks for this frame.
220 size_t m_currentLzwBlock; 220 size_t m_currentLzwBlock;
221 bool m_isComplete; 221 bool m_isComplete;
222 bool m_isHeaderDefined; 222 bool m_isHeaderDefined;
223 bool m_isDataSizeDefined; 223 bool m_isDataSizeDefined;
224 }; 224 };
225 225
226 class GIFImageReader { 226 class GIFImageReader {
227 WTF_MAKE_FAST_ALLOCATED; 227 WTF_MAKE_FAST_ALLOCATED;
228 public: 228 public:
229 GIFImageReader(WebCore::GIFImageDecoder* client = 0) 229 GIFImageReader(WebCore::GIFImageDecoder* client = 0)
230 : m_client(client) 230 : m_client(client)
231 , m_state(GIFType) 231 , m_state(GIFType)
232 , m_bytesToConsume(6) // Number of bytes for GIF type, either "GIF87a" o r "GIF89a". 232 , m_bytesToConsume(6) // Number of bytes for GIF type, either "GIF87a" o r "GIF89a".
233 , m_bytesRead(0) 233 , m_bytesRead(0)
234 , m_screenBgcolor(0) 234 , m_screenBgcolor(0)
235 , m_version(0) 235 , m_version(0)
236 , m_screenWidth(0) 236 , m_screenWidth(0)
237 , m_screenHeight(0) 237 , m_screenHeight(0)
238 , m_isGlobalColormapDefined(false) 238 , m_isGlobalColormapDefined(false)
239 , m_globalColormapPosition(0) 239 , m_globalColormapPosition(0)
240 , m_globalColormapSize(0) 240 , m_globalColormapSize(0)
241 , m_loopCount(cLoopCountNotSeen) 241 , m_loopCount(cLoopCountNotSeen)
242 , m_currentDecodingFrame(0)
243 , m_parseCompleted(false) 242 , m_parseCompleted(false)
244 { 243 {
245 } 244 }
246 245
247 ~GIFImageReader() 246 ~GIFImageReader()
248 { 247 {
249 } 248 }
250 249
251 void setData(PassRefPtr<WebCore::SharedBuffer> data) { m_data = data; } 250 void setData(PassRefPtr<WebCore::SharedBuffer> data) { m_data = data; }
252 // FIXME: haltAtFrame should be size_t. 251 bool parse(WebCore::GIFImageDecoder::GIFParseQuery);
253 bool decode(WebCore::GIFImageDecoder::GIFQuery, unsigned haltAtFrame); 252 bool decode(size_t frameIndex);
Peter Kasting 2013/05/24 03:15:22 Thumbs up on improving the API here to be noticeab
254 253
255 size_t imagesCount() const 254 size_t imagesCount() const
256 { 255 {
257 if (m_frames.isEmpty()) 256 if (m_frames.isEmpty())
258 return 0; 257 return 0;
259 258
260 // This avoids counting an empty frame when the file is truncated right after 259 // This avoids counting an empty frame when the file is truncated right after
261 // GIFControlExtension but before GIFImageHeader. 260 // GIFControlExtension but before GIFImageHeader.
262 // FIXME: This extra complexity is not necessary and we should just repo rt m_frames.size(). 261 // FIXME: This extra complexity is not necessary and we should just repo rt m_frames.size().
263 return m_frames.last()->isHeaderDefined() ? m_frames.size() : m_frames.s ize() - 1; 262 return m_frames.last()->isHeaderDefined() ? m_frames.size() : m_frames.s ize() - 1;
(...skipping 18 matching lines...) Expand all
282 return frame->isLocalColormapDefined ? frame->localColormapSize : 0; 281 return frame->isLocalColormapDefined ? frame->localColormapSize : 0;
283 } 282 }
284 283
285 const GIFFrameContext* frameContext(size_t index) const 284 const GIFFrameContext* frameContext(size_t index) const
286 { 285 {
287 return index < m_frames.size() ? m_frames[index].get() : 0; 286 return index < m_frames.size() ? m_frames[index].get() : 0;
288 } 287 }
289 288
290 bool parseCompleted() const { return m_parseCompleted; } 289 bool parseCompleted() const { return m_parseCompleted; }
291 290
291 void clearDecodeState(size_t index) { m_frames[index]->clearDecodeState(); }
292
292 private: 293 private:
293 bool parse(size_t dataPosition, size_t len, bool parseSizeOnly); 294 bool parseData(size_t dataPosition, size_t len, WebCore::GIFImageDecoder::GI FParseQuery);
294 void setRemainingBytes(size_t); 295 void setRemainingBytes(size_t);
295 296
296 const unsigned char* data(size_t dataPosition) const 297 const unsigned char* data(size_t dataPosition) const
297 { 298 {
298 return reinterpret_cast<const unsigned char*>(m_data->data()) + dataPosi tion; 299 return reinterpret_cast<const unsigned char*>(m_data->data()) + dataPosi tion;
299 } 300 }
300 301
301 void addFrameIfNecessary(); 302 void addFrameIfNecessary();
302 bool currentFrameIsFirstFrame() const 303 bool currentFrameIsFirstFrame() const
303 { 304 {
304 return m_frames.isEmpty() || (m_frames.size() == 1u && !m_frames[0]->isC omplete()); 305 return m_frames.isEmpty() || (m_frames.size() == 1u && !m_frames[0]->isC omplete());
305 } 306 }
306 307
307 WebCore::GIFImageDecoder* m_client; 308 WebCore::GIFImageDecoder* m_client;
308 309
309 // Parsing state machine. 310 // Parsing state machine.
310 GIFState m_state; // Current decoder master state. 311 GIFState m_state; // Current decoder master state.
311 size_t m_bytesToConsume; // Number of bytes to consume for next stage of par sing. 312 size_t m_bytesToConsume; // Number of bytes to consume for next stage of par sing.
312 size_t m_bytesRead; // Number of bytes processed. 313 size_t m_bytesRead; // Number of bytes processed.
313 314
314 // Global (multi-image) state. 315 // Global (multi-image) state.
315 int m_screenBgcolor; // Logical screen background color. 316 int m_screenBgcolor; // Logical screen background color.
Peter Kasting 2013/05/24 03:15:22 Tangential to your change, but I noticed while loo
Xianzhu 2013/05/28 22:54:21 Done.
316 int m_version; // Either 89 for GIF89 or 87 for GIF87. 317 int m_version; // Either 89 for GIF89 or 87 for GIF87.
317 unsigned m_screenWidth; // Logical screen width & height. 318 unsigned m_screenWidth; // Logical screen width & height.
318 unsigned m_screenHeight; 319 unsigned m_screenHeight;
319 bool m_isGlobalColormapDefined; 320 bool m_isGlobalColormapDefined;
320 size_t m_globalColormapPosition; // (3* MAX_COLORS in size) Default colormap if local not supplied, 3 bytes for each color. 321 size_t m_globalColormapPosition; // (3* MAX_COLORS in size) Default colormap if local not supplied, 3 bytes for each color.
321 int m_globalColormapSize; // Size of global colormap array. 322 int m_globalColormapSize; // Size of global colormap array.
322 int m_loopCount; // Netscape specific extension block to control the number of animation loops a GIF renders. 323 int m_loopCount; // Netscape specific extension block to control the number of animation loops a GIF renders.
323 324
324 Vector<OwnPtr<GIFFrameContext> > m_frames; 325 Vector<OwnPtr<GIFFrameContext> > m_frames;
325 size_t m_currentDecodingFrame;
326 326
327 RefPtr<WebCore::SharedBuffer> m_data; 327 RefPtr<WebCore::SharedBuffer> m_data;
328 bool m_parseCompleted; 328 bool m_parseCompleted;
329 }; 329 };
330 330
331 #endif 331 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698