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

Side by Side Diff: tests/CodexTest.cpp

Issue 1365313002: Merge SkCodec with SkScanlineDecoder (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Skip ICO in SkScaledCodec for now 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
« no previous file with comments | « src/codec/SkScanlineDecoder.cpp ('k') | tools/SkBitmapRegionCanvas.h » ('j') | 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 "SkBitmap.h" 9 #include "SkBitmap.h"
10 #include "SkCodec.h" 10 #include "SkCodec.h"
11 #include "SkMD5.h" 11 #include "SkMD5.h"
12 #include "SkRandom.h" 12 #include "SkRandom.h"
13 #include "SkScaledCodec.h" 13 #include "SkScaledCodec.h"
14 #include "SkScanlineDecoder.h"
15 #include "Test.h" 14 #include "Test.h"
16 15
17 static SkStreamAsset* resource(const char path[]) { 16 static SkStreamAsset* resource(const char path[]) {
18 SkString fullPath = GetResourcePath(path); 17 SkString fullPath = GetResourcePath(path);
19 return SkStream::NewFromFile(fullPath.c_str()); 18 return SkStream::NewFromFile(fullPath.c_str());
20 } 19 }
21 20
22 static void md5(const SkBitmap& bm, SkMD5::Digest* digest) { 21 static void md5(const SkBitmap& bm, SkMD5::Digest* digest) {
23 SkAutoLockPixels autoLockPixels(bm); 22 SkAutoLockPixels autoLockPixels(bm);
24 SkASSERT(bm.getPixels()); 23 SkASSERT(bm.getPixels());
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
140 } else { 139 } else {
141 otherAt = kPremul_SkAlphaType; 140 otherAt = kPremul_SkAlphaType;
142 } 141 }
143 // The other non-opaque alpha type should always succeed, but not ma tch. 142 // The other non-opaque alpha type should always succeed, but not ma tch.
144 test_info(r, codec, info.makeAlphaType(otherAt), SkCodec::kSuccess, nullptr); 143 test_info(r, codec, info.makeAlphaType(otherAt), SkCodec::kSuccess, nullptr);
145 } 144 }
146 } 145 }
147 146
148 // Scanline decoding follows. 147 // Scanline decoding follows.
149 148
150 stream.reset(resource(path)); 149 // Need to call start() first.
151 SkAutoTDelete<SkScanlineDecoder> scanlineDecoder( 150 REPORTER_ASSERT(r, codec->getScanlines(bm.getAddr(0, 0), 1, 0)
152 SkScanlineDecoder::NewFromStream(stream.detach())); 151 == SkCodec::kScanlineDecodingNotStarted);
152 REPORTER_ASSERT(r, codec->skipScanlines(1)
153 == SkCodec::kScanlineDecodingNotStarted);
154
155 const SkCodec::Result startResult = codec->startScanlineDecode(info);
153 if (supportsScanlineDecoding) { 156 if (supportsScanlineDecoding) {
154 bm.eraseColor(SK_ColorYELLOW); 157 bm.eraseColor(SK_ColorYELLOW);
155 REPORTER_ASSERT(r, scanlineDecoder);
156 158
157 REPORTER_ASSERT(r, scanlineDecoder->start(info) == SkCodec::kSuccess); 159 REPORTER_ASSERT(r, startResult == SkCodec::kSuccess);
158 160
159 for (int y = 0; y < info.height(); y++) { 161 for (int y = 0; y < info.height(); y++) {
160 result = scanlineDecoder->getScanlines(bm.getAddr(0, y), 1, 0); 162 result = codec->getScanlines(bm.getAddr(0, y), 1, 0);
161 REPORTER_ASSERT(r, result == SkCodec::kSuccess); 163 REPORTER_ASSERT(r, result == SkCodec::kSuccess);
162 } 164 }
163 // verify that scanline decoding gives the same result. 165 // verify that scanline decoding gives the same result.
164 if (SkScanlineDecoder::kTopDown_SkScanlineOrder == scanlineDecoder->getS canlineOrder()) { 166 if (SkCodec::kTopDown_SkScanlineOrder == codec->getScanlineOrder()) {
165 compare_to_good_digest(r, digest, bm); 167 compare_to_good_digest(r, digest, bm);
166 } 168 }
169
170 // Cannot continue to decode scanlines beyond the end
171 REPORTER_ASSERT(r, codec->getScanlines(bm.getAddr(0, 0), 1, 0)
172 == SkCodec::kInvalidParameters);
173
174 // Interrupting a scanline decode with a full decode starts from
175 // scratch
176 REPORTER_ASSERT(r, codec->startScanlineDecode(info) == SkCodec::kSuccess );
177 REPORTER_ASSERT(r, codec->getScanlines(bm.getAddr(0, 0), 1, 0)
178 == SkCodec::kSuccess);
179 REPORTER_ASSERT(r, codec->getPixels(bm.info(), bm.getPixels(), bm.rowByt es())
180 == SkCodec::kSuccess);
181 REPORTER_ASSERT(r, codec->getScanlines(bm.getAddr(0, 0), 1, 0)
182 == SkCodec::kScanlineDecodingNotStarted);
183 REPORTER_ASSERT(r, codec->skipScanlines(1)
184 == SkCodec::kScanlineDecodingNotStarted);
167 } else { 185 } else {
168 REPORTER_ASSERT(r, !scanlineDecoder); 186 REPORTER_ASSERT(r, startResult == SkCodec::kUnimplemented);
169 } 187 }
170 188
171 // The rest of this function tests decoding subsets, and will decode an arbi trary number of 189 // The rest of this function tests decoding subsets, and will decode an arbi trary number of
172 // random subsets. 190 // random subsets.
173 // Do not attempt to decode subsets of an image of only once pixel, since th ere is no 191 // Do not attempt to decode subsets of an image of only once pixel, since th ere is no
174 // meaningful subset. 192 // meaningful subset.
175 if (size.width() * size.height() == 1) { 193 if (size.width() * size.height() == 1) {
176 return; 194 return;
177 } 195 }
178 196
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
240 check(r, "baby_tux.png", SkISize::Make(240, 246), true, false); 258 check(r, "baby_tux.png", SkISize::Make(240, 246), true, false);
241 check(r, "color_wheel.png", SkISize::Make(128, 128), true, false); 259 check(r, "color_wheel.png", SkISize::Make(128, 128), true, false);
242 check(r, "half-transparent-white-pixel.png", SkISize::Make(1, 1), true, fals e); 260 check(r, "half-transparent-white-pixel.png", SkISize::Make(1, 1), true, fals e);
243 check(r, "mandrill_128.png", SkISize::Make(128, 128), true, false); 261 check(r, "mandrill_128.png", SkISize::Make(128, 128), true, false);
244 check(r, "mandrill_16.png", SkISize::Make(16, 16), true, false); 262 check(r, "mandrill_16.png", SkISize::Make(16, 16), true, false);
245 check(r, "mandrill_256.png", SkISize::Make(256, 256), true, false); 263 check(r, "mandrill_256.png", SkISize::Make(256, 256), true, false);
246 check(r, "mandrill_32.png", SkISize::Make(32, 32), true, false); 264 check(r, "mandrill_32.png", SkISize::Make(32, 32), true, false);
247 check(r, "mandrill_512.png", SkISize::Make(512, 512), true, false); 265 check(r, "mandrill_512.png", SkISize::Make(512, 512), true, false);
248 check(r, "mandrill_64.png", SkISize::Make(64, 64), true, false); 266 check(r, "mandrill_64.png", SkISize::Make(64, 64), true, false);
249 check(r, "plane.png", SkISize::Make(250, 126), true, false); 267 check(r, "plane.png", SkISize::Make(250, 126), true, false);
268 check(r, "plane_interlaced.png", SkISize::Make(250, 126), true, false);
250 check(r, "randPixels.png", SkISize::Make(8, 8), true, false); 269 check(r, "randPixels.png", SkISize::Make(8, 8), true, false);
251 check(r, "yellow_rose.png", SkISize::Make(400, 301), true, false); 270 check(r, "yellow_rose.png", SkISize::Make(400, 301), true, false);
252 } 271 }
253 272
273 // Test interlaced PNG in stripes, similar to DM's kStripe_Mode
274 DEF_TEST(Codec_stripes, r) {
275 const char * path = "plane_interlaced.png";
276 SkAutoTDelete<SkStream> stream(resource(path));
277 if (!stream) {
278 SkDebugf("Missing resource '%s'\n", path);
279 }
280
281 SkAutoTDelete<SkCodec> codec(SkCodec::NewFromStream(stream.detach()));
282 REPORTER_ASSERT(r, codec);
283
284 if (!codec) {
285 return;
286 }
287
288 switch (codec->getScanlineOrder()) {
289 case SkCodec::kBottomUp_SkScanlineOrder:
290 case SkCodec::kOutOfOrder_SkScanlineOrder:
291 ERRORF(r, "This scanline order will not match the original.");
292 return;
293 default:
294 break;
295 }
296
297 // Baseline for what the image should look like, using N32.
298 const SkImageInfo info = codec->getInfo().makeColorType(kN32_SkColorType);
299
300 SkBitmap bm;
301 bm.allocPixels(info);
302 SkAutoLockPixels autoLockPixels(bm);
303 SkCodec::Result result = codec->getPixels(info, bm.getPixels(), bm.rowBytes( ));
304 REPORTER_ASSERT(r, result == SkCodec::kSuccess);
305
306 SkMD5::Digest digest;
307 md5(bm, &digest);
308
309 // Now decode in stripes
310 const int height = info.height();
311 const int numStripes = 4;
312 int stripeHeight;
313 int remainingLines;
314 SkTDivMod(height, numStripes, &stripeHeight, &remainingLines);
315
316 bm.eraseColor(SK_ColorYELLOW);
317
318 result = codec->startScanlineDecode(info);
319 REPORTER_ASSERT(r, result == SkCodec::kSuccess);
320
321 // Odd stripes
322 for (int i = 1; i < numStripes; i += 2) {
323 // Skip the even stripes
324 result = codec->skipScanlines(stripeHeight);
325 REPORTER_ASSERT(r, result == SkCodec::kSuccess);
326
327 result = codec->getScanlines(bm.getAddr(0, i * stripeHeight), stripeHeig ht,
328 bm.rowBytes());
329 REPORTER_ASSERT(r, result == SkCodec::kSuccess);
330 }
331
332 // Even stripes
333 result = codec->startScanlineDecode(info);
334 REPORTER_ASSERT(r, result == SkCodec::kSuccess);
335
336 for (int i = 0; i < numStripes; i += 2) {
337 result = codec->getScanlines(bm.getAddr(0, i * stripeHeight), stripeHeig ht,
338 bm.rowBytes());
339 REPORTER_ASSERT(r, result == SkCodec::kSuccess);
340
341 // Skip the odd stripes
342 if (i + 1 < numStripes) {
343 result = codec->skipScanlines(stripeHeight);
344 REPORTER_ASSERT(r, result == SkCodec::kSuccess);
345 }
346 }
347
348 // Remainder at the end
349 if (remainingLines > 0) {
350 result = codec->startScanlineDecode(info);
351 REPORTER_ASSERT(r, result == SkCodec::kSuccess);
352
353 result = codec->skipScanlines(height - remainingLines);
354 REPORTER_ASSERT(r, result == SkCodec::kSuccess);
355
356 result = codec->getScanlines(bm.getAddr(0, height - remainingLines),
357 remainingLines, bm.rowBytes());
358 REPORTER_ASSERT(r, result == SkCodec::kSuccess);
359 }
360
361 compare_to_good_digest(r, digest, bm);
362 }
363
254 static void test_invalid_stream(skiatest::Reporter* r, const void* stream, size_ t len) { 364 static void test_invalid_stream(skiatest::Reporter* r, const void* stream, size_ t len) {
255 SkCodec* codec = SkCodec::NewFromStream(new SkMemoryStream(stream, len, fals e)); 365 SkCodec* codec = SkCodec::NewFromStream(new SkMemoryStream(stream, len, fals e));
256 // We should not have gotten a codec. Bots should catch us if we leaked anyt hing. 366 // We should not have gotten a codec. Bots should catch us if we leaked anyt hing.
257 REPORTER_ASSERT(r, !codec); 367 REPORTER_ASSERT(r, !codec);
258 } 368 }
259 369
260 // Ensure that SkCodec::NewFromStream handles freeing the passed in SkStream, 370 // Ensure that SkCodec::NewFromStream handles freeing the passed in SkStream,
261 // even on failure. Test some bad streams. 371 // even on failure. Test some bad streams.
262 DEF_TEST(Codec_leaks, r) { 372 DEF_TEST(Codec_leaks, r) {
263 // No codec should claim this as their format, so this tests SkCodec::NewFro mStream. 373 // No codec should claim this as their format, so this tests SkCodec::NewFro mStream.
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
362 // This image is an ico with an embedded mask-bmp. This is illegal. 472 // This image is an ico with an embedded mask-bmp. This is illegal.
363 test_invalid(r, "invalid_images/mask-bmp-ico.ico"); 473 test_invalid(r, "invalid_images/mask-bmp-ico.ico");
364 } 474 }
365 475
366 static void test_invalid_parameters(skiatest::Reporter* r, const char path[]) { 476 static void test_invalid_parameters(skiatest::Reporter* r, const char path[]) {
367 SkAutoTDelete<SkStream> stream(resource(path)); 477 SkAutoTDelete<SkStream> stream(resource(path));
368 if (!stream) { 478 if (!stream) {
369 SkDebugf("Missing resource '%s'\n", path); 479 SkDebugf("Missing resource '%s'\n", path);
370 return; 480 return;
371 } 481 }
372 SkAutoTDelete<SkScanlineDecoder> decoder(SkScanlineDecoder::NewFromStream( 482 SkAutoTDelete<SkCodec> decoder(SkCodec::NewFromStream(stream.detach()));
373 stream.detach()));
374 483
375 // This should return kSuccess because kIndex8 is supported. 484 // This should return kSuccess because kIndex8 is supported.
376 SkPMColor colorStorage[256]; 485 SkPMColor colorStorage[256];
377 int colorCount; 486 int colorCount;
378 SkCodec::Result result = decoder->start( 487 SkCodec::Result result = decoder->startScanlineDecode(
379 decoder->getInfo().makeColorType(kIndex_8_SkColorType), nullptr, colorSt orage, &colorCount); 488 decoder->getInfo().makeColorType(kIndex_8_SkColorType), nullptr, colorSt orage, &colorCount);
380 REPORTER_ASSERT(r, SkCodec::kSuccess == result); 489 REPORTER_ASSERT(r, SkCodec::kSuccess == result);
381 // The rest of the test is uninteresting if kIndex8 is not supported 490 // The rest of the test is uninteresting if kIndex8 is not supported
382 if (SkCodec::kSuccess != result) { 491 if (SkCodec::kSuccess != result) {
383 return; 492 return;
384 } 493 }
385 494
386 // This should return kInvalidParameters because, in kIndex_8 mode, we must pass in a valid 495 // This should return kInvalidParameters because, in kIndex_8 mode, we must pass in a valid
387 // colorPtr and a valid colorCountPtr. 496 // colorPtr and a valid colorCountPtr.
388 result = decoder->start( 497 result = decoder->startScanlineDecode(
389 decoder->getInfo().makeColorType(kIndex_8_SkColorType), nullptr, nullptr , nullptr); 498 decoder->getInfo().makeColorType(kIndex_8_SkColorType), nullptr, nullptr , nullptr);
390 REPORTER_ASSERT(r, SkCodec::kInvalidParameters == result); 499 REPORTER_ASSERT(r, SkCodec::kInvalidParameters == result);
391 result = decoder->start( 500 result = decoder->startScanlineDecode(
392 decoder->getInfo().makeColorType(kIndex_8_SkColorType)); 501 decoder->getInfo().makeColorType(kIndex_8_SkColorType));
393 REPORTER_ASSERT(r, SkCodec::kInvalidParameters == result); 502 REPORTER_ASSERT(r, SkCodec::kInvalidParameters == result);
394 } 503 }
395 504
396 DEF_TEST(Codec_Params, r) { 505 DEF_TEST(Codec_Params, r) {
397 test_invalid_parameters(r, "index8.png"); 506 test_invalid_parameters(r, "index8.png");
398 test_invalid_parameters(r, "mandrill.wbmp"); 507 test_invalid_parameters(r, "mandrill.wbmp");
399 } 508 }
OLDNEW
« no previous file with comments | « src/codec/SkScanlineDecoder.cpp ('k') | tools/SkBitmapRegionCanvas.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698