| 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 linesDecoded = 0; |
| 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 linesDecoded = 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 linesDecoded += line; |
| 372 } | 372 } |
| 373 break; | 373 break; |
| 374 } | 374 } |
| 375 } | 375 } |
| 376 | 376 if ((int) linesDecoded < 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 if (!decoder->skipScanlines(y)) { |
| 447 switch (skipResult) { | 445 return Error::Nonfatal("Image is incomplete, could not g
et scanlines"); |
| 448 case SkCodec::kSuccess: | |
| 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 } | 446 } |
| 455 //create and set size of subsetBm | 447 //create and set size of subsetBm |
| 456 SkBitmap subsetBm; | 448 SkBitmap subsetBm; |
| 457 SkIRect bounds = SkIRect::MakeWH(subsetWidth, subsetHeight); | 449 SkIRect bounds = SkIRect::MakeWH(subsetWidth, subsetHeight); |
| 458 bounds.setXYWH(0, 0, currentSubsetWidth, currentSubsetHeight
); | 450 bounds.setXYWH(0, 0, currentSubsetWidth, currentSubsetHeight
); |
| 459 SkAssertResult(largestSubsetBm.extractSubset(&subsetBm, boun
ds)); | 451 SkAssertResult(largestSubsetBm.extractSubset(&subsetBm, boun
ds)); |
| 460 SkAutoLockPixels autlockSubsetBm(subsetBm, true); | 452 SkAutoLockPixels autlockSubsetBm(subsetBm, true); |
| 461 const SkCodec::Result subsetResult = | 453 if ((int) decoder->getScanlines(buffer, currentSubsetHeight,
rowBytes) < |
| 462 decoder->getScanlines(buffer, currentSubsetHeight, r
owBytes); | 454 currentSubsetHeight) { |
| 463 switch (subsetResult) { | 455 return Error::Nonfatal("Image is incomplete, could not g
et scanlines"); |
| 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 } | 456 } |
| 471 const size_t bpp = decodeInfo.bytesPerPixel(); | 457 const size_t bpp = decodeInfo.bytesPerPixel(); |
| 472 /* | 458 /* |
| 473 * we copy all the lines at once becuase when calling getSca
nlines for | 459 * 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 | 460 * 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 | 461 * 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 | 462 * 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 | 463 * 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 | 464 * may be faster for other types of images. Since this is a
correctness test |
| 479 * that's okay. | 465 * that's okay. |
| (...skipping 21 matching lines...) Expand all Loading... |
| 501 // Decode odd stripes | 487 // Decode odd stripes |
| 502 SkAutoTDelete<SkScanlineDecoder> decoder( | 488 SkAutoTDelete<SkScanlineDecoder> decoder( |
| 503 start_scanline_decoder(encoded.get(), decodeInfo, colorPtr,
colorCountPtr)); | 489 start_scanline_decoder(encoded.get(), decodeInfo, colorPtr,
colorCountPtr)); |
| 504 if (nullptr == decoder || | 490 if (nullptr == decoder || |
| 505 SkScanlineDecoder::kTopDown_SkScanlineOrder != decoder->getS
canlineOrder()) { | 491 SkScanlineDecoder::kTopDown_SkScanlineOrder != decoder->getS
canlineOrder()) { |
| 506 // This mode was designed to test the new skip scanlines API in
libjpeg-turbo. | 492 // 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 | 493 // 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. | 494 // 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"); | 495 return Error::Nonfatal("Could not start top-down scanline decode
r"); |
| 510 } | 496 } |
| 497 |
| 511 for (int i = 0; i < numStripes; i += 2) { | 498 for (int i = 0; i < numStripes; i += 2) { |
| 512 // Skip a stripe | 499 // Skip a stripe |
| 513 const int linesToSkip = SkTMin(stripeHeight, height - i * stripe
Height); | 500 const int linesToSkip = SkTMin(stripeHeight, height - i * stripe
Height); |
| 514 SkCodec::Result result = decoder->skipScanlines(linesToSkip); | 501 if (!decoder->skipScanlines(linesToSkip)) { |
| 515 switch (result) { | 502 return Error::Nonfatal("Image is incomplete, could not get s
canlines"); |
| 516 case SkCodec::kSuccess: | |
| 517 case SkCodec::kIncompleteInput: | |
| 518 break; | |
| 519 default: | |
| 520 return SkStringPrintf("Cannot skip scanlines for %s.", f
Path.c_str()); | |
| 521 } | 503 } |
| 522 | 504 |
| 523 // Read a stripe | 505 // Read a stripe |
| 524 const int startY = (i + 1) * stripeHeight; | 506 const int startY = (i + 1) * stripeHeight; |
| 525 const int linesToRead = SkTMin(stripeHeight, height - startY); | 507 const int linesToRead = SkTMin(stripeHeight, height - startY); |
| 526 if (linesToRead > 0) { | 508 if (linesToRead > 0) { |
| 527 result = decoder->getScanlines(bitmap.getAddr(0, startY), | 509 if ((int) decoder->getScanlines(bitmap.getAddr(0, startY), l
inesToRead, |
| 528 linesToRead, bitmap.rowBytes()); | 510 bitmap.rowBytes()) < linesToRead) { |
| 529 switch (result) { | 511 return Error::Nonfatal("Image is incomplete, could not g
et scanlines"); |
| 530 case SkCodec::kSuccess: | |
| 531 case SkCodec::kIncompleteInput: | |
| 532 break; | |
| 533 default: | |
| 534 return SkStringPrintf("Cannot get scanlines for %s."
, fPath.c_str()); | |
| 535 } | 512 } |
| 536 } | 513 } |
| 537 } | 514 } |
| 538 | 515 |
| 539 // Decode even stripes | 516 // Decode even stripes |
| 540 const SkCodec::Result startResult = decoder->start(decodeInfo, nullp
tr, colorPtr, | 517 const SkCodec::Result startResult = decoder->start(decodeInfo, nullp
tr, colorPtr, |
| 541 colorCountPtr); | 518 colorCountPtr); |
| 542 if (SkCodec::kSuccess != startResult) { | 519 if (SkCodec::kSuccess != startResult) { |
| 543 return "Failed to restart scanline decoder with same parameters.
"; | 520 return "Failed to restart scanline decoder with same parameters.
"; |
| 544 } | 521 } |
| 545 for (int i = 0; i < numStripes; i += 2) { | 522 for (int i = 0; i < numStripes; i += 2) { |
| 546 // Read a stripe | 523 // Read a stripe |
| 547 const int startY = i * stripeHeight; | 524 const int startY = i * stripeHeight; |
| 548 const int linesToRead = SkTMin(stripeHeight, height - startY); | 525 const int linesToRead = SkTMin(stripeHeight, height - startY); |
| 549 SkCodec::Result result = decoder->getScanlines(bitmap.getAddr(0,
startY), | 526 if ((int) decoder->getScanlines(bitmap.getAddr(0, startY), lines
ToRead, |
| 550 linesToRead, bitmap.rowBytes()); | 527 bitmap.rowBytes()) < linesToRead) { |
| 551 switch (result) { | 528 return Error::Nonfatal("Image is incomplete, could not get s
canlines"); |
| 552 case SkCodec::kSuccess: | |
| 553 case SkCodec::kIncompleteInput: | |
| 554 break; | |
| 555 default: | |
| 556 return SkStringPrintf("Cannot get scanlines for %s.", fP
ath.c_str()); | |
| 557 } | 529 } |
| 558 | 530 |
| 559 // Skip a stripe | 531 // Skip a stripe |
| 560 const int linesToSkip = SkTMin(stripeHeight, height - (i + 1) *
stripeHeight); | 532 const int linesToSkip = SkTMin(stripeHeight, height - (i + 1) *
stripeHeight); |
| 561 if (linesToSkip > 0) { | 533 if (linesToSkip > 0) { |
| 562 result = decoder->skipScanlines(linesToSkip); | 534 if (!decoder->skipScanlines(linesToSkip)) { |
| 563 switch (result) { | 535 return Error::Nonfatal("Image is incomplete, could not g
et scanlines"); |
| 564 case SkCodec::kSuccess: | |
| 565 case SkCodec::kIncompleteInput: | |
| 566 break; | |
| 567 default: | |
| 568 return SkStringPrintf("Cannot skip scanlines for %s.
", fPath.c_str()); | |
| 569 } | 536 } |
| 570 } | 537 } |
| 571 } | 538 } |
| 572 canvas->drawBitmap(bitmap, 0, 0); | 539 canvas->drawBitmap(bitmap, 0, 0); |
| 573 break; | 540 break; |
| 574 } | 541 } |
| 575 case kSubset_Mode: { | 542 case kSubset_Mode: { |
| 576 // Arbitrarily choose a divisor. | 543 // Arbitrarily choose a divisor. |
| 577 int divisor = 2; | 544 int divisor = 2; |
| 578 // Total width/height of the image. | 545 // 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); | 1229 skr.visit<void>(i, drawsAsSingletonPictures); |
| 1263 } | 1230 } |
| 1264 SkAutoTUnref<SkPicture> macroPic(macroRec.endRecordingAsPicture()); | 1231 SkAutoTUnref<SkPicture> macroPic(macroRec.endRecordingAsPicture()); |
| 1265 | 1232 |
| 1266 canvas->drawPicture(macroPic); | 1233 canvas->drawPicture(macroPic); |
| 1267 return ""; | 1234 return ""; |
| 1268 }); | 1235 }); |
| 1269 } | 1236 } |
| 1270 | 1237 |
| 1271 } // namespace DM | 1238 } // namespace DM |
| OLD | NEW |