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

Side by Side Diff: tests/CodexTest.cpp

Issue 1332053002: Fill incomplete images in SkCodec parent class (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Forgot to add SkSampler.cpp Created 5 years, 2 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
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 "SkBitmap.h" 9 #include "SkBitmap.h"
10 #include "SkCodec.h" 10 #include "SkCodec.h"
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
68 rect.fLeft = rand->nextRangeU(0, w); 68 rect.fLeft = rand->nextRangeU(0, w);
69 rect.fTop = rand->nextRangeU(0, h); 69 rect.fTop = rand->nextRangeU(0, h);
70 rect.fRight = rand->nextRangeU(0, w); 70 rect.fRight = rand->nextRangeU(0, w);
71 rect.fBottom = rand->nextRangeU(0, h); 71 rect.fBottom = rand->nextRangeU(0, h);
72 rect.sort(); 72 rect.sort();
73 } while (rect.isEmpty()); 73 } while (rect.isEmpty());
74 return rect; 74 return rect;
75 } 75 }
76 76
77 static void test_codec(skiatest::Reporter* r, SkCodec* codec, SkBitmap& bm, cons t SkImageInfo& info, 77 static void test_codec(skiatest::Reporter* r, SkCodec* codec, SkBitmap& bm, cons t SkImageInfo& info,
78 const SkISize& size, bool supports565, SkMD5::Digest* digest, 78 const SkISize& size, bool supports565, SkCodec::Result expectedResult,
79 const SkMD5::Digest* goodDigest) { 79 SkMD5::Digest* digest, const SkMD5::Digest* goodDigest) {
80
80 REPORTER_ASSERT(r, info.dimensions() == size); 81 REPORTER_ASSERT(r, info.dimensions() == size);
81 bm.allocPixels(info); 82 bm.allocPixels(info);
82 SkAutoLockPixels autoLockPixels(bm); 83 SkAutoLockPixels autoLockPixels(bm);
83 84
84 SkCodec::Result result = codec->getPixels(info, bm.getPixels(), bm.rowBytes( )); 85 SkCodec::Result result = codec->getPixels(info, bm.getPixels(), bm.rowBytes( ));
85 REPORTER_ASSERT(r, result == SkCodec::kSuccess); 86 REPORTER_ASSERT(r, result == expectedResult);
86 87
87 md5(bm, digest); 88 md5(bm, digest);
88 if (goodDigest) { 89 if (goodDigest) {
89 REPORTER_ASSERT(r, *digest == *goodDigest); 90 REPORTER_ASSERT(r, *digest == *goodDigest);
90 } 91 }
91 92
92 { 93 {
93 // Test decoding to 565 94 // Test decoding to 565
94 SkImageInfo info565 = info.makeColorType(kRGB_565_SkColorType); 95 SkImageInfo info565 = info.makeColorType(kRGB_565_SkColorType);
95 SkCodec::Result expected = (supports565 && info.alphaType() == kOpaque_S kAlphaType) ? 96 SkCodec::Result expected565 = (supports565 && info.alphaType() == kOpaqu e_SkAlphaType) ?
96 SkCodec::kSuccess : SkCodec::kInvalidConversion; 97 expectedResult : SkCodec::kInvalidConversion;
97 test_info(r, codec, info565, expected, nullptr); 98 test_info(r, codec, info565, expected565, nullptr);
98 } 99 }
99 100
100 // Verify that re-decoding gives the same result. It is interesting to chec k this after 101 // Verify that re-decoding gives the same result. It is interesting to chec k this after
101 // a decode to 565, since choosing to decode to 565 may result in some of th e decode 102 // a decode to 565, since choosing to decode to 565 may result in some of th e decode
102 // options being modified. These options should return to their defaults on another 103 // options being modified. These options should return to their defaults on another
103 // decode to kN32, so the new digest should match the old digest. 104 // decode to kN32, so the new digest should match the old digest.
104 test_info(r, codec, info, SkCodec::kSuccess, digest); 105 test_info(r, codec, info, expectedResult, digest);
105 106
106 { 107 {
107 // Check alpha type conversions 108 // Check alpha type conversions
108 if (info.alphaType() == kOpaque_SkAlphaType) { 109 if (info.alphaType() == kOpaque_SkAlphaType) {
109 test_info(r, codec, info.makeAlphaType(kUnpremul_SkAlphaType), 110 test_info(r, codec, info.makeAlphaType(kUnpremul_SkAlphaType),
110 SkCodec::kInvalidConversion, nullptr); 111 SkCodec::kInvalidConversion, nullptr);
111 test_info(r, codec, info.makeAlphaType(kPremul_SkAlphaType), 112 test_info(r, codec, info.makeAlphaType(kPremul_SkAlphaType),
112 SkCodec::kInvalidConversion, nullptr); 113 SkCodec::kInvalidConversion, nullptr);
113 } else { 114 } else {
114 // Decoding to opaque should fail 115 // Decoding to opaque should fail
115 test_info(r, codec, info.makeAlphaType(kOpaque_SkAlphaType), 116 test_info(r, codec, info.makeAlphaType(kOpaque_SkAlphaType),
116 SkCodec::kInvalidConversion, nullptr); 117 SkCodec::kInvalidConversion, nullptr);
117 SkAlphaType otherAt = info.alphaType(); 118 SkAlphaType otherAt = info.alphaType();
118 if (kPremul_SkAlphaType == otherAt) { 119 if (kPremul_SkAlphaType == otherAt) {
119 otherAt = kUnpremul_SkAlphaType; 120 otherAt = kUnpremul_SkAlphaType;
120 } else { 121 } else {
121 otherAt = kPremul_SkAlphaType; 122 otherAt = kPremul_SkAlphaType;
122 } 123 }
123 // The other non-opaque alpha type should always succeed, but not ma tch. 124 // The other non-opaque alpha type should always succeed, but not ma tch.
124 test_info(r, codec, info.makeAlphaType(otherAt), SkCodec::kSuccess, nullptr); 125 test_info(r, codec, info.makeAlphaType(otherAt), expectedResult, nul lptr);
125 } 126 }
126 } 127 }
127 } 128 }
128 129
129 static void check(skiatest::Reporter* r, 130 static void check(skiatest::Reporter* r,
130 const char path[], 131 const char path[],
131 SkISize size, 132 SkISize size,
132 bool supportsScanlineDecoding, 133 bool supportsScanlineDecoding,
133 bool supportsSubsetDecoding, 134 bool supportsSubsetDecoding,
134 bool supports565 = true) { 135 bool supports565 = true,
136 bool isIncomplete = false) {
135 137
136 SkAutoTDelete<SkStream> stream(resource(path)); 138 SkAutoTDelete<SkStream> stream(resource(path));
137 if (!stream) { 139 if (!stream) {
138 SkDebugf("Missing resource '%s'\n", path); 140 SkDebugf("Missing resource '%s'\n", path);
139 return; 141 return;
140 } 142 }
141 SkAutoTDelete<SkCodec> codec(SkCodec::NewFromStream(stream.detach())); 143 SkAutoTDelete<SkCodec> codec(SkCodec::NewFromStream(stream.detach()));
142 if (!codec) { 144 if (!codec) {
143 ERRORF(r, "Unable to decode '%s'", path); 145 ERRORF(r, "Unable to decode '%s'", path);
144 return; 146 return;
145 } 147 }
146 148
147 // Test full image decodes with SkCodec 149 // Test full image decodes with SkCodec
148 SkMD5::Digest codecDigest; 150 SkMD5::Digest codecDigest;
149 SkImageInfo info = codec->getInfo().makeColorType(kN32_SkColorType); 151 SkImageInfo info = codec->getInfo().makeColorType(kN32_SkColorType);
150 SkBitmap bm; 152 SkBitmap bm;
151 test_codec(r, codec, bm, info, size, supports565, &codecDigest, nullptr); 153 SkCodec::Result expectedResult = isIncomplete ? SkCodec::kIncompleteInput : SkCodec::kSuccess;
154 test_codec(r, codec, bm, info, size, supports565, expectedResult, &codecDige st, nullptr);
152 155
153 // Scanline decoding follows. 156 // Scanline decoding follows.
154 // Need to call startScanlineDecode() first. 157 // Need to call startScanlineDecode() first.
155 REPORTER_ASSERT(r, codec->getScanlines(bm.getAddr(0, 0), 1, 0) 158 REPORTER_ASSERT(r, codec->getScanlines(bm.getAddr(0, 0), 1, 0)
156 == SkCodec::kScanlineDecodingNotStarted); 159 == 0);
157 REPORTER_ASSERT(r, codec->skipScanlines(1) 160 REPORTER_ASSERT(r, codec->skipScanlines(1)
158 == SkCodec::kScanlineDecodingNotStarted); 161 == 0);
159 162
160 const SkCodec::Result startResult = codec->startScanlineDecode(info); 163 const SkCodec::Result startResult = codec->startScanlineDecode(info);
161 if (supportsScanlineDecoding) { 164 if (supportsScanlineDecoding) {
162 bm.eraseColor(SK_ColorYELLOW); 165 bm.eraseColor(SK_ColorYELLOW);
163 166
164 REPORTER_ASSERT(r, startResult == SkCodec::kSuccess); 167 REPORTER_ASSERT(r, startResult == SkCodec::kSuccess);
165 168
166 for (int y = 0; y < info.height(); y++) { 169 for (int y = 0; y < info.height(); y++) {
167 SkCodec::Result result = codec->getScanlines(bm.getAddr(0, y), 1, 0) ; 170 const uint32_t lines = codec->getScanlines(bm.getAddr(0, y), 1, 0);
168 REPORTER_ASSERT(r, result == SkCodec::kSuccess); 171 if (!isIncomplete) {
172 REPORTER_ASSERT(r, 1 == lines);
173 }
169 } 174 }
170 // verify that scanline decoding gives the same result. 175 // verify that scanline decoding gives the same result.
171 if (SkCodec::kTopDown_SkScanlineOrder == codec->getScanlineOrder()) { 176 if (SkCodec::kTopDown_SkScanlineOrder == codec->getScanlineOrder()) {
172 compare_to_good_digest(r, codecDigest, bm); 177 compare_to_good_digest(r, codecDigest, bm);
173 } 178 }
174 179
175 // Cannot continue to decode scanlines beyond the end 180 // Cannot continue to decode scanlines beyond the end
176 REPORTER_ASSERT(r, codec->getScanlines(bm.getAddr(0, 0), 1, 0) 181 REPORTER_ASSERT(r, codec->getScanlines(bm.getAddr(0, 0), 1, 0)
177 == SkCodec::kInvalidParameters); 182 == 0);
178 183
179 // Interrupting a scanline decode with a full decode starts from 184 // Interrupting a scanline decode with a full decode starts from
180 // scratch 185 // scratch
181 REPORTER_ASSERT(r, codec->startScanlineDecode(info) == SkCodec::kSuccess ); 186 REPORTER_ASSERT(r, codec->startScanlineDecode(info) == SkCodec::kSuccess );
182 REPORTER_ASSERT(r, codec->getScanlines(bm.getAddr(0, 0), 1, 0) 187 REPORTER_ASSERT(r, codec->getScanlines(bm.getAddr(0, 0), 1, 0)
183 == SkCodec::kSuccess); 188 == 1);
184 REPORTER_ASSERT(r, codec->getPixels(bm.info(), bm.getPixels(), bm.rowByt es()) 189 REPORTER_ASSERT(r, codec->getPixels(bm.info(), bm.getPixels(), bm.rowByt es())
185 == SkCodec::kSuccess); 190 == expectedResult);
186 REPORTER_ASSERT(r, codec->getScanlines(bm.getAddr(0, 0), 1, 0) 191 REPORTER_ASSERT(r, codec->getScanlines(bm.getAddr(0, 0), 1, 0)
187 == SkCodec::kScanlineDecodingNotStarted); 192 == 0);
188 REPORTER_ASSERT(r, codec->skipScanlines(1) 193 REPORTER_ASSERT(r, codec->skipScanlines(1)
189 == SkCodec::kScanlineDecodingNotStarted); 194 == 0);
190 } else { 195 } else {
191 REPORTER_ASSERT(r, startResult == SkCodec::kUnimplemented); 196 REPORTER_ASSERT(r, startResult == SkCodec::kUnimplemented);
192 } 197 }
193 198
194 // The rest of this function tests decoding subsets, and will decode an arbi trary number of 199 // The rest of this function tests decoding subsets, and will decode an arbi trary number of
195 // random subsets. 200 // random subsets.
196 // Do not attempt to decode subsets of an image of only once pixel, since th ere is no 201 // Do not attempt to decode subsets of an image of only once pixel, since th ere is no
197 // meaningful subset. 202 // meaningful subset.
198 if (size.width() * size.height() == 1) { 203 if (size.width() * size.height() == 1) {
199 return; 204 return;
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
234 return; 239 return;
235 } 240 }
236 SkAutoTDelete<SkCodec> codec(SkScaledCodec::NewFromStream(stream.detach( ))); 241 SkAutoTDelete<SkCodec> codec(SkScaledCodec::NewFromStream(stream.detach( )));
237 if (!codec) { 242 if (!codec) {
238 ERRORF(r, "Unable to decode '%s'", path); 243 ERRORF(r, "Unable to decode '%s'", path);
239 return; 244 return;
240 } 245 }
241 246
242 SkBitmap bm; 247 SkBitmap bm;
243 SkMD5::Digest scaledCodecDigest; 248 SkMD5::Digest scaledCodecDigest;
244 test_codec(r, codec, bm, info, size, supports565, &scaledCodecDigest, &c odecDigest); 249 test_codec(r, codec, bm, info, size, supports565, expectedResult, &scale dCodecDigest,
250 &codecDigest);
245 } 251 }
246 } 252 }
247 253
248 DEF_TEST(Codec, r) { 254 DEF_TEST(Codec, r) {
249 // WBMP 255 // WBMP
250 check(r, "mandrill.wbmp", SkISize::Make(512, 512), true, false); 256 check(r, "mandrill.wbmp", SkISize::Make(512, 512), true, false);
251 257
252 // WEBP 258 // WEBP
253 check(r, "baby_tux.webp", SkISize::Make(386, 395), false, true); 259 check(r, "baby_tux.webp", SkISize::Make(386, 395), false, true);
254 check(r, "color_wheel.webp", SkISize::Make(128, 128), false, true); 260 check(r, "color_wheel.webp", SkISize::Make(128, 128), false, true);
(...skipping 29 matching lines...) Expand all
284 check(r, "mandrill_128.png", SkISize::Make(128, 128), true, false); 290 check(r, "mandrill_128.png", SkISize::Make(128, 128), true, false);
285 check(r, "mandrill_16.png", SkISize::Make(16, 16), true, false); 291 check(r, "mandrill_16.png", SkISize::Make(16, 16), true, false);
286 check(r, "mandrill_256.png", SkISize::Make(256, 256), true, false); 292 check(r, "mandrill_256.png", SkISize::Make(256, 256), true, false);
287 check(r, "mandrill_32.png", SkISize::Make(32, 32), true, false); 293 check(r, "mandrill_32.png", SkISize::Make(32, 32), true, false);
288 check(r, "mandrill_512.png", SkISize::Make(512, 512), true, false); 294 check(r, "mandrill_512.png", SkISize::Make(512, 512), true, false);
289 check(r, "mandrill_64.png", SkISize::Make(64, 64), true, false); 295 check(r, "mandrill_64.png", SkISize::Make(64, 64), true, false);
290 check(r, "plane.png", SkISize::Make(250, 126), true, false); 296 check(r, "plane.png", SkISize::Make(250, 126), true, false);
291 check(r, "plane_interlaced.png", SkISize::Make(250, 126), true, false); 297 check(r, "plane_interlaced.png", SkISize::Make(250, 126), true, false);
292 check(r, "randPixels.png", SkISize::Make(8, 8), true, false); 298 check(r, "randPixels.png", SkISize::Make(8, 8), true, false);
293 check(r, "yellow_rose.png", SkISize::Make(400, 301), true, false); 299 check(r, "yellow_rose.png", SkISize::Make(400, 301), true, false);
300 // Incomplete Image
301 check(r, "incomplete_images/android.png", SkISize::Make(1024, 1218), true, f alse, true, true);
294 } 302 }
295 303
296 // Test interlaced PNG in stripes, similar to DM's kStripe_Mode 304 // Test interlaced PNG in stripes, similar to DM's kStripe_Mode
297 DEF_TEST(Codec_stripes, r) { 305 DEF_TEST(Codec_stripes, r) {
298 const char * path = "plane_interlaced.png"; 306 const char * path = "plane_interlaced.png";
299 SkAutoTDelete<SkStream> stream(resource(path)); 307 SkAutoTDelete<SkStream> stream(resource(path));
300 if (!stream) { 308 if (!stream) {
301 SkDebugf("Missing resource '%s'\n", path); 309 SkDebugf("Missing resource '%s'\n", path);
302 } 310 }
303 311
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
337 SkTDivMod(height, numStripes, &stripeHeight, &remainingLines); 345 SkTDivMod(height, numStripes, &stripeHeight, &remainingLines);
338 346
339 bm.eraseColor(SK_ColorYELLOW); 347 bm.eraseColor(SK_ColorYELLOW);
340 348
341 result = codec->startScanlineDecode(info); 349 result = codec->startScanlineDecode(info);
342 REPORTER_ASSERT(r, result == SkCodec::kSuccess); 350 REPORTER_ASSERT(r, result == SkCodec::kSuccess);
343 351
344 // Odd stripes 352 // Odd stripes
345 for (int i = 1; i < numStripes; i += 2) { 353 for (int i = 1; i < numStripes; i += 2) {
346 // Skip the even stripes 354 // Skip the even stripes
347 result = codec->skipScanlines(stripeHeight); 355 bool skipResult = codec->skipScanlines(stripeHeight);
348 REPORTER_ASSERT(r, result == SkCodec::kSuccess); 356 REPORTER_ASSERT(r, skipResult);
349 357
350 result = codec->getScanlines(bm.getAddr(0, i * stripeHeight), stripeHeig ht, 358 int linesDecoded = codec->getScanlines(bm.getAddr(0, i * stripeHeight), stripeHeight,
351 bm.rowBytes()); 359 bm.rowBytes());
352 REPORTER_ASSERT(r, result == SkCodec::kSuccess); 360 REPORTER_ASSERT(r, linesDecoded == stripeHeight);
353 } 361 }
354 362
355 // Even stripes 363 // Even stripes
356 result = codec->startScanlineDecode(info); 364 result = codec->startScanlineDecode(info);
357 REPORTER_ASSERT(r, result == SkCodec::kSuccess); 365 REPORTER_ASSERT(r, result == SkCodec::kSuccess);
358 366
359 for (int i = 0; i < numStripes; i += 2) { 367 for (int i = 0; i < numStripes; i += 2) {
360 result = codec->getScanlines(bm.getAddr(0, i * stripeHeight), stripeHeig ht, 368 int linesDecoded = codec->getScanlines(bm.getAddr(0, i * stripeHeight), stripeHeight,
361 bm.rowBytes()); 369 bm.rowBytes());
362 REPORTER_ASSERT(r, result == SkCodec::kSuccess); 370 REPORTER_ASSERT(r, linesDecoded == stripeHeight);
363 371
364 // Skip the odd stripes 372 // Skip the odd stripes
365 if (i + 1 < numStripes) { 373 if (i + 1 < numStripes) {
366 result = codec->skipScanlines(stripeHeight); 374 bool skipResult = codec->skipScanlines(stripeHeight);
367 REPORTER_ASSERT(r, result == SkCodec::kSuccess); 375 REPORTER_ASSERT(r, skipResult);
368 } 376 }
369 } 377 }
370 378
371 // Remainder at the end 379 // Remainder at the end
372 if (remainingLines > 0) { 380 if (remainingLines > 0) {
373 result = codec->startScanlineDecode(info); 381 result = codec->startScanlineDecode(info);
374 REPORTER_ASSERT(r, result == SkCodec::kSuccess); 382 REPORTER_ASSERT(r, result == SkCodec::kSuccess);
375 383
376 result = codec->skipScanlines(height - remainingLines); 384 bool skipResult = codec->skipScanlines(height - remainingLines);
377 REPORTER_ASSERT(r, result == SkCodec::kSuccess); 385 REPORTER_ASSERT(r, skipResult);
378 386
379 result = codec->getScanlines(bm.getAddr(0, height - remainingLines), 387 int linesDecoded = codec->getScanlines(bm.getAddr(0, height - remainingL ines),
380 remainingLines, bm.rowBytes()); 388 remainingLines, bm.rowBytes());
381 REPORTER_ASSERT(r, result == SkCodec::kSuccess); 389 REPORTER_ASSERT(r, linesDecoded == remainingLines);
382 } 390 }
383 391
384 compare_to_good_digest(r, digest, bm); 392 compare_to_good_digest(r, digest, bm);
385 } 393 }
386 394
387 static void test_invalid_stream(skiatest::Reporter* r, const void* stream, size_ t len) { 395 static void test_invalid_stream(skiatest::Reporter* r, const void* stream, size_ t len) {
388 SkCodec* codec = SkCodec::NewFromStream(new SkMemoryStream(stream, len, fals e)); 396 SkCodec* codec = SkCodec::NewFromStream(new SkMemoryStream(stream, len, fals e));
389 // We should not have gotten a codec. Bots should catch us if we leaked anyt hing. 397 // We should not have gotten a codec. Bots should catch us if we leaked anyt hing.
390 REPORTER_ASSERT(r, !codec); 398 REPORTER_ASSERT(r, !codec);
391 } 399 }
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
522 REPORTER_ASSERT(r, SkCodec::kInvalidParameters == result); 530 REPORTER_ASSERT(r, SkCodec::kInvalidParameters == result);
523 result = decoder->startScanlineDecode( 531 result = decoder->startScanlineDecode(
524 decoder->getInfo().makeColorType(kIndex_8_SkColorType)); 532 decoder->getInfo().makeColorType(kIndex_8_SkColorType));
525 REPORTER_ASSERT(r, SkCodec::kInvalidParameters == result); 533 REPORTER_ASSERT(r, SkCodec::kInvalidParameters == result);
526 } 534 }
527 535
528 DEF_TEST(Codec_Params, r) { 536 DEF_TEST(Codec_Params, r) {
529 test_invalid_parameters(r, "index8.png"); 537 test_invalid_parameters(r, "index8.png");
530 test_invalid_parameters(r, "mandrill.wbmp"); 538 test_invalid_parameters(r, "mandrill.wbmp");
531 } 539 }
OLDNEW
« src/codec/SkWebpCodec.h ('K') | « src/codec/SkWebpCodec.cpp ('k') | tests/SwizzlerTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698