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

Side by Side Diff: tests/ImageDecodingTest.cpp

Issue 103753007: Revert of Change SkDecodingImageGenerator API (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: Created 7 years 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"
16 #include "SkDiscardableMemoryPool.h"
17 #include "SkForceLinking.h" 15 #include "SkForceLinking.h"
18 #include "SkGradientShader.h" 16 #include "SkGradientShader.h"
19 #include "SkImageDecoder.h" 17 #include "SkImageDecoder.h"
20 #include "SkImageEncoder.h" 18 #include "SkImageEncoder.h"
21 #include "SkImageGenerator.h"
22 #include "SkImagePriv.h"
23 #include "SkOSFile.h" 19 #include "SkOSFile.h"
24 #include "SkPoint.h" 20 #include "SkPoint.h"
25 #include "SkShader.h" 21 #include "SkShader.h"
26 #include "SkStream.h" 22 #include "SkStream.h"
27 #include "SkString.h" 23 #include "SkString.h"
28 24
29 __SK_FORCE_IMAGE_DECODER_LINKING; 25 __SK_FORCE_IMAGE_DECODER_LINKING;
30 26
31 /** 27 /**
32 * Interprets c as an unpremultiplied color, and returns the 28 * Interprets c as an unpremultiplied color, and returns the
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
149 SkString resourcePath = skiatest::Test::GetResourcePath(); 145 SkString resourcePath = skiatest::Test::GetResourcePath();
150 if (resourcePath.isEmpty()) { 146 if (resourcePath.isEmpty()) {
151 SkDebugf("Could not run unpremul test because resourcePath not specified ."); 147 SkDebugf("Could not run unpremul test because resourcePath not specified .");
152 return; 148 return;
153 } 149 }
154 SkOSFile::Iter iter(resourcePath.c_str()); 150 SkOSFile::Iter iter(resourcePath.c_str());
155 SkString basename; 151 SkString basename;
156 if (iter.next(&basename)) { 152 if (iter.next(&basename)) {
157 do { 153 do {
158 SkString filename = SkOSPath::SkPathJoin(resourcePath.c_str(), basen ame.c_str()); 154 SkString filename = SkOSPath::SkPathJoin(resourcePath.c_str(), basen ame.c_str());
159 // SkDebugf("about to decode \"%s\"\n", filename.c_str()); 155 //SkDebugf("about to decode \"%s\"\n", filename.c_str());
160 compare_unpremul(reporter, filename); 156 compare_unpremul(reporter, filename);
161 } while (iter.next(&basename)); 157 } while (iter.next(&basename));
162 } else { 158 } else {
163 SkDebugf("Failed to find any files :(\n"); 159 SkDebugf("Failed to find any files :(\n");
164 } 160 }
165 } 161 }
166 162
167 #ifdef SK_DEBUG 163 #ifdef SK_DEBUG
168 // Create a stream containing a bitmap encoded to Type type. 164 // Create a stream containing a bitmap encoded to Type type.
169 static SkMemoryStream* create_image_stream(SkImageEncoder::Type type) { 165 static SkMemoryStream* create_image_stream(SkImageEncoder::Type type) {
(...skipping 27 matching lines...) Expand all
197 // Only runs in debug mode since we are testing for a crash. 193 // Only runs in debug mode since we are testing for a crash.
198 static void test_stream_life() { 194 static void test_stream_life() {
199 const SkImageEncoder::Type gTypes[] = { 195 const SkImageEncoder::Type gTypes[] = {
200 #ifdef SK_BUILD_FOR_ANDROID 196 #ifdef SK_BUILD_FOR_ANDROID
201 SkImageEncoder::kJPEG_Type, 197 SkImageEncoder::kJPEG_Type,
202 SkImageEncoder::kPNG_Type, 198 SkImageEncoder::kPNG_Type,
203 #endif 199 #endif
204 SkImageEncoder::kWEBP_Type, 200 SkImageEncoder::kWEBP_Type,
205 }; 201 };
206 for (size_t i = 0; i < SK_ARRAY_COUNT(gTypes); ++i) { 202 for (size_t i = 0; i < SK_ARRAY_COUNT(gTypes); ++i) {
207 // SkDebugf("encoding to %i\n", i); 203 //SkDebugf("encoding to %i\n", i);
208 SkAutoTUnref<SkMemoryStream> stream(create_image_stream(gTypes[i])); 204 SkAutoTUnref<SkMemoryStream> stream(create_image_stream(gTypes[i]));
209 if (NULL == stream.get()) { 205 if (NULL == stream.get()) {
210 SkDebugf("no stream\n"); 206 SkDebugf("no stream\n");
211 continue; 207 continue;
212 } 208 }
213 SkAutoTDelete<SkImageDecoder> decoder(SkImageDecoder::Factory(stream)); 209 SkAutoTDelete<SkImageDecoder> decoder(SkImageDecoder::Factory(stream));
214 if (NULL == decoder.get()) { 210 if (NULL == decoder.get()) {
215 SkDebugf("no decoder\n"); 211 SkDebugf("no decoder\n");
216 continue; 212 continue;
217 } 213 }
218 int width, height; 214 int width, height;
219 if (!decoder->buildTileIndex(stream.get(), &width, &height)) { 215 if (!decoder->buildTileIndex(stream.get(), &width, &height)) {
220 SkDebugf("could not build a tile index\n"); 216 SkDebugf("could not build a tile index\n");
221 continue; 217 continue;
222 } 218 }
223 // Now unref the stream to make sure it survives 219 // Now unref the stream to make sure it survives
224 stream.reset(NULL); 220 stream.reset(NULL);
225 SkBitmap bm; 221 SkBitmap bm;
226 decoder->decodeSubset(&bm, SkIRect::MakeWH(width, height), 222 decoder->decodeSubset(&bm, SkIRect::MakeWH(width, height),
227 SkBitmap::kARGB_8888_Config); 223 SkBitmap::kARGB_8888_Config);
228 } 224 }
229 } 225 }
230 226
231 // Test inside SkScaledBitmapSampler.cpp 227 // Test inside SkScaledBitmapSampler.cpp
232 extern void test_row_proc_choice(); 228 extern void test_row_proc_choice();
233 229
234 #endif // SK_DEBUG 230 #endif // SK_DEBUG
235 231
236 DEF_TEST(ImageDecoding, reporter) { 232 DEF_TEST(ImageDecoding, reporter) {
237 test_unpremul(reporter); 233 test_unpremul(reporter);
238 #ifdef SK_DEBUG 234 #ifdef SK_DEBUG
239 test_stream_life(); 235 test_stream_life();
240 test_row_proc_choice(); 236 test_row_proc_choice();
241 #endif 237 #endif
242 } 238 }
243
244 ////////////////////////////////////////////////////////////////////////////////
245
246 // example of how Android will do this inside their BitmapFactory
247 static SkPixelRef* install_pixel_ref(SkBitmap* bitmap,
248 SkStreamRewindable* stream,
249 int sampleSize, bool ditherImage) {
250 SkASSERT(bitmap != NULL);
251 SkASSERT(stream != NULL);
252 SkASSERT(stream->rewind());
253 SkASSERT(stream->unique());
254 SkColorType colorType;
255 if (!SkBitmapConfigToColorType(bitmap->config(), &colorType)) {
256 return NULL;
257 }
258 SkDecodingImageGenerator::Options opts(sampleSize, ditherImage, colorType);
259 SkAutoTDelete<SkImageGenerator> gen(
260 SkDecodingImageGenerator::Create(stream, opts));
261 SkImageInfo info;
262 if ((NULL == gen.get()) || !gen->getInfo(&info)) {
263 return NULL;
264 }
265 SkDiscardableMemory::Factory* factory = NULL;
266 if (info.getSafeSize(info.minRowBytes()) < (32 * 1024)) {
267 // only use ashmem for large images, since mmaps come at a price
268 factory = SkGetGlobalDiscardableMemoryPool();
269 }
270 if (SkInstallDiscardablePixelRef(gen.detach(), bitmap, factory)) {
271 return bitmap->pixelRef();
272 }
273 return NULL;
274 }
275 /**
276 * A test for the SkDecodingImageGenerator::Create and
277 * SkInstallDiscardablePixelRef functions.
278 */
279 DEF_TEST(ImprovedBitmapFactory, reporter) {
280 SkString resourcePath = skiatest::Test::GetResourcePath();
281 SkString directory = SkOSPath::SkPathJoin(resourcePath.c_str(), "encoding");
282 SkString path = SkOSPath::SkPathJoin(directory.c_str(), "randPixels.png");
283 SkAutoTUnref<SkStreamRewindable> stream(
284 SkStream::NewFromFile(path.c_str()));
285 if (sk_exists(path.c_str())) {
286 SkBitmap bm;
287 SkAssertResult(bm.setConfig(SkBitmap::kARGB_8888_Config, 1, 1));
288 REPORTER_ASSERT(reporter,
289 NULL != install_pixel_ref(&bm, stream.detach(), 1, true));
290 SkAutoLockPixels alp(bm);
291 REPORTER_ASSERT(reporter, NULL != bm.getPixels());
292 }
293 }
294
295
296 ////////////////////////////////////////////////////////////////////////////////
297
298 #if defined(SK_BUILD_FOR_ANDROID) || defined(SK_BUILD_FOR_UNIX)
299 static inline bool check_rounding(int value, int dividend, int divisor) {
300 // returns true if (dividend/divisor) rounds up OR down to value
301 return (((divisor * value) > (dividend - divisor))
302 && ((divisor * value) < (dividend + divisor)));
303 }
304 #endif // SK_BUILD_FOR_ANDROID || SK_BUILD_FOR_UNIX
305 namespace {
306 // expected output for 8x8 bitmap
307 const int kExpectedWidth = 8;
308 const int kExpectedHeight = 8;
309 const SkColor kExpectedPixels[] = {
310 0xffbba570, 0xff395f5d, 0xffe25c39, 0xff197666,
311 0xff3cba27, 0xffdefcb0, 0xffc13874, 0xfffa0093,
312 0xffbda60e, 0xffc01db6, 0xff2bd688, 0xff9362d4,
313 0xffc641b2, 0xffa5cede, 0xff606eba, 0xff8f4bf3,
314 0xff3bf742, 0xff8f02a8, 0xff5509df, 0xffc7027e,
315 0xff24aa8a, 0xff886c96, 0xff625481, 0xff403689,
316 0xffc52152, 0xff78ccd6, 0xffdcb4ab, 0xff09d27d,
317 0xffca00f3, 0xff605d47, 0xff446fb2, 0xff576e46,
318 0xff273df9, 0xffb41a83, 0xfff812c3, 0xffccab67,
319 0xff034218, 0xff7db9a7, 0xff821048, 0xfffe4ab4,
320 0xff6fac98, 0xff941d27, 0xff5fe411, 0xfffbb283,
321 0xffd86e99, 0xff169162, 0xff71128c, 0xff39cab4,
322 0xffa7fe63, 0xff4c956b, 0xffbc22e0, 0xffb272e4,
323 0xff129f4a, 0xffe34513, 0xff3d3742, 0xffbd190a,
324 0xffb07222, 0xff2e23f8, 0xfff089d9, 0xffb35738,
325 0xffa86022, 0xff3340fe, 0xff95fe71, 0xff6a71df
326 };
327 SK_COMPILE_ASSERT((kExpectedWidth * kExpectedHeight)
328 == SK_ARRAY_COUNT(kExpectedPixels), array_size_mismatch);
329 } // namespace
330
331 /**
332 * Given either a SkStream or a SkData, try to decode the encoded
333 * image using the specified options and report errors.
334 */
335 static void test_options(skiatest::Reporter* reporter,
336 const SkDecodingImageGenerator::Options& opts,
337 SkStreamRewindable* encodedStream,
338 SkData* encodedData,
339 bool useData,
340 const SkString& path) {
341 SkBitmap bm;
342 bool success = false;
343 if (useData) {
344 if (NULL == encodedData) {
345 return;
346 }
347 success = SkInstallDiscardablePixelRef(
348 SkDecodingImageGenerator::Create(encodedData, opts), &bm, NULL);
349 } else {
350 if (NULL == encodedStream) {
351 return;
352 }
353 success = SkInstallDiscardablePixelRef(
354 SkDecodingImageGenerator::Create(encodedStream->duplicate(), opts),
355 &bm, NULL);
356 }
357
358 REPORTER_ASSERT(reporter, success
359 || (kARGB_4444_SkColorType == opts.fRequestedColorType));
360 if (!success) {
361 return;
362 }
363 #if defined(SK_BUILD_FOR_ANDROID) || defined(SK_BUILD_FOR_UNIX)
364 // Android is the only system that use Skia's image decoders in
365 // production. For now, we'll only verify that samplesize works
366 // on systems where it already is known to work.
367 REPORTER_ASSERT(reporter, check_rounding(bm.height(), kExpectedHeight,
368 opts.fSampleSize));
369 REPORTER_ASSERT(reporter, check_rounding(bm.width(), kExpectedWidth,
370 opts.fSampleSize));
371 #endif // SK_BUILD_FOR_ANDROID || SK_BUILD_FOR_UNIX
372 SkAutoLockPixels alp(bm);
373 REPORTER_ASSERT(reporter, bm.getPixels() != NULL);
374
375 SkBitmap::Config requestedConfig
376 = SkColorTypeToBitmapConfig(opts.fRequestedColorType);
377 REPORTER_ASSERT(reporter,
378 (!opts.fUseRequestedColorType)
379 || (bm.config() == requestedConfig));
380
381 // Condition under which we should check the decoding results:
382 if ((SkBitmap::kARGB_8888_Config == bm.config())
383 && (NULL != bm.getPixels())
384 && (!path.endsWith(".jpg")) // lossy
385 && (!path.endsWith(".webp")) // decoder error
386 && (opts.fSampleSize == 1)) { // scaled
387 bool pixelError = false;
388 const SkColor* correctPixels = kExpectedPixels;
389 SkASSERT(bm.height() == kExpectedHeight);
390 SkASSERT(bm.width() == kExpectedWidth);
391 for (int y = 0; y < bm.height(); ++y) {
392 for (int x = 0; x < bm.width(); ++x) {
393 pixelError |= (*correctPixels != bm.getColor(x, y));
394 ++correctPixels;
395 }
396 }
397 REPORTER_ASSERT(reporter, !pixelError);
398 }
399 }
400
401 /**
402 * SkDecodingImageGenerator has an Options struct which lets the
403 * client of the generator set sample size, dithering, and bitmap
404 * config. This test loops through many possible options and tries
405 * them on a set of 5 small encoded images (each in a different
406 * format). We test both SkData and SkStreamRewindable decoding.
407 */
408 DEF_TEST(ImageDecoderOptions, reporter) {
409 const char* files[] = {
410 "randPixels.bmp",
411 "randPixels.jpg",
412 "randPixels.png",
413 "randPixels.webp",
414 "randPixels.gif"
415 };
416
417 SkString resourceDir = skiatest::Test::GetResourcePath();
418 SkString directory = SkOSPath::SkPathJoin(resourceDir.c_str(), "encoding");
419 if (!sk_exists(directory.c_str())) {
420 return;
421 }
422
423 int scaleList[] = {1, 2, 3, 4};
424 bool ditherList[] = {true, false};
425 SkColorType colorList[] = {
426 kAlpha_8_SkColorType,
427 kRGB_565_SkColorType,
428 kARGB_4444_SkColorType, // Most decoders will fail on 4444.
429 kPMColor_SkColorType
430 // Note that indexed color is left out of the list. Lazy
431 // decoding doesn't do indexed color.
432 };
433 const bool useDataList[] = {true, false};
434
435 for (size_t fidx = 0; fidx < SK_ARRAY_COUNT(files); ++fidx) {
436 SkString path = SkOSPath::SkPathJoin(directory.c_str(), files[fidx]);
437 if (!sk_exists(path.c_str())) {
438 continue;
439 }
440
441 SkAutoDataUnref encodedData(SkData::NewFromFileName(path.c_str()));
442 REPORTER_ASSERT(reporter, encodedData.get() != NULL);
443 SkAutoTUnref<SkStreamRewindable> encodedStream(
444 SkStream::NewFromFile(path.c_str()));
445 REPORTER_ASSERT(reporter, encodedStream.get() != NULL);
446
447 for (size_t i = 0; i < SK_ARRAY_COUNT(scaleList); ++i) {
448 for (size_t j = 0; j < SK_ARRAY_COUNT(ditherList); ++j) {
449 for (size_t m = 0; m < SK_ARRAY_COUNT(useDataList); ++m) {
450 for (size_t k = 0; k < SK_ARRAY_COUNT(colorList); ++k) {
451 SkDecodingImageGenerator::Options opts(scaleList[i],
452 ditherList[j],
453 colorList[k]);
454 test_options(reporter, opts, encodedStream, encodedData,
455 useDataList[m], path);
456
457 }
458 SkDecodingImageGenerator::Options options(scaleList[i],
459 ditherList[j]);
460 test_options(reporter, options, encodedStream, encodedData,
461 useDataList[m], path);
462 }
463 }
464 }
465 }
466 }
467
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