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

Side by Side Diff: ui/gfx/codec/png_codec_unittest.cc

Issue 9496004: Support for interlaced PNGs (in gfx::PNGCodec) (Closed) Base URL: http://src.chromium.org/svn/trunk/src/
Patch Set: Created 8 years, 9 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
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #if defined(USE_SYSTEM_LIBPNG)
6 #include <png.h>
7 #else
8 #include "third_party/libpng/png.h"
9 #endif
Francois 2012/02/29 09:12:30 Required in order to encode interlaced, palette-ba
10
5 #include <algorithm> 11 #include <algorithm>
6 #include <cmath> 12 #include <cmath>
7 13
14 #include "base/logging.h"
8 #include "testing/gtest/include/gtest/gtest.h" 15 #include "testing/gtest/include/gtest/gtest.h"
9 #include "third_party/skia/include/core/SkBitmap.h" 16 #include "third_party/skia/include/core/SkBitmap.h"
17 #include "third_party/skia/include/core/SkColorPriv.h"
10 #include "third_party/skia/include/core/SkUnPreMultiply.h" 18 #include "third_party/skia/include/core/SkUnPreMultiply.h"
11 #include "third_party/zlib/zlib.h" 19 #include "third_party/zlib/zlib.h"
12 #include "ui/gfx/codec/png_codec.h" 20 #include "ui/gfx/codec/png_codec.h"
13 #include "ui/gfx/size.h" 21 #include "ui/gfx/size.h"
14 22
15 namespace gfx { 23 namespace gfx {
16 24
17 static void MakeRGBImage(int w, int h, std::vector<unsigned char>* dat) { 25 namespace {
26
27 void MakeRGBImage(int w, int h, std::vector<unsigned char>* dat) {
18 dat->resize(w * h * 3); 28 dat->resize(w * h * 3);
19 for (int y = 0; y < h; y++) { 29 for (int y = 0; y < h; y++) {
20 for (int x = 0; x < w; x++) { 30 for (int x = 0; x < w; x++) {
21 unsigned char* org_px = &(*dat)[(y * w + x) * 3]; 31 unsigned char* org_px = &(*dat)[(y * w + x) * 3];
22 org_px[0] = x * 3; // r 32 org_px[0] = x * 3; // r
23 org_px[1] = x * 3 + 1; // g 33 org_px[1] = x * 3 + 1; // g
24 org_px[2] = x * 3 + 2; // b 34 org_px[2] = x * 3 + 2; // b
25 } 35 }
26 } 36 }
27 } 37 }
28 38
29 // Set use_transparency to write data into the alpha channel, otherwise it will 39 // Set use_transparency to write data into the alpha channel, otherwise it will
30 // be filled with 0xff. With the alpha channel stripped, this should yield the 40 // be filled with 0xff. With the alpha channel stripped, this should yield the
31 // same image as MakeRGBImage above, so the code below can make reference 41 // same image as MakeRGBImage above, so the code below can make reference
32 // images for conversion testing. 42 // images for conversion testing.
33 static void MakeRGBAImage(int w, int h, bool use_transparency, 43 void MakeRGBAImage(int w, int h, bool use_transparency,
34 std::vector<unsigned char>* dat) { 44 std::vector<unsigned char>* dat) {
35 dat->resize(w * h * 4); 45 dat->resize(w * h * 4);
36 for (int y = 0; y < h; y++) { 46 for (int y = 0; y < h; y++) {
37 for (int x = 0; x < w; x++) { 47 for (int x = 0; x < w; x++) {
38 unsigned char* org_px = &(*dat)[(y * w + x) * 4]; 48 unsigned char* org_px = &(*dat)[(y * w + x) * 4];
39 org_px[0] = x * 3; // r 49 org_px[0] = x * 3; // r
40 org_px[1] = x * 3 + 1; // g 50 org_px[1] = x * 3 + 1; // g
41 org_px[2] = x * 3 + 2; // b 51 org_px[2] = x * 3 + 2; // b
42 if (use_transparency) 52 if (use_transparency)
43 org_px[3] = x*3 + 3; // a 53 org_px[3] = x*3 + 3; // a
44 else 54 else
45 org_px[3] = 0xFF; // a (opaque) 55 org_px[3] = 0xFF; // a (opaque)
46 } 56 }
47 } 57 }
48 } 58 }
49 59
60 // User write function (to be passed to libpng by EncodeImage) which writes
61 // into a buffer instead of to a file.
62 void WriteImageData(png_structp png_ptr,
63 png_bytep data,
64 png_size_t length) {
65 std::vector<unsigned char>& v =
66 *static_cast<std::vector<unsigned char>*>(png_get_io_ptr(png_ptr));
67 v.resize(v.size() + length);
68 memcpy(&v[v.size() - length], data, length);
69 }
70
71 // User flush function; goes with WriteImageData, above.
72 void FlushImageData(png_structp /*png_ptr*/) {}
tony 2012/02/29 18:57:57 Nit: closing } goes on its own line.
Francois 2012/03/01 07:53:15 Done.
73
74 // Libpng user error function which allows us to print libpng errors using
75 // Chrome's logging facilities instead of stderr.
76 void LogLibPNGError(png_structp png_ptr,
77 png_const_charp error_msg) {
78 DLOG(ERROR) << "libpng encode error: " << error_msg;
79 longjmp(png_jmpbuf(png_ptr), 1);
80 }
81
82 // Goes with LogLibPNGError, above.
83 void LogLibPNGWarning(png_structp png_ptr,
84 png_const_charp warning_msg) {
85 DLOG(ERROR) << "libpng encode warning: " << warning_msg;
86 }
87
88 // Color types supported by EncodeImage. Required because neither libpng nor
89 // PNGCodec::Encode supports all of the required values.
90 enum ColorType {
91 COLOR_TYPE_GRAY = PNG_COLOR_TYPE_GRAY,
92 COLOR_TYPE_GRAY_ALPHA = PNG_COLOR_TYPE_GRAY_ALPHA,
93 COLOR_TYPE_PALETTE = PNG_COLOR_TYPE_PALETTE,
94 COLOR_TYPE_RGB = PNG_COLOR_TYPE_RGB,
95 COLOR_TYPE_RGBA = PNG_COLOR_TYPE_RGBA,
96 COLOR_TYPE_BGR,
97 COLOR_TYPE_BGRA
98 };
99
100 // PNG encoder used for testing. Required because PNGCodec::Encode doesn't do
101 // interlaced, palette-based, or grayscale images, but PNGCodec::Decode is
102 // actually asked to decode these types of images by Chrome.
103 bool EncodeImage(const std::vector<unsigned char>& input,
104 const int width,
105 const int height,
106 ColorType output_color_type,
107 std::vector<unsigned char>* output,
108 const int interlace_type = PNG_INTERLACE_NONE,
109 std::vector<png_color>* palette = 0,
110 std::vector<unsigned char>* palette_alpha = 0) {
111 struct ScopedPNGStructs {
112 ScopedPNGStructs(png_struct** s, png_info** i) : s_(s), i_(i) {}
113 ~ScopedPNGStructs() { png_destroy_write_struct(s_, i_); }
114 png_struct** s_;
115 png_info** i_;
116 };
117
118 DCHECK(output);
119 png_struct* png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
120 NULL, NULL, NULL);
121 if (!png_ptr) return false;
tony 2012/02/29 18:57:57 Nit: return false on its own line.
Francois 2012/03/01 07:53:15 Done.
122
123 png_infop info_ptr = png_create_info_struct(png_ptr);
124 if (!info_ptr) {
125 png_destroy_write_struct(&png_ptr, NULL);
126 return false;
127 }
128
129 ScopedPNGStructs scoped_png_structs(&png_ptr, &info_ptr);
130
131 if (setjmp(png_jmpbuf(png_ptr)))
132 return false;
133
134 png_set_error_fn(png_ptr, NULL, LogLibPNGError, LogLibPNGWarning);
135
136 int input_rowbytes = 0;
137 int transforms = PNG_TRANSFORM_IDENTITY;
138
139 switch (output_color_type) {
140 case COLOR_TYPE_GRAY:
141 input_rowbytes = width;
142 break;
143 case COLOR_TYPE_GRAY_ALPHA:
144 input_rowbytes = width * 2;
145 break;
146 case COLOR_TYPE_PALETTE:
147 if (!palette) return false;
148 input_rowbytes = width;
149 break;
150 case COLOR_TYPE_RGB:
151 input_rowbytes = width * 3;
152 break;
153 case COLOR_TYPE_RGBA:
154 input_rowbytes = width * 4;
155 break;
156 case COLOR_TYPE_BGRA:
157 input_rowbytes = width * 4;
158 output_color_type = static_cast<ColorType>(PNG_COLOR_TYPE_RGBA);
159 transforms |= PNG_TRANSFORM_BGR;
160 break;
161 default:
tony 2012/02/29 18:57:57 Nit: It's better to not have a default so you get
Francois 2012/03/01 07:53:15 Done.
162 return false;
163 break;
164 };
165
166 std::vector<png_bytep> row_pointers(height);
167 for (int y = 0 ; y < height; y++) {
168 row_pointers[y] = const_cast<unsigned char*>(&input[y * input_rowbytes]);
169 }
170 png_set_rows(png_ptr, info_ptr, &row_pointers[0]);
171 png_set_write_fn(png_ptr, output, WriteImageData, FlushImageData);
172 png_set_IHDR(png_ptr, info_ptr, width, height, 8, output_color_type,
173 interlace_type, PNG_COMPRESSION_TYPE_DEFAULT,
174 PNG_FILTER_TYPE_DEFAULT);
175 if (output_color_type == COLOR_TYPE_PALETTE) {
176 png_set_PLTE(png_ptr, info_ptr, &palette->front(), palette->size());
177 if (palette_alpha)
178 png_set_tRNS(png_ptr,
tony 2012/02/29 18:57:57 Nit: I think this if requires {} because the body
Francois 2012/03/01 07:53:15 Done.
179 info_ptr,
180 &palette_alpha->front(),
181 palette_alpha->size(),
182 NULL);
183 }
184
185 png_write_png(png_ptr, info_ptr, transforms, NULL);
186
187 return true;
188 }
189
190 } // namespace
191
50 // Returns true if each channel of the given two colors are "close." This is 192 // Returns true if each channel of the given two colors are "close." This is
51 // used for comparing colors where rounding errors may cause off-by-one. 193 // used for comparing colors where rounding errors may cause off-by-one.
52 bool ColorsClose(uint32_t a, uint32_t b) { 194 bool ColorsClose(uint32_t a, uint32_t b) {
53 return abs(static_cast<int>(SkColorGetB(a) - SkColorGetB(b))) < 2 && 195 return abs(static_cast<int>(SkColorGetB(a) - SkColorGetB(b))) < 2 &&
54 abs(static_cast<int>(SkColorGetG(a) - SkColorGetG(b))) < 2 && 196 abs(static_cast<int>(SkColorGetG(a) - SkColorGetG(b))) < 2 &&
55 abs(static_cast<int>(SkColorGetR(a) - SkColorGetR(b))) < 2 && 197 abs(static_cast<int>(SkColorGetR(a) - SkColorGetR(b))) < 2 &&
56 abs(static_cast<int>(SkColorGetA(a) - SkColorGetA(b))) < 2; 198 abs(static_cast<int>(SkColorGetA(a) - SkColorGetA(b))) < 2;
57 } 199 }
58 200
59 // Returns true if the RGB components are "close." 201 // Returns true if the RGB components are "close."
(...skipping 15 matching lines...) Expand all
75 217
76 TEST(PNGCodec, EncodeDecodeRGB) { 218 TEST(PNGCodec, EncodeDecodeRGB) {
77 const int w = 20, h = 20; 219 const int w = 20, h = 20;
78 220
79 // create an image with known values 221 // create an image with known values
80 std::vector<unsigned char> original; 222 std::vector<unsigned char> original;
81 MakeRGBImage(w, h, &original); 223 MakeRGBImage(w, h, &original);
82 224
83 // encode 225 // encode
84 std::vector<unsigned char> encoded; 226 std::vector<unsigned char> encoded;
85 EXPECT_TRUE(PNGCodec::Encode(&original[0], PNGCodec::FORMAT_RGB, 227 ASSERT_TRUE(PNGCodec::Encode(&original[0], PNGCodec::FORMAT_RGB,
86 Size(w, h), w * 3, false, 228 Size(w, h), w * 3, false,
87 std::vector<PNGCodec::Comment>(), 229 std::vector<PNGCodec::Comment>(),
88 &encoded)); 230 &encoded));
89 231
90 // decode, it should have the same size as the original 232 // decode, it should have the same size as the original
91 std::vector<unsigned char> decoded; 233 std::vector<unsigned char> decoded;
92 int outw, outh; 234 int outw, outh;
93 EXPECT_TRUE(PNGCodec::Decode(&encoded[0], encoded.size(), 235 ASSERT_TRUE(PNGCodec::Decode(&encoded[0], encoded.size(),
94 PNGCodec::FORMAT_RGB, &decoded, 236 PNGCodec::FORMAT_RGB, &decoded,
95 &outw, &outh)); 237 &outw, &outh));
96 ASSERT_EQ(w, outw); 238 ASSERT_EQ(w, outw);
97 ASSERT_EQ(h, outh); 239 ASSERT_EQ(h, outh);
98 ASSERT_EQ(original.size(), decoded.size()); 240 ASSERT_EQ(original.size(), decoded.size());
99 241
100 // Images must be equal 242 // Images must be equal
101 ASSERT_TRUE(original == decoded); 243 ASSERT_TRUE(original == decoded);
102 } 244 }
103 245
104 TEST(PNGCodec, EncodeDecodeRGBA) { 246 TEST(PNGCodec, EncodeDecodeRGBA) {
105 const int w = 20, h = 20; 247 const int w = 20, h = 20;
106 248
107 // create an image with known values, a must be opaque because it will be 249 // create an image with known values, a must be opaque because it will be
108 // lost during encoding 250 // lost during encoding
109 std::vector<unsigned char> original; 251 std::vector<unsigned char> original;
110 MakeRGBAImage(w, h, true, &original); 252 MakeRGBAImage(w, h, true, &original);
111 253
112 // encode 254 // encode
113 std::vector<unsigned char> encoded; 255 std::vector<unsigned char> encoded;
114 EXPECT_TRUE(PNGCodec::Encode(&original[0], PNGCodec::FORMAT_RGBA, 256 ASSERT_TRUE(PNGCodec::Encode(&original[0], PNGCodec::FORMAT_RGBA,
115 Size(w, h), w * 4, false, 257 Size(w, h), w * 4, false,
116 std::vector<PNGCodec::Comment>(), 258 std::vector<PNGCodec::Comment>(),
117 &encoded)); 259 &encoded));
118 260
119 // decode, it should have the same size as the original 261 // decode, it should have the same size as the original
120 std::vector<unsigned char> decoded; 262 std::vector<unsigned char> decoded;
121 int outw, outh; 263 int outw, outh;
122 EXPECT_TRUE(PNGCodec::Decode(&encoded[0], encoded.size(), 264 ASSERT_TRUE(PNGCodec::Decode(&encoded[0], encoded.size(),
123 PNGCodec::FORMAT_RGBA, &decoded, 265 PNGCodec::FORMAT_RGBA, &decoded,
124 &outw, &outh)); 266 &outw, &outh));
125 ASSERT_EQ(w, outw); 267 ASSERT_EQ(w, outw);
126 ASSERT_EQ(h, outh); 268 ASSERT_EQ(h, outh);
127 ASSERT_EQ(original.size(), decoded.size()); 269 ASSERT_EQ(original.size(), decoded.size());
128 270
129 // Images must be exactly equal 271 // Images must be exactly equal
130 ASSERT_TRUE(original == decoded); 272 ASSERT_TRUE(original == decoded);
131 } 273 }
132 274
275 TEST(PNGCodec, EncodeDecodeBGRA) {
276 const int w = 20, h = 20;
277
278 // Create an image with known values, alpha must be opaque because it will be
279 // lost during encoding.
280 std::vector<unsigned char> original;
281 MakeRGBAImage(w, h, true, &original);
282
283 // Encode.
284 std::vector<unsigned char> encoded;
285 ASSERT_TRUE(PNGCodec::Encode(&original[0], PNGCodec::FORMAT_BGRA,
286 Size(w, h), w * 4, false,
287 std::vector<PNGCodec::Comment>(),
288 &encoded));
289
290 // Decode, it should have the same size as the original.
291 std::vector<unsigned char> decoded;
292 int outw, outh;
293 ASSERT_TRUE(PNGCodec::Decode(&encoded[0], encoded.size(),
294 PNGCodec::FORMAT_BGRA, &decoded,
295 &outw, &outh));
296 ASSERT_EQ(w, outw);
297 ASSERT_EQ(h, outh);
298 ASSERT_EQ(original.size(), decoded.size());
299
300 // Images must be exactly equal.
301 ASSERT_TRUE(original == decoded);
302 }
Francois 2012/02/29 09:12:30 Old code moved from further down.
303
304 TEST(PNGCodec, DecodeInterlacedRGB) {
305 const int w = 20, h = 20;
306
307 // create an image with known values
308 std::vector<unsigned char> original;
309 MakeRGBImage(w, h, &original);
310
311 // encode
312 std::vector<unsigned char> encoded;
313 ASSERT_TRUE(EncodeImage(original,
314 w, h,
315 COLOR_TYPE_RGB,
316 &encoded,
317 PNG_INTERLACE_ADAM7));
318
319 // decode, it should have the same size as the original
320 std::vector<unsigned char> decoded;
321 int outw, outh;
322 ASSERT_TRUE(PNGCodec::Decode(&encoded[0], encoded.size(),
323 PNGCodec::FORMAT_RGB, &decoded,
324 &outw, &outh));
325 ASSERT_EQ(w, outw);
326 ASSERT_EQ(h, outh);
327 ASSERT_EQ(original.size(), decoded.size());
328
329 // Images must be equal
330 ASSERT_EQ(original, decoded);
331 }
332
333 TEST(PNGCodec, DecodeInterlacedRGBA) {
334 const int w = 20, h = 20;
335
336 // create an image with known values
337 std::vector<unsigned char> original;
338 MakeRGBAImage(w, h, false, &original);
339
340 // encode
341 std::vector<unsigned char> encoded;
342 ASSERT_TRUE(EncodeImage(original,
343 w, h,
344 COLOR_TYPE_RGBA,
345 &encoded,
346 PNG_INTERLACE_ADAM7));
347
348 // decode, it should have the same size as the original
349 std::vector<unsigned char> decoded;
350 int outw, outh;
351 ASSERT_TRUE(PNGCodec::Decode(&encoded[0], encoded.size(),
352 PNGCodec::FORMAT_RGBA, &decoded,
353 &outw, &outh));
354 ASSERT_EQ(w, outw);
355 ASSERT_EQ(h, outh);
356 ASSERT_EQ(original.size(), decoded.size());
357
358 // Images must be equal
359 ASSERT_EQ(original, decoded);
360 }
361
362 TEST(PNGCodec, DecodeInterlacedRGBADiscardAlpha) {
363 const int w = 20, h = 20;
364
365 // create an image with known values
366 std::vector<unsigned char> original;
367 MakeRGBAImage(w, h, false, &original);
368
369 // encode
370 std::vector<unsigned char> encoded;
371 ASSERT_TRUE(EncodeImage(original,
372 w, h,
373 COLOR_TYPE_RGBA,
374 &encoded,
375 PNG_INTERLACE_ADAM7));
376
377 // decode
378 std::vector<unsigned char> decoded;
379 int outw, outh;
380 ASSERT_TRUE(PNGCodec::Decode(&encoded[0], encoded.size(),
381 PNGCodec::FORMAT_RGB, &decoded,
382 &outw, &outh));
383 ASSERT_EQ(w, outw);
384 ASSERT_EQ(h, outh);
385 ASSERT_EQ(decoded.size(), w * h * 3U);
386
387 // Images must be equal
388 for (int x = 0; x < w; x++) {
389 for (int y = 0; y < h; y++) {
390 unsigned char* orig_px = &original[(y * w + x) * 4];
391 unsigned char* dec_px = &decoded[(y * w + x) * 3];
392 ASSERT_EQ(dec_px[0], orig_px[0]);
393 ASSERT_EQ(dec_px[1], orig_px[1]);
394 ASSERT_EQ(dec_px[2], orig_px[2]);
395 }
396 }
397 }
398
399 TEST(PNGCodec, DecodeInterlacedBGRA) {
400 const int w = 20, h = 20;
401
402 // create an image with known values
403 std::vector<unsigned char> original;
404 MakeRGBAImage(w, h, false, &original);
405
406 // encode
407 std::vector<unsigned char> encoded;
408 ASSERT_TRUE(EncodeImage(original,
409 w, h,
410 COLOR_TYPE_BGRA,
411 &encoded,
412 PNG_INTERLACE_ADAM7));
413
414 // decode, it should have the same size as the original
415 std::vector<unsigned char> decoded;
416 int outw, outh;
417 ASSERT_TRUE(PNGCodec::Decode(&encoded[0], encoded.size(),
418 PNGCodec::FORMAT_BGRA, &decoded,
419 &outw, &outh));
420 ASSERT_EQ(w, outw);
421 ASSERT_EQ(h, outh);
422 ASSERT_EQ(original.size(), decoded.size());
423
424 // Images must be equal
425 ASSERT_EQ(original, decoded);
426 }
427
428 // Not encoding an interlaced PNG from SkBitmap because we don't do it
429 // anywhere, and the ability to do that requires more code changes.
430 TEST(PNGCodec, DecodeInterlacedRGBtoSkBitmap) {
431 const int w = 20, h = 20;
432
433 // create an image with known values
434 std::vector<unsigned char> original;
435 MakeRGBImage(w, h, &original);
436
437 // encode
438 std::vector<unsigned char> encoded;
439 ASSERT_TRUE(EncodeImage(original,
440 w, h,
441 COLOR_TYPE_RGB,
442 &encoded,
443 PNG_INTERLACE_ADAM7));
444
445 // Decode the encoded string.
446 SkBitmap decoded_bitmap;
447 ASSERT_TRUE(PNGCodec::Decode(&encoded.front(), encoded.size(),
448 &decoded_bitmap));
449
450 for (int x = 0; x < w; x++) {
451 for (int y = 0; y < h; y++) {
452 const unsigned char* original_pixel = &original[(y * w + x) * 3];
453 const uint32_t original_pixel_sk = SkPackARGB32(0xFF,
454 original_pixel[0],
455 original_pixel[1],
456 original_pixel[2]);
457 const uint32_t decoded_pixel = decoded_bitmap.getAddr32(0, y)[x];
458 ASSERT_EQ(original_pixel_sk, decoded_pixel);
459 }
460 }
461 }
462
463 TEST(PNGCodec, DecodeInterlacedRGBAtoSkBitmap) {
464 const int w = 20, h = 20;
465
466 // create an image with known values
467 std::vector<unsigned char> original;
468 MakeRGBAImage(w, h, false, &original);
469
470 // encode
471 std::vector<unsigned char> encoded;
472 ASSERT_TRUE(EncodeImage(original,
473 w, h,
474 COLOR_TYPE_RGBA,
475 &encoded,
476 PNG_INTERLACE_ADAM7));
477
478 // Decode the encoded string.
479 SkBitmap decoded_bitmap;
480 ASSERT_TRUE(PNGCodec::Decode(&encoded.front(), encoded.size(),
481 &decoded_bitmap));
482
483 for (int x = 0; x < w; x++) {
484 for (int y = 0; y < h; y++) {
485 const unsigned char* original_pixel = &original[(y * w + x) * 4];
486 const uint32_t original_pixel_sk = SkPackARGB32(original_pixel[3],
487 original_pixel[0],
488 original_pixel[1],
489 original_pixel[2]);
490 const uint32_t decoded_pixel = decoded_bitmap.getAddr32(0, y)[x];
491 ASSERT_EQ(original_pixel_sk, decoded_pixel);
492 }
493 }
494 }
495
133 // Test that corrupted data decompression causes failures. 496 // Test that corrupted data decompression causes failures.
134 TEST(PNGCodec, DecodeCorrupted) { 497 TEST(PNGCodec, DecodeCorrupted) {
135 int w = 20, h = 20; 498 int w = 20, h = 20;
136 499
137 // Make some random data (an uncompressed image). 500 // Make some random data (an uncompressed image).
138 std::vector<unsigned char> original; 501 std::vector<unsigned char> original;
139 MakeRGBImage(w, h, &original); 502 MakeRGBImage(w, h, &original);
140 503
141 // It should fail when given non-JPEG compressed data. 504 // It should fail when given non-JPEG compressed data.
142 std::vector<unsigned char> output; 505 std::vector<unsigned char> output;
143 int outw, outh; 506 int outw, outh;
144 EXPECT_FALSE(PNGCodec::Decode(&original[0], original.size(), 507 EXPECT_FALSE(PNGCodec::Decode(&original[0], original.size(),
145 PNGCodec::FORMAT_RGB, &output, 508 PNGCodec::FORMAT_RGB, &output,
146 &outw, &outh)); 509 &outw, &outh));
147 510
148 // Make some compressed data. 511 // Make some compressed data.
149 std::vector<unsigned char> compressed; 512 std::vector<unsigned char> compressed;
150 EXPECT_TRUE(PNGCodec::Encode(&original[0], PNGCodec::FORMAT_RGB, 513 ASSERT_TRUE(PNGCodec::Encode(&original[0], PNGCodec::FORMAT_RGB,
151 Size(w, h), w * 3, false, 514 Size(w, h), w * 3, false,
152 std::vector<PNGCodec::Comment>(), 515 std::vector<PNGCodec::Comment>(),
153 &compressed)); 516 &compressed));
154 517
155 // Try decompressing a truncated version. 518 // Try decompressing a truncated version.
156 EXPECT_FALSE(PNGCodec::Decode(&compressed[0], compressed.size() / 2, 519 EXPECT_FALSE(PNGCodec::Decode(&compressed[0], compressed.size() / 2,
157 PNGCodec::FORMAT_RGB, &output, 520 PNGCodec::FORMAT_RGB, &output,
158 &outw, &outh)); 521 &outw, &outh));
159 522
160 // Corrupt it and try decompressing that. 523 // Corrupt it and try decompressing that.
161 for (int i = 10; i < 30; i++) 524 for (int i = 10; i < 30; i++)
162 compressed[i] = i; 525 compressed[i] = i;
163 EXPECT_FALSE(PNGCodec::Decode(&compressed[0], compressed.size(), 526 EXPECT_FALSE(PNGCodec::Decode(&compressed[0], compressed.size(),
164 PNGCodec::FORMAT_RGB, &output, 527 PNGCodec::FORMAT_RGB, &output,
165 &outw, &outh)); 528 &outw, &outh));
166 } 529 }
167 530
168 TEST(PNGCodec, EncodeDecodeBGRA) {
169 const int w = 20, h = 20;
170
171 // Create an image with known values, alpha must be opaque because it will be
172 // lost during encoding.
173 std::vector<unsigned char> original;
174 MakeRGBAImage(w, h, true, &original);
175
176 // Encode.
177 std::vector<unsigned char> encoded;
178 EXPECT_TRUE(PNGCodec::Encode(&original[0], PNGCodec::FORMAT_BGRA,
179 Size(w, h), w * 4, false,
180 std::vector<PNGCodec::Comment>(),
181 &encoded));
182
183 // Decode, it should have the same size as the original.
184 std::vector<unsigned char> decoded;
185 int outw, outh;
186 EXPECT_TRUE(PNGCodec::Decode(&encoded[0], encoded.size(),
187 PNGCodec::FORMAT_BGRA, &decoded,
188 &outw, &outh));
189 ASSERT_EQ(w, outw);
190 ASSERT_EQ(h, outh);
191 ASSERT_EQ(original.size(), decoded.size());
192
193 // Images must be exactly equal.
194 ASSERT_TRUE(original == decoded);
Francois 2012/02/29 09:12:30 This function was moved further up.
195 }
196
197 TEST(PNGCodec, StripAddAlpha) { 531 TEST(PNGCodec, StripAddAlpha) {
198 const int w = 20, h = 20; 532 const int w = 20, h = 20;
199 533
200 // These should be the same except one has a 0xff alpha channel. 534 // These should be the same except one has a 0xff alpha channel.
201 std::vector<unsigned char> original_rgb; 535 std::vector<unsigned char> original_rgb;
202 MakeRGBImage(w, h, &original_rgb); 536 MakeRGBImage(w, h, &original_rgb);
203 std::vector<unsigned char> original_rgba; 537 std::vector<unsigned char> original_rgba;
204 MakeRGBAImage(w, h, false, &original_rgba); 538 MakeRGBAImage(w, h, false, &original_rgba);
205 539
206 // Encode RGBA data as RGB. 540 // Encode RGBA data as RGB.
207 std::vector<unsigned char> encoded; 541 std::vector<unsigned char> encoded;
208 EXPECT_TRUE(PNGCodec::Encode(&original_rgba[0], PNGCodec::FORMAT_RGBA, 542 EXPECT_TRUE(PNGCodec::Encode(&original_rgba[0], PNGCodec::FORMAT_RGBA,
209 Size(w, h), w * 4, true, 543 Size(w, h), w * 4, true,
210 std::vector<PNGCodec::Comment>(), 544 std::vector<PNGCodec::Comment>(),
211 &encoded)); 545 &encoded));
212 546
213 // Decode the RGB to RGBA. 547 // Decode the RGB to RGBA.
214 std::vector<unsigned char> decoded; 548 std::vector<unsigned char> decoded;
215 int outw, outh; 549 int outw, outh;
216 EXPECT_TRUE(PNGCodec::Decode(&encoded[0], encoded.size(), 550 EXPECT_TRUE(PNGCodec::Decode(&encoded[0], encoded.size(),
217 PNGCodec::FORMAT_RGBA, &decoded, 551 PNGCodec::FORMAT_RGBA, &decoded,
218 &outw, &outh)); 552 &outw, &outh));
219 553
220 // Decoded and reference should be the same (opaque alpha). 554 // Decoded and reference should be the same (opaque alpha).
221 ASSERT_EQ(w, outw); 555 ASSERT_EQ(w, outw);
222 ASSERT_EQ(h, outh); 556 ASSERT_EQ(h, outh);
223 ASSERT_EQ(original_rgba.size(), decoded.size()); 557 ASSERT_EQ(original_rgba.size(), decoded.size());
224 ASSERT_TRUE(original_rgba == decoded); 558 ASSERT_EQ(original_rgba, decoded);
225 559
226 // Encode RGBA to RGBA. 560 // Encode RGBA to RGBA.
227 EXPECT_TRUE(PNGCodec::Encode(&original_rgba[0], PNGCodec::FORMAT_RGBA, 561 EXPECT_TRUE(PNGCodec::Encode(&original_rgba[0], PNGCodec::FORMAT_RGBA,
228 Size(w, h), w * 4, false, 562 Size(w, h), w * 4, false,
229 std::vector<PNGCodec::Comment>(), 563 std::vector<PNGCodec::Comment>(),
230 &encoded)); 564 &encoded));
231 565
232 // Decode the RGBA to RGB. 566 // Decode the RGBA to RGB.
233 EXPECT_TRUE(PNGCodec::Decode(&encoded[0], encoded.size(), 567 EXPECT_TRUE(PNGCodec::Decode(&encoded[0], encoded.size(),
234 PNGCodec::FORMAT_RGB, &decoded, 568 PNGCodec::FORMAT_RGB, &decoded,
235 &outw, &outh)); 569 &outw, &outh));
236 570
237 // It should be the same as our non-alpha-channel reference. 571 // It should be the same as our non-alpha-channel reference.
238 ASSERT_EQ(w, outw); 572 ASSERT_EQ(w, outw);
239 ASSERT_EQ(h, outh); 573 ASSERT_EQ(h, outh);
240 ASSERT_EQ(original_rgb.size(), decoded.size()); 574 ASSERT_EQ(original_rgb.size(), decoded.size());
241 ASSERT_TRUE(original_rgb == decoded); 575 ASSERT_EQ(original_rgb, decoded);
242 } 576 }
243 577
244 TEST(PNGCodec, EncodeBGRASkBitmap) { 578 TEST(PNGCodec, EncodeBGRASkBitmap) {
245 const int w = 20, h = 20; 579 const int w = 20, h = 20;
246 580
247 SkBitmap original_bitmap; 581 SkBitmap original_bitmap;
248 MakeTestSkBitmap(w, h, &original_bitmap); 582 MakeTestSkBitmap(w, h, &original_bitmap);
249 583
250 // Encode the bitmap. 584 // Encode the bitmap.
251 std::vector<unsigned char> encoded; 585 std::vector<unsigned char> encoded;
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
379 ASSERT_EQ(w, outw); 713 ASSERT_EQ(w, outw);
380 ASSERT_EQ(h, outh); 714 ASSERT_EQ(h, outh);
381 ASSERT_EQ(original.size(), decoded.size()); 715 ASSERT_EQ(original.size(), decoded.size());
382 716
383 // Images must be exactly equal 717 // Images must be exactly equal
384 ASSERT_TRUE(original == decoded); 718 ASSERT_TRUE(original == decoded);
385 } 719 }
386 720
387 721
388 } // namespace gfx 722 } // namespace gfx
OLDNEW
« ui/gfx/codec/png_codec.cc ('K') | « ui/gfx/codec/png_codec.cc ('k') | ui/ui_unittests.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698