OLD | NEW |
1 /* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ | 1 /* -*- Mode: C; tab-width: 2; 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 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
91 #define GETN(n, s) \ | 91 #define GETN(n, s) \ |
92 do { \ | 92 do { \ |
93 m_bytesToConsume = (n); \ | 93 m_bytesToConsume = (n); \ |
94 m_state = (s); \ | 94 m_state = (s); \ |
95 } while (0) | 95 } while (0) |
96 | 96 |
97 // Get a 16-bit value stored in little-endian format. | 97 // Get a 16-bit value stored in little-endian format. |
98 #define GETINT16(p) ((p)[1]<<8|(p)[0]) | 98 #define GETINT16(p) ((p)[1]<<8|(p)[0]) |
99 | 99 |
100 // Send the data to the display front-end. | 100 // Send the data to the display front-end. |
101 bool GIFLZWContext::outputRow() | 101 bool GIFLZWContext::outputRow(GIFRow::const_iterator rowBegin) |
102 { | 102 { |
103 int drowStart = irow; | 103 int drowStart = irow; |
104 int drowEnd = irow; | 104 int drowEnd = irow; |
105 | 105 |
106 // Haeberli-inspired hack for interlaced GIFs: Replicate lines while | 106 // Haeberli-inspired hack for interlaced GIFs: Replicate lines while |
107 // displaying to diminish the "venetian-blind" effect as the image is | 107 // displaying to diminish the "venetian-blind" effect as the image is |
108 // loaded. Adjust pixel vertical positions to avoid the appearance of the | 108 // loaded. Adjust pixel vertical positions to avoid the appearance of the |
109 // image crawling up the screen as successive passes are drawn. | 109 // image crawling up the screen as successive passes are drawn. |
110 if (m_frameContext->progressiveDisplay() && m_frameContext->interlaced() &&
ipass < 4) { | 110 if (m_frameContext->progressiveDisplay() && m_frameContext->interlaced() &&
ipass < 4) { |
111 unsigned rowDup = 0; | 111 unsigned rowDup = 0; |
(...skipping 29 matching lines...) Expand all Loading... |
141 | 141 |
142 if ((unsigned)drowEnd >= m_frameContext->height()) | 142 if ((unsigned)drowEnd >= m_frameContext->height()) |
143 drowEnd = m_frameContext->height() - 1; | 143 drowEnd = m_frameContext->height() - 1; |
144 } | 144 } |
145 | 145 |
146 // Protect against too much image data. | 146 // Protect against too much image data. |
147 if ((unsigned)drowStart >= m_frameContext->height()) | 147 if ((unsigned)drowStart >= m_frameContext->height()) |
148 return true; | 148 return true; |
149 | 149 |
150 // CALLBACK: Let the client know we have decoded a row. | 150 // CALLBACK: Let the client know we have decoded a row. |
151 if (!m_client->haveDecodedRow(m_frameContext->frameId(), rowBuffer, m_frameC
ontext->width(), | 151 if (!m_client->haveDecodedRow(m_frameContext->frameId(), rowBegin, m_frameCo
ntext->width(), |
152 drowStart, drowEnd - drowStart + 1, m_frameContext->progressiveDisplay()
&& m_frameContext->interlaced() && ipass > 1)) | 152 drowStart, drowEnd - drowStart + 1, m_frameContext->progressiveDisplay()
&& m_frameContext->interlaced() && ipass > 1)) |
153 return false; | 153 return false; |
154 | 154 |
155 if (!m_frameContext->interlaced()) | 155 if (!m_frameContext->interlaced()) |
156 irow++; | 156 irow++; |
157 else { | 157 else { |
158 do { | 158 do { |
159 switch (ipass) { | 159 switch (ipass) { |
160 case 1: | 160 case 1: |
161 irow += 8; | 161 irow += 8; |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
195 } while (irow > (m_frameContext->height() - 1)); | 195 } while (irow > (m_frameContext->height() - 1)); |
196 } | 196 } |
197 return true; | 197 return true; |
198 } | 198 } |
199 | 199 |
200 // Perform Lempel-Ziv-Welch decoding. | 200 // Perform Lempel-Ziv-Welch decoding. |
201 // Returns true if decoding was successful. In this case the block will have bee
n completely consumed and/or rowsRemaining will be 0. | 201 // Returns true if decoding was successful. In this case the block will have bee
n completely consumed and/or rowsRemaining will be 0. |
202 // Otherwise, decoding failed; returns false in this case, which will always cau
se the GIFImageReader to set the "decode failed" flag. | 202 // Otherwise, decoding failed; returns false in this case, which will always cau
se the GIFImageReader to set the "decode failed" flag. |
203 bool GIFLZWContext::doLZW(const unsigned char* block, size_t bytesInBlock) | 203 bool GIFLZWContext::doLZW(const unsigned char* block, size_t bytesInBlock) |
204 { | 204 { |
205 int code; | 205 const size_t width = m_frameContext->width(); |
206 int incode; | |
207 const unsigned char *ch; | |
208 | 206 |
209 if (rowIter == rowBuffer.end()) | 207 if (rowIter == rowBuffer.end()) |
210 return true; | 208 return true; |
211 | 209 |
212 #define OUTPUT_ROW \ | 210 for (const unsigned char* ch = block; bytesInBlock-- > 0; ch++) { |
213 do { \ | |
214 if (!outputRow()) \ | |
215 return false; \ | |
216 rowsRemaining--; \ | |
217 rowIter = rowBuffer.begin(); \ | |
218 if (!rowsRemaining) \ | |
219 return true; \ | |
220 } while (0) | |
221 | |
222 for (ch = block; bytesInBlock-- > 0; ch++) { | |
223 // Feed the next byte into the decoder's 32-bit input buffer. | 211 // Feed the next byte into the decoder's 32-bit input buffer. |
224 datum += ((int) *ch) << bits; | 212 datum += ((int) *ch) << bits; |
225 bits += 8; | 213 bits += 8; |
226 | 214 |
227 // Check for underflow of decoder's 32-bit input buffer. | 215 // Check for underflow of decoder's 32-bit input buffer. |
228 while (bits >= codesize) { | 216 while (bits >= codesize) { |
229 // Get the leading variable-length symbol from the data stream. | 217 // Get the leading variable-length symbol from the data stream. |
230 code = datum & codemask; | 218 int code = datum & codemask; |
231 datum >>= codesize; | 219 datum >>= codesize; |
232 bits -= codesize; | 220 bits -= codesize; |
233 | 221 |
234 // Reset the dictionary to its original state, if requested. | 222 // Reset the dictionary to its original state, if requested. |
235 if (code == clearCode) { | 223 if (code == clearCode) { |
236 codesize = m_frameContext->dataSize() + 1; | 224 codesize = m_frameContext->dataSize() + 1; |
237 codemask = (1 << codesize) - 1; | 225 codemask = (1 << codesize) - 1; |
238 avail = clearCode + 2; | 226 avail = clearCode + 2; |
239 oldcode = -1; | 227 oldcode = -1; |
240 continue; | 228 continue; |
241 } | 229 } |
242 | 230 |
243 // Check for explicit end-of-stream code. | 231 // Check for explicit end-of-stream code. |
244 if (code == (clearCode + 1)) { | 232 if (code == (clearCode + 1)) { |
245 // end-of-stream should only appear after all image data. | 233 // end-of-stream should only appear after all image data. |
246 if (!rowsRemaining) | 234 if (!rowsRemaining) |
247 return true; | 235 return true; |
248 return false; | 236 return false; |
249 } | 237 } |
250 | 238 |
251 if (oldcode == -1) { | 239 const int tempCode = code; |
252 *rowIter++ = suffix[code]; | 240 unsigned short codeLength = 0; |
253 if (rowIter == rowBuffer.end()) | 241 if (code < avail) { |
254 OUTPUT_ROW; | 242 // This is a pre-existing code, so we already know what it |
255 | 243 // encodes. |
256 firstchar = oldcode = code; | 244 codeLength = suffixLength[code]; |
257 continue; | 245 rowIter += codeLength; |
258 } | 246 } else if (code == avail && oldcode != -1) { |
259 | 247 // This is a new code just being added to the dictionary. |
260 incode = code; | 248 // It must encode the contents of the previous code, plus |
261 if (code >= avail) { | 249 // the first character of the previous code again. |
262 stack[stackp++] = firstchar; | 250 codeLength = suffixLength[oldcode] + 1; |
| 251 rowIter += codeLength; |
| 252 *--rowIter = firstchar; |
263 code = oldcode; | 253 code = oldcode; |
264 | 254 } else { |
265 if (stackp == MAX_BYTES) | 255 // This is an invalid code. The dictionary is just initialized |
266 return false; | 256 // and the code is incomplete. We don't know how to handle |
| 257 // this case. |
| 258 return false; |
267 } | 259 } |
268 | 260 |
269 while (code >= clearCode) { | 261 while (code >= clearCode) { |
270 if (code >= MAX_BYTES || code == prefix[code]) | 262 *--rowIter = suffix[code]; |
271 return false; | |
272 | |
273 // Even though suffix[] only holds characters through suffix[ava
il - 1], | |
274 // allowing code >= avail here lets us be more tolerant of malfo
rmed | |
275 // data. As long as code < MAX_BYTES, the only risk is a garbled
image, | |
276 // which is no worse than refusing to display it. | |
277 stack[stackp++] = suffix[code]; | |
278 code = prefix[code]; | 263 code = prefix[code]; |
279 | |
280 if (stackp == MAX_BYTES) | |
281 return false; | |
282 } | 264 } |
283 | 265 |
284 stack[stackp++] = firstchar = suffix[code]; | 266 *--rowIter = firstchar = suffix[code]; |
285 | 267 |
286 // Define a new codeword in the dictionary. | 268 // Define a new codeword in the dictionary as long as we've read |
287 if (avail < 4096) { | 269 // more than one value from the stream. |
| 270 if (avail < MAX_DICTIONARY_ENTRIES && oldcode != -1) { |
288 prefix[avail] = oldcode; | 271 prefix[avail] = oldcode; |
289 suffix[avail] = firstchar; | 272 suffix[avail] = firstchar; |
290 avail++; | 273 suffixLength[avail] = suffixLength[oldcode] + 1; |
| 274 ++avail; |
291 | 275 |
292 // If we've used up all the codewords of a given length | 276 // If we've used up all the codewords of a given length |
293 // increase the length of codewords by one bit, but don't | 277 // increase the length of codewords by one bit, but don't |
294 // exceed the specified maximum codeword size of 12 bits. | 278 // exceed the specified maximum codeword size. |
295 if ((!(avail & codemask)) && (avail < 4096)) { | 279 if (!(avail & codemask) && avail < MAX_DICTIONARY_ENTRIES) { |
296 codesize++; | 280 ++codesize; |
297 codemask += avail; | 281 codemask += avail; |
298 } | 282 } |
299 } | 283 } |
300 oldcode = incode; | 284 oldcode = tempCode; |
| 285 rowIter += codeLength; |
301 | 286 |
302 // Copy the decoded data out to the scanline buffer. | 287 // Output as many rows as possible. |
303 do { | 288 GIFRow::iterator rowBegin = rowBuffer.begin(); |
304 *rowIter++ = stack[--stackp]; | 289 for (; rowBegin + width <= rowIter; rowBegin += width) { |
305 if (rowIter == rowBuffer.end()) | 290 if (!outputRow(rowBegin)) |
306 OUTPUT_ROW; | 291 return false; |
307 } while (stackp > 0); | 292 rowsRemaining--; |
| 293 if (!rowsRemaining) |
| 294 return true; |
| 295 } |
| 296 |
| 297 if (rowBegin != rowBuffer.begin()) { |
| 298 // Move the remaining bytes to the beginning of the buffer. |
| 299 const size_t bytesToCopy = rowIter - rowBegin; |
| 300 memcpy(rowBuffer.begin(), rowBegin, bytesToCopy); |
| 301 rowIter = rowBuffer.begin() + bytesToCopy; |
| 302 } |
308 } | 303 } |
309 } | 304 } |
310 | |
311 return true; | 305 return true; |
312 } | 306 } |
313 | 307 |
314 void GIFColorMap::buildTable(const unsigned char* data, size_t length) | 308 void GIFColorMap::buildTable(const unsigned char* data, size_t length) |
315 { | 309 { |
316 if (!m_isDefined || !m_table.isEmpty()) | 310 if (!m_isDefined || !m_table.isEmpty()) |
317 return; | 311 return; |
318 | 312 |
319 RELEASE_ASSERT(m_position + m_colors * GIF_COLORS <= length); | 313 RELEASE_ASSERT(m_position + m_colors * BYTES_PER_COLORMAP_ENTRY <= length); |
320 const unsigned char* srcColormap = data + m_position; | 314 const unsigned char* srcColormap = data + m_position; |
321 m_table.resize(m_colors); | 315 m_table.resize(m_colors); |
322 for (Table::iterator iter = m_table.begin(); iter != m_table.end(); ++iter)
{ | 316 for (Table::iterator iter = m_table.begin(); iter != m_table.end(); ++iter)
{ |
323 *iter = SkPackARGB32NoCheck(255, srcColormap[0], srcColormap[1], srcColo
rmap[2]); | 317 *iter = SkPackARGB32NoCheck(255, srcColormap[0], srcColormap[1], srcColo
rmap[2]); |
324 srcColormap += GIF_COLORS; | 318 srcColormap += BYTES_PER_COLORMAP_ENTRY; |
325 } | 319 } |
326 } | 320 } |
327 | 321 |
328 // Perform decoding for this frame. frameDecoded will be true if the entire fram
e is decoded. | 322 // Perform decoding for this frame. frameDecoded will be true if the entire fram
e is decoded. |
329 // Returns false if a decoding error occurred. This is a fatal error and causes
the GIFImageReader to set the "decode failed" flag. | 323 // Returns false if a decoding error occurred. This is a fatal error and causes
the GIFImageReader to set the "decode failed" flag. |
330 // Otherwise, either not enough data is available to decode further than before,
or the new data has been decoded successfully; returns true in this case. | 324 // Otherwise, either not enough data is available to decode further than before,
or the new data has been decoded successfully; returns true in this case. |
331 bool GIFFrameContext::decode(const unsigned char* data, size_t length, WebCore::
GIFImageDecoder* client, bool* frameDecoded) | 325 bool GIFFrameContext::decode(const unsigned char* data, size_t length, WebCore::
GIFImageDecoder* client, bool* frameDecoded) |
332 { | 326 { |
333 m_localColorMap.buildTable(data, length); | 327 m_localColorMap.buildTable(data, length); |
334 | 328 |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
449 | 443 |
450 // CALLBACK: Inform the decoderplugin of our size. | 444 // CALLBACK: Inform the decoderplugin of our size. |
451 // Note: A subsequent frame might have dimensions larger than the "s
creen" dimensions. | 445 // Note: A subsequent frame might have dimensions larger than the "s
creen" dimensions. |
452 if (m_client && !m_client->setSize(m_screenWidth, m_screenHeight)) | 446 if (m_client && !m_client->setSize(m_screenWidth, m_screenHeight)) |
453 return false; | 447 return false; |
454 | 448 |
455 const size_t globalColorMapColors = 2 << (currentComponent[4] & 0x07
); | 449 const size_t globalColorMapColors = 2 << (currentComponent[4] & 0x07
); |
456 | 450 |
457 if ((currentComponent[4] & 0x80) && globalColorMapColors > 0) { /* g
lobal map */ | 451 if ((currentComponent[4] & 0x80) && globalColorMapColors > 0) { /* g
lobal map */ |
458 m_globalColorMap.setTablePositionAndSize(dataPosition, globalCol
orMapColors); | 452 m_globalColorMap.setTablePositionAndSize(dataPosition, globalCol
orMapColors); |
459 GETN(GIF_COLORS * globalColorMapColors, GIFGlobalColormap); | 453 GETN(BYTES_PER_COLORMAP_ENTRY * globalColorMapColors, GIFGlobalC
olormap); |
460 break; | 454 break; |
461 } | 455 } |
462 | 456 |
463 GETN(1, GIFImageStart); | 457 GETN(1, GIFImageStart); |
464 break; | 458 break; |
465 } | 459 } |
466 | 460 |
467 case GIFGlobalColormap: { | 461 case GIFGlobalColormap: { |
468 m_globalColorMap.setDefined(); | 462 m_globalColorMap.setDefined(); |
469 GETN(1, GIFImageStart); | 463 GETN(1, GIFImageStart); |
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
689 // frame can be progressively displayed. | 683 // frame can be progressively displayed. |
690 // FIXME: It is possible that a non-transparent frame | 684 // FIXME: It is possible that a non-transparent frame |
691 // can be interlaced and progressively displayed. | 685 // can be interlaced and progressively displayed. |
692 currentFrame->setProgressiveDisplay(currentFrameIsFirstFrame()); | 686 currentFrame->setProgressiveDisplay(currentFrameIsFirstFrame()); |
693 | 687 |
694 const bool isLocalColormapDefined = currentComponent[8] & 0x80; | 688 const bool isLocalColormapDefined = currentComponent[8] & 0x80; |
695 if (isLocalColormapDefined) { | 689 if (isLocalColormapDefined) { |
696 // The three low-order bits of currentComponent[8] specify the b
its per pixel. | 690 // The three low-order bits of currentComponent[8] specify the b
its per pixel. |
697 const size_t numColors = 2 << (currentComponent[8] & 0x7); | 691 const size_t numColors = 2 << (currentComponent[8] & 0x7); |
698 currentFrame->localColorMap().setTablePositionAndSize(dataPositi
on, numColors); | 692 currentFrame->localColorMap().setTablePositionAndSize(dataPositi
on, numColors); |
699 GETN(GIF_COLORS * numColors, GIFImageColormap); | 693 GETN(BYTES_PER_COLORMAP_ENTRY * numColors, GIFImageColormap); |
700 break; | 694 break; |
701 } | 695 } |
702 | 696 |
703 GETN(1, GIFLZWStart); | 697 GETN(1, GIFLZWStart); |
704 break; | 698 break; |
705 } | 699 } |
706 | 700 |
707 case GIFImageColormap: { | 701 case GIFImageColormap: { |
708 ASSERT(!m_frames.isEmpty()); | 702 ASSERT(!m_frames.isEmpty()); |
709 m_frames.last()->localColorMap().setDefined(); | 703 m_frames.last()->localColorMap().setDefined(); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
753 if (m_frames.isEmpty() || m_frames.last()->isComplete()) | 747 if (m_frames.isEmpty() || m_frames.last()->isComplete()) |
754 m_frames.append(adoptPtr(new GIFFrameContext(m_frames.size()))); | 748 m_frames.append(adoptPtr(new GIFFrameContext(m_frames.size()))); |
755 } | 749 } |
756 | 750 |
757 // FIXME: Move this method to close to doLZW(). | 751 // FIXME: Move this method to close to doLZW(). |
758 bool GIFLZWContext::prepareToDecode() | 752 bool GIFLZWContext::prepareToDecode() |
759 { | 753 { |
760 ASSERT(m_frameContext->isDataSizeDefined() && m_frameContext->isHeaderDefine
d()); | 754 ASSERT(m_frameContext->isDataSizeDefined() && m_frameContext->isHeaderDefine
d()); |
761 | 755 |
762 // Since we use a codesize of 1 more than the datasize, we need to ensure | 756 // Since we use a codesize of 1 more than the datasize, we need to ensure |
763 // that our datasize is strictly less than the MAX_LZW_BITS value (12). | 757 // that our datasize is strictly less than the MAX_DICTIONARY_ENTRY_BITS. |
764 // This sets the largest possible codemask correctly at 4095. | 758 if (m_frameContext->dataSize() >= MAX_DICTIONARY_ENTRY_BITS) |
765 if (m_frameContext->dataSize() >= MAX_LZW_BITS) | |
766 return false; | 759 return false; |
767 clearCode = 1 << m_frameContext->dataSize(); | 760 clearCode = 1 << m_frameContext->dataSize(); |
768 if (clearCode >= MAX_BYTES) | |
769 return false; | |
770 | |
771 avail = clearCode + 2; | 761 avail = clearCode + 2; |
772 oldcode = -1; | 762 oldcode = -1; |
773 codesize = m_frameContext->dataSize() + 1; | 763 codesize = m_frameContext->dataSize() + 1; |
774 codemask = (1 << codesize) - 1; | 764 codemask = (1 << codesize) - 1; |
775 datum = bits = 0; | 765 datum = bits = 0; |
776 ipass = m_frameContext->interlaced() ? 1 : 0; | 766 ipass = m_frameContext->interlaced() ? 1 : 0; |
777 irow = 0; | 767 irow = 0; |
778 | 768 |
779 // Initialize output row buffer. | 769 // We want to know the longest sequence encodable by a dictionary with |
780 rowBuffer.resize(m_frameContext->width()); | 770 // MAX_DICTIONARY_ENTRIES entries. If we ignore the need to encode the base |
| 771 // values themselves at the beginning of the dictionary, as well as the need |
| 772 // for a clear code or a termination code, we could use every entry to |
| 773 // encode a series of multiple values. If the input value stream looked |
| 774 // like "AAAAA..." (a long string of just one value), the first dictionary |
| 775 // entry would encode AA, the next AAA, the next AAAA, and so forth. Thus |
| 776 // the longest sequence would be MAX_DICTIONARY_ENTRIES + 1 values. |
| 777 // |
| 778 // However, we have to account for reserved entries. The first |datasize| |
| 779 // bits are reserved for the base values, and the next two entries are |
| 780 // reserved for the clear code and termination code. In theory a GIF can |
| 781 // set the datasize to 0, meaning we have just two reserved entries, making |
| 782 // the longest sequence (MAX_DICTIONARY_ENTIRES + 1) - 2 values long. Since |
| 783 // each value is a byte, this is also the number of bytes in the longest |
| 784 // encodable sequence. |
| 785 const size_t maxBytes = MAX_DICTIONARY_ENTRIES - 1; |
| 786 |
| 787 // Now allocate the output buffer. We decode directly into this buffer |
| 788 // until we have at least one row worth of data, then call outputRow(). |
| 789 // This means worst case we may have (row width - 1) bytes in the buffer |
| 790 // and then decode a sequence |maxBytes| long to append. |
| 791 rowBuffer.resize(m_frameContext->width() - 1 + maxBytes); |
781 rowIter = rowBuffer.begin(); | 792 rowIter = rowBuffer.begin(); |
782 rowsRemaining = m_frameContext->height(); | 793 rowsRemaining = m_frameContext->height(); |
783 | 794 |
784 // Clearing the whole suffix table lets us be more tolerant of bad data. | 795 // Clearing the whole suffix table lets us be more tolerant of bad data. |
785 memset(suffix, 0, sizeof(suffix)); | 796 for (int i = 0; i < clearCode; ++i) { |
786 | |
787 // Clearing the whole prefix table to prevent uninitialized access. | |
788 memset(prefix, 0, sizeof(prefix)); | |
789 for (int i = 0; i < clearCode; i++) | |
790 suffix[i] = i; | 797 suffix[i] = i; |
791 stackp = 0; | 798 suffixLength[i] = 1; |
| 799 } |
792 return true; | 800 return true; |
793 } | 801 } |
OLD | NEW |