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

Side by Side Diff: src/codec/SkCodec_libgif.cpp

Issue 1315583003: Interlaced gifs without the iterator (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 5 years, 4 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
« no previous file with comments | « gyp/codec.gyp ('k') | src/codec/SkGifInterlaceIter.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2015 Google Inc. 2 * Copyright 2015 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "SkCodec_libgif.h" 8 #include "SkCodec_libgif.h"
9 #include "SkCodecPriv.h" 9 #include "SkCodecPriv.h"
10 #include "SkColorPriv.h" 10 #include "SkColorPriv.h"
11 #include "SkColorTable.h" 11 #include "SkColorTable.h"
12 #include "SkGifInterlaceIter.h"
13 #include "SkStream.h" 12 #include "SkStream.h"
14 #include "SkSwizzler.h" 13 #include "SkSwizzler.h"
15 #include "SkUtils.h" 14 #include "SkUtils.h"
16 15
17 /* 16 /*
18 * Checks the start of the stream to see if the image is a gif 17 * Checks the start of the stream to see if the image is a gif
19 */ 18 */
20 bool SkGifCodec::IsGif(SkStream* stream) { 19 bool SkGifCodec::IsGif(SkStream* stream) {
21 char buf[GIF_STAMP_LEN]; 20 char buf[GIF_STAMP_LEN];
22 if (stream->read(buf, GIF_STAMP_LEN) == GIF_STAMP_LEN) { 21 if (stream->read(buf, GIF_STAMP_LEN) == GIF_STAMP_LEN) {
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
115 // There should only be one graphics control extension for the image frame 114 // There should only be one graphics control extension for the image frame
116 break; 115 break;
117 } 116 }
118 } 117 }
119 118
120 // Use maximum unsigned int (surely an invalid index) to indicate that a val id 119 // Use maximum unsigned int (surely an invalid index) to indicate that a val id
121 // index was not found. 120 // index was not found.
122 return SK_MaxU32; 121 return SK_MaxU32;
123 } 122 }
124 123
124 static inline uint32_t ceil_div(uint32_t a, uint32_t b) {
125 return (a + b - 1) / b;
126 }
127
128 /*
129 * Gets the output row corresponding to the encoded row for interlaced gifs
130 */
131 static uint32_t get_output_row_interlaced(uint32_t encodedRow, uint32_t height) {
132 SkASSERT(encodedRow < height);
133 // First pass
134 if (encodedRow * 8 < height) {
135 return encodedRow * 8;
136 // Second pass
137 } else if (encodedRow * 4 < height) {
scroggo 2015/08/28 13:42:32 nit: These do not need to be else statements, sinc
msarett 2015/08/28 14:30:36 Fixing.
138 return 4 + 8 * (encodedRow - ceil_div(height, 8));
139 // Third pass
140 } else if (encodedRow * 2 < height) {
141 return 2 + 4 * (encodedRow - ceil_div(height, 4));
142 // Fourth pass
143 } else {
144 return 1 + 2 * (encodedRow - ceil_div(height, 2));
145 }
146 }
147
125 /* 148 /*
126 * Read enough of the stream to initialize the SkGifCodec. 149 * Read enough of the stream to initialize the SkGifCodec.
127 * Returns a bool representing success or failure. 150 * Returns a bool representing success or failure.
128 * 151 *
129 * @param codecOut 152 * @param codecOut
130 * If it returned true, and codecOut was not NULL, 153 * If it returned true, and codecOut was not NULL,
131 * codecOut will be set to a new SkGifCodec. 154 * codecOut will be set to a new SkGifCodec.
132 * 155 *
133 * @param gifOut 156 * @param gifOut
134 * If it returned true, and codecOut was NULL, 157 * If it returned true, and codecOut was NULL,
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after
417 SkSwizzler::kIndex, colorTable, dstInfo, 440 SkSwizzler::kIndex, colorTable, dstInfo,
418 zeroInit, this->getInfo())); 441 zeroInit, this->getInfo()));
419 } 442 }
420 443
421 // Stores output from dgiflib and input to the swizzler 444 // Stores output from dgiflib and input to the swizzler
422 SkAutoTDeleteArray<uint8_t> 445 SkAutoTDeleteArray<uint8_t>
423 buffer(SkNEW_ARRAY(uint8_t, innerWidth)); 446 buffer(SkNEW_ARRAY(uint8_t, innerWidth));
424 447
425 // Check the interlace flag and iterate over rows of the input 448 // Check the interlace flag and iterate over rows of the input
426 if (fGif->Image.Interlace) { 449 if (fGif->Image.Interlace) {
427 // In interlace mode, the rows of input are rearranged in
428 // the output image. We use an iterator to take care of
429 // the rearranging.
430 SkGifInterlaceIter iter(innerHeight);
431 for (int32_t y = 0; y < innerHeight; y++) { 450 for (int32_t y = 0; y < innerHeight; y++) {
432 if (GIF_ERROR == DGifGetLine(fGif, buffer.get(), 451 if (GIF_ERROR == DGifGetLine(fGif, buffer.get(),
433 innerWidth)) { 452 innerWidth)) {
434 // Recover from error by filling remainder of image 453 // Recover from error by filling remainder of image
435 if (!skipBackground) { 454 if (!skipBackground) {
436 memset(buffer.get(), fillIndex, innerWidth); 455 memset(buffer.get(), fillIndex, innerWidth);
437 for (; y < innerHeight; y++) { 456 for (; y < innerHeight; y++) {
438 void* dstRow = SkTAddOffset<void>(dst, 457 void* dstRow = SkTAddOffset<void>(dst,
439 dstRowBytes * iter.nextY()); 458 dstRowBytes *
459 get_output_row_interlaced(y, innerHe ight));
440 swizzler->swizzle(dstRow, buffer.get()); 460 swizzler->swizzle(dstRow, buffer.get());
441 } 461 }
442 } 462 }
443 return gif_error(SkStringPrintf( 463 return gif_error(SkStringPrintf(
444 "Could not decode line %d of %d.\n", 464 "Could not decode line %d of %d.\n",
445 y, height - 1).c_str(), kIncompleteInput); 465 y, height - 1).c_str(), kIncompleteInput);
446 } 466 }
447 void* dstRow = SkTAddOffset<void>( 467 void* dstRow = SkTAddOffset<void>(
448 dst, dstRowBytes * iter.nextY()); 468 dst, dstRowBytes *
469 get_output_row_interlaced(y, innerHeight));
449 swizzler->swizzle(dstRow, buffer.get()); 470 swizzler->swizzle(dstRow, buffer.get());
450 } 471 }
451 } else { 472 } else {
452 // Standard mode 473 // Standard mode
453 void* dstRow = dst; 474 void* dstRow = dst;
454 for (int32_t y = 0; y < innerHeight; y++) { 475 for (int32_t y = 0; y < innerHeight; y++) {
455 if (GIF_ERROR == DGifGetLine(fGif, buffer.get(), 476 if (GIF_ERROR == DGifGetLine(fGif, buffer.get(),
456 innerWidth)) { 477 innerWidth)) {
457 if (!skipBackground) { 478 if (!skipBackground) {
458 SkSwizzler::Fill(dstRow, dstInfo, dstRowBytes, 479 SkSwizzler::Fill(dstRow, dstInfo, dstRowBytes,
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
527 // giflib returns an error code if the record type is not known. 548 // giflib returns an error code if the record type is not known.
528 // We should catch this error immediately. 549 // We should catch this error immediately.
529 SkASSERT(false); 550 SkASSERT(false);
530 break; 551 break;
531 } 552 }
532 } while (TERMINATE_RECORD_TYPE != recordType); 553 } while (TERMINATE_RECORD_TYPE != recordType);
533 554
534 return gif_error("Could not find any images to decode in gif file.\n", 555 return gif_error("Could not find any images to decode in gif file.\n",
535 kInvalidInput); 556 kInvalidInput);
536 } 557 }
OLDNEW
« no previous file with comments | « gyp/codec.gyp ('k') | src/codec/SkGifInterlaceIter.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698