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 "Resources.h" | 9 #include "Resources.h" |
10 #include "SkAndroidCodec.h" | 10 #include "SkAndroidCodec.h" |
(...skipping 20 matching lines...) Expand all Loading... |
31 #include "SkPictureRecorder.h" | 31 #include "SkPictureRecorder.h" |
32 #include "SkPipe.h" | 32 #include "SkPipe.h" |
33 #include "SkRandom.h" | 33 #include "SkRandom.h" |
34 #include "SkRecordDraw.h" | 34 #include "SkRecordDraw.h" |
35 #include "SkRecorder.h" | 35 #include "SkRecorder.h" |
36 #include "SkSVGCanvas.h" | 36 #include "SkSVGCanvas.h" |
37 #include "SkStream.h" | 37 #include "SkStream.h" |
38 #include "SkTLogic.h" | 38 #include "SkTLogic.h" |
39 #include "SkSwizzler.h" | 39 #include "SkSwizzler.h" |
40 #include <functional> | 40 #include <functional> |
| 41 #include <cmath> |
41 | 42 |
42 #if defined(SK_BUILD_FOR_WIN) | 43 #if defined(SK_BUILD_FOR_WIN) |
43 #include "SkAutoCoInitialize.h" | 44 #include "SkAutoCoInitialize.h" |
44 #endif | 45 #endif |
45 | 46 |
46 #if defined(SK_TEST_QCMS) | 47 #if defined(SK_TEST_QCMS) |
47 #include "qcms.h" | 48 #include "qcms.h" |
48 #endif | 49 #endif |
49 | 50 |
50 #if defined(SK_XML) | 51 #if defined(SK_XML) |
(...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
426 bitmapInfo = bitmapInfo.makeColorType(kN32_SkColorType); | 427 bitmapInfo = bitmapInfo.makeColorType(kN32_SkColorType); |
427 } | 428 } |
428 | 429 |
429 switch (fMode) { | 430 switch (fMode) { |
430 case kAnimated_Mode: { | 431 case kAnimated_Mode: { |
431 std::vector<SkCodec::FrameInfo> frameInfos = codec->getFrameInfo(); | 432 std::vector<SkCodec::FrameInfo> frameInfos = codec->getFrameInfo(); |
432 if (frameInfos.size() <= 1) { | 433 if (frameInfos.size() <= 1) { |
433 return SkStringPrintf("%s is not an animated image.", fPath.c_st
r()); | 434 return SkStringPrintf("%s is not an animated image.", fPath.c_st
r()); |
434 } | 435 } |
435 | 436 |
436 SkAutoCanvasRestore acr(canvas, true); | 437 // As in CodecSrc::size(), compute a roughly square grid to draw the
frames |
| 438 // into. "factor" is the number of frames to draw on one row. There
will be |
| 439 // up to "factor" rows as well. |
| 440 const float root = sqrt((float) frameInfos.size()); |
| 441 const int factor = sk_float_ceil2int(root); |
| 442 |
437 // Used to cache a frame that future frames will depend on. | 443 // Used to cache a frame that future frames will depend on. |
438 SkAutoMalloc priorFramePixels; | 444 SkAutoMalloc priorFramePixels; |
439 size_t cachedFrame = SkCodec::kNone; | 445 size_t cachedFrame = SkCodec::kNone; |
440 for (size_t i = 0; i < frameInfos.size(); i++) { | 446 for (size_t i = 0; i < frameInfos.size(); i++) { |
441 options.fFrameIndex = i; | 447 options.fFrameIndex = i; |
442 // Check for a prior frame | 448 // Check for a prior frame |
443 const size_t reqFrame = frameInfos[i].fRequiredFrame; | 449 const size_t reqFrame = frameInfos[i].fRequiredFrame; |
444 if (reqFrame != SkCodec::kNone && reqFrame == cachedFrame | 450 if (reqFrame != SkCodec::kNone && reqFrame == cachedFrame |
445 && priorFramePixels.get()) { | 451 && priorFramePixels.get()) { |
446 // Copy into pixels | 452 // Copy into pixels |
447 memcpy(pixels.get(), priorFramePixels.get(), safeSize); | 453 memcpy(pixels.get(), priorFramePixels.get(), safeSize); |
448 options.fHasPriorFrame = true; | 454 options.fHasPriorFrame = true; |
449 } else { | 455 } else { |
450 options.fHasPriorFrame = false; | 456 options.fHasPriorFrame = false; |
451 } | 457 } |
452 const SkCodec::Result result = codec->getPixels(decodeInfo, pixe
ls.get(), | 458 const SkCodec::Result result = codec->getPixels(decodeInfo, pixe
ls.get(), |
453 rowBytes, &optio
ns, | 459 rowBytes, &optio
ns, |
454 colorPtr, &color
Count); | 460 colorPtr, &color
Count); |
455 switch (result) { | 461 switch (result) { |
456 case SkCodec::kSuccess: | 462 case SkCodec::kSuccess: |
457 case SkCodec::kIncompleteInput: | 463 case SkCodec::kIncompleteInput: { |
| 464 SkAutoCanvasRestore acr(canvas, true); |
| 465 const int xTranslate = (i % factor) * decodeInfo.width()
; |
| 466 const int yTranslate = (i / factor) * decodeInfo.height(
); |
| 467 canvas->translate(SkIntToScalar(xTranslate), SkIntToScal
ar(yTranslate)); |
458 draw_to_canvas(canvas, bitmapInfo, pixels.get(), rowByte
s, | 468 draw_to_canvas(canvas, bitmapInfo, pixels.get(), rowByte
s, |
459 colorPtr, colorCount, fDstColorType); | 469 colorPtr, colorCount, fDstColorType); |
460 if (result == SkCodec::kIncompleteInput) { | 470 if (result == SkCodec::kIncompleteInput) { |
461 return ""; | 471 return ""; |
462 } | 472 } |
463 break; | 473 break; |
| 474 } |
464 default: | 475 default: |
465 return SkStringPrintf("Couldn't getPixels for frame %i i
n %s.", | 476 return SkStringPrintf("Couldn't getPixels for frame %i i
n %s.", |
466 i, fPath.c_str()); | 477 i, fPath.c_str()); |
467 } | 478 } |
468 | 479 |
469 // If a future frame depends on this one, store it in priorFrame
. | 480 // If a future frame depends on this one, store it in priorFrame
. |
470 // (Note that if i+1 does *not* depend on i, then no future fram
e can.) | 481 // (Note that if i+1 does *not* depend on i, then no future fram
e can.) |
471 if (i+1 < frameInfos.size() && frameInfos[i+1].fRequiredFrame ==
i) { | 482 if (i+1 < frameInfos.size() && frameInfos[i+1].fRequiredFrame ==
i) { |
472 memcpy(priorFramePixels.reset(safeSize), pixels.get(), safeS
ize); | 483 memcpy(priorFramePixels.reset(safeSize), pixels.get(), safeS
ize); |
473 cachedFrame = i; | 484 cachedFrame = i; |
474 } | 485 } |
475 | |
476 canvas->translate(SkIntToScalar(0), SkIntToScalar(decodeInfo.hei
ght())); | |
477 } | 486 } |
478 break; | 487 break; |
479 } | 488 } |
480 case kCodecZeroInit_Mode: | 489 case kCodecZeroInit_Mode: |
481 case kCodec_Mode: { | 490 case kCodec_Mode: { |
482 switch (codec->getPixels(decodeInfo, pixels.get(), rowBytes, &option
s, | 491 switch (codec->getPixels(decodeInfo, pixels.get(), rowBytes, &option
s, |
483 colorPtr, &colorCount)) { | 492 colorPtr, &colorCount)) { |
484 case SkCodec::kSuccess: | 493 case SkCodec::kSuccess: |
485 // We consider incomplete to be valid, since we should still
decode what is | 494 // We consider incomplete to be valid, since we should still
decode what is |
486 // available. | 495 // available. |
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
705 | 714 |
706 SkISize CodecSrc::size() const { | 715 SkISize CodecSrc::size() const { |
707 sk_sp<SkData> encoded(SkData::MakeFromFileName(fPath.c_str())); | 716 sk_sp<SkData> encoded(SkData::MakeFromFileName(fPath.c_str())); |
708 SkAutoTDelete<SkCodec> codec(SkCodec::NewFromData(encoded)); | 717 SkAutoTDelete<SkCodec> codec(SkCodec::NewFromData(encoded)); |
709 if (nullptr == codec) { | 718 if (nullptr == codec) { |
710 return SkISize::Make(0, 0); | 719 return SkISize::Make(0, 0); |
711 } | 720 } |
712 | 721 |
713 auto imageSize = codec->getScaledDimensions(fScale); | 722 auto imageSize = codec->getScaledDimensions(fScale); |
714 if (fMode == kAnimated_Mode) { | 723 if (fMode == kAnimated_Mode) { |
715 // We'll draw one of each frame, so make it big enough to hold them all. | 724 // We'll draw one of each frame, so make it big enough to hold them all |
| 725 // in a grid. The grid will be roughly square, with "factor" frames per |
| 726 // row and up to "factor" rows. |
716 const size_t count = codec->getFrameInfo().size(); | 727 const size_t count = codec->getFrameInfo().size(); |
717 imageSize.fHeight = imageSize.fHeight * count; | 728 const float root = sqrt((float) count); |
| 729 const int factor = sk_float_ceil2int(root); |
| 730 imageSize.fWidth = imageSize.fWidth * factor; |
| 731 imageSize.fHeight = imageSize.fHeight * sk_float_ceil2int((float) count
/ (float) factor); |
718 } | 732 } |
719 return imageSize; | 733 return imageSize; |
720 } | 734 } |
721 | 735 |
722 Name CodecSrc::name() const { | 736 Name CodecSrc::name() const { |
723 if (1.0f == fScale) { | 737 if (1.0f == fScale) { |
724 Name name = SkOSPath::Basename(fPath.c_str()); | 738 Name name = SkOSPath::Basename(fPath.c_str()); |
725 if (fMode == kAnimated_Mode) { | 739 if (fMode == kAnimated_Mode) { |
726 name.append("_animated"); | 740 name.append("_animated"); |
727 } | 741 } |
(...skipping 1044 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1772 Error err = src.draw(&rec); | 1786 Error err = src.draw(&rec); |
1773 if (!err.isEmpty()) { | 1787 if (!err.isEmpty()) { |
1774 return err; | 1788 return err; |
1775 } | 1789 } |
1776 dl->draw(canvas); | 1790 dl->draw(canvas); |
1777 return check_against_reference(bitmap, src, fSink); | 1791 return check_against_reference(bitmap, src, fSink); |
1778 }); | 1792 }); |
1779 } | 1793 } |
1780 | 1794 |
1781 } // namespace DM | 1795 } // namespace DM |
OLD | NEW |