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

Side by Side Diff: tests/ImageDecodingTest.cpp

Issue 93703004: Change SkDecodingImageGenerator API (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: rebased Created 6 years, 11 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 | Annotate | Revision Log
« no previous file with comments | « tests/CachedDecodingPixelRefTest.cpp ('k') | tests/PictureTest.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 2013 Google Inc. 2 * Copyright 2013 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 "Test.h" 8 #include "Test.h"
9 #include "TestClassDef.h" 9 #include "TestClassDef.h"
10 #include "SkBitmap.h" 10 #include "SkBitmap.h"
11 #include "SkCanvas.h" 11 #include "SkCanvas.h"
12 #include "SkColor.h" 12 #include "SkColor.h"
13 #include "SkColorPriv.h" 13 #include "SkColorPriv.h"
14 #include "SkData.h" 14 #include "SkData.h"
15 #include "SkDecodingImageGenerator.h" 15 #include "SkDecodingImageGenerator.h"
16 #include "SkDiscardableMemoryPool.h"
16 #include "SkForceLinking.h" 17 #include "SkForceLinking.h"
17 #include "SkGradientShader.h" 18 #include "SkGradientShader.h"
18 #include "SkImageDecoder.h" 19 #include "SkImageDecoder.h"
19 #include "SkImageEncoder.h" 20 #include "SkImageEncoder.h"
21 #include "SkImageGenerator.h"
22 #include "SkImagePriv.h"
20 #include "SkOSFile.h" 23 #include "SkOSFile.h"
21 #include "SkPoint.h" 24 #include "SkPoint.h"
22 #include "SkShader.h" 25 #include "SkShader.h"
23 #include "SkStream.h" 26 #include "SkStream.h"
24 #include "SkString.h" 27 #include "SkString.h"
25 28
26 __SK_FORCE_IMAGE_DECODER_LINKING; 29 __SK_FORCE_IMAGE_DECODER_LINKING;
27 30
28 /** 31 /**
29 * Interprets c as an unpremultiplied color, and returns the 32 * Interprets c as an unpremultiplied color, and returns the
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
146 SkString resourcePath = skiatest::Test::GetResourcePath(); 149 SkString resourcePath = skiatest::Test::GetResourcePath();
147 if (resourcePath.isEmpty()) { 150 if (resourcePath.isEmpty()) {
148 SkDebugf("Could not run unpremul test because resourcePath not specified ."); 151 SkDebugf("Could not run unpremul test because resourcePath not specified .");
149 return; 152 return;
150 } 153 }
151 SkOSFile::Iter iter(resourcePath.c_str()); 154 SkOSFile::Iter iter(resourcePath.c_str());
152 SkString basename; 155 SkString basename;
153 if (iter.next(&basename)) { 156 if (iter.next(&basename)) {
154 do { 157 do {
155 SkString filename = SkOSPath::SkPathJoin(resourcePath.c_str(), basen ame.c_str()); 158 SkString filename = SkOSPath::SkPathJoin(resourcePath.c_str(), basen ame.c_str());
156 //SkDebugf("about to decode \"%s\"\n", filename.c_str()); 159 // SkDebugf("about to decode \"%s\"\n", filename.c_str());
157 compare_unpremul(reporter, filename); 160 compare_unpremul(reporter, filename);
158 } while (iter.next(&basename)); 161 } while (iter.next(&basename));
159 } else { 162 } else {
160 SkDebugf("Failed to find any files :(\n"); 163 SkDebugf("Failed to find any files :(\n");
161 } 164 }
162 } 165 }
163 166
164 #ifdef SK_DEBUG 167 #ifdef SK_DEBUG
165 // Create a stream containing a bitmap encoded to Type type. 168 // Create a stream containing a bitmap encoded to Type type.
166 static SkMemoryStream* create_image_stream(SkImageEncoder::Type type) { 169 static SkMemoryStream* create_image_stream(SkImageEncoder::Type type) {
(...skipping 27 matching lines...) Expand all
194 // Only runs in debug mode since we are testing for a crash. 197 // Only runs in debug mode since we are testing for a crash.
195 static void test_stream_life() { 198 static void test_stream_life() {
196 const SkImageEncoder::Type gTypes[] = { 199 const SkImageEncoder::Type gTypes[] = {
197 #ifdef SK_BUILD_FOR_ANDROID 200 #ifdef SK_BUILD_FOR_ANDROID
198 SkImageEncoder::kJPEG_Type, 201 SkImageEncoder::kJPEG_Type,
199 SkImageEncoder::kPNG_Type, 202 SkImageEncoder::kPNG_Type,
200 #endif 203 #endif
201 SkImageEncoder::kWEBP_Type, 204 SkImageEncoder::kWEBP_Type,
202 }; 205 };
203 for (size_t i = 0; i < SK_ARRAY_COUNT(gTypes); ++i) { 206 for (size_t i = 0; i < SK_ARRAY_COUNT(gTypes); ++i) {
204 //SkDebugf("encoding to %i\n", i); 207 // SkDebugf("encoding to %i\n", i);
205 SkAutoTUnref<SkMemoryStream> stream(create_image_stream(gTypes[i])); 208 SkAutoTUnref<SkMemoryStream> stream(create_image_stream(gTypes[i]));
206 if (NULL == stream.get()) { 209 if (NULL == stream.get()) {
207 SkDebugf("no stream\n"); 210 SkDebugf("no stream\n");
208 continue; 211 continue;
209 } 212 }
210 SkAutoTDelete<SkImageDecoder> decoder(SkImageDecoder::Factory(stream)); 213 SkAutoTDelete<SkImageDecoder> decoder(SkImageDecoder::Factory(stream));
211 if (NULL == decoder.get()) { 214 if (NULL == decoder.get()) {
212 SkDebugf("no decoder\n"); 215 SkDebugf("no decoder\n");
213 continue; 216 continue;
214 } 217 }
215 int width, height; 218 int width, height;
216 if (!decoder->buildTileIndex(stream.get(), &width, &height)) { 219 if (!decoder->buildTileIndex(stream.get(), &width, &height)) {
217 SkDebugf("could not build a tile index\n"); 220 SkDebugf("could not build a tile index\n");
218 continue; 221 continue;
219 } 222 }
220 // Now unref the stream to make sure it survives 223 // Now unref the stream to make sure it survives
221 stream.reset(NULL); 224 stream.reset(NULL);
222 SkBitmap bm; 225 SkBitmap bm;
223 decoder->decodeSubset(&bm, SkIRect::MakeWH(width, height), 226 decoder->decodeSubset(&bm, SkIRect::MakeWH(width, height),
224 SkBitmap::kARGB_8888_Config); 227 SkBitmap::kARGB_8888_Config);
225 } 228 }
226 } 229 }
227 230
228 // Test inside SkScaledBitmapSampler.cpp 231 // Test inside SkScaledBitmapSampler.cpp
229 extern void test_row_proc_choice(); 232 extern void test_row_proc_choice();
230 233
231 #endif // SK_DEBUG 234 #endif // SK_DEBUG
232 235
233 DEF_TEST(ImageDecoding, reporter) { 236 DEF_TEST(ImageDecoding, reporter) {
234 test_unpremul(reporter); 237 test_unpremul(reporter);
235 #ifdef SK_DEBUG 238 #ifdef SK_DEBUG
236 test_stream_life(); 239 test_stream_life();
237 test_row_proc_choice(); 240 test_row_proc_choice();
238 #endif 241 #endif
239 } 242 }
240 243
241 //////////////////////////////////////////////////////////////////////////////// 244 ////////////////////////////////////////////////////////////////////////////////
245 namespace {
246 // expected output for 8x8 bitmap
247 const int kExpectedWidth = 8;
248 const int kExpectedHeight = 8;
249 const SkColor kExpectedPixels[] = {
250 0xffbba570, 0xff395f5d, 0xffe25c39, 0xff197666,
251 0xff3cba27, 0xffdefcb0, 0xffc13874, 0xfffa0093,
252 0xffbda60e, 0xffc01db6, 0xff2bd688, 0xff9362d4,
253 0xffc641b2, 0xffa5cede, 0xff606eba, 0xff8f4bf3,
254 0xff3bf742, 0xff8f02a8, 0xff5509df, 0xffc7027e,
255 0xff24aa8a, 0xff886c96, 0xff625481, 0xff403689,
256 0xffc52152, 0xff78ccd6, 0xffdcb4ab, 0xff09d27d,
257 0xffca00f3, 0xff605d47, 0xff446fb2, 0xff576e46,
258 0xff273df9, 0xffb41a83, 0xfff812c3, 0xffccab67,
259 0xff034218, 0xff7db9a7, 0xff821048, 0xfffe4ab4,
260 0xff6fac98, 0xff941d27, 0xff5fe411, 0xfffbb283,
261 0xffd86e99, 0xff169162, 0xff71128c, 0xff39cab4,
262 0xffa7fe63, 0xff4c956b, 0xffbc22e0, 0xffb272e4,
263 0xff129f4a, 0xffe34513, 0xff3d3742, 0xffbd190a,
264 0xffb07222, 0xff2e23f8, 0xfff089d9, 0xffb35738,
265 0xffa86022, 0xff3340fe, 0xff95fe71, 0xff6a71df
266 };
267 SK_COMPILE_ASSERT((kExpectedWidth * kExpectedHeight)
268 == SK_ARRAY_COUNT(kExpectedPixels), array_size_mismatch);
269 } // namespace
242 270
243 DEF_TEST(WebP, reporter) { 271 DEF_TEST(WebP, reporter) {
244 const unsigned char encodedWebP[] = { 272 const unsigned char encodedWebP[] = {
245 0x52, 0x49, 0x46, 0x46, 0x2c, 0x01, 0x00, 0x00, 0x57, 0x45, 0x42, 0x50, 273 0x52, 0x49, 0x46, 0x46, 0x2c, 0x01, 0x00, 0x00, 0x57, 0x45, 0x42, 0x50,
246 0x56, 0x50, 0x38, 0x4c, 0x20, 0x01, 0x00, 0x00, 0x2f, 0x07, 0xc0, 0x01, 274 0x56, 0x50, 0x38, 0x4c, 0x20, 0x01, 0x00, 0x00, 0x2f, 0x07, 0xc0, 0x01,
247 0x00, 0xff, 0x01, 0x45, 0x03, 0x00, 0xe2, 0xd5, 0xae, 0x60, 0x2b, 0xad, 275 0x00, 0xff, 0x01, 0x45, 0x03, 0x00, 0xe2, 0xd5, 0xae, 0x60, 0x2b, 0xad,
248 0xd9, 0x68, 0x76, 0xb6, 0x8d, 0x6a, 0x1d, 0xc0, 0xe6, 0x19, 0xd6, 0x16, 276 0xd9, 0x68, 0x76, 0xb6, 0x8d, 0x6a, 0x1d, 0xc0, 0xe6, 0x19, 0xd6, 0x16,
249 0xb7, 0xb4, 0xef, 0xcf, 0xc3, 0x15, 0x6c, 0xb3, 0xbd, 0x77, 0x0d, 0x85, 277 0xb7, 0xb4, 0xef, 0xcf, 0xc3, 0x15, 0x6c, 0xb3, 0xbd, 0x77, 0x0d, 0x85,
250 0x6d, 0x1b, 0xa9, 0xb1, 0x2b, 0xdc, 0x3d, 0x83, 0xdb, 0x00, 0x00, 0xc8, 278 0x6d, 0x1b, 0xa9, 0xb1, 0x2b, 0xdc, 0x3d, 0x83, 0xdb, 0x00, 0x00, 0xc8,
251 0x26, 0xe5, 0x01, 0x99, 0x8a, 0xd5, 0xdd, 0xfc, 0x82, 0xcd, 0xcd, 0x9a, 279 0x26, 0xe5, 0x01, 0x99, 0x8a, 0xd5, 0xdd, 0xfc, 0x82, 0xcd, 0xcd, 0x9a,
(...skipping 10 matching lines...) Expand all
262 0x03, 0x45, 0x29, 0xe0, 0xe2, 0x4a, 0xc3, 0xa2, 0xe8, 0xe0, 0x25, 0x12, 290 0x03, 0x45, 0x29, 0xe0, 0xe2, 0x4a, 0xc3, 0xa2, 0xe8, 0xe0, 0x25, 0x12,
263 0x74, 0xc6, 0xe8, 0xfb, 0x93, 0x4f, 0x9f, 0x5e, 0xc0, 0xa6, 0x91, 0x1b, 291 0x74, 0xc6, 0xe8, 0xfb, 0x93, 0x4f, 0x9f, 0x5e, 0xc0, 0xa6, 0x91, 0x1b,
264 0xa4, 0x24, 0x82, 0xc3, 0x61, 0x07, 0x4c, 0x49, 0x4f, 0x53, 0xae, 0x5f, 292 0xa4, 0x24, 0x82, 0xc3, 0x61, 0x07, 0x4c, 0x49, 0x4f, 0x53, 0xae, 0x5f,
265 0x5d, 0x39, 0x36, 0xc0, 0x5b, 0x57, 0x54, 0x60, 0x10, 0x00, 0x00, 0xd1, 293 0x5d, 0x39, 0x36, 0xc0, 0x5b, 0x57, 0x54, 0x60, 0x10, 0x00, 0x00, 0xd1,
266 0x68, 0xb6, 0x6d, 0xdb, 0x36, 0x22, 0xfa, 0x1f, 0x35, 0x75, 0x22, 0xec, 294 0x68, 0xb6, 0x6d, 0xdb, 0x36, 0x22, 0xfa, 0x1f, 0x35, 0x75, 0x22, 0xec,
267 0x31, 0xbc, 0x5d, 0x8f, 0x87, 0x53, 0xa2, 0x05, 0x8c, 0x2f, 0xcd, 0xa8, 295 0x31, 0xbc, 0x5d, 0x8f, 0x87, 0x53, 0xa2, 0x05, 0x8c, 0x2f, 0xcd, 0xa8,
268 0xa7, 0xf3, 0xa3, 0xbd, 0x83, 0x8b, 0x2a, 0xc8, 0x58, 0xf5, 0xac, 0x80, 296 0xa7, 0xf3, 0xa3, 0xbd, 0x83, 0x8b, 0x2a, 0xc8, 0x58, 0xf5, 0xac, 0x80,
269 0xe3, 0xfe, 0x66, 0xa4, 0x7c, 0x1b, 0x6c, 0xd1, 0xa9, 0xd8, 0x14, 0xd0, 297 0xe3, 0xfe, 0x66, 0xa4, 0x7c, 0x1b, 0x6c, 0xd1, 0xa9, 0xd8, 0x14, 0xd0,
270 0xc5, 0xb5, 0x39, 0x71, 0x97, 0x19, 0x19, 0x1b 298 0xc5, 0xb5, 0x39, 0x71, 0x97, 0x19, 0x19, 0x1b
271 }; 299 };
272 const SkColor thePixels[] = {
273 0xffbba570, 0xff395f5d, 0xffe25c39, 0xff197666,
274 0xff3cba27, 0xffdefcb0, 0xffc13874, 0xfffa0093,
275 0xffbda60e, 0xffc01db6, 0xff2bd688, 0xff9362d4,
276 0xffc641b2, 0xffa5cede, 0xff606eba, 0xff8f4bf3,
277 0xff3bf742, 0xff8f02a8, 0xff5509df, 0xffc7027e,
278 0xff24aa8a, 0xff886c96, 0xff625481, 0xff403689,
279 0xffc52152, 0xff78ccd6, 0xffdcb4ab, 0xff09d27d,
280 0xffca00f3, 0xff605d47, 0xff446fb2, 0xff576e46,
281 0xff273df9, 0xffb41a83, 0xfff812c3, 0xffccab67,
282 0xff034218, 0xff7db9a7, 0xff821048, 0xfffe4ab4,
283 0xff6fac98, 0xff941d27, 0xff5fe411, 0xfffbb283,
284 0xffd86e99, 0xff169162, 0xff71128c, 0xff39cab4,
285 0xffa7fe63, 0xff4c956b, 0xffbc22e0, 0xffb272e4,
286 0xff129f4a, 0xffe34513, 0xff3d3742, 0xffbd190a,
287 0xffb07222, 0xff2e23f8, 0xfff089d9, 0xffb35738,
288 0xffa86022, 0xff3340fe, 0xff95fe71, 0xff6a71df
289 };
290 SkAutoDataUnref encoded(SkData::NewWithCopy(encodedWebP, 300 SkAutoDataUnref encoded(SkData::NewWithCopy(encodedWebP,
291 sizeof(encodedWebP))); 301 sizeof(encodedWebP)));
292 SkBitmap bm; 302 SkBitmap bm;
293 bool success = SkDecodingImageGenerator::Install(encoded, &bm, NULL); 303
304 bool success = SkInstallDiscardablePixelRef(
305 SkDecodingImageGenerator::Create(encoded,
306 SkDecodingImageGenerator::Options()), &bm, NULL);
307
294 REPORTER_ASSERT(reporter, success); 308 REPORTER_ASSERT(reporter, success);
295 if (!success) { 309 if (!success) {
296 return; 310 return;
297 } 311 }
298 SkAutoLockPixels alp(bm); 312 SkAutoLockPixels alp(bm);
299 bool rightSize = SK_ARRAY_COUNT(thePixels) == bm.width() * bm.height(); 313
314 bool rightSize = ((kExpectedWidth == bm.width())
315 && (kExpectedHeight == bm.height()));
300 REPORTER_ASSERT(reporter, rightSize); 316 REPORTER_ASSERT(reporter, rightSize);
301 if (rightSize) { 317 if (rightSize) {
302 bool error = false; 318 bool error = false;
303 const SkColor* correctPixel = thePixels; 319 const SkColor* correctPixel = kExpectedPixels;
304 for (int y = 0; y < bm.height(); ++y) { 320 for (int y = 0; y < bm.height(); ++y) {
305 for (int x = 0; x < bm.width(); ++x) { 321 for (int x = 0; x < bm.width(); ++x) {
306 error |= (*correctPixel != bm.getColor(x, y)); 322 error |= (*correctPixel != bm.getColor(x, y));
307 ++correctPixel; 323 ++correctPixel;
308 } 324 }
309 } 325 }
310 REPORTER_ASSERT(reporter, !error); 326 REPORTER_ASSERT(reporter, !error);
311 } 327 }
312 } 328 }
329
330 ////////////////////////////////////////////////////////////////////////////////
331
332 // example of how Android will do this inside their BitmapFactory
333 static SkPixelRef* install_pixel_ref(SkBitmap* bitmap,
334 SkStreamRewindable* stream,
335 int sampleSize, bool ditherImage) {
336 SkASSERT(bitmap != NULL);
337 SkASSERT(stream != NULL);
338 SkASSERT(stream->rewind());
339 SkASSERT(stream->unique());
340 SkColorType colorType;
341 if (!SkBitmapConfigToColorType(bitmap->config(), &colorType)) {
342 return NULL;
343 }
344 SkDecodingImageGenerator::Options opts(sampleSize, ditherImage, colorType);
345 SkAutoTDelete<SkImageGenerator> gen(
346 SkDecodingImageGenerator::Create(stream, opts));
347 SkImageInfo info;
348 if ((NULL == gen.get()) || !gen->getInfo(&info)) {
349 return NULL;
350 }
351 SkDiscardableMemory::Factory* factory = NULL;
352 if (info.getSafeSize(info.minRowBytes()) < (32 * 1024)) {
353 // only use ashmem for large images, since mmaps come at a price
354 factory = SkGetGlobalDiscardableMemoryPool();
355 }
356 if (SkInstallDiscardablePixelRef(gen.detach(), bitmap, factory)) {
357 return bitmap->pixelRef();
358 }
359 return NULL;
360 }
361 /**
362 * A test for the SkDecodingImageGenerator::Create and
363 * SkInstallDiscardablePixelRef functions.
364 */
365 DEF_TEST(ImprovedBitmapFactory, reporter) {
366 SkString resourcePath = skiatest::Test::GetResourcePath();
367 SkString directory = SkOSPath::SkPathJoin(resourcePath.c_str(), "encoding");
368 SkString path = SkOSPath::SkPathJoin(directory.c_str(), "randPixels.png");
369 SkAutoTUnref<SkStreamRewindable> stream(
370 SkStream::NewFromFile(path.c_str()));
371 if (sk_exists(path.c_str())) {
372 SkBitmap bm;
373 SkAssertResult(bm.setConfig(SkBitmap::kARGB_8888_Config, 1, 1));
374 REPORTER_ASSERT(reporter,
375 NULL != install_pixel_ref(&bm, stream.detach(), 1, true));
376 SkAutoLockPixels alp(bm);
377 REPORTER_ASSERT(reporter, NULL != bm.getPixels());
378 }
379 }
380
381
382 ////////////////////////////////////////////////////////////////////////////////
383
384 #if defined(SK_BUILD_FOR_ANDROID) || defined(SK_BUILD_FOR_UNIX)
385 static inline bool check_rounding(int value, int dividend, int divisor) {
386 // returns true if (dividend/divisor) rounds up OR down to value
387 return (((divisor * value) > (dividend - divisor))
388 && ((divisor * value) < (dividend + divisor)));
389 }
390 #endif // SK_BUILD_FOR_ANDROID || SK_BUILD_FOR_UNIX
391
392
393 #if SK_PMCOLOR_BYTE_ORDER(B,G,R,A)
394 #define kBackwards_SkColorType kRGBA_8888_SkColorType
395 #elif SK_PMCOLOR_BYTE_ORDER(R,G,B,A)
396 #define kBackwards_SkColorType kBGRA_8888_SkColorType
397 #else
398 #error "SK_*32_SHFIT values must correspond to BGRA or RGBA byte order"
399 #endif
400
401 static inline const char* SkColorType_to_string(SkColorType colorType) {
402 switch(colorType) {
403 case kAlpha_8_SkColorType: return "Alpha_8";
404 case kRGB_565_SkColorType: return "RGB_565";
405 case kARGB_4444_SkColorType: return "ARGB_4444";
406 case kPMColor_SkColorType: return "PMColor";
407 case kBackwards_SkColorType: return "Backwards";
408 case kIndex_8_SkColorType: return "Index_8";
409 default: return "ERROR";
410 }
411 }
412
413 /**
414 * Given either a SkStream or a SkData, try to decode the encoded
415 * image using the specified options and report errors.
416 */
417 static void test_options(skiatest::Reporter* reporter,
418 const SkDecodingImageGenerator::Options& opts,
419 SkStreamRewindable* encodedStream,
420 SkData* encodedData,
421 bool useData,
422 const SkString& path) {
423 SkBitmap bm;
424 bool success = false;
425 if (useData) {
426 if (NULL == encodedData) {
427 return;
428 }
429 success = SkInstallDiscardablePixelRef(
430 SkDecodingImageGenerator::Create(encodedData, opts), &bm, NULL);
431 } else {
432 if (NULL == encodedStream) {
433 return;
434 }
435 success = SkInstallDiscardablePixelRef(
436 SkDecodingImageGenerator::Create(encodedStream->duplicate(), opts),
437 &bm, NULL);
438 }
439 if (!success) {
440 if (opts.fUseRequestedColorType
441 && (kARGB_4444_SkColorType == opts.fRequestedColorType)) {
442 return; // Ignore known conversion inabilities.
443 }
444 // If we get here, it's a failure and we will need more
445 // information about why it failed.
446 reporter->reportFailed(SkStringPrintf(
447 "Bounds decode failed "
448 "[sampleSize=%d dither=%s colorType=%s %s] %s:%d",
449 opts.fSampleSize, (opts.fDitherImage ? "yes" : "no"),
450 (opts.fUseRequestedColorType
451 ? SkColorType_to_string(opts.fRequestedColorType) : "(none)"),
452 path.c_str(), __FILE__, __LINE__));
453 return;
454 }
455 #if defined(SK_BUILD_FOR_ANDROID) || defined(SK_BUILD_FOR_UNIX)
456 // Android is the only system that use Skia's image decoders in
457 // production. For now, we'll only verify that samplesize works
458 // on systems where it already is known to work.
459 REPORTER_ASSERT(reporter, check_rounding(bm.height(), kExpectedHeight,
460 opts.fSampleSize));
461 REPORTER_ASSERT(reporter, check_rounding(bm.width(), kExpectedWidth,
462 opts.fSampleSize));
463 #endif // SK_BUILD_FOR_ANDROID || SK_BUILD_FOR_UNIX
464 SkAutoLockPixels alp(bm);
465 if (bm.getPixels() == NULL) {
466 reporter->reportFailed(SkStringPrintf(
467 "Pixel decode failed "
468 "[sampleSize=%d dither=%s colorType=%s %s] %s:%d",
469 opts.fSampleSize, (opts.fDitherImage ? "yes" : "no"),
470 (opts.fUseRequestedColorType
471 ? SkColorType_to_string(opts.fRequestedColorType) : "(none)"),
472 path.c_str(), __FILE__, __LINE__));
473 return;
474 }
475
476 SkBitmap::Config requestedConfig
477 = SkColorTypeToBitmapConfig(opts.fRequestedColorType);
478 REPORTER_ASSERT(reporter,
479 (!opts.fUseRequestedColorType)
480 || (bm.config() == requestedConfig));
481
482 // Condition under which we should check the decoding results:
483 if ((SkBitmap::kARGB_8888_Config == bm.config())
484 && (!path.endsWith(".jpg")) // lossy
485 && (opts.fSampleSize == 1)) { // scaled
486 const SkColor* correctPixels = kExpectedPixels;
487 SkASSERT(bm.height() == kExpectedHeight);
488 SkASSERT(bm.width() == kExpectedWidth);
489 int pixelErrors = 0;
490 for (int y = 0; y < bm.height(); ++y) {
491 for (int x = 0; x < bm.width(); ++x) {
492 if (*correctPixels != bm.getColor(x, y)) {
493 ++pixelErrors;
494 }
495 ++correctPixels;
496 }
497 }
498 if (pixelErrors != 0) {
499 reporter->reportFailed(SkStringPrintf(
500 "Pixel-level mismatch (%d of %d) [sampleSize=%d "
501 "dither=%s colorType=%s %s] %s:%d",
502 pixelErrors, kExpectedHeight * kExpectedWidth,
503 opts.fSampleSize, (opts.fDitherImage ? "yes" : "no"),
504 (opts.fUseRequestedColorType
505 ? SkColorType_to_string(opts.fRequestedColorType)
506 : "(none)"), path.c_str(), __FILE__, __LINE__));
507 }
508 }
509 }
510
511 /**
512 * SkDecodingImageGenerator has an Options struct which lets the
513 * client of the generator set sample size, dithering, and bitmap
514 * config. This test loops through many possible options and tries
515 * them on a set of 5 small encoded images (each in a different
516 * format). We test both SkData and SkStreamRewindable decoding.
517 */
518 DEF_TEST(ImageDecoderOptions, reporter) {
519 const char* files[] = {
520 "randPixels.bmp",
521 "randPixels.jpg",
522 "randPixels.png",
523 "randPixels.webp",
524 #if !defined(SK_BUILD_FOR_WIN)
525 // TODO(halcanary): Find out why this fails sometimes.
526 "randPixels.gif",
527 #endif
528 };
529
530 SkString resourceDir = skiatest::Test::GetResourcePath();
531 SkString directory = SkOSPath::SkPathJoin(resourceDir.c_str(), "encoding");
532 if (!sk_exists(directory.c_str())) {
533 return;
534 }
535
536 int scaleList[] = {1, 2, 3, 4};
537 bool ditherList[] = {true, false};
538 SkColorType colorList[] = {
539 kAlpha_8_SkColorType,
540 kRGB_565_SkColorType,
541 kARGB_4444_SkColorType, // Most decoders will fail on 4444.
542 kPMColor_SkColorType
543 // Note that indexed color is left out of the list. Lazy
544 // decoding doesn't do indexed color.
545 };
546 const bool useDataList[] = {true, false};
547
548 for (size_t fidx = 0; fidx < SK_ARRAY_COUNT(files); ++fidx) {
549 SkString path = SkOSPath::SkPathJoin(directory.c_str(), files[fidx]);
550 if (!sk_exists(path.c_str())) {
551 continue;
552 }
553
554 SkAutoDataUnref encodedData(SkData::NewFromFileName(path.c_str()));
555 REPORTER_ASSERT(reporter, encodedData.get() != NULL);
556 SkAutoTUnref<SkStreamRewindable> encodedStream(
557 SkStream::NewFromFile(path.c_str()));
558 REPORTER_ASSERT(reporter, encodedStream.get() != NULL);
559
560 for (size_t i = 0; i < SK_ARRAY_COUNT(scaleList); ++i) {
561 for (size_t j = 0; j < SK_ARRAY_COUNT(ditherList); ++j) {
562 for (size_t m = 0; m < SK_ARRAY_COUNT(useDataList); ++m) {
563 for (size_t k = 0; k < SK_ARRAY_COUNT(colorList); ++k) {
564 SkDecodingImageGenerator::Options opts(scaleList[i],
565 ditherList[j],
566 colorList[k]);
567 test_options(reporter, opts, encodedStream, encodedData,
568 useDataList[m], path);
569
570 }
571 SkDecodingImageGenerator::Options options(scaleList[i],
572 ditherList[j]);
573 test_options(reporter, options, encodedStream, encodedData,
574 useDataList[m], path);
575 }
576 }
577 }
578 }
579 }
580 ////////////////////////////////////////////////////////////////////////////////
581
OLDNEW
« no previous file with comments | « tests/CachedDecodingPixelRefTest.cpp ('k') | tests/PictureTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698