| 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 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 77 GIFConsumeNetscapeExtension, | 77 GIFConsumeNetscapeExtension, |
| 78 GIFConsumeComment | 78 GIFConsumeComment |
| 79 }; | 79 }; |
| 80 | 80 |
| 81 struct GIFFrameContext; | 81 struct GIFFrameContext; |
| 82 | 82 |
| 83 // LZW decoder state machine. | 83 // LZW decoder state machine. |
| 84 class GIFLZWContext { | 84 class GIFLZWContext { |
| 85 WTF_MAKE_FAST_ALLOCATED; | 85 WTF_MAKE_FAST_ALLOCATED; |
| 86 public: | 86 public: |
| 87 GIFLZWContext(WebCore::GIFImageDecoder* client, const GIFFrameContext* frame
Context) | 87 GIFLZWContext(blink::GIFImageDecoder* client, const GIFFrameContext* frameCo
ntext) |
| 88 : codesize(0) | 88 : codesize(0) |
| 89 , codemask(0) | 89 , codemask(0) |
| 90 , clearCode(0) | 90 , clearCode(0) |
| 91 , avail(0) | 91 , avail(0) |
| 92 , oldcode(0) | 92 , oldcode(0) |
| 93 , firstchar(0) | 93 , firstchar(0) |
| 94 , bits(0) | 94 , bits(0) |
| 95 , datum(0) | 95 , datum(0) |
| 96 , ipass(0) | 96 , ipass(0) |
| 97 , irow(0) | 97 , irow(0) |
| (...skipping 22 matching lines...) Expand all Loading... |
| 120 size_t irow; // Current output row, starting at zero. | 120 size_t irow; // Current output row, starting at zero. |
| 121 size_t rowsRemaining; // Rows remaining to be output. | 121 size_t rowsRemaining; // Rows remaining to be output. |
| 122 | 122 |
| 123 unsigned short prefix[MAX_DICTIONARY_ENTRIES]; | 123 unsigned short prefix[MAX_DICTIONARY_ENTRIES]; |
| 124 unsigned char suffix[MAX_DICTIONARY_ENTRIES]; | 124 unsigned char suffix[MAX_DICTIONARY_ENTRIES]; |
| 125 unsigned short suffixLength[MAX_DICTIONARY_ENTRIES]; | 125 unsigned short suffixLength[MAX_DICTIONARY_ENTRIES]; |
| 126 GIFRow rowBuffer; // Single scanline temporary buffer. | 126 GIFRow rowBuffer; // Single scanline temporary buffer. |
| 127 GIFRow::iterator rowIter; | 127 GIFRow::iterator rowIter; |
| 128 | 128 |
| 129 // Initialized during construction and read-only. | 129 // Initialized during construction and read-only. |
| 130 WebCore::GIFImageDecoder* m_client; | 130 blink::GIFImageDecoder* m_client; |
| 131 const GIFFrameContext* m_frameContext; | 131 const GIFFrameContext* m_frameContext; |
| 132 }; | 132 }; |
| 133 | 133 |
| 134 // Data structure for one LZW block. | 134 // Data structure for one LZW block. |
| 135 struct GIFLZWBlock { | 135 struct GIFLZWBlock { |
| 136 WTF_MAKE_FAST_ALLOCATED; | 136 WTF_MAKE_FAST_ALLOCATED; |
| 137 public: | 137 public: |
| 138 GIFLZWBlock(size_t position, size_t size) | 138 GIFLZWBlock(size_t position, size_t size) |
| 139 : blockPosition(position) | 139 : blockPosition(position) |
| 140 , blockSize(size) | 140 , blockSize(size) |
| 141 { | 141 { |
| 142 } | 142 } |
| 143 | 143 |
| 144 size_t blockPosition; | 144 size_t blockPosition; |
| 145 size_t blockSize; | 145 size_t blockSize; |
| 146 }; | 146 }; |
| 147 | 147 |
| 148 class GIFColorMap { | 148 class GIFColorMap { |
| 149 WTF_MAKE_FAST_ALLOCATED; | 149 WTF_MAKE_FAST_ALLOCATED; |
| 150 public: | 150 public: |
| 151 typedef Vector<WebCore::ImageFrame::PixelData> Table; | 151 typedef Vector<blink::ImageFrame::PixelData> Table; |
| 152 | 152 |
| 153 GIFColorMap() | 153 GIFColorMap() |
| 154 : m_isDefined(false) | 154 : m_isDefined(false) |
| 155 , m_position(0) | 155 , m_position(0) |
| 156 , m_colors(0) | 156 , m_colors(0) |
| 157 { | 157 { |
| 158 } | 158 } |
| 159 | 159 |
| 160 // Set position and number of colors for the RGB table in the data stream. | 160 // Set position and number of colors for the RGB table in the data stream. |
| 161 void setTablePositionAndSize(size_t position, size_t colors) | 161 void setTablePositionAndSize(size_t position, size_t colors) |
| (...skipping 19 matching lines...) Expand all Loading... |
| 181 struct GIFFrameContext { | 181 struct GIFFrameContext { |
| 182 WTF_MAKE_FAST_ALLOCATED; WTF_MAKE_NONCOPYABLE(GIFFrameContext); | 182 WTF_MAKE_FAST_ALLOCATED; WTF_MAKE_NONCOPYABLE(GIFFrameContext); |
| 183 public: | 183 public: |
| 184 GIFFrameContext(int id) | 184 GIFFrameContext(int id) |
| 185 : m_frameId(id) | 185 : m_frameId(id) |
| 186 , m_xOffset(0) | 186 , m_xOffset(0) |
| 187 , m_yOffset(0) | 187 , m_yOffset(0) |
| 188 , m_width(0) | 188 , m_width(0) |
| 189 , m_height(0) | 189 , m_height(0) |
| 190 , m_transparentPixel(kNotFound) | 190 , m_transparentPixel(kNotFound) |
| 191 , m_disposalMethod(WebCore::ImageFrame::DisposeNotSpecified) | 191 , m_disposalMethod(blink::ImageFrame::DisposeNotSpecified) |
| 192 , m_dataSize(0) | 192 , m_dataSize(0) |
| 193 , m_progressiveDisplay(false) | 193 , m_progressiveDisplay(false) |
| 194 , m_interlaced(false) | 194 , m_interlaced(false) |
| 195 , m_delayTime(0) | 195 , m_delayTime(0) |
| 196 , m_currentLzwBlock(0) | 196 , m_currentLzwBlock(0) |
| 197 , m_isComplete(false) | 197 , m_isComplete(false) |
| 198 , m_isHeaderDefined(false) | 198 , m_isHeaderDefined(false) |
| 199 , m_isDataSizeDefined(false) | 199 , m_isDataSizeDefined(false) |
| 200 { | 200 { |
| 201 } | 201 } |
| 202 | 202 |
| 203 ~GIFFrameContext() | 203 ~GIFFrameContext() |
| 204 { | 204 { |
| 205 } | 205 } |
| 206 | 206 |
| 207 void addLzwBlock(size_t position, size_t size) | 207 void addLzwBlock(size_t position, size_t size) |
| 208 { | 208 { |
| 209 m_lzwBlocks.append(GIFLZWBlock(position, size)); | 209 m_lzwBlocks.append(GIFLZWBlock(position, size)); |
| 210 } | 210 } |
| 211 | 211 |
| 212 bool decode(const unsigned char* data, size_t length, WebCore::GIFImageDecod
er* client, bool* frameDecoded); | 212 bool decode(const unsigned char* data, size_t length, blink::GIFImageDecoder
* client, bool* frameDecoded); |
| 213 | 213 |
| 214 int frameId() const { return m_frameId; } | 214 int frameId() const { return m_frameId; } |
| 215 void setRect(unsigned x, unsigned y, unsigned width, unsigned height) | 215 void setRect(unsigned x, unsigned y, unsigned width, unsigned height) |
| 216 { | 216 { |
| 217 m_xOffset = x; | 217 m_xOffset = x; |
| 218 m_yOffset = y; | 218 m_yOffset = y; |
| 219 m_width = width; | 219 m_width = width; |
| 220 m_height = height; | 220 m_height = height; |
| 221 } | 221 } |
| 222 WebCore::IntRect frameRect() const { return WebCore::IntRect(m_xOffset, m_yO
ffset, m_width, m_height); } | 222 blink::IntRect frameRect() const { return blink::IntRect(m_xOffset, m_yOffse
t, m_width, m_height); } |
| 223 unsigned xOffset() const { return m_xOffset; } | 223 unsigned xOffset() const { return m_xOffset; } |
| 224 unsigned yOffset() const { return m_yOffset; } | 224 unsigned yOffset() const { return m_yOffset; } |
| 225 unsigned width() const { return m_width; } | 225 unsigned width() const { return m_width; } |
| 226 unsigned height() const { return m_height; } | 226 unsigned height() const { return m_height; } |
| 227 size_t transparentPixel() const { return m_transparentPixel; } | 227 size_t transparentPixel() const { return m_transparentPixel; } |
| 228 void setTransparentPixel(size_t pixel) { m_transparentPixel = pixel; } | 228 void setTransparentPixel(size_t pixel) { m_transparentPixel = pixel; } |
| 229 WebCore::ImageFrame::DisposalMethod disposalMethod() const { return m_dispos
alMethod; } | 229 blink::ImageFrame::DisposalMethod disposalMethod() const { return m_disposal
Method; } |
| 230 void setDisposalMethod(WebCore::ImageFrame::DisposalMethod disposalMethod) {
m_disposalMethod = disposalMethod; } | 230 void setDisposalMethod(blink::ImageFrame::DisposalMethod disposalMethod) { m
_disposalMethod = disposalMethod; } |
| 231 unsigned delayTime() const { return m_delayTime; } | 231 unsigned delayTime() const { return m_delayTime; } |
| 232 void setDelayTime(unsigned delay) { m_delayTime = delay; } | 232 void setDelayTime(unsigned delay) { m_delayTime = delay; } |
| 233 bool isComplete() const { return m_isComplete; } | 233 bool isComplete() const { return m_isComplete; } |
| 234 void setComplete() { m_isComplete = true; } | 234 void setComplete() { m_isComplete = true; } |
| 235 bool isHeaderDefined() const { return m_isHeaderDefined; } | 235 bool isHeaderDefined() const { return m_isHeaderDefined; } |
| 236 void setHeaderDefined() { m_isHeaderDefined = true; } | 236 void setHeaderDefined() { m_isHeaderDefined = true; } |
| 237 bool isDataSizeDefined() const { return m_isDataSizeDefined; } | 237 bool isDataSizeDefined() const { return m_isDataSizeDefined; } |
| 238 int dataSize() const { return m_dataSize; } | 238 int dataSize() const { return m_dataSize; } |
| 239 void setDataSize(int size) | 239 void setDataSize(int size) |
| 240 { | 240 { |
| 241 m_dataSize = size; | 241 m_dataSize = size; |
| 242 m_isDataSizeDefined = true; | 242 m_isDataSizeDefined = true; |
| 243 } | 243 } |
| 244 bool progressiveDisplay() const { return m_progressiveDisplay; } | 244 bool progressiveDisplay() const { return m_progressiveDisplay; } |
| 245 void setProgressiveDisplay(bool progressiveDisplay) { m_progressiveDisplay =
progressiveDisplay; } | 245 void setProgressiveDisplay(bool progressiveDisplay) { m_progressiveDisplay =
progressiveDisplay; } |
| 246 bool interlaced() const { return m_interlaced; } | 246 bool interlaced() const { return m_interlaced; } |
| 247 void setInterlaced(bool interlaced) { m_interlaced = interlaced; } | 247 void setInterlaced(bool interlaced) { m_interlaced = interlaced; } |
| 248 | 248 |
| 249 void clearDecodeState() { m_lzwContext.clear(); } | 249 void clearDecodeState() { m_lzwContext.clear(); } |
| 250 const GIFColorMap& localColorMap() const { return m_localColorMap; } | 250 const GIFColorMap& localColorMap() const { return m_localColorMap; } |
| 251 GIFColorMap& localColorMap() { return m_localColorMap; } | 251 GIFColorMap& localColorMap() { return m_localColorMap; } |
| 252 | 252 |
| 253 private: | 253 private: |
| 254 int m_frameId; | 254 int m_frameId; |
| 255 unsigned m_xOffset; | 255 unsigned m_xOffset; |
| 256 unsigned m_yOffset; // With respect to "screen" origin. | 256 unsigned m_yOffset; // With respect to "screen" origin. |
| 257 unsigned m_width; | 257 unsigned m_width; |
| 258 unsigned m_height; | 258 unsigned m_height; |
| 259 size_t m_transparentPixel; // Index of transparent pixel. Value is kNotFound
if there is no transparent pixel. | 259 size_t m_transparentPixel; // Index of transparent pixel. Value is kNotFound
if there is no transparent pixel. |
| 260 WebCore::ImageFrame::DisposalMethod m_disposalMethod; // Restore to backgrou
nd, leave in place, etc. | 260 blink::ImageFrame::DisposalMethod m_disposalMethod; // Restore to background
, leave in place, etc. |
| 261 int m_dataSize; | 261 int m_dataSize; |
| 262 | 262 |
| 263 bool m_progressiveDisplay; // If true, do Haeberli interlace hack. | 263 bool m_progressiveDisplay; // If true, do Haeberli interlace hack. |
| 264 bool m_interlaced; // True, if scanlines arrive interlaced order. | 264 bool m_interlaced; // True, if scanlines arrive interlaced order. |
| 265 | 265 |
| 266 unsigned m_delayTime; // Display time, in milliseconds, for this image in a
multi-image GIF. | 266 unsigned m_delayTime; // Display time, in milliseconds, for this image in a
multi-image GIF. |
| 267 | 267 |
| 268 OwnPtr<GIFLZWContext> m_lzwContext; | 268 OwnPtr<GIFLZWContext> m_lzwContext; |
| 269 Vector<GIFLZWBlock> m_lzwBlocks; // LZW blocks for this frame. | 269 Vector<GIFLZWBlock> m_lzwBlocks; // LZW blocks for this frame. |
| 270 GIFColorMap m_localColorMap; | 270 GIFColorMap m_localColorMap; |
| 271 | 271 |
| 272 size_t m_currentLzwBlock; | 272 size_t m_currentLzwBlock; |
| 273 bool m_isComplete; | 273 bool m_isComplete; |
| 274 bool m_isHeaderDefined; | 274 bool m_isHeaderDefined; |
| 275 bool m_isDataSizeDefined; | 275 bool m_isDataSizeDefined; |
| 276 }; | 276 }; |
| 277 | 277 |
| 278 class PLATFORM_EXPORT GIFImageReader { | 278 class PLATFORM_EXPORT GIFImageReader { |
| 279 WTF_MAKE_FAST_ALLOCATED; WTF_MAKE_NONCOPYABLE(GIFImageReader); | 279 WTF_MAKE_FAST_ALLOCATED; WTF_MAKE_NONCOPYABLE(GIFImageReader); |
| 280 public: | 280 public: |
| 281 GIFImageReader(WebCore::GIFImageDecoder* client = 0) | 281 GIFImageReader(blink::GIFImageDecoder* client = 0) |
| 282 : m_client(client) | 282 : m_client(client) |
| 283 , m_state(GIFType) | 283 , m_state(GIFType) |
| 284 , m_bytesToConsume(6) // Number of bytes for GIF type, either "GIF87a" o
r "GIF89a". | 284 , m_bytesToConsume(6) // Number of bytes for GIF type, either "GIF87a" o
r "GIF89a". |
| 285 , m_bytesRead(0) | 285 , m_bytesRead(0) |
| 286 , m_version(0) | 286 , m_version(0) |
| 287 , m_screenWidth(0) | 287 , m_screenWidth(0) |
| 288 , m_screenHeight(0) | 288 , m_screenHeight(0) |
| 289 , m_loopCount(cLoopCountNotSeen) | 289 , m_loopCount(cLoopCountNotSeen) |
| 290 , m_parseCompleted(false) | 290 , m_parseCompleted(false) |
| 291 { | 291 { |
| 292 } | 292 } |
| 293 | 293 |
| 294 ~GIFImageReader() | 294 ~GIFImageReader() |
| 295 { | 295 { |
| 296 } | 296 } |
| 297 | 297 |
| 298 void setData(PassRefPtr<WebCore::SharedBuffer> data) { m_data = data; } | 298 void setData(PassRefPtr<blink::SharedBuffer> data) { m_data = data; } |
| 299 bool parse(WebCore::GIFImageDecoder::GIFParseQuery); | 299 bool parse(blink::GIFImageDecoder::GIFParseQuery); |
| 300 bool decode(size_t frameIndex); | 300 bool decode(size_t frameIndex); |
| 301 | 301 |
| 302 size_t imagesCount() const | 302 size_t imagesCount() const |
| 303 { | 303 { |
| 304 if (m_frames.isEmpty()) | 304 if (m_frames.isEmpty()) |
| 305 return 0; | 305 return 0; |
| 306 | 306 |
| 307 // This avoids counting an empty frame when the file is truncated right
after | 307 // This avoids counting an empty frame when the file is truncated right
after |
| 308 // GIFControlExtension but before GIFImageHeader. | 308 // GIFControlExtension but before GIFImageHeader. |
| 309 // FIXME: This extra complexity is not necessary and we should just repo
rt m_frames.size(). | 309 // FIXME: This extra complexity is not necessary and we should just repo
rt m_frames.size(). |
| 310 return m_frames.last()->isHeaderDefined() ? m_frames.size() : m_frames.s
ize() - 1; | 310 return m_frames.last()->isHeaderDefined() ? m_frames.size() : m_frames.s
ize() - 1; |
| 311 } | 311 } |
| 312 int loopCount() const { return m_loopCount; } | 312 int loopCount() const { return m_loopCount; } |
| 313 | 313 |
| 314 const GIFColorMap& globalColorMap() const | 314 const GIFColorMap& globalColorMap() const |
| 315 { | 315 { |
| 316 return m_globalColorMap; | 316 return m_globalColorMap; |
| 317 } | 317 } |
| 318 | 318 |
| 319 const GIFFrameContext* frameContext(size_t index) const | 319 const GIFFrameContext* frameContext(size_t index) const |
| 320 { | 320 { |
| 321 return index < m_frames.size() ? m_frames[index].get() : 0; | 321 return index < m_frames.size() ? m_frames[index].get() : 0; |
| 322 } | 322 } |
| 323 | 323 |
| 324 bool parseCompleted() const { return m_parseCompleted; } | 324 bool parseCompleted() const { return m_parseCompleted; } |
| 325 | 325 |
| 326 void clearDecodeState(size_t index) { m_frames[index]->clearDecodeState(); } | 326 void clearDecodeState(size_t index) { m_frames[index]->clearDecodeState(); } |
| 327 | 327 |
| 328 private: | 328 private: |
| 329 bool parseData(size_t dataPosition, size_t len, WebCore::GIFImageDecoder::GI
FParseQuery); | 329 bool parseData(size_t dataPosition, size_t len, blink::GIFImageDecoder::GIFP
arseQuery); |
| 330 void setRemainingBytes(size_t); | 330 void setRemainingBytes(size_t); |
| 331 | 331 |
| 332 const unsigned char* data(size_t dataPosition) const | 332 const unsigned char* data(size_t dataPosition) const |
| 333 { | 333 { |
| 334 return reinterpret_cast<const unsigned char*>(m_data->data()) + dataPosi
tion; | 334 return reinterpret_cast<const unsigned char*>(m_data->data()) + dataPosi
tion; |
| 335 } | 335 } |
| 336 | 336 |
| 337 void addFrameIfNecessary(); | 337 void addFrameIfNecessary(); |
| 338 bool currentFrameIsFirstFrame() const | 338 bool currentFrameIsFirstFrame() const |
| 339 { | 339 { |
| 340 return m_frames.isEmpty() || (m_frames.size() == 1u && !m_frames[0]->isC
omplete()); | 340 return m_frames.isEmpty() || (m_frames.size() == 1u && !m_frames[0]->isC
omplete()); |
| 341 } | 341 } |
| 342 | 342 |
| 343 WebCore::GIFImageDecoder* m_client; | 343 blink::GIFImageDecoder* m_client; |
| 344 | 344 |
| 345 // Parsing state machine. | 345 // Parsing state machine. |
| 346 GIFState m_state; // Current decoder master state. | 346 GIFState m_state; // Current decoder master state. |
| 347 size_t m_bytesToConsume; // Number of bytes to consume for next stage of par
sing. | 347 size_t m_bytesToConsume; // Number of bytes to consume for next stage of par
sing. |
| 348 size_t m_bytesRead; // Number of bytes processed. | 348 size_t m_bytesRead; // Number of bytes processed. |
| 349 | 349 |
| 350 // Global (multi-image) state. | 350 // Global (multi-image) state. |
| 351 int m_version; // Either 89 for GIF89 or 87 for GIF87. | 351 int m_version; // Either 89 for GIF89 or 87 for GIF87. |
| 352 unsigned m_screenWidth; // Logical screen width & height. | 352 unsigned m_screenWidth; // Logical screen width & height. |
| 353 unsigned m_screenHeight; | 353 unsigned m_screenHeight; |
| 354 GIFColorMap m_globalColorMap; | 354 GIFColorMap m_globalColorMap; |
| 355 int m_loopCount; // Netscape specific extension block to control the number
of animation loops a GIF renders. | 355 int m_loopCount; // Netscape specific extension block to control the number
of animation loops a GIF renders. |
| 356 | 356 |
| 357 Vector<OwnPtr<GIFFrameContext> > m_frames; | 357 Vector<OwnPtr<GIFFrameContext> > m_frames; |
| 358 | 358 |
| 359 RefPtr<WebCore::SharedBuffer> m_data; | 359 RefPtr<blink::SharedBuffer> m_data; |
| 360 bool m_parseCompleted; | 360 bool m_parseCompleted; |
| 361 }; | 361 }; |
| 362 | 362 |
| 363 #endif | 363 #endif |
| OLD | NEW |