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

Side by Side Diff: dm/DMSrcSink.cpp

Issue 1332053002: Fill incomplete images in SkCodec parent class (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: 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 | « no previous file | gyp/tools.gyp » ('j') | include/codec/SkCodec.h » ('J')
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 "DMSrcSink.h" 8 #include "DMSrcSink.h"
9 #include "SamplePipeControllers.h" 9 #include "SamplePipeControllers.h"
10 #include "SkCodec.h" 10 #include "SkCodec.h"
(...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after
345 canvas->drawBitmap(bitmap, 0, 0); 345 canvas->drawBitmap(bitmap, 0, 0);
346 break; 346 break;
347 } 347 }
348 case kScanline_Mode: { 348 case kScanline_Mode: {
349 SkAutoTDelete<SkScanlineDecoder> scanlineDecoder( 349 SkAutoTDelete<SkScanlineDecoder> scanlineDecoder(
350 start_scanline_decoder(encoded.get(), decodeInfo, colorPtr, colorCountPtr)); 350 start_scanline_decoder(encoded.get(), decodeInfo, colorPtr, colorCountPtr));
351 if (nullptr == scanlineDecoder) { 351 if (nullptr == scanlineDecoder) {
352 return Error::Nonfatal("Could not start scanline decoder"); 352 return Error::Nonfatal("Could not start scanline decoder");
353 } 353 }
354 354
355 SkCodec::Result result = SkCodec::kUnimplemented; 355 uint32_t lines = 0;
scroggo 2015/09/22 18:02:48 Maybe this should be linesDecoded?
msarett 2015/09/23 13:22:39 Done.
356 switch (scanlineDecoder->getScanlineOrder()) { 356 switch (scanlineDecoder->getScanlineOrder()) {
357 case SkScanlineDecoder::kTopDown_SkScanlineOrder: 357 case SkScanlineDecoder::kTopDown_SkScanlineOrder:
358 case SkScanlineDecoder::kBottomUp_SkScanlineOrder: 358 case SkScanlineDecoder::kBottomUp_SkScanlineOrder:
359 case SkScanlineDecoder::kNone_SkScanlineOrder: 359 case SkScanlineDecoder::kNone_SkScanlineOrder:
360 result = scanlineDecoder->getScanlines(bitmap.getAddr(0, 0), 360 lines = scanlineDecoder->getScanlines(bitmap.getAddr(0, 0),
361 decodeInfo.height(), bitmap.rowBytes()); 361 decodeInfo.height(), bitmap.rowBytes());
362 break; 362 break;
363 case SkScanlineDecoder::kOutOfOrder_SkScanlineOrder: { 363 case SkScanlineDecoder::kOutOfOrder_SkScanlineOrder: {
364 for (int y = 0; y < decodeInfo.height(); y++) { 364 for (int y = 0; y < decodeInfo.height(); y++) {
365 int dstY = scanlineDecoder->getY(); 365 int dstY = scanlineDecoder->getY();
366 void* dstPtr = bitmap.getAddr(0, dstY); 366 void* dstPtr = bitmap.getAddr(0, dstY);
367 result = scanlineDecoder->getScanlines(dstPtr, 1, bitmap .rowBytes()); 367 uint32_t line = scanlineDecoder->getScanlines(dstPtr, 1, bitmap.rowBytes());
368 if (SkCodec::kSuccess != result && SkCodec::kIncompleteI nput != result) { 368 if (1 != line) {
369 return SkStringPrintf("%s failed with error message %d", 369 break;
370 fPath.c_str(), (int) result);
371 } 370 }
371 lines += line;
372 } 372 }
373 break; 373 break;
374 } 374 }
375 } 375 }
376 376 if ((int) lines < decodeInfo.height()) {
377 switch (result) { 377 // We have not implemented a function in SkScanlineDecoder to fi ll remaining
378 case SkCodec::kSuccess: 378 // scanlines on an incomplete decode. As long as we are the onl y client that
379 case SkCodec::kIncompleteInput: 379 // uses SkScanlineDecoder, I think this is ok. If this changes, maybe we want
380 break; 380 // to consider providing an API for this?
381 default: 381 return Error::Nonfatal("Image is incomplete, could not get scanl ines");
382 return SkStringPrintf("%s failed with error message %d",
383 fPath.c_str(), (int) result);
384 } 382 }
385 canvas->drawBitmap(bitmap, 0, 0); 383 canvas->drawBitmap(bitmap, 0, 0);
386 break; 384 break;
387 } 385 }
388 case kScanline_Subset_Mode: { 386 case kScanline_Subset_Mode: {
389 //this mode decodes the image in divisor*divisor subsets, using a sc anline decoder 387 //this mode decodes the image in divisor*divisor subsets, using a sc anline decoder
390 const int divisor = 2; 388 const int divisor = 2;
391 const int w = decodeInfo.width(); 389 const int w = decodeInfo.width();
392 const int h = decodeInfo.height(); 390 const int h = decodeInfo.height();
393 if (divisor > w || divisor > h) { 391 if (divisor > w || divisor > h) {
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
436 if (nullptr == decoder || SkScanlineDecoder::kTopDown_SkScan lineOrder != 434 if (nullptr == decoder || SkScanlineDecoder::kTopDown_SkScan lineOrder !=
437 decoder->getScanlineOrder()) { 435 decoder->getScanlineOrder()) {
438 if (x == 0 && y == 0) { 436 if (x == 0 && y == 0) {
439 //first try, image may not be compatible 437 //first try, image may not be compatible
440 return Error::Nonfatal("Could not start top-down sca nline decoder"); 438 return Error::Nonfatal("Could not start top-down sca nline decoder");
441 } else { 439 } else {
442 return "Error scanline decoder is nullptr"; 440 return "Error scanline decoder is nullptr";
443 } 441 }
444 } 442 }
445 //skip to first line of subset 443 //skip to first line of subset
446 const SkCodec::Result skipResult = decoder->skipScanlines(y) ; 444 int lines = decoder->skipScanlines(y);
447 switch (skipResult) { 445 if (lines < y) {
448 case SkCodec::kSuccess: 446 return Error::Nonfatal("Image is incomplete, could not g et scanlines");
449 case SkCodec::kIncompleteInput:
450 break;
451 default:
452 return SkStringPrintf("%s failed after attempting to skip %d scanlines"
453 "with error message %d", fPath.c_str(), y, ( int) skipResult);
454 } 447 }
455 //create and set size of subsetBm 448 //create and set size of subsetBm
456 SkBitmap subsetBm; 449 SkBitmap subsetBm;
457 SkIRect bounds = SkIRect::MakeWH(subsetWidth, subsetHeight); 450 SkIRect bounds = SkIRect::MakeWH(subsetWidth, subsetHeight);
458 bounds.setXYWH(0, 0, currentSubsetWidth, currentSubsetHeight ); 451 bounds.setXYWH(0, 0, currentSubsetWidth, currentSubsetHeight );
459 SkAssertResult(largestSubsetBm.extractSubset(&subsetBm, boun ds)); 452 SkAssertResult(largestSubsetBm.extractSubset(&subsetBm, boun ds));
460 SkAutoLockPixels autlockSubsetBm(subsetBm, true); 453 SkAutoLockPixels autlockSubsetBm(subsetBm, true);
461 const SkCodec::Result subsetResult = 454 lines = decoder->getScanlines(buffer, currentSubsetHeight, r owBytes);
462 decoder->getScanlines(buffer, currentSubsetHeight, r owBytes); 455 if (lines < currentSubsetHeight) {
463 switch (subsetResult) { 456 return Error::Nonfatal("Image is incomplete, could not g et scanlines");
scroggo 2015/09/22 18:02:48 This is going to change the behavior, right? Previ
msarett 2015/09/23 13:22:39 Yes I should have been more explicit about behavio
scroggo 2015/09/25 15:55:05 Sure we can. We just need to make DM fill the buff
msarett 2015/10/01 12:44:51 kScanlineSubset_Mode now fills on incomplete image
464 case SkCodec::kSuccess:
465 case SkCodec::kIncompleteInput:
466 break;
467 default:
468 return SkStringPrintf("%s failed with error message %d",
469 fPath.c_str(), (int) subsetResult);
470 } 457 }
471 const size_t bpp = decodeInfo.bytesPerPixel(); 458 const size_t bpp = decodeInfo.bytesPerPixel();
472 /* 459 /*
473 * we copy all the lines at once becuase when calling getSca nlines for 460 * we copy all the lines at once becuase when calling getSca nlines for
474 * interlaced pngs the entire image must be read regardless of the number 461 * interlaced pngs the entire image must be read regardless of the number
475 * of lines requested. Reading an interlaced png in a loop, line-by-line, would 462 * of lines requested. Reading an interlaced png in a loop, line-by-line, would
476 * decode the entire image height times, which is very slow 463 * decode the entire image height times, which is very slow
477 * it is aknowledged that copying each line as you read it i n a loop 464 * it is aknowledged that copying each line as you read it i n a loop
478 * may be faster for other types of images. Since this is a correctness test 465 * may be faster for other types of images. Since this is a correctness test
479 * that's okay. 466 * that's okay.
(...skipping 21 matching lines...) Expand all
501 // Decode odd stripes 488 // Decode odd stripes
502 SkAutoTDelete<SkScanlineDecoder> decoder( 489 SkAutoTDelete<SkScanlineDecoder> decoder(
503 start_scanline_decoder(encoded.get(), decodeInfo, colorPtr, colorCountPtr)); 490 start_scanline_decoder(encoded.get(), decodeInfo, colorPtr, colorCountPtr));
504 if (nullptr == decoder || 491 if (nullptr == decoder ||
505 SkScanlineDecoder::kTopDown_SkScanlineOrder != decoder->getS canlineOrder()) { 492 SkScanlineDecoder::kTopDown_SkScanlineOrder != decoder->getS canlineOrder()) {
506 // This mode was designed to test the new skip scanlines API in libjpeg-turbo. 493 // This mode was designed to test the new skip scanlines API in libjpeg-turbo.
507 // Jpegs have kTopDown_SkScanlineOrder, and at this time, it is not interesting 494 // Jpegs have kTopDown_SkScanlineOrder, and at this time, it is not interesting
508 // to run this test for image types that do not have this scanli ne ordering. 495 // to run this test for image types that do not have this scanli ne ordering.
509 return Error::Nonfatal("Could not start top-down scanline decode r"); 496 return Error::Nonfatal("Could not start top-down scanline decode r");
510 } 497 }
498 int lines;
scroggo 2015/09/22 18:02:48 I would lean towards removing this variable and in
msarett 2015/09/23 13:22:39 Done.
511 for (int i = 0; i < numStripes; i += 2) { 499 for (int i = 0; i < numStripes; i += 2) {
512 // Skip a stripe 500 // Skip a stripe
513 const int linesToSkip = SkTMin(stripeHeight, height - i * stripe Height); 501 const int linesToSkip = SkTMin(stripeHeight, height - i * stripe Height);
514 SkCodec::Result result = decoder->skipScanlines(linesToSkip); 502 lines = decoder->skipScanlines(linesToSkip);
515 switch (result) { 503 if (lines < linesToSkip) {
516 case SkCodec::kSuccess: 504 return Error::Nonfatal("Image is incomplete, could not get s canlines");
517 case SkCodec::kIncompleteInput:
518 break;
519 default:
520 return SkStringPrintf("Cannot skip scanlines for %s.", f Path.c_str());
521 } 505 }
522 506
523 // Read a stripe 507 // Read a stripe
524 const int startY = (i + 1) * stripeHeight; 508 const int startY = (i + 1) * stripeHeight;
525 const int linesToRead = SkTMin(stripeHeight, height - startY); 509 const int linesToRead = SkTMin(stripeHeight, height - startY);
526 if (linesToRead > 0) { 510 if (linesToRead > 0) {
527 result = decoder->getScanlines(bitmap.getAddr(0, startY), 511 lines = decoder->getScanlines(bitmap.getAddr(0, startY), lin esToRead,
528 linesToRead, bitmap.rowBytes()); 512 bitmap.rowBytes());
529 switch (result) { 513 if (lines < linesToRead) {
530 case SkCodec::kSuccess: 514 return Error::Nonfatal("Image is incomplete, could not g et scanlines");
531 case SkCodec::kIncompleteInput:
532 break;
533 default:
534 return SkStringPrintf("Cannot get scanlines for %s." , fPath.c_str());
535 } 515 }
536 } 516 }
537 } 517 }
538 518
539 // Decode even stripes 519 // Decode even stripes
540 const SkCodec::Result startResult = decoder->start(decodeInfo, nullp tr, colorPtr, 520 const SkCodec::Result startResult = decoder->start(decodeInfo, nullp tr, colorPtr,
541 colorCountPtr); 521 colorCountPtr);
542 if (SkCodec::kSuccess != startResult) { 522 if (SkCodec::kSuccess != startResult) {
543 return "Failed to restart scanline decoder with same parameters. "; 523 return "Failed to restart scanline decoder with same parameters. ";
544 } 524 }
545 for (int i = 0; i < numStripes; i += 2) { 525 for (int i = 0; i < numStripes; i += 2) {
546 // Read a stripe 526 // Read a stripe
547 const int startY = i * stripeHeight; 527 const int startY = i * stripeHeight;
548 const int linesToRead = SkTMin(stripeHeight, height - startY); 528 const int linesToRead = SkTMin(stripeHeight, height - startY);
549 SkCodec::Result result = decoder->getScanlines(bitmap.getAddr(0, startY), 529 lines = decoder->getScanlines(bitmap.getAddr(0, startY), linesTo Read,
550 linesToRead, bitmap.rowBytes()); 530 bitmap.rowBytes());
551 switch (result) { 531 if (lines < linesToRead) {
552 case SkCodec::kSuccess: 532 return Error::Nonfatal("Image is incomplete, could not get s canlines");
553 case SkCodec::kIncompleteInput:
554 break;
555 default:
556 return SkStringPrintf("Cannot get scanlines for %s.", fP ath.c_str());
557 } 533 }
558 534
559 // Skip a stripe 535 // Skip a stripe
560 const int linesToSkip = SkTMin(stripeHeight, height - (i + 1) * stripeHeight); 536 const int linesToSkip = SkTMin(stripeHeight, height - (i + 1) * stripeHeight);
561 if (linesToSkip > 0) { 537 if (linesToSkip > 0) {
562 result = decoder->skipScanlines(linesToSkip); 538 lines = decoder->skipScanlines(linesToSkip);
563 switch (result) { 539 if (lines < linesToSkip) {
564 case SkCodec::kSuccess: 540 return Error::Nonfatal("Image is incomplete, could not g et scanlines");
565 case SkCodec::kIncompleteInput:
566 break;
567 default:
568 return SkStringPrintf("Cannot skip scanlines for %s. ", fPath.c_str());
569 } 541 }
570 } 542 }
571 } 543 }
572 canvas->drawBitmap(bitmap, 0, 0); 544 canvas->drawBitmap(bitmap, 0, 0);
573 break; 545 break;
574 } 546 }
575 case kSubset_Mode: { 547 case kSubset_Mode: {
576 // Arbitrarily choose a divisor. 548 // Arbitrarily choose a divisor.
577 int divisor = 2; 549 int divisor = 2;
578 // Total width/height of the image. 550 // Total width/height of the image.
(...skipping 683 matching lines...) Expand 10 before | Expand all | Expand 10 after
1262 skr.visit<void>(i, drawsAsSingletonPictures); 1234 skr.visit<void>(i, drawsAsSingletonPictures);
1263 } 1235 }
1264 SkAutoTUnref<SkPicture> macroPic(macroRec.endRecordingAsPicture()); 1236 SkAutoTUnref<SkPicture> macroPic(macroRec.endRecordingAsPicture());
1265 1237
1266 canvas->drawPicture(macroPic); 1238 canvas->drawPicture(macroPic);
1267 return ""; 1239 return "";
1268 }); 1240 });
1269 } 1241 }
1270 1242
1271 } // namespace DM 1243 } // namespace DM
OLDNEW
« no previous file with comments | « no previous file | gyp/tools.gyp » ('j') | include/codec/SkCodec.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698