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

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: Rebase Created 5 years, 3 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 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
109 // There should only be one graphics control extension for the image frame 108 // There should only be one graphics control extension for the image frame
110 break; 109 break;
111 } 110 }
112 } 111 }
113 112
114 // Use maximum unsigned int (surely an invalid index) to indicate that a val id 113 // Use maximum unsigned int (surely an invalid index) to indicate that a val id
115 // index was not found. 114 // index was not found.
116 return SK_MaxU32; 115 return SK_MaxU32;
117 } 116 }
118 117
118 static inline uint32_t ceil_div(uint32_t a, uint32_t b) {
119 return (a + b - 1) / b;
120 }
121
122 /*
123 * Gets the output row corresponding to the encoded row for interlaced gifs
124 */
125 static uint32_t get_output_row_interlaced(uint32_t encodedRow, uint32_t height) {
126 SkASSERT(encodedRow < height);
127 // First pass
128 if (encodedRow * 8 < height) {
129 return encodedRow * 8;
130 }
131 // Second pass
132 if (encodedRow * 4 < height) {
133 return 4 + 8 * (encodedRow - ceil_div(height, 8));
134 }
135 // Third pass
136 if (encodedRow * 2 < height) {
137 return 2 + 4 * (encodedRow - ceil_div(height, 4));
138 }
139 // Fourth pass
140 return 1 + 2 * (encodedRow - ceil_div(height, 2));
141 }
142
119 /* 143 /*
120 * Read enough of the stream to initialize the SkGifCodec. 144 * Read enough of the stream to initialize the SkGifCodec.
121 * Returns a bool representing success or failure. 145 * Returns a bool representing success or failure.
122 * 146 *
123 * @param codecOut 147 * @param codecOut
124 * If it returned true, and codecOut was not nullptr, 148 * If it returned true, and codecOut was not nullptr,
125 * codecOut will be set to a new SkGifCodec. 149 * codecOut will be set to a new SkGifCodec.
126 * 150 *
127 * @param gifOut 151 * @param gifOut
128 * If it returned true, and codecOut was nullptr, 152 * If it returned true, and codecOut was nullptr,
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after
402 swizzler.reset(SkSwizzler::CreateSwizzler( 426 swizzler.reset(SkSwizzler::CreateSwizzler(
403 SkSwizzler::kIndex, colorTable, dstInfo, 427 SkSwizzler::kIndex, colorTable, dstInfo,
404 zeroInit, this->getInfo())); 428 zeroInit, this->getInfo()));
405 } 429 }
406 430
407 // Stores output from dgiflib and input to the swizzler 431 // Stores output from dgiflib and input to the swizzler
408 SkAutoTDeleteArray<uint8_t> buffer(new uint8_t[innerWidth]); 432 SkAutoTDeleteArray<uint8_t> buffer(new uint8_t[innerWidth]);
409 433
410 // Check the interlace flag and iterate over rows of the input 434 // Check the interlace flag and iterate over rows of the input
411 if (fGif->Image.Interlace) { 435 if (fGif->Image.Interlace) {
412 // In interlace mode, the rows of input are rearranged in
413 // the output image. We use an iterator to take care of
414 // the rearranging.
415 SkGifInterlaceIter iter(innerHeight);
416 for (int32_t y = 0; y < innerHeight; y++) { 436 for (int32_t y = 0; y < innerHeight; y++) {
417 if (GIF_ERROR == DGifGetLine(fGif, buffer.get(), innerWi dth)) { 437 if (GIF_ERROR == DGifGetLine(fGif, buffer.get(), innerWi dth)) {
418 // Recover from error by filling remainder of image 438 // Recover from error by filling remainder of image
419 if (!skipBackground) { 439 if (!skipBackground) {
420 memset(buffer.get(), fillIndex, innerWidth); 440 memset(buffer.get(), fillIndex, innerWidth);
421 for (; y < innerHeight; y++) { 441 for (; y < innerHeight; y++) {
422 void* dstRow = SkTAddOffset<void>(dst, 442 void* dstRow = SkTAddOffset<void>(dst, dstRo wBytes *
423 dstRowByte s * iter.nextY()); 443 get_output_row_interlaced(y, innerHe ight));
424 swizzler->swizzle(dstRow, buffer.get()); 444 swizzler->swizzle(dstRow, buffer.get());
425 } 445 }
426 } 446 }
427 return gif_error(SkStringPrintf( 447 return gif_error(SkStringPrintf(
428 "Could not decode line %d of %d.\n", 448 "Could not decode line %d of %d.\n",
429 y, height - 1).c_str(), kIncompleteInput); 449 y, height - 1).c_str(), kIncompleteInput);
430 } 450 }
431 void* dstRow = SkTAddOffset<void>(dst, dstRowBytes * ite r.nextY()); 451 void* dstRow = SkTAddOffset<void>(dst,
452 dstRowBytes * get_output_row_interlaced(y, inner Height));
432 swizzler->swizzle(dstRow, buffer.get()); 453 swizzler->swizzle(dstRow, buffer.get());
433 } 454 }
434 } else { 455 } else {
435 // Standard mode 456 // Standard mode
436 void* dstRow = dst; 457 void* dstRow = dst;
437 for (int32_t y = 0; y < innerHeight; y++) { 458 for (int32_t y = 0; y < innerHeight; y++) {
438 if (GIF_ERROR == DGifGetLine(fGif, buffer.get(), innerWi dth)) { 459 if (GIF_ERROR == DGifGetLine(fGif, buffer.get(), innerWi dth)) {
439 if (!skipBackground) { 460 if (!skipBackground) {
440 SkSwizzler::Fill(dstRow, dstInfo, dstRowBytes, 461 SkSwizzler::Fill(dstRow, dstInfo, dstRowBytes,
441 innerHeight - y, fillIndex, col orTable); 462 innerHeight - y, fillIndex, col orTable);
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
504 default: 525 default:
505 // giflib returns an error code if the record type is not known. 526 // giflib returns an error code if the record type is not known.
506 // We should catch this error immediately. 527 // We should catch this error immediately.
507 SkASSERT(false); 528 SkASSERT(false);
508 break; 529 break;
509 } 530 }
510 } while (TERMINATE_RECORD_TYPE != recordType); 531 } while (TERMINATE_RECORD_TYPE != recordType);
511 532
512 return gif_error("Could not find any images to decode in gif file.\n", kInva lidInput); 533 return gif_error("Could not find any images to decode in gif file.\n", kInva lidInput);
513 } 534 }
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