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

Side by Side Diff: tests/CodecTest.cpp

Issue 2045293002: Add support for multiple frames in SkCodec (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Fix a test - we now draw transparent background for missing color table Created 4 years, 1 month 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 | « tests/CodecPartialTest.cpp ('k') | tests/GifTest.cpp » ('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 "SkAndroidCodec.h" 9 #include "SkAndroidCodec.h"
10 #include "SkBitmap.h" 10 #include "SkBitmap.h"
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after
283 SkMD5::Digest codecDigest; 283 SkMD5::Digest codecDigest;
284 const SkImageInfo info = codec->getInfo().makeColorType(kN32_SkColorType); 284 const SkImageInfo info = codec->getInfo().makeColorType(kN32_SkColorType);
285 SkBitmap bm; 285 SkBitmap bm;
286 SkCodec::Result expectedResult = isIncomplete ? SkCodec::kIncompleteInput : SkCodec::kSuccess; 286 SkCodec::Result expectedResult = isIncomplete ? SkCodec::kIncompleteInput : SkCodec::kSuccess;
287 test_codec(r, codec.get(), bm, info, size, expectedResult, &codecDigest, nul lptr); 287 test_codec(r, codec.get(), bm, info, size, expectedResult, &codecDigest, nul lptr);
288 288
289 // Scanline decoding follows. 289 // Scanline decoding follows.
290 290
291 if (supportsNewScanlineDecoding && !isIncomplete) { 291 if (supportsNewScanlineDecoding && !isIncomplete) {
292 test_incremental_decode(r, codec, info, codecDigest); 292 test_incremental_decode(r, codec, info, codecDigest);
293 test_in_stripes(r, codec, info, codecDigest); 293 // This is only supported by codecs that use incremental decoding to
294 // support subset decodes - png and jpeg (once SkJpegCodec is
295 // converted).
296 if (SkStrEndsWith(path, "png") || SkStrEndsWith(path, "PNG")) {
297 test_in_stripes(r, codec, info, codecDigest);
298 }
294 } 299 }
295 300
296 // Need to call startScanlineDecode() first. 301 // Need to call startScanlineDecode() first.
297 REPORTER_ASSERT(r, codec->getScanlines(bm.getAddr(0, 0), 1, 0) == 0); 302 REPORTER_ASSERT(r, codec->getScanlines(bm.getAddr(0, 0), 1, 0) == 0);
298 REPORTER_ASSERT(r, !codec->skipScanlines(1)); 303 REPORTER_ASSERT(r, !codec->skipScanlines(1));
299 const SkCodec::Result startResult = codec->startScanlineDecode(info); 304 const SkCodec::Result startResult = codec->startScanlineDecode(info);
300 if (supportsScanlineDecoding) { 305 if (supportsScanlineDecoding) {
301 bm.eraseColor(SK_ColorYELLOW); 306 bm.eraseColor(SK_ColorYELLOW);
302 307
303 REPORTER_ASSERT(r, startResult == SkCodec::kSuccess); 308 REPORTER_ASSERT(r, startResult == SkCodec::kSuccess);
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
463 468
464 // ICO 469 // ICO
465 // FIXME: We are not ready to test incomplete ICOs 470 // FIXME: We are not ready to test incomplete ICOs
466 // These two tests examine interestingly different behavior: 471 // These two tests examine interestingly different behavior:
467 // Decodes an embedded BMP image 472 // Decodes an embedded BMP image
468 check(r, "color_wheel.ico", SkISize::Make(128, 128), true, false, false); 473 check(r, "color_wheel.ico", SkISize::Make(128, 128), true, false, false);
469 // Decodes an embedded PNG image 474 // Decodes an embedded PNG image
470 check(r, "google_chrome.ico", SkISize::Make(256, 256), false, false, false, true); 475 check(r, "google_chrome.ico", SkISize::Make(256, 256), false, false, false, true);
471 476
472 // GIF 477 // GIF
473 // FIXME: We are not ready to test incomplete GIFs 478 check(r, "box.gif", SkISize::Make(200, 55), false, false, true, true);
474 check(r, "box.gif", SkISize::Make(200, 55), true, false, false); 479 check(r, "color_wheel.gif", SkISize::Make(128, 128), false, false, true, tru e);
475 check(r, "color_wheel.gif", SkISize::Make(128, 128), true, false, false);
476 // randPixels.gif is too small to test incomplete 480 // randPixels.gif is too small to test incomplete
477 check(r, "randPixels.gif", SkISize::Make(8, 8), true, false, false); 481 check(r, "randPixels.gif", SkISize::Make(8, 8), false, false, false, true);
478 482
479 // JPG 483 // JPG
480 check(r, "CMYK.jpg", SkISize::Make(642, 516), true, false, true); 484 check(r, "CMYK.jpg", SkISize::Make(642, 516), true, false, true);
481 check(r, "color_wheel.jpg", SkISize::Make(128, 128), true, false, true); 485 check(r, "color_wheel.jpg", SkISize::Make(128, 128), true, false, true);
482 // grayscale.jpg is too small to test incomplete 486 // grayscale.jpg is too small to test incomplete
483 check(r, "grayscale.jpg", SkISize::Make(128, 128), true, false, false); 487 check(r, "grayscale.jpg", SkISize::Make(128, 128), true, false, false);
484 check(r, "mandrill_512_q075.jpg", SkISize::Make(512, 512), true, false, true ); 488 check(r, "mandrill_512_q075.jpg", SkISize::Make(512, 512), true, false, true );
485 // randPixels.jpg is too small to test incomplete 489 // randPixels.jpg is too small to test incomplete
486 check(r, "randPixels.jpg", SkISize::Make(8, 8), true, false, false); 490 check(r, "randPixels.jpg", SkISize::Make(8, 8), true, false, false);
487 491
(...skipping 723 matching lines...) Expand 10 before | Expand all | Expand 10 after
1211 REPORTER_ASSERT(r, SkCodec::kUnimplemented == result); 1215 REPORTER_ASSERT(r, SkCodec::kUnimplemented == result);
1212 } 1216 }
1213 } 1217 }
1214 1218
1215 DEF_TEST(Codec_F16ConversionPossible, r) { 1219 DEF_TEST(Codec_F16ConversionPossible, r) {
1216 test_conversion_possible(r, "color_wheel.webp", false, false); 1220 test_conversion_possible(r, "color_wheel.webp", false, false);
1217 test_conversion_possible(r, "mandrill_512_q075.jpg", true, false); 1221 test_conversion_possible(r, "mandrill_512_q075.jpg", true, false);
1218 test_conversion_possible(r, "yellow_rose.png", false, true); 1222 test_conversion_possible(r, "yellow_rose.png", false, true);
1219 } 1223 }
1220 1224
1225 static void decode_frame(skiatest::Reporter* r, SkCodec* codec, size_t frame) {
1226 SkBitmap bm;
1227 auto info = codec->getInfo().makeColorType(kN32_SkColorType);
1228 bm.allocPixels(info);
1229
1230 SkCodec::Options opts;
1231 opts.fFrameIndex = frame;
1232 REPORTER_ASSERT(r, SkCodec::kSuccess == codec->getPixels(info,
1233 bm.getPixels(), bm.rowBytes(), &opts, nullptr, nullptr));
1234 }
1235
1236 // For an animated image, we should only read enough to decode the requested
1237 // frame if the client never calls getFrameInfo.
1238 DEF_TEST(Codec_skipFullParse, r) {
1239 auto path = "test640x479.gif";
1240 SkStream* stream(GetResourceAsStream(path));
1241 if (!stream) {
1242 return;
1243 }
1244
1245 // Note that we cheat and hold on to the stream pointer, but SkCodec will
1246 // take ownership. We will not refer to the stream after the SkCodec
1247 // deletes it.
1248 std::unique_ptr<SkCodec> codec(SkCodec::NewFromStream(stream));
1249 if (!codec) {
1250 ERRORF(r, "Failed to create codec for %s", path);
1251 return;
1252 }
1253
1254 REPORTER_ASSERT(r, stream->hasPosition());
1255 const size_t sizePosition = stream->getPosition();
1256 REPORTER_ASSERT(r, stream->hasLength() && sizePosition < stream->getLength() );
1257
1258 // This should read more of the stream, but not the whole stream.
1259 decode_frame(r, codec.get(), 0);
1260 const size_t positionAfterFirstFrame = stream->getPosition();
1261 REPORTER_ASSERT(r, positionAfterFirstFrame > sizePosition
1262 && positionAfterFirstFrame < stream->getLength());
1263
1264 // Again, this should read more of the stream.
1265 decode_frame(r, codec.get(), 2);
1266 const size_t positionAfterThirdFrame = stream->getPosition();
1267 REPORTER_ASSERT(r, positionAfterThirdFrame > positionAfterFirstFrame
1268 && positionAfterThirdFrame < stream->getLength());
1269
1270 // This does not need to read any more of the stream, since it has already
1271 // parsed the second frame.
1272 decode_frame(r, codec.get(), 1);
1273 REPORTER_ASSERT(r, stream->getPosition() == positionAfterThirdFrame);
1274
1275 // This should read the rest of the frames.
1276 decode_frame(r, codec.get(), 3);
1277 const size_t finalPosition = stream->getPosition();
1278 REPORTER_ASSERT(r, finalPosition > positionAfterThirdFrame);
1279
1280 // There may be more data in the stream.
1281 auto frameInfo = codec->getFrameInfo();
1282 REPORTER_ASSERT(r, frameInfo.size() == 4);
1283 REPORTER_ASSERT(r, stream->getPosition() >= finalPosition);
1284 }
1285
1221 // Only rewinds up to a limit. 1286 // Only rewinds up to a limit.
1222 class LimitedRewindingStream : public SkStream { 1287 class LimitedRewindingStream : public SkStream {
1223 public: 1288 public:
1224 static SkStream* Make(const char path[], size_t limit) { 1289 static SkStream* Make(const char path[], size_t limit) {
1225 SkStream* stream = GetResourceAsStream(path); 1290 SkStream* stream = GetResourceAsStream(path);
1226 if (!stream) { 1291 if (!stream) {
1227 return nullptr; 1292 return nullptr;
1228 } 1293 }
1229 return new LimitedRewindingStream(stream, limit); 1294 return new LimitedRewindingStream(stream, limit);
1230 } 1295 }
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1262 } 1327 }
1263 }; 1328 };
1264 1329
1265 DEF_TEST(Codec_fallBack, r) { 1330 DEF_TEST(Codec_fallBack, r) {
1266 // SkAndroidCodec needs to be able to fall back to scanline decoding 1331 // SkAndroidCodec needs to be able to fall back to scanline decoding
1267 // if incremental decoding does not work. Make sure this does not 1332 // if incremental decoding does not work. Make sure this does not
1268 // require a rewind. 1333 // require a rewind.
1269 1334
1270 // Formats that currently do not support incremental decoding 1335 // Formats that currently do not support incremental decoding
1271 auto files = { 1336 auto files = {
1272 "box.gif",
1273 "CMYK.jpg", 1337 "CMYK.jpg",
1274 "color_wheel.ico", 1338 "color_wheel.ico",
1275 "mandrill.wbmp", 1339 "mandrill.wbmp",
1276 "randPixels.bmp", 1340 "randPixels.bmp",
1277 }; 1341 };
1278 for (auto file : files) { 1342 for (auto file : files) {
1279 SkStream* stream = LimitedRewindingStream::Make(file, 14); 1343 SkStream* stream = LimitedRewindingStream::Make(file, 14);
1280 if (!stream) { 1344 if (!stream) {
1281 SkDebugf("Missing resources (%s). Set --resourcePath.\n", file); 1345 SkDebugf("Missing resources (%s). Set --resourcePath.\n", file);
1282 return; 1346 return;
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
1364 REPORTER_ASSERT(r, result == SkCodec::kIncompleteInput); 1428 REPORTER_ASSERT(r, result == SkCodec::kIncompleteInput);
1365 REPORTER_ASSERT(r, rowsDecoded == 0); 1429 REPORTER_ASSERT(r, rowsDecoded == 0);
1366 } 1430 }
1367 1431
1368 DEF_TEST(Codec_IcoIntOverflow, r) { 1432 DEF_TEST(Codec_IcoIntOverflow, r) {
1369 // ASAN will complain if there is an issue. 1433 // ASAN will complain if there is an issue.
1370 SkBitmap bitmap; 1434 SkBitmap bitmap;
1371 const bool success = GetResourceAsBitmap("invalid_images/int_overflow.ico", &bitmap); 1435 const bool success = GetResourceAsBitmap("invalid_images/int_overflow.ico", &bitmap);
1372 REPORTER_ASSERT(r, !success); 1436 REPORTER_ASSERT(r, !success);
1373 } 1437 }
OLDNEW
« no previous file with comments | « tests/CodecPartialTest.cpp ('k') | tests/GifTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698