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" |
11 #include "SkCodecTools.h" | 11 #include "SkCodecTools.h" |
12 #include "SkCommonFlags.h" | 12 #include "SkCommonFlags.h" |
13 #include "SkData.h" | 13 #include "SkData.h" |
14 #include "SkDocument.h" | 14 #include "SkDocument.h" |
15 #include "SkError.h" | 15 #include "SkError.h" |
16 #include "SkFunction.h" | 16 #include "SkFunction.h" |
17 #include "SkImageGenerator.h" | 17 #include "SkImageGenerator.h" |
18 #include "SkMultiPictureDraw.h" | 18 #include "SkMultiPictureDraw.h" |
19 #include "SkNullCanvas.h" | 19 #include "SkNullCanvas.h" |
20 #include "SkOSFile.h" | 20 #include "SkOSFile.h" |
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 "SkScanlineDecoder.h" | |
29 #include "SkStream.h" | 28 #include "SkStream.h" |
30 #include "SkTLogic.h" | 29 #include "SkTLogic.h" |
31 #include "SkXMLWriter.h" | 30 #include "SkXMLWriter.h" |
32 | 31 |
33 DEFINE_bool(multiPage, false, "For document-type backends, render the source" | 32 DEFINE_bool(multiPage, false, "For document-type backends, render the source" |
34 " into multiple pages"); | 33 " into multiple pages"); |
35 | 34 |
36 static bool lazy_decode_bitmap(const void* src, size_t size, SkBitmap* dst) { | 35 static bool lazy_decode_bitmap(const void* src, size_t size, SkBitmap* dst) { |
37 SkAutoTUnref<SkData> encoded(SkData::NewWithCopy(src, size)); | 36 SkAutoTUnref<SkData> encoded(SkData::NewWithCopy(src, size)); |
38 return encoded && SkDEPRECATED_InstallDiscardablePixelRef(encoded, dst); | 37 return encoded && SkDEPRECATED_InstallDiscardablePixelRef(encoded, dst); |
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
231 {} | 230 {} |
232 | 231 |
233 bool CodecSrc::veto(SinkFlags flags) const { | 232 bool CodecSrc::veto(SinkFlags flags) const { |
234 // No need to test decoding to non-raster or indirect backend. | 233 // No need to test decoding to non-raster or indirect backend. |
235 // TODO: Once we implement GPU paths (e.g. JPEG YUV), we should use a deferr
ed decode to | 234 // TODO: Once we implement GPU paths (e.g. JPEG YUV), we should use a deferr
ed decode to |
236 // let the GPU handle it. | 235 // let the GPU handle it. |
237 return flags.type != SinkFlags::kRaster | 236 return flags.type != SinkFlags::kRaster |
238 || flags.approach != SinkFlags::kDirect; | 237 || flags.approach != SinkFlags::kDirect; |
239 } | 238 } |
240 | 239 |
241 SkScanlineDecoder* start_scanline_decoder(SkData* encoded, const SkImageInfo& in
fo, | |
242 SkPMColor* colorPtr, int* colorCountPtr) { | |
243 SkAutoTDelete<SkScanlineDecoder> scanlineDecoder(SkScanlineDecoder::NewFromD
ata(encoded)); | |
244 if (nullptr == scanlineDecoder) { | |
245 return nullptr; | |
246 } | |
247 if (SkCodec::kSuccess != scanlineDecoder->start(info, NULL, colorPtr, colorC
ountPtr)) { | |
248 return nullptr; | |
249 } | |
250 return scanlineDecoder.detach(); | |
251 } | |
252 | |
253 Error CodecSrc::draw(SkCanvas* canvas) const { | 240 Error CodecSrc::draw(SkCanvas* canvas) const { |
254 SkAutoTUnref<SkData> encoded(SkData::NewFromFileName(fPath.c_str())); | 241 SkAutoTUnref<SkData> encoded(SkData::NewFromFileName(fPath.c_str())); |
255 if (!encoded) { | 242 if (!encoded) { |
256 return SkStringPrintf("Couldn't read %s.", fPath.c_str()); | 243 return SkStringPrintf("Couldn't read %s.", fPath.c_str()); |
257 } | 244 } |
258 SkAutoTDelete<SkCodec> codec(NULL); | 245 SkAutoTDelete<SkCodec> codec(NULL); |
259 if (kScaledCodec_Mode == fMode) { | 246 if (kScaledCodec_Mode == fMode) { |
260 codec.reset(SkScaledCodec::NewFromData(encoded)); | 247 codec.reset(SkScaledCodec::NewFromData(encoded)); |
261 // TODO (msarett): This should fall through to a fatal error once we sup
port scaled | 248 // TODO (msarett): This should fall through to a fatal error once we sup
port scaled |
262 // codecs for all image types. | 249 // codecs for all image types. |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
341 case SkCodec::kInvalidConversion: | 328 case SkCodec::kInvalidConversion: |
342 return Error::Nonfatal("Incompatible colortype conversion"); | 329 return Error::Nonfatal("Incompatible colortype conversion"); |
343 default: | 330 default: |
344 // Everything else is considered a failure. | 331 // Everything else is considered a failure. |
345 return SkStringPrintf("Couldn't getPixels %s.", fPath.c_str(
)); | 332 return SkStringPrintf("Couldn't getPixels %s.", fPath.c_str(
)); |
346 } | 333 } |
347 canvas->drawBitmap(bitmap, 0, 0); | 334 canvas->drawBitmap(bitmap, 0, 0); |
348 break; | 335 break; |
349 } | 336 } |
350 case kScanline_Mode: { | 337 case kScanline_Mode: { |
351 SkAutoTDelete<SkScanlineDecoder> scanlineDecoder( | 338 if (SkCodec::kSuccess != codec->startScanlineDecode(decodeInfo, NULL
, colorPtr, |
352 start_scanline_decoder(encoded.get(), decodeInfo, colorPtr,
colorCountPtr)); | 339 colorCountPtr))
{ |
353 if (nullptr == scanlineDecoder) { | |
354 return Error::Nonfatal("Could not start scanline decoder"); | 340 return Error::Nonfatal("Could not start scanline decoder"); |
355 } | 341 } |
356 | 342 |
357 SkCodec::Result result = SkCodec::kUnimplemented; | 343 SkCodec::Result result = SkCodec::kUnimplemented; |
358 switch (scanlineDecoder->getScanlineOrder()) { | 344 switch (codec->getScanlineOrder()) { |
359 case SkScanlineDecoder::kTopDown_SkScanlineOrder: | 345 case SkCodec::kTopDown_SkScanlineOrder: |
360 case SkScanlineDecoder::kBottomUp_SkScanlineOrder: | 346 case SkCodec::kBottomUp_SkScanlineOrder: |
361 case SkScanlineDecoder::kNone_SkScanlineOrder: | 347 case SkCodec::kNone_SkScanlineOrder: |
362 result = scanlineDecoder->getScanlines(bitmap.getAddr(0, 0), | 348 result = codec->getScanlines(bitmap.getAddr(0, 0), |
363 decodeInfo.height(), bitmap.rowBytes()); | 349 decodeInfo.height(), bitmap.rowBytes()); |
364 break; | 350 break; |
365 case SkScanlineDecoder::kOutOfOrder_SkScanlineOrder: { | 351 case SkCodec::kOutOfOrder_SkScanlineOrder: { |
366 for (int y = 0; y < decodeInfo.height(); y++) { | 352 for (int y = 0; y < decodeInfo.height(); y++) { |
367 int dstY = scanlineDecoder->getY(); | 353 int dstY = codec->nextScanline(); |
368 void* dstPtr = bitmap.getAddr(0, dstY); | 354 void* dstPtr = bitmap.getAddr(0, dstY); |
369 result = scanlineDecoder->getScanlines(dstPtr, 1, bitmap
.rowBytes()); | 355 result = codec->getScanlines(dstPtr, 1, bitmap.rowBytes(
)); |
370 if (SkCodec::kSuccess != result && SkCodec::kIncompleteI
nput != result) { | 356 if (SkCodec::kSuccess != result && SkCodec::kIncompleteI
nput != result) { |
371 return SkStringPrintf("%s failed with error message
%d", | 357 return SkStringPrintf("%s failed with error message
%d", |
372 fPath.c_str(), (int) result); | 358 fPath.c_str(), (int) result); |
373 } | 359 } |
374 } | 360 } |
375 break; | 361 break; |
376 } | 362 } |
377 } | 363 } |
378 | 364 |
379 switch (result) { | 365 switch (result) { |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
425 //currentSubsetWidth may be larger than subsetWidth for rightmos
t subsets | 411 //currentSubsetWidth may be larger than subsetWidth for rightmos
t subsets |
426 const int currentSubsetWidth = (col + 1 == divisor) ? | 412 const int currentSubsetWidth = (col + 1 == divisor) ? |
427 subsetWidth + extraX : subsetWidth; | 413 subsetWidth + extraX : subsetWidth; |
428 const int x = col * subsetWidth; | 414 const int x = col * subsetWidth; |
429 for (int row = 0; row < divisor; row++) { | 415 for (int row = 0; row < divisor; row++) { |
430 //currentSubsetHeight may be larger than subsetHeight for bo
ttom subsets | 416 //currentSubsetHeight may be larger than subsetHeight for bo
ttom subsets |
431 const int currentSubsetHeight = (row + 1 == divisor) ? | 417 const int currentSubsetHeight = (row + 1 == divisor) ? |
432 subsetHeight + extraY : subsetHeight; | 418 subsetHeight + extraY : subsetHeight; |
433 const int y = row * subsetHeight; | 419 const int y = row * subsetHeight; |
434 //create scanline decoder for each subset | 420 //create scanline decoder for each subset |
435 SkAutoTDelete<SkScanlineDecoder> decoder(start_scanline_deco
der(encoded.get(), | 421 if (SkCodec::kSuccess != codec->startScanlineDecode(decodeIn
fo, NULL, colorPtr, |
436 decodeInfo, colorPtr, colorCountPtr)); | 422 colorCou
ntPtr) |
437 // TODO (msarett): Support this mode for all scanline orderi
ngs. | 423 // TODO (msarett): Support this mode for all scanlin
e orderings. |
438 if (nullptr == decoder || SkScanlineDecoder::kTopDown_SkScan
lineOrder != | 424 || SkCodec::kTopDown_SkScanlineOrder != codec->getSc
anlineOrder()) { |
439 decoder->getScanlineOrder()) { | |
440 if (x == 0 && y == 0) { | 425 if (x == 0 && y == 0) { |
441 //first try, image may not be compatible | 426 //first try, image may not be compatible |
442 return Error::Nonfatal("Could not start top-down sca
nline decoder"); | 427 return Error::Nonfatal("Could not start top-down sca
nline decoder"); |
443 } else { | 428 } else { |
444 return "Error scanline decoder is nullptr"; | 429 return "Error scanline decoder is nullptr"; |
445 } | 430 } |
446 } | 431 } |
447 //skip to first line of subset | 432 //skip to first line of subset |
448 const SkCodec::Result skipResult = decoder->skipScanlines(y)
; | 433 const SkCodec::Result skipResult = codec->skipScanlines(y); |
449 switch (skipResult) { | 434 switch (skipResult) { |
450 case SkCodec::kSuccess: | 435 case SkCodec::kSuccess: |
451 case SkCodec::kIncompleteInput: | 436 case SkCodec::kIncompleteInput: |
452 break; | 437 break; |
453 default: | 438 default: |
454 return SkStringPrintf("%s failed after attempting to
skip %d scanlines" | 439 return SkStringPrintf("%s failed after attempting to
skip %d scanlines" |
455 "with error message %d", fPath.c_str(), y, (
int) skipResult); | 440 "with error message %d", fPath.c_str(), y, (
int) skipResult); |
456 } | 441 } |
457 //create and set size of subsetBm | 442 //create and set size of subsetBm |
458 SkBitmap subsetBm; | 443 SkBitmap subsetBm; |
459 SkIRect bounds = SkIRect::MakeWH(subsetWidth, subsetHeight); | 444 SkIRect bounds = SkIRect::MakeWH(subsetWidth, subsetHeight); |
460 bounds.setXYWH(0, 0, currentSubsetWidth, currentSubsetHeight
); | 445 bounds.setXYWH(0, 0, currentSubsetWidth, currentSubsetHeight
); |
461 SkAssertResult(largestSubsetBm.extractSubset(&subsetBm, boun
ds)); | 446 SkAssertResult(largestSubsetBm.extractSubset(&subsetBm, boun
ds)); |
462 SkAutoLockPixels autlockSubsetBm(subsetBm, true); | 447 SkAutoLockPixels autlockSubsetBm(subsetBm, true); |
463 const SkCodec::Result subsetResult = | 448 const SkCodec::Result subsetResult = |
464 decoder->getScanlines(buffer, currentSubsetHeight, r
owBytes); | 449 codec->getScanlines(buffer, currentSubsetHeight, row
Bytes); |
465 switch (subsetResult) { | 450 switch (subsetResult) { |
466 case SkCodec::kSuccess: | 451 case SkCodec::kSuccess: |
467 case SkCodec::kIncompleteInput: | 452 case SkCodec::kIncompleteInput: |
468 break; | 453 break; |
469 default: | 454 default: |
470 return SkStringPrintf("%s failed with error message
%d", | 455 return SkStringPrintf("%s failed with error message
%d", |
471 fPath.c_str(), (int) subsetResult); | 456 fPath.c_str(), (int) subsetResult); |
472 } | 457 } |
473 const size_t bpp = decodeInfo.bytesPerPixel(); | 458 const size_t bpp = decodeInfo.bytesPerPixel(); |
474 /* | 459 /* |
(...skipping 19 matching lines...) Expand all Loading... |
494 break; | 479 break; |
495 } | 480 } |
496 case kStripe_Mode: { | 481 case kStripe_Mode: { |
497 const int height = decodeInfo.height(); | 482 const int height = decodeInfo.height(); |
498 // This value is chosen arbitrarily. We exercise more cases by choo
sing a value that | 483 // This value is chosen arbitrarily. We exercise more cases by choo
sing a value that |
499 // does not align with image blocks. | 484 // does not align with image blocks. |
500 const int stripeHeight = 37; | 485 const int stripeHeight = 37; |
501 const int numStripes = (height + stripeHeight - 1) / stripeHeight; | 486 const int numStripes = (height + stripeHeight - 1) / stripeHeight; |
502 | 487 |
503 // Decode odd stripes | 488 // Decode odd stripes |
504 SkAutoTDelete<SkScanlineDecoder> decoder( | 489 if (SkCodec::kSuccess != codec->startScanlineDecode(decodeInfo, NULL
, colorPtr, |
505 start_scanline_decoder(encoded.get(), decodeInfo, colorPtr,
colorCountPtr)); | 490 colorCountPtr) |
506 if (nullptr == decoder || | 491 || SkCodec::kTopDown_SkScanlineOrder != codec->getScanlineOr
der()) { |
507 SkScanlineDecoder::kTopDown_SkScanlineOrder != decoder->getS
canlineOrder()) { | |
508 // 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. |
509 // 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 |
510 // 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. |
511 return Error::Nonfatal("Could not start top-down scanline decode
r"); | 495 return Error::Nonfatal("Could not start top-down scanline decode
r"); |
512 } | 496 } |
513 for (int i = 0; i < numStripes; i += 2) { | 497 for (int i = 0; i < numStripes; i += 2) { |
514 // Skip a stripe | 498 // Skip a stripe |
515 const int linesToSkip = SkTMin(stripeHeight, height - i * stripe
Height); | 499 const int linesToSkip = SkTMin(stripeHeight, height - i * stripe
Height); |
516 SkCodec::Result result = decoder->skipScanlines(linesToSkip); | 500 SkCodec::Result result = codec->skipScanlines(linesToSkip); |
517 switch (result) { | 501 switch (result) { |
518 case SkCodec::kSuccess: | 502 case SkCodec::kSuccess: |
519 case SkCodec::kIncompleteInput: | 503 case SkCodec::kIncompleteInput: |
520 break; | 504 break; |
521 default: | 505 default: |
522 return SkStringPrintf("Cannot skip scanlines for %s.", f
Path.c_str()); | 506 return SkStringPrintf("Cannot skip scanlines for %s.", f
Path.c_str()); |
523 } | 507 } |
524 | 508 |
525 // Read a stripe | 509 // Read a stripe |
526 const int startY = (i + 1) * stripeHeight; | 510 const int startY = (i + 1) * stripeHeight; |
527 const int linesToRead = SkTMin(stripeHeight, height - startY); | 511 const int linesToRead = SkTMin(stripeHeight, height - startY); |
528 if (linesToRead > 0) { | 512 if (linesToRead > 0) { |
529 result = decoder->getScanlines(bitmap.getAddr(0, startY), | 513 result = codec->getScanlines(bitmap.getAddr(0, startY), |
530 linesToRead, bitmap.rowBytes()); | 514 linesToRead, bitmap.rowBytes()); |
531 switch (result) { | 515 switch (result) { |
532 case SkCodec::kSuccess: | 516 case SkCodec::kSuccess: |
533 case SkCodec::kIncompleteInput: | 517 case SkCodec::kIncompleteInput: |
534 break; | 518 break; |
535 default: | 519 default: |
536 return SkStringPrintf("Cannot get scanlines for %s."
, fPath.c_str()); | 520 return SkStringPrintf("Cannot get scanlines for %s."
, fPath.c_str()); |
537 } | 521 } |
538 } | 522 } |
539 } | 523 } |
540 | 524 |
541 // Decode even stripes | 525 // Decode even stripes |
542 const SkCodec::Result startResult = decoder->start(decodeInfo, nullp
tr, colorPtr, | 526 const SkCodec::Result startResult = codec->startScanlineDecode(decod
eInfo, nullptr, |
543 colorCountPtr); | 527 colorPtr, colorCountPtr); |
544 if (SkCodec::kSuccess != startResult) { | 528 if (SkCodec::kSuccess != startResult) { |
545 return "Failed to restart scanline decoder with same parameters.
"; | 529 return "Failed to restart scanline decoder with same parameters.
"; |
546 } | 530 } |
547 for (int i = 0; i < numStripes; i += 2) { | 531 for (int i = 0; i < numStripes; i += 2) { |
548 // Read a stripe | 532 // Read a stripe |
549 const int startY = i * stripeHeight; | 533 const int startY = i * stripeHeight; |
550 const int linesToRead = SkTMin(stripeHeight, height - startY); | 534 const int linesToRead = SkTMin(stripeHeight, height - startY); |
551 SkCodec::Result result = decoder->getScanlines(bitmap.getAddr(0,
startY), | 535 SkCodec::Result result = codec->getScanlines(bitmap.getAddr(0, s
tartY), |
552 linesToRead, bitmap.rowBytes()); | 536 linesToRead, bitmap.rowBytes()); |
553 switch (result) { | 537 switch (result) { |
554 case SkCodec::kSuccess: | 538 case SkCodec::kSuccess: |
555 case SkCodec::kIncompleteInput: | 539 case SkCodec::kIncompleteInput: |
556 break; | 540 break; |
557 default: | 541 default: |
558 return SkStringPrintf("Cannot get scanlines for %s.", fP
ath.c_str()); | 542 return SkStringPrintf("Cannot get scanlines for %s.", fP
ath.c_str()); |
559 } | 543 } |
560 | 544 |
561 // Skip a stripe | 545 // Skip a stripe |
562 const int linesToSkip = SkTMin(stripeHeight, height - (i + 1) *
stripeHeight); | 546 const int linesToSkip = SkTMin(stripeHeight, height - (i + 1) *
stripeHeight); |
563 if (linesToSkip > 0) { | 547 if (linesToSkip > 0) { |
564 result = decoder->skipScanlines(linesToSkip); | 548 result = codec->skipScanlines(linesToSkip); |
565 switch (result) { | 549 switch (result) { |
566 case SkCodec::kSuccess: | 550 case SkCodec::kSuccess: |
567 case SkCodec::kIncompleteInput: | 551 case SkCodec::kIncompleteInput: |
568 break; | 552 break; |
569 default: | 553 default: |
570 return SkStringPrintf("Cannot skip scanlines for %s.
", fPath.c_str()); | 554 return SkStringPrintf("Cannot skip scanlines for %s.
", fPath.c_str()); |
571 } | 555 } |
572 } | 556 } |
573 } | 557 } |
574 canvas->drawBitmap(bitmap, 0, 0); | 558 canvas->drawBitmap(bitmap, 0, 0); |
(...skipping 696 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1271 skr.visit<void>(i, drawsAsSingletonPictures); | 1255 skr.visit<void>(i, drawsAsSingletonPictures); |
1272 } | 1256 } |
1273 SkAutoTUnref<SkPicture> macroPic(macroRec.endRecordingAsPicture()); | 1257 SkAutoTUnref<SkPicture> macroPic(macroRec.endRecordingAsPicture()); |
1274 | 1258 |
1275 canvas->drawPicture(macroPic); | 1259 canvas->drawPicture(macroPic); |
1276 return ""; | 1260 return ""; |
1277 }); | 1261 }); |
1278 } | 1262 } |
1279 | 1263 |
1280 } // namespace DM | 1264 } // namespace DM |
OLD | NEW |