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 10 matching lines...) Expand all Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |