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

Side by Side Diff: src/images/SkImageDecoder_libgif.cpp

Issue 647023006: Qualify the return value of SkImageDecoder::decode (Closed) Base URL: https://skia.googlesource.com/skia.git/+/master
Patch Set: fix a sample Created 6 years, 1 month 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 | « src/images/SkImageDecoder_libbmp.cpp ('k') | src/images/SkImageDecoder_libico.cpp » ('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 2006 The Android Open Source Project 2 * Copyright 2006 The Android Open Source Project
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 "SkColor.h" 8 #include "SkColor.h"
9 #include "SkColorPriv.h" 9 #include "SkColorPriv.h"
10 #include "SkColorTable.h" 10 #include "SkColorTable.h"
11 #include "SkImageDecoder.h" 11 #include "SkImageDecoder.h"
12 #include "SkRTConf.h" 12 #include "SkRTConf.h"
13 #include "SkScaledBitmapSampler.h" 13 #include "SkScaledBitmapSampler.h"
14 #include "SkStream.h" 14 #include "SkStream.h"
15 #include "SkTemplates.h" 15 #include "SkTemplates.h"
16 #include "SkUtils.h" 16 #include "SkUtils.h"
17 17
18 #include "gif_lib.h" 18 #include "gif_lib.h"
19 19
20 class SkGIFImageDecoder : public SkImageDecoder { 20 class SkGIFImageDecoder : public SkImageDecoder {
21 public: 21 public:
22 virtual Format getFormat() const SK_OVERRIDE { 22 virtual Format getFormat() const SK_OVERRIDE {
23 return kGIF_Format; 23 return kGIF_Format;
24 } 24 }
25 25
26 protected: 26 protected:
27 virtual bool onDecode(SkStream* stream, SkBitmap* bm, Mode mode) SK_OVERRIDE ; 27 virtual Result onDecode(SkStream* stream, SkBitmap* bm, Mode mode) SK_OVERRI DE;
28 28
29 private: 29 private:
30 typedef SkImageDecoder INHERITED; 30 typedef SkImageDecoder INHERITED;
31 }; 31 };
32 32
33 static const uint8_t gStartingIterlaceYValue[] = { 33 static const uint8_t gStartingIterlaceYValue[] = {
34 0, 4, 2, 1 34 0, 4, 2, 1
35 }; 35 };
36 static const uint8_t gDeltaIterlaceYValue[] = { 36 static const uint8_t gDeltaIterlaceYValue[] = {
37 8, 8, 4, 2 37 8, 8, 4, 2
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
145 if (transpIndex >= colorCount) { 145 if (transpIndex >= colorCount) {
146 transpIndex = -1; 146 transpIndex = -1;
147 } 147 }
148 break; 148 break;
149 } 149 }
150 } 150 }
151 } 151 }
152 return transpIndex; 152 return transpIndex;
153 } 153 }
154 154
155 static bool error_return(const SkBitmap& bm, const char msg[]) { 155 static SkImageDecoder::Result error_return(const SkBitmap& bm, const char msg[]) {
156 if (!c_suppressGIFImageDecoderWarnings) { 156 if (!c_suppressGIFImageDecoderWarnings) {
157 SkDebugf("libgif error [%s] bitmap [%d %d] pixels %p colortable %p\n", 157 SkDebugf("libgif error [%s] bitmap [%d %d] pixels %p colortable %p\n",
158 msg, bm.width(), bm.height(), bm.getPixels(), 158 msg, bm.width(), bm.height(), bm.getPixels(),
159 bm.getColorTable()); 159 bm.getColorTable());
160 } 160 }
161 return false; 161 return SkImageDecoder::kFailure;
162 } 162 }
163
163 static void gif_warning(const SkBitmap& bm, const char msg[]) { 164 static void gif_warning(const SkBitmap& bm, const char msg[]) {
164 if (!c_suppressGIFImageDecoderWarnings) { 165 if (!c_suppressGIFImageDecoderWarnings) {
165 SkDebugf("libgif warning [%s] bitmap [%d %d] pixels %p colortable %p\n", 166 SkDebugf("libgif warning [%s] bitmap [%d %d] pixels %p colortable %p\n",
166 msg, bm.width(), bm.height(), bm.getPixels(), 167 msg, bm.width(), bm.height(), bm.getPixels(),
167 bm.getColorTable()); 168 bm.getColorTable());
168 } 169 }
169 } 170 }
170 171
171 /** 172 /**
172 * Skip rows in the source gif image. 173 * Skip rows in the source gif image.
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
221 addr += rowBytes; 222 addr += rowBytes;
222 } 223 }
223 if (warning) { 224 if (warning) {
224 gif_warning(*bm, "Index out of bounds."); 225 gif_warning(*bm, "Index out of bounds.");
225 } 226 }
226 } 227 }
227 } 228 }
228 } 229 }
229 } 230 }
230 231
231 bool SkGIFImageDecoder::onDecode(SkStream* sk_stream, SkBitmap* bm, Mode mode) { 232 SkImageDecoder::Result SkGIFImageDecoder::onDecode(SkStream* sk_stream, SkBitmap * bm, Mode mode) {
232 #if GIFLIB_MAJOR < 5 233 #if GIFLIB_MAJOR < 5
233 GifFileType* gif = DGifOpen(sk_stream, DecodeCallBackProc); 234 GifFileType* gif = DGifOpen(sk_stream, DecodeCallBackProc);
234 #else 235 #else
235 GifFileType* gif = DGifOpen(sk_stream, DecodeCallBackProc, NULL); 236 GifFileType* gif = DGifOpen(sk_stream, DecodeCallBackProc, NULL);
236 #endif 237 #endif
237 if (NULL == gif) { 238 if (NULL == gif) {
238 return error_return(*bm, "DGifOpen"); 239 return error_return(*bm, "DGifOpen");
239 } 240 }
240 241
241 SkAutoTCallIProc<GifFileType, DGifCloseFile> acp(gif); 242 SkAutoTCallIProc<GifFileType, DGifCloseFile> acp(gif);
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
315 return error_return(*bm, "chooseFromOneChoice"); 316 return error_return(*bm, "chooseFromOneChoice");
316 } 317 }
317 #endif 318 #endif
318 319
319 SkScaledBitmapSampler sampler(width, height, this->getSampleSize()); 320 SkScaledBitmapSampler sampler(width, height, this->getSampleSize());
320 321
321 bm->setInfo(SkImageInfo::Make(sampler.scaledWidth(), sampler.scaledH eight(), 322 bm->setInfo(SkImageInfo::Make(sampler.scaledWidth(), sampler.scaledH eight(),
322 kIndex_8_SkColorType, kPremul_SkAlphaT ype)); 323 kIndex_8_SkColorType, kPremul_SkAlphaT ype));
323 324
324 if (SkImageDecoder::kDecodeBounds_Mode == mode) { 325 if (SkImageDecoder::kDecodeBounds_Mode == mode) {
325 return true; 326 return kSuccess;
326 } 327 }
327 328
328 329
329 // now we decode the colortable 330 // now we decode the colortable
330 int colorCount = 0; 331 int colorCount = 0;
331 { 332 {
332 // Declare colorPtr here for scope. 333 // Declare colorPtr here for scope.
333 SkPMColor colorPtr[256]; // storage for worst-case 334 SkPMColor colorPtr[256]; // storage for worst-case
334 const ColorMapObject* cmap = find_colormap(gif); 335 const ColorMapObject* cmap = find_colormap(gif);
335 if (cmap != NULL) { 336 if (cmap != NULL) {
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
416 // take care of skipping unneeded rows. 417 // take care of skipping unneeded rows.
417 GifInterlaceIter iter(innerHeight); 418 GifInterlaceIter iter(innerHeight);
418 for (int y = 0; y < innerHeight; y++) { 419 for (int y = 0; y < innerHeight; y++) {
419 if (DGifGetLine(gif, scanline, innerWidth) == GIF_ERROR) { 420 if (DGifGetLine(gif, scanline, innerWidth) == GIF_ERROR) {
420 gif_warning(*bm, "interlace DGifGetLine"); 421 gif_warning(*bm, "interlace DGifGetLine");
421 memset(scanline, fillIndex, innerWidth); 422 memset(scanline, fillIndex, innerWidth);
422 for (; y < innerHeight; y++) { 423 for (; y < innerHeight; y++) {
423 sampler.sampleInterlaced(scanline, iter.currY()); 424 sampler.sampleInterlaced(scanline, iter.currY());
424 iter.next(); 425 iter.next();
425 } 426 }
426 return true; 427 return kPartialSuccess;
427 } 428 }
428 sampler.sampleInterlaced(scanline, iter.currY()); 429 sampler.sampleInterlaced(scanline, iter.currY());
429 iter.next(); 430 iter.next();
430 } 431 }
431 } else { 432 } else {
432 // easy, non-interlace case 433 // easy, non-interlace case
433 const int outHeight = workingBitmap->height(); 434 const int outHeight = workingBitmap->height();
434 skip_src_rows(gif, scanline, innerWidth, sampler.srcY0()); 435 skip_src_rows(gif, scanline, innerWidth, sampler.srcY0());
435 for (int y = 0; y < outHeight; y++) { 436 for (int y = 0; y < outHeight; y++) {
436 if (DGifGetLine(gif, scanline, innerWidth) == GIF_ERROR) { 437 if (DGifGetLine(gif, scanline, innerWidth) == GIF_ERROR) {
437 gif_warning(*bm, "DGifGetLine"); 438 gif_warning(*bm, "DGifGetLine");
438 memset(scanline, fillIndex, innerWidth); 439 memset(scanline, fillIndex, innerWidth);
439 for (; y < outHeight; y++) { 440 for (; y < outHeight; y++) {
440 sampler.next(scanline); 441 sampler.next(scanline);
441 } 442 }
442 return true; 443 return kPartialSuccess;
443 } 444 }
444 // scanline now contains the raw data. Sample it. 445 // scanline now contains the raw data. Sample it.
445 sampler.next(scanline); 446 sampler.next(scanline);
446 if (y < outHeight - 1) { 447 if (y < outHeight - 1) {
447 skip_src_rows(gif, scanline, innerWidth, sampler.srcDY() - 1); 448 skip_src_rows(gif, scanline, innerWidth, sampler.srcDY() - 1);
448 } 449 }
449 } 450 }
450 // skip the rest of the rows (if any) 451 // skip the rest of the rows (if any)
451 int read = (outHeight - 1) * sampler.srcDY() + sampler.srcY0() + 1; 452 int read = (outHeight - 1) * sampler.srcDY() + sampler.srcY0() + 1;
452 SkASSERT(read <= innerHeight); 453 SkASSERT(read <= innerHeight);
453 skip_src_rows(gif, scanline, innerWidth, innerHeight - read); 454 skip_src_rows(gif, scanline, innerWidth, innerHeight - read);
454 } 455 }
455 sanitize_indexed_bitmap(bm); 456 sanitize_indexed_bitmap(bm);
456 return true; 457 return kSuccess;
457 } break; 458 } break;
458 459
459 case EXTENSION_RECORD_TYPE: 460 case EXTENSION_RECORD_TYPE:
460 #if GIFLIB_MAJOR < 5 461 #if GIFLIB_MAJOR < 5
461 if (DGifGetExtension(gif, &temp_save.Function, 462 if (DGifGetExtension(gif, &temp_save.Function,
462 &extData) == GIF_ERROR) { 463 &extData) == GIF_ERROR) {
463 #else 464 #else
464 if (DGifGetExtension(gif, &extFunction, &extData) == GIF_ERROR) { 465 if (DGifGetExtension(gif, &extFunction, &extData) == GIF_ERROR) {
465 #endif 466 #endif
466 return error_return(*bm, "DGifGetExtension"); 467 return error_return(*bm, "DGifGetExtension");
(...skipping 24 matching lines...) Expand all
491 492
492 case TERMINATE_RECORD_TYPE: 493 case TERMINATE_RECORD_TYPE:
493 break; 494 break;
494 495
495 default: /* Should be trapped by DGifGetRecordType */ 496 default: /* Should be trapped by DGifGetRecordType */
496 break; 497 break;
497 } 498 }
498 } while (recType != TERMINATE_RECORD_TYPE); 499 } while (recType != TERMINATE_RECORD_TYPE);
499 500
500 sanitize_indexed_bitmap(bm); 501 sanitize_indexed_bitmap(bm);
501 return true; 502 return kSuccess;
502 } 503 }
503 504
504 /////////////////////////////////////////////////////////////////////////////// 505 ///////////////////////////////////////////////////////////////////////////////
505 DEFINE_DECODER_CREATOR(GIFImageDecoder); 506 DEFINE_DECODER_CREATOR(GIFImageDecoder);
506 /////////////////////////////////////////////////////////////////////////////// 507 ///////////////////////////////////////////////////////////////////////////////
507 508
508 static bool is_gif(SkStreamRewindable* stream) { 509 static bool is_gif(SkStreamRewindable* stream) {
509 char buf[GIF_STAMP_LEN]; 510 char buf[GIF_STAMP_LEN];
510 if (stream->read(buf, GIF_STAMP_LEN) == GIF_STAMP_LEN) { 511 if (stream->read(buf, GIF_STAMP_LEN) == GIF_STAMP_LEN) {
511 if (memcmp(GIF_STAMP, buf, GIF_STAMP_LEN) == 0 || 512 if (memcmp(GIF_STAMP, buf, GIF_STAMP_LEN) == 0 ||
(...skipping 15 matching lines...) Expand all
527 static SkImageDecoder_DecodeReg gReg(sk_libgif_dfactory); 528 static SkImageDecoder_DecodeReg gReg(sk_libgif_dfactory);
528 529
529 static SkImageDecoder::Format get_format_gif(SkStreamRewindable* stream) { 530 static SkImageDecoder::Format get_format_gif(SkStreamRewindable* stream) {
530 if (is_gif(stream)) { 531 if (is_gif(stream)) {
531 return SkImageDecoder::kGIF_Format; 532 return SkImageDecoder::kGIF_Format;
532 } 533 }
533 return SkImageDecoder::kUnknown_Format; 534 return SkImageDecoder::kUnknown_Format;
534 } 535 }
535 536
536 static SkImageDecoder_FormatReg gFormatReg(get_format_gif); 537 static SkImageDecoder_FormatReg gFormatReg(get_format_gif);
OLDNEW
« no previous file with comments | « src/images/SkImageDecoder_libbmp.cpp ('k') | src/images/SkImageDecoder_libico.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698