| OLD | NEW |
| 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 "SkData.h" |
| 11 #include "SkMD5.h" | 12 #include "SkMD5.h" |
| 12 #include "SkRandom.h" | 13 #include "SkRandom.h" |
| 13 #include "SkScaledCodec.h" | 14 #include "SkScaledCodec.h" |
| 14 #include "Test.h" | 15 #include "Test.h" |
| 15 | 16 |
| 16 static SkStreamAsset* resource(const char path[]) { | 17 static SkStreamAsset* resource(const char path[]) { |
| 17 SkString fullPath = GetResourcePath(path); | 18 SkString fullPath = GetResourcePath(path); |
| 18 return SkStream::NewFromFile(fullPath.c_str()); | 19 return SkStream::NewFromFile(fullPath.c_str()); |
| 19 } | 20 } |
| 20 | 21 |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 68 rect.fLeft = rand->nextRangeU(0, w); | 69 rect.fLeft = rand->nextRangeU(0, w); |
| 69 rect.fTop = rand->nextRangeU(0, h); | 70 rect.fTop = rand->nextRangeU(0, h); |
| 70 rect.fRight = rand->nextRangeU(0, w); | 71 rect.fRight = rand->nextRangeU(0, w); |
| 71 rect.fBottom = rand->nextRangeU(0, h); | 72 rect.fBottom = rand->nextRangeU(0, h); |
| 72 rect.sort(); | 73 rect.sort(); |
| 73 } while (rect.isEmpty()); | 74 } while (rect.isEmpty()); |
| 74 return rect; | 75 return rect; |
| 75 } | 76 } |
| 76 | 77 |
| 77 static void test_codec(skiatest::Reporter* r, SkCodec* codec, SkBitmap& bm, cons
t SkImageInfo& info, | 78 static void test_codec(skiatest::Reporter* r, SkCodec* codec, SkBitmap& bm, cons
t SkImageInfo& info, |
| 78 const SkISize& size, bool supports565, SkMD5::Digest* digest, | 79 const SkISize& size, bool supports565, SkCodec::Result expectedResult, |
| 79 const SkMD5::Digest* goodDigest) { | 80 SkMD5::Digest* digest, const SkMD5::Digest* goodDigest) { |
| 81 |
| 80 REPORTER_ASSERT(r, info.dimensions() == size); | 82 REPORTER_ASSERT(r, info.dimensions() == size); |
| 81 bm.allocPixels(info); | 83 bm.allocPixels(info); |
| 82 SkAutoLockPixels autoLockPixels(bm); | 84 SkAutoLockPixels autoLockPixels(bm); |
| 83 | 85 |
| 84 SkCodec::Result result = codec->getPixels(info, bm.getPixels(), bm.rowBytes(
)); | 86 SkCodec::Result result = codec->getPixels(info, bm.getPixels(), bm.rowBytes(
)); |
| 85 REPORTER_ASSERT(r, result == SkCodec::kSuccess); | 87 REPORTER_ASSERT(r, result == expectedResult); |
| 86 | 88 |
| 87 md5(bm, digest); | 89 md5(bm, digest); |
| 88 if (goodDigest) { | 90 if (goodDigest) { |
| 89 REPORTER_ASSERT(r, *digest == *goodDigest); | 91 REPORTER_ASSERT(r, *digest == *goodDigest); |
| 90 } | 92 } |
| 91 | 93 |
| 92 { | 94 { |
| 93 // Test decoding to 565 | 95 // Test decoding to 565 |
| 94 SkImageInfo info565 = info.makeColorType(kRGB_565_SkColorType); | 96 SkImageInfo info565 = info.makeColorType(kRGB_565_SkColorType); |
| 95 SkCodec::Result expected = (supports565 && info.alphaType() == kOpaque_S
kAlphaType) ? | 97 SkCodec::Result expected565 = (supports565 && info.alphaType() == kOpaqu
e_SkAlphaType) ? |
| 96 SkCodec::kSuccess : SkCodec::kInvalidConversion; | 98 expectedResult : SkCodec::kInvalidConversion; |
| 97 test_info(r, codec, info565, expected, nullptr); | 99 test_info(r, codec, info565, expected565, nullptr); |
| 98 } | 100 } |
| 99 | 101 |
| 100 // Verify that re-decoding gives the same result. It is interesting to chec
k this after | 102 // 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 | 103 // 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 | 104 // 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. | 105 // decode to kN32, so the new digest should match the old digest. |
| 104 test_info(r, codec, info, SkCodec::kSuccess, digest); | 106 test_info(r, codec, info, expectedResult, digest); |
| 105 | 107 |
| 106 { | 108 { |
| 107 // Check alpha type conversions | 109 // Check alpha type conversions |
| 108 if (info.alphaType() == kOpaque_SkAlphaType) { | 110 if (info.alphaType() == kOpaque_SkAlphaType) { |
| 109 test_info(r, codec, info.makeAlphaType(kUnpremul_SkAlphaType), | 111 test_info(r, codec, info.makeAlphaType(kUnpremul_SkAlphaType), |
| 110 SkCodec::kInvalidConversion, nullptr); | 112 SkCodec::kInvalidConversion, nullptr); |
| 111 test_info(r, codec, info.makeAlphaType(kPremul_SkAlphaType), | 113 test_info(r, codec, info.makeAlphaType(kPremul_SkAlphaType), |
| 112 SkCodec::kInvalidConversion, nullptr); | 114 SkCodec::kInvalidConversion, nullptr); |
| 113 } else { | 115 } else { |
| 114 // Decoding to opaque should fail | 116 // Decoding to opaque should fail |
| 115 test_info(r, codec, info.makeAlphaType(kOpaque_SkAlphaType), | 117 test_info(r, codec, info.makeAlphaType(kOpaque_SkAlphaType), |
| 116 SkCodec::kInvalidConversion, nullptr); | 118 SkCodec::kInvalidConversion, nullptr); |
| 117 SkAlphaType otherAt = info.alphaType(); | 119 SkAlphaType otherAt = info.alphaType(); |
| 118 if (kPremul_SkAlphaType == otherAt) { | 120 if (kPremul_SkAlphaType == otherAt) { |
| 119 otherAt = kUnpremul_SkAlphaType; | 121 otherAt = kUnpremul_SkAlphaType; |
| 120 } else { | 122 } else { |
| 121 otherAt = kPremul_SkAlphaType; | 123 otherAt = kPremul_SkAlphaType; |
| 122 } | 124 } |
| 123 // The other non-opaque alpha type should always succeed, but not ma
tch. | 125 // The other non-opaque alpha type should always succeed, but not ma
tch. |
| 124 test_info(r, codec, info.makeAlphaType(otherAt), SkCodec::kSuccess,
nullptr); | 126 test_info(r, codec, info.makeAlphaType(otherAt), expectedResult, nul
lptr); |
| 125 } | 127 } |
| 126 } | 128 } |
| 127 } | 129 } |
| 128 | 130 |
| 129 static void check(skiatest::Reporter* r, | 131 static void check(skiatest::Reporter* r, |
| 130 const char path[], | 132 const char path[], |
| 131 SkISize size, | 133 SkISize size, |
| 132 bool supportsScanlineDecoding, | 134 bool supportsScanlineDecoding, |
| 133 bool supportsSubsetDecoding, | 135 bool supportsSubsetDecoding, |
| 134 bool supports565 = true) { | 136 bool supports565 = true, |
| 137 bool supportsIncomplete = true) { |
| 135 | 138 |
| 136 SkAutoTDelete<SkStream> stream(resource(path)); | 139 SkAutoTDelete<SkStream> stream(resource(path)); |
| 137 if (!stream) { | 140 if (!stream) { |
| 138 SkDebugf("Missing resource '%s'\n", path); | 141 SkDebugf("Missing resource '%s'\n", path); |
| 139 return; | 142 return; |
| 140 } | 143 } |
| 141 SkAutoTDelete<SkCodec> codec(SkCodec::NewFromStream(stream.detach())); | 144 |
| 145 SkAutoTDelete<SkCodec> codec(nullptr); |
| 146 bool isIncomplete = supportsIncomplete; |
| 147 if (isIncomplete) { |
| 148 size_t size = stream->getLength(); |
| 149 SkAutoTUnref<SkData> data((SkData::NewFromStream(stream, 2 * size / 3)))
; |
| 150 codec.reset(SkCodec::NewFromData(data)); |
| 151 } else { |
| 152 codec.reset(SkCodec::NewFromStream(stream.detach())); |
| 153 } |
| 142 if (!codec) { | 154 if (!codec) { |
| 143 ERRORF(r, "Unable to decode '%s'", path); | 155 ERRORF(r, "Unable to decode '%s'", path); |
| 144 return; | 156 return; |
| 145 } | 157 } |
| 146 | 158 |
| 147 // Test full image decodes with SkCodec | 159 // Test full image decodes with SkCodec |
| 148 SkMD5::Digest codecDigest; | 160 SkMD5::Digest codecDigest; |
| 149 SkImageInfo info = codec->getInfo().makeColorType(kN32_SkColorType); | 161 SkImageInfo info = codec->getInfo().makeColorType(kN32_SkColorType); |
| 150 SkBitmap bm; | 162 SkBitmap bm; |
| 151 test_codec(r, codec, bm, info, size, supports565, &codecDigest, nullptr); | 163 SkCodec::Result expectedResult = isIncomplete ? SkCodec::kIncompleteInput :
SkCodec::kSuccess; |
| 164 test_codec(r, codec, bm, info, size, supports565, expectedResult, &codecDige
st, nullptr); |
| 152 | 165 |
| 153 // Scanline decoding follows. | 166 // Scanline decoding follows. |
| 154 // Need to call startScanlineDecode() first. | 167 // Need to call startScanlineDecode() first. |
| 155 REPORTER_ASSERT(r, codec->getScanlines(bm.getAddr(0, 0), 1, 0) | 168 REPORTER_ASSERT(r, codec->getScanlines(bm.getAddr(0, 0), 1, 0) |
| 156 == SkCodec::kScanlineDecodingNotStarted); | 169 == 0); |
| 157 REPORTER_ASSERT(r, codec->skipScanlines(1) | 170 REPORTER_ASSERT(r, codec->skipScanlines(1) |
| 158 == SkCodec::kScanlineDecodingNotStarted); | 171 == 0); |
| 159 | 172 |
| 160 const SkCodec::Result startResult = codec->startScanlineDecode(info); | 173 const SkCodec::Result startResult = codec->startScanlineDecode(info); |
| 161 if (supportsScanlineDecoding) { | 174 if (supportsScanlineDecoding) { |
| 162 bm.eraseColor(SK_ColorYELLOW); | 175 bm.eraseColor(SK_ColorYELLOW); |
| 163 | 176 |
| 164 REPORTER_ASSERT(r, startResult == SkCodec::kSuccess); | 177 REPORTER_ASSERT(r, startResult == SkCodec::kSuccess); |
| 165 | 178 |
| 166 for (int y = 0; y < info.height(); y++) { | 179 for (int y = 0; y < info.height(); y++) { |
| 167 SkCodec::Result result = codec->getScanlines(bm.getAddr(0, y), 1, 0)
; | 180 const int lines = codec->getScanlines(bm.getAddr(0, y), 1, 0); |
| 168 REPORTER_ASSERT(r, result == SkCodec::kSuccess); | 181 if (!isIncomplete) { |
| 182 REPORTER_ASSERT(r, 1 == lines); |
| 183 } |
| 169 } | 184 } |
| 170 // verify that scanline decoding gives the same result. | 185 // verify that scanline decoding gives the same result. |
| 171 if (SkCodec::kTopDown_SkScanlineOrder == codec->getScanlineOrder()) { | 186 if (SkCodec::kTopDown_SkScanlineOrder == codec->getScanlineOrder()) { |
| 172 compare_to_good_digest(r, codecDigest, bm); | 187 compare_to_good_digest(r, codecDigest, bm); |
| 173 } | 188 } |
| 174 | 189 |
| 175 // Cannot continue to decode scanlines beyond the end | 190 // Cannot continue to decode scanlines beyond the end |
| 176 REPORTER_ASSERT(r, codec->getScanlines(bm.getAddr(0, 0), 1, 0) | 191 REPORTER_ASSERT(r, codec->getScanlines(bm.getAddr(0, 0), 1, 0) |
| 177 == SkCodec::kInvalidParameters); | 192 == 0); |
| 178 | 193 |
| 179 // Interrupting a scanline decode with a full decode starts from | 194 // Interrupting a scanline decode with a full decode starts from |
| 180 // scratch | 195 // scratch |
| 181 REPORTER_ASSERT(r, codec->startScanlineDecode(info) == SkCodec::kSuccess
); | 196 REPORTER_ASSERT(r, codec->startScanlineDecode(info) == SkCodec::kSuccess
); |
| 197 const int lines = codec->getScanlines(bm.getAddr(0, 0), 1, 0); |
| 198 if (!isIncomplete) { |
| 199 REPORTER_ASSERT(r, lines == 1); |
| 200 } |
| 201 REPORTER_ASSERT(r, codec->getPixels(bm.info(), bm.getPixels(), bm.rowByt
es()) |
| 202 == expectedResult); |
| 182 REPORTER_ASSERT(r, codec->getScanlines(bm.getAddr(0, 0), 1, 0) | 203 REPORTER_ASSERT(r, codec->getScanlines(bm.getAddr(0, 0), 1, 0) |
| 183 == SkCodec::kSuccess); | 204 == 0); |
| 184 REPORTER_ASSERT(r, codec->getPixels(bm.info(), bm.getPixels(), bm.rowByt
es()) | |
| 185 == SkCodec::kSuccess); | |
| 186 REPORTER_ASSERT(r, codec->getScanlines(bm.getAddr(0, 0), 1, 0) | |
| 187 == SkCodec::kScanlineDecodingNotStarted); | |
| 188 REPORTER_ASSERT(r, codec->skipScanlines(1) | 205 REPORTER_ASSERT(r, codec->skipScanlines(1) |
| 189 == SkCodec::kScanlineDecodingNotStarted); | 206 == 0); |
| 190 } else { | 207 } else { |
| 191 REPORTER_ASSERT(r, startResult == SkCodec::kUnimplemented); | 208 REPORTER_ASSERT(r, startResult == SkCodec::kUnimplemented); |
| 192 } | 209 } |
| 193 | 210 |
| 194 // The rest of this function tests decoding subsets, and will decode an arbi
trary number of | 211 // The rest of this function tests decoding subsets, and will decode an arbi
trary number of |
| 195 // random subsets. | 212 // random subsets. |
| 196 // Do not attempt to decode subsets of an image of only once pixel, since th
ere is no | 213 // Do not attempt to decode subsets of an image of only once pixel, since th
ere is no |
| 197 // meaningful subset. | 214 // meaningful subset. |
| 198 if (size.width() * size.height() == 1) { | 215 if (size.width() * size.height() == 1) { |
| 199 return; | 216 return; |
| 200 } | 217 } |
| 201 | 218 |
| 202 SkRandom rand; | 219 SkRandom rand; |
| 203 SkIRect subset; | 220 SkIRect subset; |
| 204 SkCodec::Options opts; | 221 SkCodec::Options opts; |
| 205 opts.fSubset = ⊂ | 222 opts.fSubset = ⊂ |
| 206 for (int i = 0; i < 5; i++) { | 223 for (int i = 0; i < 5; i++) { |
| 207 subset = generate_random_subset(&rand, size.width(), size.height()); | 224 subset = generate_random_subset(&rand, size.width(), size.height()); |
| 208 SkASSERT(!subset.isEmpty()); | 225 SkASSERT(!subset.isEmpty()); |
| 209 const bool supported = codec->getValidSubset(&subset); | 226 const bool supported = codec->getValidSubset(&subset); |
| 210 REPORTER_ASSERT(r, supported == supportsSubsetDecoding); | 227 REPORTER_ASSERT(r, supported == supportsSubsetDecoding); |
| 211 | 228 |
| 212 SkImageInfo subsetInfo = info.makeWH(subset.width(), subset.height()); | 229 SkImageInfo subsetInfo = info.makeWH(subset.width(), subset.height()); |
| 213 SkBitmap bm; | 230 SkBitmap bm; |
| 214 bm.allocPixels(subsetInfo); | 231 bm.allocPixels(subsetInfo); |
| 215 const SkCodec::Result result = codec->getPixels(bm.info(), bm.getPixels(
), bm.rowBytes(), | 232 const SkCodec::Result result = codec->getPixels(bm.info(), bm.getPixels(
), bm.rowBytes(), |
| 216 &opts, nullptr, nullptr)
; | 233 &opts, nullptr, nullptr)
; |
| 217 | 234 |
| 218 if (supportsSubsetDecoding) { | 235 if (supportsSubsetDecoding) { |
| 219 REPORTER_ASSERT(r, result == SkCodec::kSuccess); | 236 REPORTER_ASSERT(r, result == expectedResult); |
| 220 // Webp is the only codec that supports subsets, and it will have mo
dified the subset | 237 // Webp is the only codec that supports subsets, and it will have mo
dified the subset |
| 221 // to have even left/top. | 238 // to have even left/top. |
| 222 REPORTER_ASSERT(r, SkIsAlign2(subset.fLeft) && SkIsAlign2(subset.fTo
p)); | 239 REPORTER_ASSERT(r, SkIsAlign2(subset.fLeft) && SkIsAlign2(subset.fTo
p)); |
| 223 } else { | 240 } else { |
| 224 // No subsets will work. | 241 // No subsets will work. |
| 225 REPORTER_ASSERT(r, result == SkCodec::kUnimplemented); | 242 REPORTER_ASSERT(r, result == SkCodec::kUnimplemented); |
| 226 } | 243 } |
| 227 } | 244 } |
| 228 | 245 |
| 229 // SkScaledCodec tests | 246 // SkScaledCodec tests |
| 230 if (supportsScanlineDecoding || supportsSubsetDecoding){ | 247 if (supportsScanlineDecoding || supportsSubsetDecoding){ |
| 231 SkAutoTDelete<SkStream> stream(resource(path)); | 248 SkAutoTDelete<SkStream> stream(resource(path)); |
| 232 if (!stream) { | 249 if (!stream) { |
| 233 SkDebugf("Missing resource '%s'\n", path); | 250 SkDebugf("Missing resource '%s'\n", path); |
| 234 return; | 251 return; |
| 235 } | 252 } |
| 236 SkAutoTDelete<SkCodec> codec(SkScaledCodec::NewFromStream(stream.detach(
))); | 253 |
| 254 SkAutoTDelete<SkCodec> codec(nullptr); |
| 255 if (isIncomplete) { |
| 256 size_t size = stream->getLength(); |
| 257 SkAutoTUnref<SkData> data((SkData::NewFromStream(stream, 2 * size /
3))); |
| 258 codec.reset(SkScaledCodec::NewFromData(data)); |
| 259 } else { |
| 260 codec.reset(SkScaledCodec::NewFromStream(stream.detach())); |
| 261 } |
| 237 if (!codec) { | 262 if (!codec) { |
| 238 ERRORF(r, "Unable to decode '%s'", path); | 263 ERRORF(r, "Unable to decode '%s'", path); |
| 239 return; | 264 return; |
| 240 } | 265 } |
| 241 | 266 |
| 242 SkBitmap bm; | 267 SkBitmap bm; |
| 243 SkMD5::Digest scaledCodecDigest; | 268 SkMD5::Digest scaledCodecDigest; |
| 244 test_codec(r, codec, bm, info, size, supports565, &scaledCodecDigest, &c
odecDigest); | 269 test_codec(r, codec, bm, info, size, supports565, expectedResult, &scale
dCodecDigest, |
| 270 &codecDigest); |
| 271 } |
| 272 |
| 273 // If we've just tested incomplete decodes, let's run the same test again on
full decodes. |
| 274 if (isIncomplete) { |
| 275 check(r, path, size, supportsScanlineDecoding, supportsSubsetDecoding, s
upports565, false); |
| 245 } | 276 } |
| 246 } | 277 } |
| 247 | 278 |
| 248 DEF_TEST(Codec, r) { | 279 DEF_TEST(Codec, r) { |
| 249 // WBMP | 280 // WBMP |
| 250 check(r, "mandrill.wbmp", SkISize::Make(512, 512), true, false); | 281 check(r, "mandrill.wbmp", SkISize::Make(512, 512), true, false); |
| 251 | 282 |
| 252 // WEBP | 283 // WEBP |
| 253 check(r, "baby_tux.webp", SkISize::Make(386, 395), false, true); | 284 check(r, "baby_tux.webp", SkISize::Make(386, 395), false, true); |
| 254 check(r, "color_wheel.webp", SkISize::Make(128, 128), false, true); | 285 check(r, "color_wheel.webp", SkISize::Make(128, 128), false, true); |
| 255 check(r, "yellow_rose.webp", SkISize::Make(400, 301), false, true); | 286 check(r, "yellow_rose.webp", SkISize::Make(400, 301), false, true); |
| 256 | 287 |
| 257 // BMP | 288 // BMP |
| 258 check(r, "randPixels.bmp", SkISize::Make(8, 8), true, false); | 289 check(r, "randPixels.bmp", SkISize::Make(8, 8), true, false); |
| 259 | 290 |
| 260 // ICO | 291 // ICO |
| 292 // FIXME: We are not ready to test incomplete ICOs |
| 261 // These two tests examine interestingly different behavior: | 293 // These two tests examine interestingly different behavior: |
| 262 // Decodes an embedded BMP image | 294 // Decodes an embedded BMP image |
| 263 check(r, "color_wheel.ico", SkISize::Make(128, 128), false, false); | 295 check(r, "color_wheel.ico", SkISize::Make(128, 128), false, false, true, fal
se); |
| 264 // Decodes an embedded PNG image | 296 // Decodes an embedded PNG image |
| 265 check(r, "google_chrome.ico", SkISize::Make(256, 256), false, false); | 297 check(r, "google_chrome.ico", SkISize::Make(256, 256), false, false, true, f
alse); |
| 266 | 298 |
| 267 // GIF | 299 // GIF |
| 268 check(r, "box.gif", SkISize::Make(200, 55), true, false); | 300 // FIXME: We are not ready to test incomplete GIFs |
| 269 check(r, "color_wheel.gif", SkISize::Make(128, 128), true, false); | 301 check(r, "box.gif", SkISize::Make(200, 55), true, false, true, false); |
| 270 check(r, "randPixels.gif", SkISize::Make(8, 8), true, false); | 302 check(r, "color_wheel.gif", SkISize::Make(128, 128), true, false, true, fals
e); |
| 303 // randPixels.gif is too small to test incomplete |
| 304 check(r, "randPixels.gif", SkISize::Make(8, 8), true, false, true, false); |
| 271 | 305 |
| 272 // JPG | 306 // JPG |
| 273 check(r, "CMYK.jpg", SkISize::Make(642, 516), true, false, false); | 307 check(r, "CMYK.jpg", SkISize::Make(642, 516), true, false, false); |
| 274 check(r, "color_wheel.jpg", SkISize::Make(128, 128), true, false); | 308 check(r, "color_wheel.jpg", SkISize::Make(128, 128), true, false); |
| 275 check(r, "grayscale.jpg", SkISize::Make(128, 128), true, false); | 309 // grayscale.jpg is too small to test incomplete |
| 310 check(r, "grayscale.jpg", SkISize::Make(128, 128), true, false, true, false)
; |
| 276 check(r, "mandrill_512_q075.jpg", SkISize::Make(512, 512), true, false); | 311 check(r, "mandrill_512_q075.jpg", SkISize::Make(512, 512), true, false); |
| 277 check(r, "randPixels.jpg", SkISize::Make(8, 8), true, false); | 312 // randPixels.jpg is too small to test incomplete |
| 313 check(r, "randPixels.jpg", SkISize::Make(8, 8), true, false, true, false); |
| 278 | 314 |
| 279 // PNG | 315 // PNG |
| 280 check(r, "arrow.png", SkISize::Make(187, 312), true, false); | 316 check(r, "arrow.png", SkISize::Make(187, 312), true, false, true, false); |
| 281 check(r, "baby_tux.png", SkISize::Make(240, 246), true, false); | 317 check(r, "baby_tux.png", SkISize::Make(240, 246), true, false, true, false); |
| 282 check(r, "color_wheel.png", SkISize::Make(128, 128), true, false); | 318 check(r, "color_wheel.png", SkISize::Make(128, 128), true, false, true, fals
e); |
| 283 check(r, "half-transparent-white-pixel.png", SkISize::Make(1, 1), true, fals
e); | 319 check(r, "half-transparent-white-pixel.png", SkISize::Make(1, 1), true, fals
e, true, false); |
| 284 check(r, "mandrill_128.png", SkISize::Make(128, 128), true, false); | 320 check(r, "mandrill_128.png", SkISize::Make(128, 128), true, false, true, fal
se); |
| 285 check(r, "mandrill_16.png", SkISize::Make(16, 16), true, false); | 321 check(r, "mandrill_16.png", SkISize::Make(16, 16), true, false, true, false)
; |
| 286 check(r, "mandrill_256.png", SkISize::Make(256, 256), true, false); | 322 check(r, "mandrill_256.png", SkISize::Make(256, 256), true, false, true, fal
se); |
| 287 check(r, "mandrill_32.png", SkISize::Make(32, 32), true, false); | 323 check(r, "mandrill_32.png", SkISize::Make(32, 32), true, false, true, false)
; |
| 288 check(r, "mandrill_512.png", SkISize::Make(512, 512), true, false); | 324 check(r, "mandrill_512.png", SkISize::Make(512, 512), true, false, true, fal
se); |
| 289 check(r, "mandrill_64.png", SkISize::Make(64, 64), true, false); | 325 check(r, "mandrill_64.png", SkISize::Make(64, 64), true, false, true, false)
; |
| 290 check(r, "plane.png", SkISize::Make(250, 126), true, false); | 326 check(r, "plane.png", SkISize::Make(250, 126), true, false, true, false); |
| 291 check(r, "plane_interlaced.png", SkISize::Make(250, 126), true, false); | 327 // FIXME: We are not ready to test incomplete interlaced pngs |
| 292 check(r, "randPixels.png", SkISize::Make(8, 8), true, false); | 328 check(r, "plane_interlaced.png", SkISize::Make(250, 126), true, false, true,
false); |
| 293 check(r, "yellow_rose.png", SkISize::Make(400, 301), true, false); | 329 check(r, "randPixels.png", SkISize::Make(8, 8), true, false, true, false); |
| 330 check(r, "yellow_rose.png", SkISize::Make(400, 301), true, false, true, fals
e); |
| 294 } | 331 } |
| 295 | 332 |
| 296 // Test interlaced PNG in stripes, similar to DM's kStripe_Mode | 333 // Test interlaced PNG in stripes, similar to DM's kStripe_Mode |
| 297 DEF_TEST(Codec_stripes, r) { | 334 DEF_TEST(Codec_stripes, r) { |
| 298 const char * path = "plane_interlaced.png"; | 335 const char * path = "plane_interlaced.png"; |
| 299 SkAutoTDelete<SkStream> stream(resource(path)); | 336 SkAutoTDelete<SkStream> stream(resource(path)); |
| 300 if (!stream) { | 337 if (!stream) { |
| 301 SkDebugf("Missing resource '%s'\n", path); | 338 SkDebugf("Missing resource '%s'\n", path); |
| 302 } | 339 } |
| 303 | 340 |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 337 SkTDivMod(height, numStripes, &stripeHeight, &remainingLines); | 374 SkTDivMod(height, numStripes, &stripeHeight, &remainingLines); |
| 338 | 375 |
| 339 bm.eraseColor(SK_ColorYELLOW); | 376 bm.eraseColor(SK_ColorYELLOW); |
| 340 | 377 |
| 341 result = codec->startScanlineDecode(info); | 378 result = codec->startScanlineDecode(info); |
| 342 REPORTER_ASSERT(r, result == SkCodec::kSuccess); | 379 REPORTER_ASSERT(r, result == SkCodec::kSuccess); |
| 343 | 380 |
| 344 // Odd stripes | 381 // Odd stripes |
| 345 for (int i = 1; i < numStripes; i += 2) { | 382 for (int i = 1; i < numStripes; i += 2) { |
| 346 // Skip the even stripes | 383 // Skip the even stripes |
| 347 result = codec->skipScanlines(stripeHeight); | 384 bool skipResult = codec->skipScanlines(stripeHeight); |
| 348 REPORTER_ASSERT(r, result == SkCodec::kSuccess); | 385 REPORTER_ASSERT(r, skipResult); |
| 349 | 386 |
| 350 result = codec->getScanlines(bm.getAddr(0, i * stripeHeight), stripeHeig
ht, | 387 int linesDecoded = codec->getScanlines(bm.getAddr(0, i * stripeHeight),
stripeHeight, |
| 351 bm.rowBytes()); | 388 bm.rowBytes()); |
| 352 REPORTER_ASSERT(r, result == SkCodec::kSuccess); | 389 REPORTER_ASSERT(r, linesDecoded == stripeHeight); |
| 353 } | 390 } |
| 354 | 391 |
| 355 // Even stripes | 392 // Even stripes |
| 356 result = codec->startScanlineDecode(info); | 393 result = codec->startScanlineDecode(info); |
| 357 REPORTER_ASSERT(r, result == SkCodec::kSuccess); | 394 REPORTER_ASSERT(r, result == SkCodec::kSuccess); |
| 358 | 395 |
| 359 for (int i = 0; i < numStripes; i += 2) { | 396 for (int i = 0; i < numStripes; i += 2) { |
| 360 result = codec->getScanlines(bm.getAddr(0, i * stripeHeight), stripeHeig
ht, | 397 int linesDecoded = codec->getScanlines(bm.getAddr(0, i * stripeHeight),
stripeHeight, |
| 361 bm.rowBytes()); | 398 bm.rowBytes()); |
| 362 REPORTER_ASSERT(r, result == SkCodec::kSuccess); | 399 REPORTER_ASSERT(r, linesDecoded == stripeHeight); |
| 363 | 400 |
| 364 // Skip the odd stripes | 401 // Skip the odd stripes |
| 365 if (i + 1 < numStripes) { | 402 if (i + 1 < numStripes) { |
| 366 result = codec->skipScanlines(stripeHeight); | 403 bool skipResult = codec->skipScanlines(stripeHeight); |
| 367 REPORTER_ASSERT(r, result == SkCodec::kSuccess); | 404 REPORTER_ASSERT(r, skipResult); |
| 368 } | 405 } |
| 369 } | 406 } |
| 370 | 407 |
| 371 // Remainder at the end | 408 // Remainder at the end |
| 372 if (remainingLines > 0) { | 409 if (remainingLines > 0) { |
| 373 result = codec->startScanlineDecode(info); | 410 result = codec->startScanlineDecode(info); |
| 374 REPORTER_ASSERT(r, result == SkCodec::kSuccess); | 411 REPORTER_ASSERT(r, result == SkCodec::kSuccess); |
| 375 | 412 |
| 376 result = codec->skipScanlines(height - remainingLines); | 413 bool skipResult = codec->skipScanlines(height - remainingLines); |
| 377 REPORTER_ASSERT(r, result == SkCodec::kSuccess); | 414 REPORTER_ASSERT(r, skipResult); |
| 378 | 415 |
| 379 result = codec->getScanlines(bm.getAddr(0, height - remainingLines), | 416 int linesDecoded = codec->getScanlines(bm.getAddr(0, height - remainingL
ines), |
| 380 remainingLines, bm.rowBytes()); | 417 remainingLines, bm.rowBytes()); |
| 381 REPORTER_ASSERT(r, result == SkCodec::kSuccess); | 418 REPORTER_ASSERT(r, linesDecoded == remainingLines); |
| 382 } | 419 } |
| 383 | 420 |
| 384 compare_to_good_digest(r, digest, bm); | 421 compare_to_good_digest(r, digest, bm); |
| 385 } | 422 } |
| 386 | 423 |
| 387 static void test_invalid_stream(skiatest::Reporter* r, const void* stream, size_
t len) { | 424 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)); | 425 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. | 426 // We should not have gotten a codec. Bots should catch us if we leaked anyt
hing. |
| 390 REPORTER_ASSERT(r, !codec); | 427 REPORTER_ASSERT(r, !codec); |
| 391 } | 428 } |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 522 REPORTER_ASSERT(r, SkCodec::kInvalidParameters == result); | 559 REPORTER_ASSERT(r, SkCodec::kInvalidParameters == result); |
| 523 result = decoder->startScanlineDecode( | 560 result = decoder->startScanlineDecode( |
| 524 decoder->getInfo().makeColorType(kIndex_8_SkColorType)); | 561 decoder->getInfo().makeColorType(kIndex_8_SkColorType)); |
| 525 REPORTER_ASSERT(r, SkCodec::kInvalidParameters == result); | 562 REPORTER_ASSERT(r, SkCodec::kInvalidParameters == result); |
| 526 } | 563 } |
| 527 | 564 |
| 528 DEF_TEST(Codec_Params, r) { | 565 DEF_TEST(Codec_Params, r) { |
| 529 test_invalid_parameters(r, "index8.png"); | 566 test_invalid_parameters(r, "index8.png"); |
| 530 test_invalid_parameters(r, "mandrill.wbmp"); | 567 test_invalid_parameters(r, "mandrill.wbmp"); |
| 531 } | 568 } |
| OLD | NEW |