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

Side by Side Diff: third_party/WebKit/Source/platform/image-decoders/gif/GIFImageReader.cpp

Issue 1460523002: GIF decoding to Index8, unit tests and misusing unit test as benchmark (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years 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: 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 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
139 139
140 if ((unsigned)drowEnd >= m_frameContext->height()) 140 if ((unsigned)drowEnd >= m_frameContext->height())
141 drowEnd = m_frameContext->height() - 1; 141 drowEnd = m_frameContext->height() - 1;
142 } 142 }
143 143
144 // Protect against too much image data. 144 // Protect against too much image data.
145 if ((unsigned)drowStart >= m_frameContext->height()) 145 if ((unsigned)drowStart >= m_frameContext->height())
146 return true; 146 return true;
147 147
148 // CALLBACK: Let the client know we have decoded a row. 148 // CALLBACK: Let the client know we have decoded a row.
149 if (!m_client->haveDecodedRow(m_frameContext->frameId(), rowBegin, m_frameCo ntext->width(), 149 if (!m_client->haveDecodedRow(*m_frameContext, rowBegin,
150 drowStart, drowEnd - drowStart + 1, m_frameContext->progressiveDisplay() && m_frameContext->interlaced() && ipass > 1)) 150 drowStart, drowEnd - drowStart + 1, m_frameContext->progressiveDisplay() && m_frameContext->interlaced() && ipass > 1))
151 return false; 151 return false;
152 152
153 if (!m_frameContext->interlaced()) 153 if (!m_frameContext->interlaced())
154 irow++; 154 irow++;
155 else { 155 else {
156 do { 156 do {
157 switch (ipass) { 157 switch (ipass) {
158 case 1: 158 case 1:
159 irow += 8; 159 irow += 8;
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
198 // Perform Lempel-Ziv-Welch decoding. 198 // Perform Lempel-Ziv-Welch decoding.
199 // Returns true if decoding was successful. In this case the block will have bee n completely consumed and/or rowsRemaining will be 0. 199 // Returns true if decoding was successful. In this case the block will have bee n completely consumed and/or rowsRemaining will be 0.
200 // Otherwise, decoding failed; returns false in this case, which will always cau se the GIFImageReader to set the "decode failed" flag. 200 // Otherwise, decoding failed; returns false in this case, which will always cau se the GIFImageReader to set the "decode failed" flag.
201 bool GIFLZWContext::doLZW(const unsigned char* block, size_t bytesInBlock) 201 bool GIFLZWContext::doLZW(const unsigned char* block, size_t bytesInBlock)
202 { 202 {
203 const size_t width = m_frameContext->width(); 203 const size_t width = m_frameContext->width();
204 204
205 if (rowIter == rowBuffer.end()) 205 if (rowIter == rowBuffer.end())
206 return true; 206 return true;
207 207
208 for (const unsigned char* ch = block; bytesInBlock-- > 0; ch++) { 208 for (const unsigned char* ch = block; bytesInBlock-- > 0; ++ch) {
scroggo_chromium 2016/01/06 21:50:41 This seems like an unnecessary change, and at leas
aleksandar.stojiljkovic 2016/01/18 13:58:50 Done.
209 // Feed the next byte into the decoder's 32-bit input buffer. 209 // Feed the next byte into the decoder's 32-bit input buffer.
210 datum += ((int) *ch) << bits; 210 datum += ((int) *ch) << bits;
211 bits += 8; 211 bits += 8;
212 212
213 // Check for underflow of decoder's 32-bit input buffer. 213 // Check for underflow of decoder's 32-bit input buffer.
214 while (bits >= codesize) { 214 while (bits >= codesize) {
215 // Get the leading variable-length symbol from the data stream. 215 // Get the leading variable-length symbol from the data stream.
216 int code = datum & codemask; 216 int code = datum & codemask;
217 datum >>= codesize; 217 datum >>= codesize;
218 bits -= codesize; 218 bits -= codesize;
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
277 if (!(avail & codemask) && avail < MAX_DICTIONARY_ENTRIES) { 277 if (!(avail & codemask) && avail < MAX_DICTIONARY_ENTRIES) {
278 ++codesize; 278 ++codesize;
279 codemask += avail; 279 codemask += avail;
280 } 280 }
281 } 281 }
282 oldcode = tempCode; 282 oldcode = tempCode;
283 rowIter += codeLength; 283 rowIter += codeLength;
284 284
285 // Output as many rows as possible. 285 // Output as many rows as possible.
286 GIFRow::iterator rowBegin = rowBuffer.begin(); 286 GIFRow::iterator rowBegin = rowBuffer.begin();
287 for (; rowBegin + width <= rowIter; rowBegin += width) { 287 if (rowBegin + width <= rowIter) {
288 if (!outputRow(rowBegin)) 288 for (; rowBegin + width <= rowIter; rowBegin += width) {
289 return false; 289 if (!outputRow(rowBegin))
290 rowsRemaining--; 290 return false;
291 if (!rowsRemaining) 291 rowsRemaining--;
292 return true; 292 if (!rowsRemaining)
293 } 293 return true;
294 }
294 295
295 if (rowBegin != rowBuffer.begin()) {
296 // Move the remaining bytes to the beginning of the buffer. 296 // Move the remaining bytes to the beginning of the buffer.
297 const size_t bytesToCopy = rowIter - rowBegin; 297 const size_t bytesToCopy = rowIter - rowBegin;
298 memcpy(rowBuffer.begin(), rowBegin, bytesToCopy); 298 if (bytesToCopy)
299 memcpy(rowBuffer.begin(), rowBegin, bytesToCopy);
299 rowIter = rowBuffer.begin() + bytesToCopy; 300 rowIter = rowBuffer.begin() + bytesToCopy;
300 } 301 }
301 } 302 }
302 } 303 }
303 return true; 304 return true;
304 } 305 }
305 306
306 void GIFColorMap::buildTable(blink::FastSharedBufferReader* reader) 307 void GIFColorMap::buildTable(blink::FastSharedBufferReader* reader)
307 { 308 {
308 if (!m_isDefined || !m_table.isEmpty()) 309 if (!m_isDefined || !m_table.isEmpty())
(...skipping 27 matching lines...) Expand all
336 337
337 m_lzwContext = adoptPtr(new GIFLZWContext(client, this)); 338 m_lzwContext = adoptPtr(new GIFLZWContext(client, this));
338 if (!m_lzwContext->prepareToDecode()) { 339 if (!m_lzwContext->prepareToDecode()) {
339 m_lzwContext.clear(); 340 m_lzwContext.clear();
340 return false; 341 return false;
341 } 342 }
342 343
343 m_currentLzwBlock = 0; 344 m_currentLzwBlock = 0;
344 } 345 }
345 346
347 if (m_lzwContext->hasRemainingRows()) {
348 if (!client->initFrameBuffer(m_frameId))
scroggo_chromium 2016/01/06 21:50:41 This function (GIFFrameContext::decode) may be cal
aleksandar.stojiljkovic 2016/01/18 13:58:50 Acknowledged. It is intentional. initFrameBuffer d
349 return false;
350 }
351
346 // Some bad GIFs have extra blocks beyond the last row, which we don't want to decode. 352 // Some bad GIFs have extra blocks beyond the last row, which we don't want to decode.
347 while (m_currentLzwBlock < m_lzwBlocks.size() && m_lzwContext->hasRemainingR ows()) { 353 while (m_currentLzwBlock < m_lzwBlocks.size() && m_lzwContext->hasRemainingR ows()) {
348 size_t blockPosition = m_lzwBlocks[m_currentLzwBlock].blockPosition; 354 size_t blockPosition = m_lzwBlocks[m_currentLzwBlock].blockPosition;
349 size_t blockSize = m_lzwBlocks[m_currentLzwBlock].blockSize; 355 size_t blockSize = m_lzwBlocks[m_currentLzwBlock].blockSize;
350 if (blockPosition + blockSize > reader->size()) 356 if (blockPosition + blockSize > reader->size())
351 return false; 357 return false;
352 358
353 while (blockSize) { 359 while (blockSize) {
354 const char* segment = 0; 360 const char* segment = 0;
355 size_t segmentLength = reader->getSomeData(segment, blockPosition); 361 size_t segmentLength = reader->getSomeData(segment, blockPosition);
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
447 m_version = 87; 453 m_version = 87;
448 else 454 else
449 return false; 455 return false;
450 GETN(7, GIFGlobalHeader); 456 GETN(7, GIFGlobalHeader);
451 break; 457 break;
452 } 458 }
453 459
454 case GIFGlobalHeader: { 460 case GIFGlobalHeader: {
455 const unsigned char* currentComponent = 461 const unsigned char* currentComponent =
456 reinterpret_cast<const unsigned char*>( 462 reinterpret_cast<const unsigned char*>(
457 reader.getConsecutiveData(currentComponentPosition, 5, readB uffer)); 463 reader.getConsecutiveData(currentComponentPosition, 6, readB uffer));
458 464
459 // This is the height and width of the "screen" or frame into which 465 // This is the height and width of the "screen" or frame into which
460 // images are rendered. The individual images can be smaller than 466 // images are rendered. The individual images can be smaller than
461 // the screen size and located with an origin anywhere within the 467 // the screen size and located with an origin anywhere within the
462 // screen. 468 // screen.
463 // Note that we don't inform the client of the size yet, as it might 469 // Note that we don't inform the client of the size yet, as it might
464 // change after we read the first frame's image header. 470 // change after we read the first frame's image header.
465 m_screenWidth = GETINT16(currentComponent); 471 m_screenWidth = GETINT16(currentComponent);
466 m_screenHeight = GETINT16(currentComponent + 2); 472 m_screenHeight = GETINT16(currentComponent + 2);
467 473
468 const size_t globalColorMapColors = 2 << (currentComponent[4] & 0x07 ); 474 const size_t globalColorMapColors = 2 << (currentComponent[4] & 0x07 );
475 m_backgroundIndex = currentComponent[5];
469 476
470 if ((currentComponent[4] & 0x80) && globalColorMapColors > 0) { /* g lobal map */ 477 if ((currentComponent[4] & 0x80) && globalColorMapColors > 0) { /* g lobal map */
471 m_globalColorMap.setTablePositionAndSize(dataPosition, globalCol orMapColors); 478 m_globalColorMap.setTablePositionAndSize(dataPosition, globalCol orMapColors);
472 GETN(BYTES_PER_COLORMAP_ENTRY * globalColorMapColors, GIFGlobalC olormap); 479 GETN(BYTES_PER_COLORMAP_ENTRY * globalColorMapColors, GIFGlobalC olormap);
473 break; 480 break;
474 } 481 }
475 482
476 GETN(1, GIFImageStart); 483 GETN(1, GIFImageStart);
477 break; 484 break;
478 } 485 }
(...skipping 362 matching lines...) Expand 10 before | Expand all | Expand 10 after
841 rowIter = rowBuffer.begin(); 848 rowIter = rowBuffer.begin();
842 rowsRemaining = m_frameContext->height(); 849 rowsRemaining = m_frameContext->height();
843 850
844 // Clearing the whole suffix table lets us be more tolerant of bad data. 851 // Clearing the whole suffix table lets us be more tolerant of bad data.
845 for (int i = 0; i < clearCode; ++i) { 852 for (int i = 0; i < clearCode; ++i) {
846 suffix[i] = i; 853 suffix[i] = i;
847 suffixLength[i] = 1; 854 suffixLength[i] = 1;
848 } 855 }
849 return true; 856 return true;
850 } 857 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698