OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |