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

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: Response to comments from previous patch sets 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
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 347 matching lines...) Expand 10 before | Expand all | Expand 10 after
358 // If there is a transparent index, we also use this as 358 // If there is a transparent index, we also use this as
359 // the fill index. 359 // the fill index.
360 fillIndex = transIndex; 360 fillIndex = transIndex;
361 } else if (fillIndex >= colorCount) { 361 } else if (fillIndex >= colorCount) {
362 // If the fill index is invalid, we default to 0. This 362 // If the fill index is invalid, we default to 0. This
363 // behavior is unspecified but matches SkImageDecoder. 363 // behavior is unspecified but matches SkImageDecoder.
364 fillIndex = 0; 364 fillIndex = 0;
365 } 365 }
366 } 366 }
367 367
368 // Check if we can skip filling the background of the image. We
369 // may be able to if the memory is zero initialized.
370 bool skipBackground =
371 ((kN32_SkColorType == dstColorType && colorTable[fillInd ex] == 0) ||
372 (kIndex_8_SkColorType == dstColorType && fillIndex == 0) ) &&
373 kYes_ZeroInitialized == zeroInit;
374
375
376 // Fill in the color table for indices greater than color count. 368 // Fill in the color table for indices greater than color count.
377 // This allows for predictable, safe behavior. 369 // This allows for predictable, safe behavior.
378 for (uint32_t i = colorCount; i < maxColors; i++) { 370 for (uint32_t i = colorCount; i < maxColors; i++) {
379 colorTable[i] = colorTable[fillIndex]; 371 colorTable[i] = colorTable[fillIndex];
380 } 372 }
381 373
382 // Check if image is only a subset of the image frame 374 // Check if image is only a subset of the image frame
383 SkAutoTDelete<SkSwizzler> swizzler(NULL); 375 SkAutoTDelete<SkSwizzler> swizzler(NULL);
384 if (innerWidth < width || innerHeight < height) { 376 if (innerWidth < width || innerHeight < height) {
385 377
386 // Modify the destination info 378 // Modify the destination info
387 const SkImageInfo subsetDstInfo = 379 const SkImageInfo subsetDstInfo =
388 dstInfo.makeWH(innerWidth, innerHeight); 380 dstInfo.makeWH(innerWidth, innerHeight);
389 381
390 // Fill the destination with the fill color 382 // Fill the destination with the fill color
391 // FIXME: This may not be the behavior that we want for 383 // FIXME: This may not be the behavior that we want for
392 // animated gifs where we draw on top of the 384 // animated gifs where we draw on top of the
393 // previous frame. 385 // previous frame.
394 if (!skipBackground) { 386 SkSwizzler::Fill(dst, dstInfo, dstRowBytes, height,
395 SkSwizzler::Fill(dst, dstInfo, dstRowBytes, height, 387 fillIndex, colorTable, zeroInit);
396 fillIndex, colorTable);
397 }
398 388
399 // Modify the dst pointer 389 // Modify the dst pointer
400 const int32_t dstBytesPerPixel = 390 const int32_t dstBytesPerPixel =
401 SkColorTypeBytesPerPixel(dstColorType); 391 SkColorTypeBytesPerPixel(dstColorType);
402 dst = SkTAddOffset<void*>(dst, 392 dst = SkTAddOffset<void*>(dst,
403 dstRowBytes * imageTop + 393 dstRowBytes * imageTop +
404 dstBytesPerPixel * imageLeft); 394 dstBytesPerPixel * imageLeft);
405 395
406 // Create the subset swizzler 396 // Create the subset swizzler
407 swizzler.reset(SkSwizzler::CreateSwizzler( 397 swizzler.reset(SkSwizzler::CreateSwizzler(
(...skipping 13 matching lines...) Expand all
421 // Check the interlace flag and iterate over rows of the input 411 // Check the interlace flag and iterate over rows of the input
422 if (fGif->Image.Interlace) { 412 if (fGif->Image.Interlace) {
423 // In interlace mode, the rows of input are rearranged in 413 // In interlace mode, the rows of input are rearranged in
424 // the output image. We use an iterator to take care of 414 // the output image. We use an iterator to take care of
425 // the rearranging. 415 // the rearranging.
426 SkGifInterlaceIter iter(innerHeight); 416 SkGifInterlaceIter iter(innerHeight);
427 for (int32_t y = 0; y < innerHeight; y++) { 417 for (int32_t y = 0; y < innerHeight; y++) {
428 if (GIF_ERROR == DGifGetLine(fGif, buffer.get(), 418 if (GIF_ERROR == DGifGetLine(fGif, buffer.get(),
429 innerWidth)) { 419 innerWidth)) {
430 // Recover from error by filling remainder of image 420 // Recover from error by filling remainder of image
431 if (!skipBackground) { 421 memset(buffer.get(), fillIndex, innerWidth);
432 memset(buffer.get(), fillIndex, innerWidth); 422 for (; y < innerHeight; y++) {
433 for (; y < innerHeight; y++) { 423 void* dstRow = SkTAddOffset<void>(dst,
434 void* dstRow = SkTAddOffset<void>(dst, 424 dstRowBytes * iter.nextY());
435 dstRowBytes * iter.nextY()); 425 swizzler->swizzle(dstRow, buffer.get());
436 swizzler->swizzle(dstRow, buffer.get());
437 }
438 } 426 }
439 return gif_error(SkStringPrintf( 427 return gif_error(SkStringPrintf(
440 "Could not decode line %d of %d.\n", 428 "Could not decode line %d of %d.\n",
441 y, height - 1).c_str(), kIncompleteInput); 429 y, height - 1).c_str(), kIncompleteInput);
442 } 430 }
443 void* dstRow = SkTAddOffset<void>( 431 void* dstRow = SkTAddOffset<void>(
444 dst, dstRowBytes * iter.nextY()); 432 dst, dstRowBytes * iter.nextY());
445 swizzler->swizzle(dstRow, buffer.get()); 433 swizzler->swizzle(dstRow, buffer.get());
446 } 434 }
447 } else { 435 } else {
448 // Standard mode 436 // Standard mode
449 void* dstRow = dst; 437 void* dstRow = dst;
450 for (int32_t y = 0; y < innerHeight; y++) { 438 for (int32_t y = 0; y < innerHeight; y++) {
451 if (GIF_ERROR == DGifGetLine(fGif, buffer.get(), 439 if (GIF_ERROR == DGifGetLine(fGif, buffer.get(),
452 innerWidth)) { 440 innerWidth)) {
453 if (!skipBackground) { 441 SkSwizzler::Fill(dstRow, dstInfo, dstRowBytes,
454 SkSwizzler::Fill(dstRow, dstInfo, dstRowBytes, 442 innerHeight - y, fillIndex, colorTable,
455 innerHeight - y, fillIndex, colorTable); 443 zeroInit);
456 }
457 return gif_error(SkStringPrintf( 444 return gif_error(SkStringPrintf(
458 "Could not decode line %d of %d.\n", 445 "Could not decode line %d of %d.\n",
459 y, height - 1).c_str(), kIncompleteInput); 446 y, height - 1).c_str(), kIncompleteInput);
460 } 447 }
461 swizzler->swizzle(dstRow, buffer.get()); 448 swizzler->swizzle(dstRow, buffer.get());
462 dstRow = SkTAddOffset<void>(dstRow, dstRowBytes); 449 dstRow = SkTAddOffset<void>(dstRow, dstRowBytes);
463 } 450 }
464 } 451 }
465 452
466 // FIXME: Gif files may have multiple images stored in a single 453 // FIXME: Gif files may have multiple images stored in a single
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
523 // giflib returns an error code if the record type is not known. 510 // giflib returns an error code if the record type is not known.
524 // We should catch this error immediately. 511 // We should catch this error immediately.
525 SkASSERT(false); 512 SkASSERT(false);
526 break; 513 break;
527 } 514 }
528 } while (TERMINATE_RECORD_TYPE != recordType); 515 } while (TERMINATE_RECORD_TYPE != recordType);
529 516
530 return gif_error("Could not find any images to decode in gif file.\n", 517 return gif_error("Could not find any images to decode in gif file.\n",
531 kInvalidInput); 518 kInvalidInput);
532 } 519 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698