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

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

Issue 1287423002: Scanline decoding for bmp (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Fix windows errors 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 | « src/codec/SkCodecPriv.h ('k') | src/codec/SkCodec_libpng.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 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"
(...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after
375 // If there is a transparent index, we also use this as 375 // If there is a transparent index, we also use this as
376 // the fill index. 376 // the fill index.
377 fillIndex = transIndex; 377 fillIndex = transIndex;
378 } else if (fillIndex >= colorCount) { 378 } else if (fillIndex >= colorCount) {
379 // If the fill index is invalid, we default to 0. This 379 // If the fill index is invalid, we default to 0. This
380 // behavior is unspecified but matches SkImageDecoder. 380 // behavior is unspecified but matches SkImageDecoder.
381 fillIndex = 0; 381 fillIndex = 0;
382 } 382 }
383 } 383 }
384 384
385 // Check if we can skip filling the background of the image. We
386 // may be able to if the memory is zero initialized.
387 bool skipBackground =
388 ((kN32_SkColorType == dstColorType && colorTable[fillInd ex] == 0) ||
389 (kIndex_8_SkColorType == dstColorType && fillIndex == 0) ) &&
390 kYes_ZeroInitialized == zeroInit;
391
392
393 // Fill in the color table for indices greater than color count. 385 // Fill in the color table for indices greater than color count.
394 // This allows for predictable, safe behavior. 386 // This allows for predictable, safe behavior.
395 for (uint32_t i = colorCount; i < maxColors; i++) { 387 for (uint32_t i = colorCount; i < maxColors; i++) {
396 colorTable[i] = colorTable[fillIndex]; 388 colorTable[i] = colorTable[fillIndex];
397 } 389 }
398 390
399 // Check if image is only a subset of the image frame 391 // Check if image is only a subset of the image frame
400 SkAutoTDelete<SkSwizzler> swizzler(nullptr); 392 SkAutoTDelete<SkSwizzler> swizzler(nullptr);
401 if (innerWidth < width || innerHeight < height) { 393 if (innerWidth < width || innerHeight < height) {
402 394
403 // Modify the destination info 395 // Modify the destination info
404 const SkImageInfo subsetDstInfo = dstInfo.makeWH(innerWidth, innerHeight); 396 const SkImageInfo subsetDstInfo = dstInfo.makeWH(innerWidth, innerHeight);
405 397
406 // Fill the destination with the fill color 398 // Fill the destination with the fill color
407 // FIXME: This may not be the behavior that we want for 399 // FIXME: This may not be the behavior that we want for
408 // animated gifs where we draw on top of the 400 // animated gifs where we draw on top of the
409 // previous frame. 401 // previous frame.
410 if (!skipBackground) { 402 SkSwizzler::Fill(dst, dstInfo, dstRowBytes, height, fillInde x, colorTable,
411 SkSwizzler::Fill(dst, dstInfo, dstRowBytes, height, fill Index, colorTable); 403 zeroInit);
412 }
413 404
414 // Modify the dst pointer 405 // Modify the dst pointer
415 const int32_t dstBytesPerPixel = SkColorTypeBytesPerPixel(ds tColorType); 406 const int32_t dstBytesPerPixel = SkColorTypeBytesPerPixel(ds tColorType);
416 dst = SkTAddOffset<void*>(dst, 407 dst = SkTAddOffset<void*>(dst,
417 dstRowBytes * imageTop + 408 dstRowBytes * imageTop +
418 dstBytesPerPixel * imageLeft); 409 dstBytesPerPixel * imageLeft);
419 410
420 // Create the subset swizzler 411 // Create the subset swizzler
421 swizzler.reset(SkSwizzler::CreateSwizzler( 412 swizzler.reset(SkSwizzler::CreateSwizzler(
422 SkSwizzler::kIndex, colorTable, subsetDstInfo, 413 SkSwizzler::kIndex, colorTable, subsetDstInfo,
423 zeroInit, this->getInfo())); 414 zeroInit, this->getInfo()));
424 } else { 415 } else {
425 // Create the fully dimensional swizzler 416 // Create the fully dimensional swizzler
426 swizzler.reset(SkSwizzler::CreateSwizzler( 417 swizzler.reset(SkSwizzler::CreateSwizzler(
427 SkSwizzler::kIndex, colorTable, dstInfo, 418 SkSwizzler::kIndex, colorTable, dstInfo,
428 zeroInit, this->getInfo())); 419 zeroInit, this->getInfo()));
429 } 420 }
430 421
431 // Stores output from dgiflib and input to the swizzler 422 // Stores output from dgiflib and input to the swizzler
432 SkAutoTDeleteArray<uint8_t> buffer(new uint8_t[innerWidth]); 423 SkAutoTDeleteArray<uint8_t> buffer(new uint8_t[innerWidth]);
433 424
434 // Check the interlace flag and iterate over rows of the input 425 // Check the interlace flag and iterate over rows of the input
435 if (fGif->Image.Interlace) { 426 if (fGif->Image.Interlace) {
436 for (int32_t y = 0; y < innerHeight; y++) { 427 for (int32_t y = 0; y < innerHeight; y++) {
437 if (GIF_ERROR == DGifGetLine(fGif, buffer.get(), innerWi dth)) { 428 if (GIF_ERROR == DGifGetLine(fGif, buffer.get(), innerWi dth)) {
438 // Recover from error by filling remainder of image 429 // Recover from error by filling remainder of image
439 if (!skipBackground) { 430 memset(buffer.get(), fillIndex, innerWidth);
440 memset(buffer.get(), fillIndex, innerWidth); 431 for (; y < innerHeight; y++) {
441 for (; y < innerHeight; y++) { 432 void* dstRow = SkTAddOffset<void>(dst, dstRowByt es *
442 void* dstRow = SkTAddOffset<void>(dst, dstRo wBytes * 433 get_output_row_interlaced(y, innerHeight ));
443 get_output_row_interlaced(y, innerHe ight)); 434 swizzler->swizzle(dstRow, buffer.get());
444 swizzler->swizzle(dstRow, buffer.get());
445 }
446 } 435 }
447 return gif_error(SkStringPrintf( 436 return gif_error(SkStringPrintf(
448 "Could not decode line %d of %d.\n", 437 "Could not decode line %d of %d.\n",
449 y, height - 1).c_str(), kIncompleteInput); 438 y, height - 1).c_str(), kIncompleteInput);
450 } 439 }
451 void* dstRow = SkTAddOffset<void>(dst, 440 void* dstRow = SkTAddOffset<void>(dst,
452 dstRowBytes * get_output_row_interlaced(y, inner Height)); 441 dstRowBytes * get_output_row_interlaced(y, inner Height));
453 swizzler->swizzle(dstRow, buffer.get()); 442 swizzler->swizzle(dstRow, buffer.get());
454 } 443 }
455 } else { 444 } else {
456 // Standard mode 445 // Standard mode
457 void* dstRow = dst; 446 void* dstRow = dst;
458 for (int32_t y = 0; y < innerHeight; y++) { 447 for (int32_t y = 0; y < innerHeight; y++) {
459 if (GIF_ERROR == DGifGetLine(fGif, buffer.get(), innerWi dth)) { 448 if (GIF_ERROR == DGifGetLine(fGif, buffer.get(), innerWi dth)) {
460 if (!skipBackground) { 449 SkSwizzler::Fill(dstRow, dstInfo, dstRowBytes, inner Height - y,
461 SkSwizzler::Fill(dstRow, dstInfo, dstRowBytes, 450 fillIndex, colorTable, zeroInit);
462 innerHeight - y, fillIndex, col orTable);
463 }
464 return gif_error(SkStringPrintf( 451 return gif_error(SkStringPrintf(
465 "Could not decode line %d of %d.\n", 452 "Could not decode line %d of %d.\n",
466 y, height - 1).c_str(), kIncompleteInput); 453 y, height - 1).c_str(), kIncompleteInput);
467 } 454 }
468 swizzler->swizzle(dstRow, buffer.get()); 455 swizzler->swizzle(dstRow, buffer.get());
469 dstRow = SkTAddOffset<void>(dstRow, dstRowBytes); 456 dstRow = SkTAddOffset<void>(dstRow, dstRowBytes);
470 } 457 }
471 } 458 }
472 459
473 // FIXME: Gif files may have multiple images stored in a single 460 // FIXME: Gif files may have multiple images stored in a single
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
525 default: 512 default:
526 // giflib returns an error code if the record type is not known. 513 // giflib returns an error code if the record type is not known.
527 // We should catch this error immediately. 514 // We should catch this error immediately.
528 SkASSERT(false); 515 SkASSERT(false);
529 break; 516 break;
530 } 517 }
531 } while (TERMINATE_RECORD_TYPE != recordType); 518 } while (TERMINATE_RECORD_TYPE != recordType);
532 519
533 return gif_error("Could not find any images to decode in gif file.\n", kInva lidInput); 520 return gif_error("Could not find any images to decode in gif file.\n", kInva lidInput);
534 } 521 }
OLDNEW
« no previous file with comments | « src/codec/SkCodecPriv.h ('k') | src/codec/SkCodec_libpng.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698