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

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: Rebase on merged SkCodec and SkScanlineDecoder Created 5 years, 2 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 10 matching lines...) Expand all
21 #include "SkPictureData.h" 21 #include "SkPictureData.h"
22 #include "SkPictureRecorder.h" 22 #include "SkPictureRecorder.h"
23 #include "SkRandom.h" 23 #include "SkRandom.h"
24 #include "SkRecordDraw.h" 24 #include "SkRecordDraw.h"
25 #include "SkRecorder.h" 25 #include "SkRecorder.h"
26 #include "SkSVGCanvas.h" 26 #include "SkSVGCanvas.h"
27 #include "SkScaledCodec.h" 27 #include "SkScaledCodec.h"
28 #include "SkStream.h" 28 #include "SkStream.h"
29 #include "SkTLogic.h" 29 #include "SkTLogic.h"
30 #include "SkXMLWriter.h" 30 #include "SkXMLWriter.h"
31 #include "SkScaledCodec.h"
32 #include "SkSwizzler.h"
31 33
32 DEFINE_bool(multiPage, false, "For document-type backends, render the source" 34 DEFINE_bool(multiPage, false, "For document-type backends, render the source"
33 " into multiple pages"); 35 " into multiple pages");
34 36
35 static bool lazy_decode_bitmap(const void* src, size_t size, SkBitmap* dst) { 37 static bool lazy_decode_bitmap(const void* src, size_t size, SkBitmap* dst) {
36 SkAutoTUnref<SkData> encoded(SkData::NewWithCopy(src, size)); 38 SkAutoTUnref<SkData> encoded(SkData::NewWithCopy(src, size));
37 return encoded && SkDEPRECATED_InstallDiscardablePixelRef(encoded, dst); 39 return encoded && SkDEPRECATED_InstallDiscardablePixelRef(encoded, dst);
38 } 40 }
39 41
40 namespace DM { 42 namespace DM {
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after
333 } 335 }
334 canvas->drawBitmap(bitmap, 0, 0); 336 canvas->drawBitmap(bitmap, 0, 0);
335 break; 337 break;
336 } 338 }
337 case kScanline_Mode: { 339 case kScanline_Mode: {
338 if (SkCodec::kSuccess != codec->startScanlineDecode(decodeInfo, NULL , colorPtr, 340 if (SkCodec::kSuccess != codec->startScanlineDecode(decodeInfo, NULL , colorPtr,
339 colorCountPtr)) { 341 colorCountPtr)) {
340 return Error::Nonfatal("Could not start scanline decoder"); 342 return Error::Nonfatal("Could not start scanline decoder");
341 } 343 }
342 344
343 SkCodec::Result result = SkCodec::kUnimplemented; 345 void* dst = bitmap.getAddr(0, 0);
346 size_t rowBytes = bitmap.rowBytes();
347 uint32_t height = decodeInfo.height();
344 switch (codec->getScanlineOrder()) { 348 switch (codec->getScanlineOrder()) {
345 case SkCodec::kTopDown_SkScanlineOrder: 349 case SkCodec::kTopDown_SkScanlineOrder:
346 case SkCodec::kBottomUp_SkScanlineOrder: 350 case SkCodec::kBottomUp_SkScanlineOrder:
347 case SkCodec::kNone_SkScanlineOrder: 351 case SkCodec::kNone_SkScanlineOrder:
348 result = codec->getScanlines(bitmap.getAddr(0, 0), 352 codec->getScanlines(dst, height, rowBytes);
msarett 2015/10/01 12:44:52 getScanlines() now fills when it cannot get all of
349 decodeInfo.height(), bitmap.rowBytes());
350 break; 353 break;
351 case SkCodec::kOutOfOrder_SkScanlineOrder: { 354 case SkCodec::kOutOfOrder_SkScanlineOrder: {
352 for (int y = 0; y < decodeInfo.height(); y++) { 355 for (int y = 0; y < decodeInfo.height(); y++) {
353 int dstY = codec->nextScanline(); 356 int dstY = codec->nextScanline(y);
354 void* dstPtr = bitmap.getAddr(0, dstY); 357 void* dstPtr = bitmap.getAddr(0, dstY);
355 result = codec->getScanlines(dstPtr, 1, bitmap.rowBytes( )); 358 codec->getScanlines(dstPtr, 1, bitmap.rowBytes());
scroggo 2015/10/01 14:48:31 Don't we want to break out of the loop if 0 is ret
msarett 2015/10/01 18:14:13 We could do that. But then we need to iterate ove
scroggo 2015/10/01 20:48:57 Oh yeah, now I remember talking about this, but I
msarett 2015/10/01 22:34:51 Acknowledged.
356 if (SkCodec::kSuccess != result && SkCodec::kIncompleteI nput != result) {
357 return SkStringPrintf("%s failed with error message %d",
358 fPath.c_str(), (int) result);
359 }
360 } 359 }
361 break; 360 break;
362 } 361 }
363 } 362 }
364 363
365 switch (result) {
366 case SkCodec::kSuccess:
367 case SkCodec::kIncompleteInput:
368 break;
369 default:
370 return SkStringPrintf("%s failed with error message %d",
371 fPath.c_str(), (int) result);
372 }
373 canvas->drawBitmap(bitmap, 0, 0); 364 canvas->drawBitmap(bitmap, 0, 0);
374 break; 365 break;
375 } 366 }
376 case kScanline_Subset_Mode: { 367 case kScanline_Subset_Mode: {
377 //this mode decodes the image in divisor*divisor subsets, using a sc anline decoder 368 //this mode decodes the image in divisor*divisor subsets, using a sc anline decoder
378 const int divisor = 2; 369 const int divisor = 2;
379 const int w = decodeInfo.width(); 370 const int w = decodeInfo.width();
380 const int h = decodeInfo.height(); 371 const int h = decodeInfo.height();
381 if (divisor > w || divisor > h) { 372 if (divisor > w || divisor > h) {
382 return Error::Nonfatal(SkStringPrintf("Cannot decode subset: div isor %d is too big" 373 return Error::Nonfatal(SkStringPrintf("Cannot decode subset: div isor %d is too big"
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
423 // TODO (msarett): Support this mode for all scanlin e orderings. 414 // TODO (msarett): Support this mode for all scanlin e orderings.
424 || SkCodec::kTopDown_SkScanlineOrder != codec->getSc anlineOrder()) { 415 || SkCodec::kTopDown_SkScanlineOrder != codec->getSc anlineOrder()) {
425 if (x == 0 && y == 0) { 416 if (x == 0 && y == 0) {
426 //first try, image may not be compatible 417 //first try, image may not be compatible
427 return Error::Nonfatal("Could not start top-down sca nline decoder"); 418 return Error::Nonfatal("Could not start top-down sca nline decoder");
428 } else { 419 } else {
429 return "Error scanline decoder is nullptr"; 420 return "Error scanline decoder is nullptr";
430 } 421 }
431 } 422 }
432 //skip to first line of subset 423 //skip to first line of subset
433 const SkCodec::Result skipResult = codec->skipScanlines(y); 424 if (!codec->skipScanlines(y)) {
434 switch (skipResult) { 425 return Error::Nonfatal("Image is incomplete, could not g et scanlines");
scroggo 2015/10/01 14:48:31 Since we've returned an error, we will not be able
msarett 2015/10/01 18:14:13 Yeah the way the test is written now, we will only
435 case SkCodec::kSuccess:
436 case SkCodec::kIncompleteInput:
437 break;
438 default:
439 return SkStringPrintf("%s failed after attempting to skip %d scanlines"
440 "with error message %d", fPath.c_str(), y, ( int) skipResult);
441 } 426 }
427
442 //create and set size of subsetBm 428 //create and set size of subsetBm
443 SkBitmap subsetBm; 429 SkBitmap subsetBm;
444 SkIRect bounds = SkIRect::MakeWH(subsetWidth, subsetHeight); 430 SkIRect bounds = SkIRect::MakeWH(subsetWidth, subsetHeight);
445 bounds.setXYWH(0, 0, currentSubsetWidth, currentSubsetHeight ); 431 bounds.setXYWH(0, 0, currentSubsetWidth, currentSubsetHeight );
446 SkAssertResult(largestSubsetBm.extractSubset(&subsetBm, boun ds)); 432 SkAssertResult(largestSubsetBm.extractSubset(&subsetBm, boun ds));
447 SkAutoLockPixels autlockSubsetBm(subsetBm, true); 433 SkAutoLockPixels autlockSubsetBm(subsetBm, true);
448 const SkCodec::Result subsetResult = 434 codec->getScanlines(buffer, currentSubsetHeight, rowBytes);
scroggo 2015/10/01 14:48:31 Note that you do something different if skipScanli
msarett 2015/10/01 18:14:13 Acknowledged.
449 codec->getScanlines(buffer, currentSubsetHeight, row Bytes); 435
450 switch (subsetResult) {
451 case SkCodec::kSuccess:
452 case SkCodec::kIncompleteInput:
453 break;
454 default:
455 return SkStringPrintf("%s failed with error message %d",
456 fPath.c_str(), (int) subsetResult);
457 }
458 const size_t bpp = decodeInfo.bytesPerPixel(); 436 const size_t bpp = decodeInfo.bytesPerPixel();
459 /* 437 /*
460 * we copy all the lines at once becuase when calling getSca nlines for 438 * we copy all the lines at once becuase when calling getSca nlines for
scroggo 2015/10/01 14:48:31 This isn't due to your CL, but it seems like this
msarett 2015/10/01 18:14:13 Yeah I'm a bit confused by this comment. Removing
461 * interlaced pngs the entire image must be read regardless of the number 439 * interlaced pngs the entire image must be read regardless of the number
462 * of lines requested. Reading an interlaced png in a loop, line-by-line, would 440 * of lines requested. Reading an interlaced png in a loop, line-by-line, would
463 * decode the entire image height times, which is very slow 441 * decode the entire image height times, which is very slow
464 * it is aknowledged that copying each line as you read it i n a loop 442 * it is aknowledged that copying each line as you read it i n a loop
465 * may be faster for other types of images. Since this is a correctness test 443 * may be faster for other types of images. Since this is a correctness test
466 * that's okay. 444 * that's okay.
467 */ 445 */
468 char* bufferRow = buffer; 446 char* bufferRow = buffer;
469 for (int subsetY = 0; subsetY < currentSubsetHeight; ++subse tY) { 447 for (int subsetY = 0; subsetY < currentSubsetHeight; ++subse tY) {
470 memcpy(subsetBm.getAddr(0, subsetY), bufferRow + x*bpp, 448 memcpy(subsetBm.getAddr(0, subsetY), bufferRow + x*bpp,
(...skipping 16 matching lines...) Expand all
487 465
488 // Decode odd stripes 466 // Decode odd stripes
489 if (SkCodec::kSuccess != codec->startScanlineDecode(decodeInfo, NULL , colorPtr, 467 if (SkCodec::kSuccess != codec->startScanlineDecode(decodeInfo, NULL , colorPtr,
490 colorCountPtr) 468 colorCountPtr)
491 || SkCodec::kTopDown_SkScanlineOrder != codec->getScanlineOr der()) { 469 || SkCodec::kTopDown_SkScanlineOrder != codec->getScanlineOr der()) {
492 // This mode was designed to test the new skip scanlines API in libjpeg-turbo. 470 // This mode was designed to test the new skip scanlines API in libjpeg-turbo.
493 // Jpegs have kTopDown_SkScanlineOrder, and at this time, it is not interesting 471 // Jpegs have kTopDown_SkScanlineOrder, and at this time, it is not interesting
494 // to run this test for image types that do not have this scanli ne ordering. 472 // to run this test for image types that do not have this scanli ne ordering.
495 return Error::Nonfatal("Could not start top-down scanline decode r"); 473 return Error::Nonfatal("Could not start top-down scanline decode r");
496 } 474 }
475
497 for (int i = 0; i < numStripes; i += 2) { 476 for (int i = 0; i < numStripes; i += 2) {
498 // Skip a stripe 477 // Skip a stripe
499 const int linesToSkip = SkTMin(stripeHeight, height - i * stripe Height); 478 const int linesToSkip = SkTMin(stripeHeight, height - i * stripe Height);
500 SkCodec::Result result = codec->skipScanlines(linesToSkip); 479 if (!codec->skipScanlines(linesToSkip)) {
501 switch (result) { 480 return Error::Nonfatal("Image is incomplete, could not get s canlines");
scroggo 2015/10/01 14:48:31 Not only was the image incomplete, but it was so i
msarett 2015/10/01 18:14:13 This could be improved as well.
502 case SkCodec::kSuccess:
503 case SkCodec::kIncompleteInput:
504 break;
505 default:
506 return SkStringPrintf("Cannot skip scanlines for %s.", f Path.c_str());
507 } 481 }
508 482
509 // Read a stripe 483 // Read a stripe
510 const int startY = (i + 1) * stripeHeight; 484 const int startY = (i + 1) * stripeHeight;
511 const int linesToRead = SkTMin(stripeHeight, height - startY); 485 const int linesToRead = SkTMin(stripeHeight, height - startY);
512 if (linesToRead > 0) { 486 if (linesToRead > 0) {
513 result = codec->getScanlines(bitmap.getAddr(0, startY), 487 if ((int) codec->getScanlines(bitmap.getAddr(0, startY), lin esToRead,
514 linesToRead, bitmap.rowBytes()); 488 bitmap.rowBytes()) < linesToRead) {
515 switch (result) { 489 return Error::Nonfatal("Image is incomplete, could not g et scanlines");
516 case SkCodec::kSuccess:
517 case SkCodec::kIncompleteInput:
518 break;
519 default:
520 return SkStringPrintf("Cannot get scanlines for %s." , fPath.c_str());
521 } 490 }
522 } 491 }
523 } 492 }
524 493
525 // Decode even stripes 494 // Decode even stripes
526 const SkCodec::Result startResult = codec->startScanlineDecode(decod eInfo, nullptr, 495 const SkCodec::Result startResult = codec->startScanlineDecode(decod eInfo, nullptr,
527 colorPtr, colorCountPtr); 496 colorPtr, colorCountPtr);
528 if (SkCodec::kSuccess != startResult) { 497 if (SkCodec::kSuccess != startResult) {
529 return "Failed to restart scanline decoder with same parameters. "; 498 return "Failed to restart scanline decoder with same parameters. ";
530 } 499 }
531 for (int i = 0; i < numStripes; i += 2) { 500 for (int i = 0; i < numStripes; i += 2) {
532 // Read a stripe 501 // Read a stripe
533 const int startY = i * stripeHeight; 502 const int startY = i * stripeHeight;
534 const int linesToRead = SkTMin(stripeHeight, height - startY); 503 const int linesToRead = SkTMin(stripeHeight, height - startY);
535 SkCodec::Result result = codec->getScanlines(bitmap.getAddr(0, s tartY), 504 if ((int) codec->getScanlines(bitmap.getAddr(0, startY), linesTo Read,
536 linesToRead, bitmap.rowBytes()); 505 bitmap.rowBytes()) < linesToRead) {
537 switch (result) { 506 return Error::Nonfatal("Image is incomplete, could not get s canlines");
538 case SkCodec::kSuccess:
539 case SkCodec::kIncompleteInput:
540 break;
541 default:
542 return SkStringPrintf("Cannot get scanlines for %s.", fP ath.c_str());
543 } 507 }
544 508
545 // Skip a stripe 509 // Skip a stripe
546 const int linesToSkip = SkTMin(stripeHeight, height - (i + 1) * stripeHeight); 510 const int linesToSkip = SkTMin(stripeHeight, height - (i + 1) * stripeHeight);
547 if (linesToSkip > 0) { 511 if (linesToSkip > 0) {
548 result = codec->skipScanlines(linesToSkip); 512 if (!codec->skipScanlines(linesToSkip)) {
549 switch (result) { 513 return Error::Nonfatal("Image is incomplete, could not g et scanlines");
550 case SkCodec::kSuccess:
551 case SkCodec::kIncompleteInput:
552 break;
553 default:
554 return SkStringPrintf("Cannot skip scanlines for %s. ", fPath.c_str());
555 } 514 }
556 } 515 }
557 } 516 }
558 canvas->drawBitmap(bitmap, 0, 0); 517 canvas->drawBitmap(bitmap, 0, 0);
559 break; 518 break;
560 } 519 }
561 case kSubset_Mode: { 520 case kSubset_Mode: {
562 // Arbitrarily choose a divisor. 521 // Arbitrarily choose a divisor.
563 int divisor = 2; 522 int divisor = 2;
564 // Total width/height of the image. 523 // Total width/height of the image.
(...skipping 690 matching lines...) Expand 10 before | Expand all | Expand 10 after
1255 skr.visit<void>(i, drawsAsSingletonPictures); 1214 skr.visit<void>(i, drawsAsSingletonPictures);
1256 } 1215 }
1257 SkAutoTUnref<SkPicture> macroPic(macroRec.endRecordingAsPicture()); 1216 SkAutoTUnref<SkPicture> macroPic(macroRec.endRecordingAsPicture());
1258 1217
1259 canvas->drawPicture(macroPic); 1218 canvas->drawPicture(macroPic);
1260 return ""; 1219 return "";
1261 }); 1220 });
1262 } 1221 }
1263 1222
1264 } // namespace DM 1223 } // 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