Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(496)

Side by Side Diff: tests/CodexTest.cpp

Issue 1647153002: Add SkAndroidCodec::getPixels (Closed) Base URL: https://skia.googlesource.com/skia.git@opaque
Patch Set: Preemptive rebase Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « include/codec/SkAndroidCodec.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 "Resources.h" 8 #include "Resources.h"
9 #include "SkAndroidCodec.h" 9 #include "SkAndroidCodec.h"
10 #include "SkBitmap.h" 10 #include "SkBitmap.h"
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
49 md5(bm, &digest); 49 md5(bm, &digest);
50 REPORTER_ASSERT(r, digest == goodDigest); 50 REPORTER_ASSERT(r, digest == goodDigest);
51 } 51 }
52 52
53 /** 53 /**
54 * Test decoding an SkCodec to a particular SkImageInfo. 54 * Test decoding an SkCodec to a particular SkImageInfo.
55 * 55 *
56 * Calling getPixels(info) should return expectedResult, and if goodDigest is n on nullptr, 56 * Calling getPixels(info) should return expectedResult, and if goodDigest is n on nullptr,
57 * the resulting decode should match. 57 * the resulting decode should match.
58 */ 58 */
59 static void test_info(skiatest::Reporter* r, SkCodec* codec, const SkImageInfo& info, 59 template<typename Codec>
60 static void test_info(skiatest::Reporter* r, Codec* codec, const SkImageInfo& in fo,
60 SkCodec::Result expectedResult, const SkMD5::Digest* goodD igest) { 61 SkCodec::Result expectedResult, const SkMD5::Digest* goodD igest) {
61 SkBitmap bm; 62 SkBitmap bm;
62 bm.allocPixels(info); 63 bm.allocPixels(info);
63 SkAutoLockPixels autoLockPixels(bm); 64 SkAutoLockPixels autoLockPixels(bm);
64 65
65 SkCodec::Result result = codec->getPixels(info, bm.getPixels(), bm.rowBytes( )); 66 SkCodec::Result result = codec->getPixels(info, bm.getPixels(), bm.rowBytes( ));
66 REPORTER_ASSERT(r, result == expectedResult); 67 REPORTER_ASSERT(r, result == expectedResult);
67 68
68 if (goodDigest) { 69 if (goodDigest) {
69 compare_to_good_digest(r, *goodDigest, bm); 70 compare_to_good_digest(r, *goodDigest, bm);
70 } 71 }
71 } 72 }
72 73
73 static void test_android_info(skiatest::Reporter* r, SkAndroidCodec* codec, cons t SkImageInfo& info,
74 SkCodec::Result expectedResult, const SkMD5::Diges t* goodDigest) {
75 SkBitmap bm;
76 bm.allocPixels(info);
77 SkAutoLockPixels autoLockPixels(bm);
78
79 SkCodec::Result result = codec->getAndroidPixels(info, bm.getPixels(), bm.ro wBytes());
80 REPORTER_ASSERT(r, result == expectedResult);
81
82 if (goodDigest) {
83 compare_to_good_digest(r, *goodDigest, bm);
84 }
85 }
86
87 SkIRect generate_random_subset(SkRandom* rand, int w, int h) { 74 SkIRect generate_random_subset(SkRandom* rand, int w, int h) {
88 SkIRect rect; 75 SkIRect rect;
89 do { 76 do {
90 rect.fLeft = rand->nextRangeU(0, w); 77 rect.fLeft = rand->nextRangeU(0, w);
91 rect.fTop = rand->nextRangeU(0, h); 78 rect.fTop = rand->nextRangeU(0, h);
92 rect.fRight = rand->nextRangeU(0, w); 79 rect.fRight = rand->nextRangeU(0, w);
93 rect.fBottom = rand->nextRangeU(0, h); 80 rect.fBottom = rand->nextRangeU(0, h);
94 rect.sort(); 81 rect.sort();
95 } while (rect.isEmpty()); 82 } while (rect.isEmpty());
96 return rect; 83 return rect;
97 } 84 }
98 85
99 static void test_codec(skiatest::Reporter* r, SkCodec* codec, SkBitmap& bm, cons t SkImageInfo& info, 86 template<typename Codec>
87 static void test_codec(skiatest::Reporter* r, Codec* codec, SkBitmap& bm, const SkImageInfo& info,
100 const SkISize& size, SkCodec::Result expectedResult, SkMD5::Digest* dige st, 88 const SkISize& size, SkCodec::Result expectedResult, SkMD5::Digest* dige st,
101 const SkMD5::Digest* goodDigest) { 89 const SkMD5::Digest* goodDigest) {
102 90
103 REPORTER_ASSERT(r, info.dimensions() == size); 91 REPORTER_ASSERT(r, info.dimensions() == size);
104 bm.allocPixels(info); 92 bm.allocPixels(info);
105 SkAutoLockPixels autoLockPixels(bm); 93 SkAutoLockPixels autoLockPixels(bm);
106 94
107 SkCodec::Result result = codec->getPixels(info, bm.getPixels(), bm.rowBytes( )); 95 SkCodec::Result result = codec->getPixels(info, bm.getPixels(), bm.rowBytes( ));
108 REPORTER_ASSERT(r, result == expectedResult); 96 REPORTER_ASSERT(r, result == expectedResult);
109 97
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
142 otherAt = kUnpremul_SkAlphaType; 130 otherAt = kUnpremul_SkAlphaType;
143 } else { 131 } else {
144 otherAt = kPremul_SkAlphaType; 132 otherAt = kPremul_SkAlphaType;
145 } 133 }
146 // The other non-opaque alpha type should always succeed, but not ma tch. 134 // The other non-opaque alpha type should always succeed, but not ma tch.
147 test_info(r, codec, info.makeAlphaType(otherAt), expectedResult, nul lptr); 135 test_info(r, codec, info.makeAlphaType(otherAt), expectedResult, nul lptr);
148 } 136 }
149 } 137 }
150 } 138 }
151 139
152 static void test_android_codec(skiatest::Reporter* r, SkAndroidCodec* codec, SkB itmap& bm,
153 const SkImageInfo& info, const SkISize& size, SkCodec::Result expectedRe sult,
154 SkMD5::Digest* digest, const SkMD5::Digest* goodDigest) {
155
156 REPORTER_ASSERT(r, info.dimensions() == size);
157 bm.allocPixels(info);
158 SkAutoLockPixels autoLockPixels(bm);
159
160 SkCodec::Result result = codec->getAndroidPixels(info, bm.getPixels(), bm.ro wBytes());
161 REPORTER_ASSERT(r, result == expectedResult);
162
163 md5(bm, digest);
164 if (goodDigest) {
165 REPORTER_ASSERT(r, *digest == *goodDigest);
166 }
167
168 {
169 // Test decoding to 565
170 SkImageInfo info565 = info.makeColorType(kRGB_565_SkColorType);
171 SkCodec::Result expected565 = info.alphaType() == kOpaque_SkAlphaType ?
172 expectedResult : SkCodec::kInvalidConversion;
173 test_android_info(r, codec, info565, expected565, nullptr);
174 }
175
176 // Verify that re-decoding gives the same result. It is interesting to chec k this after
177 // a decode to 565, since choosing to decode to 565 may result in some of th e decode
178 // options being modified. These options should return to their defaults on another
179 // decode to kN32, so the new digest should match the old digest.
180 test_android_info(r, codec, info, expectedResult, digest);
181
182 {
183 // Check alpha type conversions
184 if (info.alphaType() == kOpaque_SkAlphaType) {
185 test_android_info(r, codec, info.makeAlphaType(kUnpremul_SkAlphaType ),
186 expectedResult, digest);
187 test_android_info(r, codec, info.makeAlphaType(kPremul_SkAlphaType),
188 expectedResult, digest);
189 } else {
190 // Decoding to opaque should fail
191 test_android_info(r, codec, info.makeAlphaType(kOpaque_SkAlphaType),
192 SkCodec::kInvalidConversion, nullptr);
193 SkAlphaType otherAt = info.alphaType();
194 if (kPremul_SkAlphaType == otherAt) {
195 otherAt = kUnpremul_SkAlphaType;
196 } else {
197 otherAt = kPremul_SkAlphaType;
198 }
199 // The other non-opaque alpha type should always succeed, but not ma tch.
200 test_android_info(r, codec, info.makeAlphaType(otherAt), expectedRes ult, nullptr);
201 }
202 }
203 }
204
205 // FIXME: SkScaledCodec is currently only supported for types used by BRD 140 // FIXME: SkScaledCodec is currently only supported for types used by BRD
206 // https://bug.skia.org/4428 141 // https://bug.skia.org/4428
207 static bool supports_scaled_codec(const char path[]) { 142 static bool supports_scaled_codec(const char path[]) {
208 static const char* const exts[] = { 143 static const char* const exts[] = {
209 "jpg", "jpeg", "png", "webp" 144 "jpg", "jpeg", "png", "webp"
210 "JPG", "JPEG", "PNG", "WEBP" 145 "JPG", "JPEG", "PNG", "WEBP"
211 }; 146 };
212 147
213 for (uint32_t i = 0; i < SK_ARRAY_COUNT(exts); i++) { 148 for (uint32_t i = 0; i < SK_ARRAY_COUNT(exts); i++) {
214 if (SkStrEndsWith(path, exts[i])) { 149 if (SkStrEndsWith(path, exts[i])) {
(...skipping 28 matching lines...) Expand all
243 if (!codec) { 178 if (!codec) {
244 ERRORF(r, "Unable to decode '%s'", path); 179 ERRORF(r, "Unable to decode '%s'", path);
245 return; 180 return;
246 } 181 }
247 182
248 // Test full image decodes with SkCodec 183 // Test full image decodes with SkCodec
249 SkMD5::Digest codecDigest; 184 SkMD5::Digest codecDigest;
250 SkImageInfo info = codec->getInfo().makeColorType(kN32_SkColorType); 185 SkImageInfo info = codec->getInfo().makeColorType(kN32_SkColorType);
251 SkBitmap bm; 186 SkBitmap bm;
252 SkCodec::Result expectedResult = isIncomplete ? SkCodec::kIncompleteInput : SkCodec::kSuccess; 187 SkCodec::Result expectedResult = isIncomplete ? SkCodec::kIncompleteInput : SkCodec::kSuccess;
253 test_codec(r, codec, bm, info, size, expectedResult, &codecDigest, nullptr); 188 test_codec(r, codec.get(), bm, info, size, expectedResult, &codecDigest, nul lptr);
254 189
255 // Scanline decoding follows. 190 // Scanline decoding follows.
256 // Need to call startScanlineDecode() first. 191 // Need to call startScanlineDecode() first.
257 REPORTER_ASSERT(r, codec->getScanlines(bm.getAddr(0, 0), 1, 0) 192 REPORTER_ASSERT(r, codec->getScanlines(bm.getAddr(0, 0), 1, 0)
258 == 0); 193 == 0);
259 REPORTER_ASSERT(r, codec->skipScanlines(1) 194 REPORTER_ASSERT(r, codec->skipScanlines(1)
260 == 0); 195 == 0);
261 196
262 const SkCodec::Result startResult = codec->startScanlineDecode(info); 197 const SkCodec::Result startResult = codec->startScanlineDecode(info);
263 if (supportsScanlineDecoding) { 198 if (supportsScanlineDecoding) {
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
354 289
355 // SkScaledCodec tests 290 // SkScaledCodec tests
356 if ((supportsScanlineDecoding || supportsSubsetDecoding) && supports_scaled_ codec(path)) { 291 if ((supportsScanlineDecoding || supportsSubsetDecoding) && supports_scaled_ codec(path)) {
357 292
358 SkAutoTDelete<SkStream> stream(resource(path)); 293 SkAutoTDelete<SkStream> stream(resource(path));
359 if (!stream) { 294 if (!stream) {
360 SkDebugf("Missing resource '%s'\n", path); 295 SkDebugf("Missing resource '%s'\n", path);
361 return; 296 return;
362 } 297 }
363 298
364 SkAutoTDelete<SkAndroidCodec> codec(nullptr); 299 SkAutoTDelete<SkAndroidCodec> androidCodec(nullptr);
365 if (isIncomplete) { 300 if (isIncomplete) {
366 size_t size = stream->getLength(); 301 size_t size = stream->getLength();
367 SkAutoTUnref<SkData> data((SkData::NewFromStream(stream, 2 * size / 3))); 302 SkAutoTUnref<SkData> data((SkData::NewFromStream(stream, 2 * size / 3)));
368 codec.reset(SkAndroidCodec::NewFromData(data)); 303 androidCodec.reset(SkAndroidCodec::NewFromData(data));
369 } else { 304 } else {
370 codec.reset(SkAndroidCodec::NewFromStream(stream.detach())); 305 androidCodec.reset(SkAndroidCodec::NewFromStream(stream.detach()));
371 } 306 }
372 if (!codec) { 307 if (!androidCodec) {
373 ERRORF(r, "Unable to decode '%s'", path); 308 ERRORF(r, "Unable to decode '%s'", path);
374 return; 309 return;
375 } 310 }
376 311
377 SkBitmap bm; 312 SkBitmap bm;
378 SkMD5::Digest scaledCodecDigest; 313 SkMD5::Digest scaledCodecDigest;
379 test_android_codec(r, codec, bm, info, size, expectedResult, 314 test_codec(r, androidCodec.get(), bm, info, size, expectedResult, &scale dCodecDigest,
380 &scaledCodecDigest, &codecDigest); 315 &codecDigest);
381 } 316 }
382 317
383 // Test SkCodecImageGenerator 318 // Test SkCodecImageGenerator
384 if (!isIncomplete) { 319 if (!isIncomplete) {
385 SkAutoTDelete<SkStream> stream(resource(path)); 320 SkAutoTDelete<SkStream> stream(resource(path));
386 SkAutoTUnref<SkData> fullData(SkData::NewFromStream(stream, stream->getL ength())); 321 SkAutoTUnref<SkData> fullData(SkData::NewFromStream(stream, stream->getL ength()));
387 SkAutoTDelete<SkImageGenerator> gen(SkCodecImageGenerator::NewFromEncode dCodec(fullData)); 322 SkAutoTDelete<SkImageGenerator> gen(SkCodecImageGenerator::NewFromEncode dCodec(fullData));
388 SkBitmap bm; 323 SkBitmap bm;
389 bm.allocPixels(info); 324 bm.allocPixels(info);
390 SkAutoLockPixels autoLockPixels(bm); 325 SkAutoLockPixels autoLockPixels(bm);
(...skipping 511 matching lines...) Expand 10 before | Expand all | Expand 10 after
902 SkAutoTUnref<SkData> data(SkData::NewFromFileName(fullPath.c_str())); 837 SkAutoTUnref<SkData> data(SkData::NewFromFileName(fullPath.c_str()));
903 if (!data) { 838 if (!data) {
904 SkDebugf("Missing resource '%s'\n", path); 839 SkDebugf("Missing resource '%s'\n", path);
905 return; 840 return;
906 } 841 }
907 842
908 // The limit is less than webp needs to peek or read. 843 // The limit is less than webp needs to peek or read.
909 SkAutoTDelete<SkCodec> codec(SkCodec::NewFromStream(new LimitedPeekingMemStr eam(data, 25))); 844 SkAutoTDelete<SkCodec> codec(SkCodec::NewFromStream(new LimitedPeekingMemStr eam(data, 25)));
910 REPORTER_ASSERT(r, codec); 845 REPORTER_ASSERT(r, codec);
911 846
912 test_info(r, codec, codec->getInfo(), SkCodec::kSuccess, nullptr); 847 test_info(r, codec.get(), codec->getInfo(), SkCodec::kSuccess, nullptr);
913 848
914 // Similarly, a stream which does not peek should still succeed. 849 // Similarly, a stream which does not peek should still succeed.
915 codec.reset(SkCodec::NewFromStream(new LimitedPeekingMemStream(data, 0))); 850 codec.reset(SkCodec::NewFromStream(new LimitedPeekingMemStream(data, 0)));
916 REPORTER_ASSERT(r, codec); 851 REPORTER_ASSERT(r, codec);
917 852
918 test_info(r, codec, codec->getInfo(), SkCodec::kSuccess, nullptr); 853 test_info(r, codec.get(), codec->getInfo(), SkCodec::kSuccess, nullptr);
919 } 854 }
920 855
921 // SkCodec's wbmp decoder was initially more restrictive than SkImageDecoder. 856 // SkCodec's wbmp decoder was initially more restrictive than SkImageDecoder.
922 // It required the second byte to be zero. But SkImageDecoder allowed a couple 857 // It required the second byte to be zero. But SkImageDecoder allowed a couple
923 // of bits to be 1 (so long as they do not overlap with 0x9F). Test that 858 // of bits to be 1 (so long as they do not overlap with 0x9F). Test that
924 // SkCodec now supports an image with these bits set. 859 // SkCodec now supports an image with these bits set.
925 DEF_TEST(Codec_wbmp, r) { 860 DEF_TEST(Codec_wbmp, r) {
926 const char* path = "mandrill.wbmp"; 861 const char* path = "mandrill.wbmp";
927 SkAutoTDelete<SkStream> stream(resource(path)); 862 SkAutoTDelete<SkStream> stream(resource(path));
928 if (!stream) { 863 if (!stream) {
929 SkDebugf("Missing resource '%s'\n", path); 864 SkDebugf("Missing resource '%s'\n", path);
930 return; 865 return;
931 } 866 }
932 867
933 // Modify the stream to contain a second byte with some bits set. 868 // Modify the stream to contain a second byte with some bits set.
934 SkAutoTUnref<SkData> data(SkCopyStreamToData(stream)); 869 SkAutoTUnref<SkData> data(SkCopyStreamToData(stream));
935 uint8_t* writeableData = static_cast<uint8_t*>(data->writable_data()); 870 uint8_t* writeableData = static_cast<uint8_t*>(data->writable_data());
936 writeableData[1] = static_cast<uint8_t>(~0x9F); 871 writeableData[1] = static_cast<uint8_t>(~0x9F);
937 872
938 // SkImageDecoder supports this. 873 // SkImageDecoder supports this.
939 SkBitmap bitmap; 874 SkBitmap bitmap;
940 REPORTER_ASSERT(r, SkImageDecoder::DecodeMemory(data->data(), data->size(), &bitmap)); 875 REPORTER_ASSERT(r, SkImageDecoder::DecodeMemory(data->data(), data->size(), &bitmap));
941 876
942 // So SkCodec should, too. 877 // So SkCodec should, too.
943 SkAutoTDelete<SkCodec> codec(SkCodec::NewFromData(data)); 878 SkAutoTDelete<SkCodec> codec(SkCodec::NewFromData(data));
944 REPORTER_ASSERT(r, codec); 879 REPORTER_ASSERT(r, codec);
945 if (!codec) { 880 if (!codec) {
946 return; 881 return;
947 } 882 }
948 test_info(r, codec, codec->getInfo(), SkCodec::kSuccess, nullptr); 883 test_info(r, codec.get(), codec->getInfo(), SkCodec::kSuccess, nullptr);
949 } 884 }
950 885
951 // wbmp images have a header that can be arbitrarily large, depending on the 886 // wbmp images have a header that can be arbitrarily large, depending on the
952 // size of the image. We cap the size at 65535, meaning we only need to look at 887 // size of the image. We cap the size at 65535, meaning we only need to look at
953 // 8 bytes to determine whether we can read the image. This is important 888 // 8 bytes to determine whether we can read the image. This is important
954 // because SkCodec only passes 14 bytes to SkWbmpCodec to determine whether the 889 // because SkCodec only passes 14 bytes to SkWbmpCodec to determine whether the
955 // image is a wbmp. 890 // image is a wbmp.
956 DEF_TEST(Codec_wbmp_max_size, r) { 891 DEF_TEST(Codec_wbmp_max_size, r) {
957 const unsigned char maxSizeWbmp[] = { 0x00, 0x00, // Header 892 const unsigned char maxSizeWbmp[] = { 0x00, 0x00, // Header
958 0x83, 0xFF, 0x7F, // W: 65535 893 0x83, 0xFF, 0x7F, // W: 65535
(...skipping 10 matching lines...) Expand all
969 // Now test an image which is too big. Any image with a larger header (i.e. 904 // Now test an image which is too big. Any image with a larger header (i.e.
970 // has bigger width/height) is also too big. 905 // has bigger width/height) is also too big.
971 const unsigned char tooBigWbmp[] = { 0x00, 0x00, // Header 906 const unsigned char tooBigWbmp[] = { 0x00, 0x00, // Header
972 0x84, 0x80, 0x00, // W: 65536 907 0x84, 0x80, 0x00, // W: 65536
973 0x84, 0x80, 0x00 }; // H: 65536 908 0x84, 0x80, 0x00 }; // H: 65536
974 stream.reset(new SkMemoryStream(tooBigWbmp, sizeof(tooBigWbmp), false)); 909 stream.reset(new SkMemoryStream(tooBigWbmp, sizeof(tooBigWbmp), false));
975 codec.reset(SkCodec::NewFromStream(stream.detach())); 910 codec.reset(SkCodec::NewFromStream(stream.detach()));
976 911
977 REPORTER_ASSERT(r, !codec); 912 REPORTER_ASSERT(r, !codec);
978 } 913 }
OLDNEW
« no previous file with comments | « include/codec/SkAndroidCodec.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698