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

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: Fixes 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
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 361 matching lines...) Expand 10 before | Expand all | Expand 10 after
372 // If there is a transparent index, we also use this as 372 // If there is a transparent index, we also use this as
373 // the fill index. 373 // the fill index.
374 fillIndex = transIndex; 374 fillIndex = transIndex;
375 } else if (fillIndex >= colorCount) { 375 } else if (fillIndex >= colorCount) {
376 // If the fill index is invalid, we default to 0. This 376 // If the fill index is invalid, we default to 0. This
377 // behavior is unspecified but matches SkImageDecoder. 377 // behavior is unspecified but matches SkImageDecoder.
378 fillIndex = 0; 378 fillIndex = 0;
379 } 379 }
380 } 380 }
381 381
382 // Check if we can skip filling the background of the image. We
383 // may be able to if the memory is zero initialized.
384 bool skipBackground =
385 ((kN32_SkColorType == dstColorType && colorTable[fillInd ex] == 0) ||
386 (kIndex_8_SkColorType == dstColorType && fillIndex == 0) ) &&
387 kYes_ZeroInitialized == zeroInit;
388
389
390 // Fill in the color table for indices greater than color count. 382 // Fill in the color table for indices greater than color count.
391 // This allows for predictable, safe behavior. 383 // This allows for predictable, safe behavior.
392 for (uint32_t i = colorCount; i < maxColors; i++) { 384 for (uint32_t i = colorCount; i < maxColors; i++) {
393 colorTable[i] = colorTable[fillIndex]; 385 colorTable[i] = colorTable[fillIndex];
394 } 386 }
395 387
396 // Check if image is only a subset of the image frame 388 // Check if image is only a subset of the image frame
397 SkAutoTDelete<SkSwizzler> swizzler(NULL); 389 SkAutoTDelete<SkSwizzler> swizzler(NULL);
398 if (innerWidth < width || innerHeight < height) { 390 if (innerWidth < width || innerHeight < height) {
399 391
400 // Modify the destination info 392 // Modify the destination info
401 const SkImageInfo subsetDstInfo = 393 const SkImageInfo subsetDstInfo =
402 dstInfo.makeWH(innerWidth, innerHeight); 394 dstInfo.makeWH(innerWidth, innerHeight);
403 395
404 // Fill the destination with the fill color 396 // Fill the destination with the fill color
405 // FIXME: This may not be the behavior that we want for 397 // FIXME: This may not be the behavior that we want for
406 // animated gifs where we draw on top of the 398 // animated gifs where we draw on top of the
407 // previous frame. 399 // previous frame.
408 if (!skipBackground) { 400 SkSwizzler::Fill(dst, dstInfo, dstRowBytes, height,
409 SkSwizzler::Fill(dst, dstInfo, dstRowBytes, height, 401 fillIndex, colorTable, zeroInit);
410 fillIndex, colorTable);
411 }
412 402
413 // Modify the dst pointer 403 // Modify the dst pointer
414 const int32_t dstBytesPerPixel = 404 const int32_t dstBytesPerPixel =
415 SkColorTypeBytesPerPixel(dstColorType); 405 SkColorTypeBytesPerPixel(dstColorType);
416 dst = SkTAddOffset<void*>(dst, 406 dst = SkTAddOffset<void*>(dst,
417 dstRowBytes * imageTop + 407 dstRowBytes * imageTop +
418 dstBytesPerPixel * imageLeft); 408 dstBytesPerPixel * imageLeft);
419 409
420 // Create the subset swizzler 410 // Create the subset swizzler
421 swizzler.reset(SkSwizzler::CreateSwizzler( 411 swizzler.reset(SkSwizzler::CreateSwizzler(
(...skipping 13 matching lines...) Expand all
435 // Check the interlace flag and iterate over rows of the input 425 // Check the interlace flag and iterate over rows of the input
436 if (fGif->Image.Interlace) { 426 if (fGif->Image.Interlace) {
437 // In interlace mode, the rows of input are rearranged in 427 // In interlace mode, the rows of input are rearranged in
438 // the output image. We use an iterator to take care of 428 // the output image. We use an iterator to take care of
439 // the rearranging. 429 // the rearranging.
440 SkGifInterlaceIter iter(innerHeight); 430 SkGifInterlaceIter iter(innerHeight);
441 for (int32_t y = 0; y < innerHeight; y++) { 431 for (int32_t y = 0; y < innerHeight; y++) {
442 if (GIF_ERROR == DGifGetLine(fGif, buffer.get(), 432 if (GIF_ERROR == DGifGetLine(fGif, buffer.get(),
443 innerWidth)) { 433 innerWidth)) {
444 // Recover from error by filling remainder of image 434 // Recover from error by filling remainder of image
445 if (!skipBackground) { 435 memset(buffer.get(), fillIndex, innerWidth);
446 memset(buffer.get(), fillIndex, innerWidth); 436 for (; y < innerHeight; y++) {
447 for (; y < innerHeight; y++) { 437 void* dstRow = SkTAddOffset<void>(dst,
448 void* dstRow = SkTAddOffset<void>(dst, 438 dstRowBytes * iter.nextY());
449 dstRowBytes * iter.nextY()); 439 swizzler->swizzle(dstRow, buffer.get());
450 swizzler->swizzle(dstRow, buffer.get());
451 }
452 } 440 }
453 return gif_error(SkStringPrintf( 441 return gif_error(SkStringPrintf(
454 "Could not decode line %d of %d.\n", 442 "Could not decode line %d of %d.\n",
455 y, height - 1).c_str(), kIncompleteInput); 443 y, height - 1).c_str(), kIncompleteInput);
456 } 444 }
457 void* dstRow = SkTAddOffset<void>( 445 void* dstRow = SkTAddOffset<void>(
458 dst, dstRowBytes * iter.nextY()); 446 dst, dstRowBytes * iter.nextY());
459 swizzler->swizzle(dstRow, buffer.get()); 447 swizzler->swizzle(dstRow, buffer.get());
460 } 448 }
461 } else { 449 } else {
462 // Standard mode 450 // Standard mode
463 void* dstRow = dst; 451 void* dstRow = dst;
464 for (int32_t y = 0; y < innerHeight; y++) { 452 for (int32_t y = 0; y < innerHeight; y++) {
465 if (GIF_ERROR == DGifGetLine(fGif, buffer.get(), 453 if (GIF_ERROR == DGifGetLine(fGif, buffer.get(),
466 innerWidth)) { 454 innerWidth)) {
467 if (!skipBackground) { 455 SkSwizzler::Fill(dstRow, dstInfo, dstRowBytes,
468 SkSwizzler::Fill(dstRow, dstInfo, dstRowBytes, 456 innerHeight - y, fillIndex, colorTable,
469 innerHeight - y, fillIndex, colorTable); 457 zeroInit);
470 }
471 return gif_error(SkStringPrintf( 458 return gif_error(SkStringPrintf(
472 "Could not decode line %d of %d.\n", 459 "Could not decode line %d of %d.\n",
473 y, height - 1).c_str(), kIncompleteInput); 460 y, height - 1).c_str(), kIncompleteInput);
474 } 461 }
475 swizzler->swizzle(dstRow, buffer.get()); 462 swizzler->swizzle(dstRow, buffer.get());
476 dstRow = SkTAddOffset<void>(dstRow, dstRowBytes); 463 dstRow = SkTAddOffset<void>(dstRow, dstRowBytes);
477 } 464 }
478 } 465 }
479 466
480 // FIXME: Gif files may have multiple images stored in a single 467 // FIXME: Gif files may have multiple images stored in a single
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
550 // giflib returns an error code if the record type is not known. 537 // giflib returns an error code if the record type is not known.
551 // We should catch this error immediately. 538 // We should catch this error immediately.
552 SkASSERT(false); 539 SkASSERT(false);
553 break; 540 break;
554 } 541 }
555 } while (TERMINATE_RECORD_TYPE != recordType); 542 } while (TERMINATE_RECORD_TYPE != recordType);
556 543
557 return gif_error("Could not find any images to decode in gif file.\n", 544 return gif_error("Could not find any images to decode in gif file.\n",
558 kInvalidInput); 545 kInvalidInput);
559 } 546 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698