OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2013 Google Inc. | 2 * Copyright 2013 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 "Resources.h" | 8 #include "Resources.h" |
9 #include "SkBitmap.h" | 9 #include "SkBitmap.h" |
10 #include "SkCanvas.h" | 10 #include "SkCanvas.h" |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
80 SkBitmap bm8888Unpremul; | 80 SkBitmap bm8888Unpremul; |
81 | 81 |
82 SkFILEStream stream(filename.c_str()); | 82 SkFILEStream stream(filename.c_str()); |
83 | 83 |
84 SkImageDecoder::Format format = SkImageDecoder::GetStreamFormat(&stream); | 84 SkImageDecoder::Format format = SkImageDecoder::GetStreamFormat(&stream); |
85 if (skip_image_format(format)) { | 85 if (skip_image_format(format)) { |
86 return; | 86 return; |
87 } | 87 } |
88 | 88 |
89 SkAutoTDelete<SkImageDecoder> decoder(SkImageDecoder::Factory(&stream)); | 89 SkAutoTDelete<SkImageDecoder> decoder(SkImageDecoder::Factory(&stream)); |
90 if (NULL == decoder.get()) { | 90 if (nullptr == decoder.get()) { |
91 SkDebugf("couldn't decode %s\n", filename.c_str()); | 91 SkDebugf("couldn't decode %s\n", filename.c_str()); |
92 return; | 92 return; |
93 } | 93 } |
94 | 94 |
95 bool success = decoder->decode(&stream, &bm8888, kN32_SkColorType, | 95 bool success = decoder->decode(&stream, &bm8888, kN32_SkColorType, |
96 SkImageDecoder::kDecodePixels_Mode) != SkImag
eDecoder::kFailure; | 96 SkImageDecoder::kDecodePixels_Mode) != SkImag
eDecoder::kFailure; |
97 if (!success) { | 97 if (!success) { |
98 return; | 98 return; |
99 } | 99 } |
100 | 100 |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
169 } | 169 } |
170 | 170 |
171 #if defined(SK_BUILD_FOR_ANDROID) || defined(SK_BUILD_FOR_UNIX) | 171 #if defined(SK_BUILD_FOR_ANDROID) || defined(SK_BUILD_FOR_UNIX) |
172 // Test that the alpha type is what we expect. | 172 // Test that the alpha type is what we expect. |
173 static void test_alphaType(skiatest::Reporter* reporter, const SkString& filenam
e, | 173 static void test_alphaType(skiatest::Reporter* reporter, const SkString& filenam
e, |
174 bool requireUnpremul) { | 174 bool requireUnpremul) { |
175 SkBitmap bm; | 175 SkBitmap bm; |
176 SkFILEStream stream(filename.c_str()); | 176 SkFILEStream stream(filename.c_str()); |
177 | 177 |
178 SkAutoTDelete<SkImageDecoder> decoder(SkImageDecoder::Factory(&stream)); | 178 SkAutoTDelete<SkImageDecoder> decoder(SkImageDecoder::Factory(&stream)); |
179 if (NULL == decoder.get()) { | 179 if (nullptr == decoder.get()) { |
180 return; | 180 return; |
181 } | 181 } |
182 | 182 |
183 decoder->setRequireUnpremultipliedColors(requireUnpremul); | 183 decoder->setRequireUnpremultipliedColors(requireUnpremul); |
184 | 184 |
185 // Decode just the bounds. This should always succeed. | 185 // Decode just the bounds. This should always succeed. |
186 bool success = decoder->decode(&stream, &bm, kN32_SkColorType, | 186 bool success = decoder->decode(&stream, &bm, kN32_SkColorType, |
187 SkImageDecoder::kDecodeBounds_Mode); | 187 SkImageDecoder::kDecodeBounds_Mode); |
188 REPORTER_ASSERT(reporter, success); | 188 REPORTER_ASSERT(reporter, success); |
189 if (!success) { | 189 if (!success) { |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
274 | 274 |
275 if (!stream.isValid()) { | 275 if (!stream.isValid()) { |
276 SkDebugf("file %s missing from resource directoy %s\n", | 276 SkDebugf("file %s missing from resource directoy %s\n", |
277 basename.c_str(), resourcePath.c_str()); | 277 basename.c_str(), resourcePath.c_str()); |
278 continue; | 278 continue; |
279 } | 279 } |
280 | 280 |
281 // This should never fail since we know the images we're decoding. | 281 // This should never fail since we know the images we're decoding. |
282 SkAutoTDelete<SkImageDecoder> decoder(SkImageDecoder::Factory(&stream)); | 282 SkAutoTDelete<SkImageDecoder> decoder(SkImageDecoder::Factory(&stream)); |
283 REPORTER_ASSERT(reporter, decoder.get()); | 283 REPORTER_ASSERT(reporter, decoder.get()); |
284 if (NULL == decoder.get()) { | 284 if (nullptr == decoder.get()) { |
285 continue; | 285 continue; |
286 } | 286 } |
287 | 287 |
288 // Test unpremultiplied. We know what color this should result in. | 288 // Test unpremultiplied. We know what color this should result in. |
289 decoder->setRequireUnpremultipliedColors(true); | 289 decoder->setRequireUnpremultipliedColors(true); |
290 bool success = decoder->decode(&stream, &bm, kN32_SkColorType, | 290 bool success = decoder->decode(&stream, &bm, kN32_SkColorType, |
291 SkImageDecoder::kDecodePixels_Mode); | 291 SkImageDecoder::kDecodePixels_Mode); |
292 REPORTER_ASSERT(reporter, success); | 292 REPORTER_ASSERT(reporter, success); |
293 if (!success) { | 293 if (!success) { |
294 continue; | 294 continue; |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
417 REPORTER_ASSERT(reporter, !error); | 417 REPORTER_ASSERT(reporter, !error); |
418 } | 418 } |
419 } | 419 } |
420 | 420 |
421 //////////////////////////////////////////////////////////////////////////////// | 421 //////////////////////////////////////////////////////////////////////////////// |
422 | 422 |
423 // example of how Android will do this inside their BitmapFactory | 423 // example of how Android will do this inside their BitmapFactory |
424 static SkPixelRef* install_pixel_ref(SkBitmap* bitmap, | 424 static SkPixelRef* install_pixel_ref(SkBitmap* bitmap, |
425 SkStreamRewindable* stream, | 425 SkStreamRewindable* stream, |
426 int sampleSize, bool ditherImage) { | 426 int sampleSize, bool ditherImage) { |
427 SkASSERT(bitmap != NULL); | 427 SkASSERT(bitmap != nullptr); |
428 SkASSERT(stream != NULL); | 428 SkASSERT(stream != nullptr); |
429 SkASSERT(stream->rewind()); | 429 SkASSERT(stream->rewind()); |
430 SkColorType colorType = bitmap->colorType(); | 430 SkColorType colorType = bitmap->colorType(); |
431 SkDecodingImageGenerator::Options opts(sampleSize, ditherImage, colorType); | 431 SkDecodingImageGenerator::Options opts(sampleSize, ditherImage, colorType); |
432 if (SkInstallDiscardablePixelRef( | 432 if (SkInstallDiscardablePixelRef( |
433 SkDecodingImageGenerator::Create(stream, opts), bitmap)) { | 433 SkDecodingImageGenerator::Create(stream, opts), bitmap)) { |
434 return bitmap->pixelRef(); | 434 return bitmap->pixelRef(); |
435 } | 435 } |
436 return NULL; | 436 return nullptr; |
437 } | 437 } |
438 /** | 438 /** |
439 * A test for the SkDecodingImageGenerator::Create and | 439 * A test for the SkDecodingImageGenerator::Create and |
440 * SkInstallDiscardablePixelRef functions. | 440 * SkInstallDiscardablePixelRef functions. |
441 */ | 441 */ |
442 DEF_TEST(ImprovedBitmapFactory, reporter) { | 442 DEF_TEST(ImprovedBitmapFactory, reporter) { |
443 SkString pngFilename = GetResourcePath("randPixels.png"); | 443 SkString pngFilename = GetResourcePath("randPixels.png"); |
444 SkAutoTDelete<SkStreamRewindable> stream(SkStream::NewFromFile(pngFilename.c
_str())); | 444 SkAutoTDelete<SkStreamRewindable> stream(SkStream::NewFromFile(pngFilename.c
_str())); |
445 if (sk_exists(pngFilename.c_str())) { | 445 if (sk_exists(pngFilename.c_str())) { |
446 SkBitmap bm; | 446 SkBitmap bm; |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
508 */ | 508 */ |
509 static void test_options(skiatest::Reporter* reporter, | 509 static void test_options(skiatest::Reporter* reporter, |
510 const SkDecodingImageGenerator::Options& opts, | 510 const SkDecodingImageGenerator::Options& opts, |
511 SkStreamRewindable* encodedStream, | 511 SkStreamRewindable* encodedStream, |
512 SkData* encodedData, | 512 SkData* encodedData, |
513 bool useData, | 513 bool useData, |
514 const SkString& path) { | 514 const SkString& path) { |
515 SkBitmap bm; | 515 SkBitmap bm; |
516 bool success = false; | 516 bool success = false; |
517 if (useData) { | 517 if (useData) { |
518 if (NULL == encodedData) { | 518 if (nullptr == encodedData) { |
519 return; | 519 return; |
520 } | 520 } |
521 success = SkInstallDiscardablePixelRef( | 521 success = SkInstallDiscardablePixelRef( |
522 SkDecodingImageGenerator::Create(encodedData, opts), &bm); | 522 SkDecodingImageGenerator::Create(encodedData, opts), &bm); |
523 } else { | 523 } else { |
524 if (NULL == encodedStream) { | 524 if (nullptr == encodedStream) { |
525 return; | 525 return; |
526 } | 526 } |
527 success = SkInstallDiscardablePixelRef( | 527 success = SkInstallDiscardablePixelRef( |
528 SkDecodingImageGenerator::Create(encodedStream->duplicate(), opts),
&bm); | 528 SkDecodingImageGenerator::Create(encodedStream->duplicate(), opts),
&bm); |
529 } | 529 } |
530 if (!success) { | 530 if (!success) { |
531 if (opts.fUseRequestedColorType | 531 if (opts.fUseRequestedColorType |
532 && (kARGB_4444_SkColorType == opts.fRequestedColorType)) { | 532 && (kARGB_4444_SkColorType == opts.fRequestedColorType)) { |
533 return; // Ignore known conversion inabilities. | 533 return; // Ignore known conversion inabilities. |
534 } | 534 } |
(...skipping 12 matching lines...) Expand all Loading... |
547 opts.fSampleSize)); | 547 opts.fSampleSize)); |
548 REPORTER_ASSERT(reporter, check_rounding(bm.width(), kExpectedWidth, | 548 REPORTER_ASSERT(reporter, check_rounding(bm.width(), kExpectedWidth, |
549 opts.fSampleSize)); | 549 opts.fSampleSize)); |
550 // The ImageDecoder API doesn't guarantee that SampleSize does | 550 // The ImageDecoder API doesn't guarantee that SampleSize does |
551 // anything at all, but the decoders that this test excercises all | 551 // anything at all, but the decoders that this test excercises all |
552 // produce an output size in the following range: | 552 // produce an output size in the following range: |
553 // (((sample_size * out_size) > (in_size - sample_size)) | 553 // (((sample_size * out_size) > (in_size - sample_size)) |
554 // && out_size <= SkNextPow2(((in_size - 1) / sample_size) + 1)); | 554 // && out_size <= SkNextPow2(((in_size - 1) / sample_size) + 1)); |
555 #endif // SK_BUILD_FOR_ANDROID || SK_BUILD_FOR_UNIX | 555 #endif // SK_BUILD_FOR_ANDROID || SK_BUILD_FOR_UNIX |
556 SkAutoLockPixels alp(bm); | 556 SkAutoLockPixels alp(bm); |
557 if (bm.getPixels() == NULL) { | 557 if (bm.getPixels() == nullptr) { |
558 ERRORF(reporter, "Pixel decode failed [sampleSize=%d dither=%s " | 558 ERRORF(reporter, "Pixel decode failed [sampleSize=%d dither=%s " |
559 "colorType=%s %s]", opts.fSampleSize, yn(opts.fDitherImage), | 559 "colorType=%s %s]", opts.fSampleSize, yn(opts.fDitherImage), |
560 options_colorType(opts), path.c_str()); | 560 options_colorType(opts), path.c_str()); |
561 return; | 561 return; |
562 } | 562 } |
563 | 563 |
564 SkColorType requestedColorType = opts.fRequestedColorType; | 564 SkColorType requestedColorType = opts.fRequestedColorType; |
565 REPORTER_ASSERT(reporter, | 565 REPORTER_ASSERT(reporter, |
566 (!opts.fUseRequestedColorType) | 566 (!opts.fUseRequestedColorType) |
567 || (bm.colorType() == requestedColorType)); | 567 || (bm.colorType() == requestedColorType)); |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
628 }; | 628 }; |
629 const bool useDataList[] = {true, false}; | 629 const bool useDataList[] = {true, false}; |
630 | 630 |
631 for (size_t fidx = 0; fidx < SK_ARRAY_COUNT(files); ++fidx) { | 631 for (size_t fidx = 0; fidx < SK_ARRAY_COUNT(files); ++fidx) { |
632 SkString path = SkOSPath::Join(resourceDir.c_str(), files[fidx]); | 632 SkString path = SkOSPath::Join(resourceDir.c_str(), files[fidx]); |
633 if (!sk_exists(path.c_str())) { | 633 if (!sk_exists(path.c_str())) { |
634 continue; | 634 continue; |
635 } | 635 } |
636 | 636 |
637 SkAutoDataUnref encodedData(SkData::NewFromFileName(path.c_str())); | 637 SkAutoDataUnref encodedData(SkData::NewFromFileName(path.c_str())); |
638 REPORTER_ASSERT(reporter, encodedData.get() != NULL); | 638 REPORTER_ASSERT(reporter, encodedData.get() != nullptr); |
639 SkAutoTDelete<SkStreamRewindable> encodedStream( | 639 SkAutoTDelete<SkStreamRewindable> encodedStream( |
640 SkStream::NewFromFile(path.c_str())); | 640 SkStream::NewFromFile(path.c_str())); |
641 REPORTER_ASSERT(reporter, encodedStream.get() != NULL); | 641 REPORTER_ASSERT(reporter, encodedStream.get() != nullptr); |
642 | 642 |
643 for (size_t i = 0; i < SK_ARRAY_COUNT(scaleList); ++i) { | 643 for (size_t i = 0; i < SK_ARRAY_COUNT(scaleList); ++i) { |
644 for (size_t j = 0; j < SK_ARRAY_COUNT(ditherList); ++j) { | 644 for (size_t j = 0; j < SK_ARRAY_COUNT(ditherList); ++j) { |
645 for (size_t m = 0; m < SK_ARRAY_COUNT(useDataList); ++m) { | 645 for (size_t m = 0; m < SK_ARRAY_COUNT(useDataList); ++m) { |
646 for (size_t k = 0; k < SK_ARRAY_COUNT(colorList); ++k) { | 646 for (size_t k = 0; k < SK_ARRAY_COUNT(colorList); ++k) { |
647 SkDecodingImageGenerator::Options opts(scaleList[i], | 647 SkDecodingImageGenerator::Options opts(scaleList[i], |
648 ditherList[j], | 648 ditherList[j], |
649 colorList[k]); | 649 colorList[k]); |
650 test_options(reporter, opts, encodedStream, encodedData, | 650 test_options(reporter, opts, encodedStream, encodedData, |
651 useDataList[m], path); | 651 useDataList[m], path); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
695 namespace { | 695 namespace { |
696 class SingleAllocator : public SkBitmap::Allocator { | 696 class SingleAllocator : public SkBitmap::Allocator { |
697 public: | 697 public: |
698 SingleAllocator(void* p, size_t s) : fPixels(p), fSize(s) { } | 698 SingleAllocator(void* p, size_t s) : fPixels(p), fSize(s) { } |
699 ~SingleAllocator() {} | 699 ~SingleAllocator() {} |
700 // If the pixels in fPixels are big enough, use them. | 700 // If the pixels in fPixels are big enough, use them. |
701 bool allocPixelRef(SkBitmap* bm, SkColorTable* ct) override { | 701 bool allocPixelRef(SkBitmap* bm, SkColorTable* ct) override { |
702 SkASSERT(bm); | 702 SkASSERT(bm); |
703 if (bm->info().getSafeSize(bm->rowBytes()) <= fSize) { | 703 if (bm->info().getSafeSize(bm->rowBytes()) <= fSize) { |
704 bm->setPixels(fPixels, ct); | 704 bm->setPixels(fPixels, ct); |
705 fPixels = NULL; | 705 fPixels = nullptr; |
706 fSize = 0; | 706 fSize = 0; |
707 return true; | 707 return true; |
708 } | 708 } |
709 return bm->tryAllocPixels(NULL, ct); | 709 return bm->tryAllocPixels(nullptr, ct); |
710 } | 710 } |
711 bool ready() { return fPixels != NULL; } | 711 bool ready() { return fPixels != nullptr; } |
712 private: | 712 private: |
713 void* fPixels; | 713 void* fPixels; |
714 size_t fSize; | 714 size_t fSize; |
715 }; | 715 }; |
716 } // namespace | 716 } // namespace |
717 | 717 |
718 /* This tests for a bug in libjpeg where INT32 is typedefed to long | 718 /* This tests for a bug in libjpeg where INT32 is typedefed to long |
719 and memory can be written to outside of the array. */ | 719 and memory can be written to outside of the array. */ |
720 DEF_TEST(ImageDecoding_JpegOverwrite, r) { | 720 DEF_TEST(ImageDecoding_JpegOverwrite, r) { |
721 SkString resourceDir = GetResourcePath(); | 721 SkString resourceDir = GetResourcePath(); |
722 SkString path = SkOSPath::Join(resourceDir.c_str(), "randPixels.jpg"); | 722 SkString path = SkOSPath::Join(resourceDir.c_str(), "randPixels.jpg"); |
723 SkAutoTDelete<SkStreamAsset> stream( | 723 SkAutoTDelete<SkStreamAsset> stream( |
724 SkStream::NewFromFile(path.c_str())); | 724 SkStream::NewFromFile(path.c_str())); |
725 if (!stream.get()) { | 725 if (!stream.get()) { |
726 SkDebugf("\nPath '%s' missing.\n", path.c_str()); | 726 SkDebugf("\nPath '%s' missing.\n", path.c_str()); |
727 return; | 727 return; |
728 } | 728 } |
729 SkAutoTDelete<SkImageDecoder> decoder(SkImageDecoder::Factory(stream)); | 729 SkAutoTDelete<SkImageDecoder> decoder(SkImageDecoder::Factory(stream)); |
730 if (NULL == decoder.get()) { | 730 if (nullptr == decoder.get()) { |
731 ERRORF(r, "\nSkImageDecoder::Factory failed.\n"); | 731 ERRORF(r, "\nSkImageDecoder::Factory failed.\n"); |
732 return; | 732 return; |
733 } | 733 } |
734 SkAssertResult(stream->rewind()); | 734 SkAssertResult(stream->rewind()); |
735 | 735 |
736 static const uint16_t sentinal = 0xBEEF; | 736 static const uint16_t sentinal = 0xBEEF; |
737 static const int pixelCount = 16; | 737 static const int pixelCount = 16; |
738 SkAutoTMalloc<uint16_t> pixels(pixelCount + 1); | 738 SkAutoTMalloc<uint16_t> pixels(pixelCount + 1); |
739 // pixels.get() should be 4-byte aligned. | 739 // pixels.get() should be 4-byte aligned. |
740 // This is necessary to reproduce the bug. | 740 // This is necessary to reproduce the bug. |
741 | 741 |
742 pixels[pixelCount] = sentinal; // This value should not be changed. | 742 pixels[pixelCount] = sentinal; // This value should not be changed. |
743 | 743 |
744 SkAutoTUnref<SingleAllocator> allocator( | 744 SkAutoTUnref<SingleAllocator> allocator( |
745 new SingleAllocator((void*)pixels.get(), sizeof(uint16_t) * pixelCou
nt)); | 745 new SingleAllocator((void*)pixels.get(), sizeof(uint16_t) * pixelCou
nt)); |
746 decoder->setAllocator(allocator); | 746 decoder->setAllocator(allocator); |
747 decoder->setSampleSize(2); | 747 decoder->setSampleSize(2); |
748 SkBitmap bitmap; | 748 SkBitmap bitmap; |
749 bool success = decoder->decode(stream, &bitmap, kRGB_565_SkColorType, | 749 bool success = decoder->decode(stream, &bitmap, kRGB_565_SkColorType, |
750 SkImageDecoder::kDecodePixels_Mode) != SkImag
eDecoder::kFailure; | 750 SkImageDecoder::kDecodePixels_Mode) != SkImag
eDecoder::kFailure; |
751 REPORTER_ASSERT(r, success); | 751 REPORTER_ASSERT(r, success); |
752 REPORTER_ASSERT(r, !allocator->ready()); // Decoder used correct memory | 752 REPORTER_ASSERT(r, !allocator->ready()); // Decoder used correct memory |
753 REPORTER_ASSERT(r, sentinal == pixels[pixelCount]); | 753 REPORTER_ASSERT(r, sentinal == pixels[pixelCount]); |
754 } | 754 } |
OLD | NEW |