Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |