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

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: Improved explanation of kBottomUp mode 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 340 matching lines...) Expand 10 before | Expand all | Expand 10 after
351 // If there is a transparent index, we also use this as 351 // If there is a transparent index, we also use this as
352 // the fill index. 352 // the fill index.
353 fillIndex = transIndex; 353 fillIndex = transIndex;
354 } else if (fillIndex >= colorCount) { 354 } else if (fillIndex >= colorCount) {
355 // If the fill index is invalid, we default to 0. This 355 // If the fill index is invalid, we default to 0. This
356 // behavior is unspecified but matches SkImageDecoder. 356 // behavior is unspecified but matches SkImageDecoder.
357 fillIndex = 0; 357 fillIndex = 0;
358 } 358 }
359 } 359 }
360 360
361 // Check if we can skip filling the background of the image. We
362 // may be able to if the memory is zero initialized.
363 bool skipBackground =
364 ((kN32_SkColorType == dstColorType && colorTable[fillInd ex] == 0) ||
365 (kIndex_8_SkColorType == dstColorType && fillIndex == 0) ) &&
366 kYes_ZeroInitialized == zeroInit;
367
368
369 // Fill in the color table for indices greater than color count. 361 // Fill in the color table for indices greater than color count.
370 // This allows for predictable, safe behavior. 362 // This allows for predictable, safe behavior.
371 for (uint32_t i = colorCount; i < maxColors; i++) { 363 for (uint32_t i = colorCount; i < maxColors; i++) {
372 colorTable[i] = colorTable[fillIndex]; 364 colorTable[i] = colorTable[fillIndex];
373 } 365 }
374 366
375 // Check if image is only a subset of the image frame 367 // Check if image is only a subset of the image frame
376 SkAutoTDelete<SkSwizzler> swizzler(nullptr); 368 SkAutoTDelete<SkSwizzler> swizzler(nullptr);
377 if (innerWidth < width || innerHeight < height) { 369 if (innerWidth < width || innerHeight < height) {
378 370
379 // Modify the destination info 371 // Modify the destination info
380 const SkImageInfo subsetDstInfo = dstInfo.makeWH(innerWidth, innerHeight); 372 const SkImageInfo subsetDstInfo = dstInfo.makeWH(innerWidth, innerHeight);
381 373
382 // Fill the destination with the fill color 374 // Fill the destination with the fill color
383 // FIXME: This may not be the behavior that we want for 375 // FIXME: This may not be the behavior that we want for
384 // animated gifs where we draw on top of the 376 // animated gifs where we draw on top of the
385 // previous frame. 377 // previous frame.
386 if (!skipBackground) { 378 SkSwizzler::Fill(dst, dstInfo, dstRowBytes, height, fillInde x, colorTable,
387 SkSwizzler::Fill(dst, dstInfo, dstRowBytes, height, fill Index, colorTable); 379 zeroInit);
388 }
389 380
390 // Modify the dst pointer 381 // Modify the dst pointer
391 const int32_t dstBytesPerPixel = SkColorTypeBytesPerPixel(ds tColorType); 382 const int32_t dstBytesPerPixel = SkColorTypeBytesPerPixel(ds tColorType);
392 dst = SkTAddOffset<void*>(dst, 383 dst = SkTAddOffset<void*>(dst,
393 dstRowBytes * imageTop + 384 dstRowBytes * imageTop +
394 dstBytesPerPixel * imageLeft); 385 dstBytesPerPixel * imageLeft);
395 386
396 // Create the subset swizzler 387 // Create the subset swizzler
397 swizzler.reset(SkSwizzler::CreateSwizzler( 388 swizzler.reset(SkSwizzler::CreateSwizzler(
398 SkSwizzler::kIndex, colorTable, subsetDstInfo, 389 SkSwizzler::kIndex, colorTable, subsetDstInfo,
(...skipping 10 matching lines...) Expand all
409 400
410 // Check the interlace flag and iterate over rows of the input 401 // Check the interlace flag and iterate over rows of the input
411 if (fGif->Image.Interlace) { 402 if (fGif->Image.Interlace) {
412 // In interlace mode, the rows of input are rearranged in 403 // In interlace mode, the rows of input are rearranged in
413 // the output image. We use an iterator to take care of 404 // the output image. We use an iterator to take care of
414 // the rearranging. 405 // the rearranging.
415 SkGifInterlaceIter iter(innerHeight); 406 SkGifInterlaceIter iter(innerHeight);
416 for (int32_t y = 0; y < innerHeight; y++) { 407 for (int32_t y = 0; y < innerHeight; y++) {
417 if (GIF_ERROR == DGifGetLine(fGif, buffer.get(), innerWi dth)) { 408 if (GIF_ERROR == DGifGetLine(fGif, buffer.get(), innerWi dth)) {
418 // Recover from error by filling remainder of image 409 // Recover from error by filling remainder of image
419 if (!skipBackground) { 410 memset(buffer.get(), fillIndex, innerWidth);
420 memset(buffer.get(), fillIndex, innerWidth); 411 for (; y < innerHeight; y++) {
421 for (; y < innerHeight; y++) { 412 void* dstRow = SkTAddOffset<void>(dst, dstRowByt es * iter.nextY());
422 void* dstRow = SkTAddOffset<void>(dst, 413 swizzler->swizzle(dstRow, buffer.get());
423 dstRowByte s * iter.nextY());
424 swizzler->swizzle(dstRow, buffer.get());
425 }
426 } 414 }
427 return gif_error(SkStringPrintf( 415 return gif_error(SkStringPrintf(
428 "Could not decode line %d of %d.\n", 416 "Could not decode line %d of %d.\n",
429 y, height - 1).c_str(), kIncompleteInput); 417 y, height - 1).c_str(), kIncompleteInput);
430 } 418 }
431 void* dstRow = SkTAddOffset<void>(dst, dstRowBytes * ite r.nextY()); 419 void* dstRow = SkTAddOffset<void>(dst, dstRowBytes * ite r.nextY());
432 swizzler->swizzle(dstRow, buffer.get()); 420 swizzler->swizzle(dstRow, buffer.get());
433 } 421 }
434 } else { 422 } else {
435 // Standard mode 423 // Standard mode
436 void* dstRow = dst; 424 void* dstRow = dst;
437 for (int32_t y = 0; y < innerHeight; y++) { 425 for (int32_t y = 0; y < innerHeight; y++) {
438 if (GIF_ERROR == DGifGetLine(fGif, buffer.get(), innerWi dth)) { 426 if (GIF_ERROR == DGifGetLine(fGif, buffer.get(), innerWi dth)) {
439 if (!skipBackground) { 427 SkSwizzler::Fill(dstRow, dstInfo, dstRowBytes, inner Height - y,
440 SkSwizzler::Fill(dstRow, dstInfo, dstRowBytes, 428 fillIndex, colorTable, zeroInit);
441 innerHeight - y, fillIndex, col orTable);
442 }
443 return gif_error(SkStringPrintf( 429 return gif_error(SkStringPrintf(
444 "Could not decode line %d of %d.\n", 430 "Could not decode line %d of %d.\n",
445 y, height - 1).c_str(), kIncompleteInput); 431 y, height - 1).c_str(), kIncompleteInput);
446 } 432 }
447 swizzler->swizzle(dstRow, buffer.get()); 433 swizzler->swizzle(dstRow, buffer.get());
448 dstRow = SkTAddOffset<void>(dstRow, dstRowBytes); 434 dstRow = SkTAddOffset<void>(dstRow, dstRowBytes);
449 } 435 }
450 } 436 }
451 437
452 // FIXME: Gif files may have multiple images stored in a single 438 // FIXME: Gif files may have multiple images stored in a single
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
504 default: 490 default:
505 // giflib returns an error code if the record type is not known. 491 // giflib returns an error code if the record type is not known.
506 // We should catch this error immediately. 492 // We should catch this error immediately.
507 SkASSERT(false); 493 SkASSERT(false);
508 break; 494 break;
509 } 495 }
510 } while (TERMINATE_RECORD_TYPE != recordType); 496 } while (TERMINATE_RECORD_TYPE != recordType);
511 497
512 return gif_error("Could not find any images to decode in gif file.\n", kInva lidInput); 498 return gif_error("Could not find any images to decode in gif file.\n", kInva lidInput);
513 } 499 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698