blob: 0d9a44a18e3d3991d27274426a841360b2970e1d [file] [log] [blame]
license.botf003cfe2008-08-24 09:55:55 +09001// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commit3f4a7322008-07-27 06:49:38 +09004
5#include <math.h>
6
7#include "base/gfx/png_encoder.h"
8#include "base/gfx/png_decoder.h"
9#include "testing/gtest/include/gtest/gtest.h"
10
11static void MakeRGBImage(int w, int h, std::vector<unsigned char>* dat) {
12 dat->resize(w * h * 3);
13 for (int y = 0; y < h; y++) {
14 for (int x = 0; x < w; x++) {
15 unsigned char* org_px = &(*dat)[(y * w + x) * 3];
16 org_px[0] = x * 3; // r
17 org_px[1] = x * 3 + 1; // g
18 org_px[2] = x * 3 + 2; // b
19 }
20 }
21}
22
23// Set use_transparency to write data into the alpha channel, otherwise it will
24// be filled with 0xff. With the alpha channel stripped, this should yield the
25// same image as MakeRGBImage above, so the code below can make reference
26// images for conversion testing.
27static void MakeRGBAImage(int w, int h, bool use_transparency,
28 std::vector<unsigned char>* dat) {
29 dat->resize(w * h * 4);
30 for (int y = 0; y < h; y++) {
31 for (int x = 0; x < w; x++) {
32 unsigned char* org_px = &(*dat)[(y * w + x) * 4];
33 org_px[0] = x * 3; // r
34 org_px[1] = x * 3 + 1; // g
35 org_px[2] = x * 3 + 2; // b
36 if (use_transparency)
37 org_px[3] = x*3 + 3; // a
38 else
39 org_px[3] = 0xFF; // a (opaque)
40 }
41 }
42}
43
44TEST(PNGCodec, EncodeDecodeRGB) {
45 const int w = 20, h = 20;
46
47 // create an image with known values
48 std::vector<unsigned char> original;
49 MakeRGBImage(w, h, &original);
50
51 // encode
52 std::vector<unsigned char> encoded;
53 EXPECT_TRUE(PNGEncoder::Encode(&original[0], PNGEncoder::FORMAT_RGB, w, h,
54 w * 3, false, &encoded));
55
56 // decode, it should have the same size as the original
57 std::vector<unsigned char> decoded;
58 int outw, outh;
59 EXPECT_TRUE(PNGDecoder::Decode(&encoded[0], encoded.size(),
60 PNGDecoder::FORMAT_RGB, &decoded,
61 &outw, &outh));
62 ASSERT_EQ(w, outw);
63 ASSERT_EQ(h, outh);
64 ASSERT_EQ(original.size(), decoded.size());
65
66 // Images must be equal
67 ASSERT_TRUE(original == decoded);
68}
69
70TEST(PNGCodec, EncodeDecodeRGBA) {
71 const int w = 20, h = 20;
72
73 // create an image with known values, a must be opaque because it will be
74 // lost during encoding
75 std::vector<unsigned char> original;
76 MakeRGBAImage(w, h, true, &original);
77
78 // encode
79 std::vector<unsigned char> encoded;
80 EXPECT_TRUE(PNGEncoder::Encode(&original[0], PNGEncoder::FORMAT_RGBA, w, h,
81 w * 4, false, &encoded));
82
83 // decode, it should have the same size as the original
84 std::vector<unsigned char> decoded;
85 int outw, outh;
86 EXPECT_TRUE(PNGDecoder::Decode(&encoded[0], encoded.size(),
87 PNGDecoder::FORMAT_RGBA, &decoded,
88 &outw, &outh));
89 ASSERT_EQ(w, outw);
90 ASSERT_EQ(h, outh);
91 ASSERT_EQ(original.size(), decoded.size());
92
93 // Images must be exactly equal
94 ASSERT_TRUE(original == decoded);
95}
96
97// Test that corrupted data decompression causes failures.
98TEST(PNGCodec, DecodeCorrupted) {
99 int w = 20, h = 20;
100
101 // Make some random data (an uncompressed image).
102 std::vector<unsigned char> original;
103 MakeRGBImage(w, h, &original);
104
105 // It should fail when given non-JPEG compressed data.
106 std::vector<unsigned char> output;
107 int outw, outh;
108 EXPECT_FALSE(PNGDecoder::Decode(&original[0], original.size(),
109 PNGDecoder::FORMAT_RGB, &output,
110 &outw, &outh));
111
112 // Make some compressed data.
113 std::vector<unsigned char> compressed;
114 EXPECT_TRUE(PNGEncoder::Encode(&original[0], PNGEncoder::FORMAT_RGB, w, h,
115 w * 3, false, &compressed));
116
117 // Try decompressing a truncated version.
118 EXPECT_FALSE(PNGDecoder::Decode(&compressed[0], compressed.size() / 2,
119 PNGDecoder::FORMAT_RGB, &output,
120 &outw, &outh));
121
122 // Corrupt it and try decompressing that.
123 for (int i = 10; i < 30; i++)
124 compressed[i] = i;
125 EXPECT_FALSE(PNGDecoder::Decode(&compressed[0], compressed.size(),
126 PNGDecoder::FORMAT_RGB, &output,
127 &outw, &outh));
128}
129
130TEST(PNGCodec, EncodeDecodeBGRA) {
131 const int w = 20, h = 20;
132
133 // Create an image with known values, alpha must be opaque because it will be
134 // lost during encoding.
135 std::vector<unsigned char> original;
136 MakeRGBAImage(w, h, true, &original);
137
138 // Encode.
139 std::vector<unsigned char> encoded;
140 EXPECT_TRUE(PNGEncoder::Encode(&original[0], PNGEncoder::FORMAT_BGRA, w, h,
141 w * 4, false, &encoded));
142
143 // Decode, it should have the same size as the original.
144 std::vector<unsigned char> decoded;
145 int outw, outh;
146 EXPECT_TRUE(PNGDecoder::Decode(&encoded[0], encoded.size(),
147 PNGDecoder::FORMAT_BGRA, &decoded,
148 &outw, &outh));
149 ASSERT_EQ(w, outw);
150 ASSERT_EQ(h, outh);
151 ASSERT_EQ(original.size(), decoded.size());
152
153 // Images must be exactly equal.
154 ASSERT_TRUE(original == decoded);
155}
156
157TEST(PNGCodec, StripAddAlpha) {
158 const int w = 20, h = 20;
159
160 // These should be the same except one has a 0xff alpha channel.
161 std::vector<unsigned char> original_rgb;
162 MakeRGBImage(w, h, &original_rgb);
163 std::vector<unsigned char> original_rgba;
164 MakeRGBAImage(w, h, false, &original_rgba);
165
166 // Encode RGBA data as RGB.
167 std::vector<unsigned char> encoded;
168 EXPECT_TRUE(PNGEncoder::Encode(&original_rgba[0], PNGEncoder::FORMAT_RGBA, w, h,
169 w * 4, true, &encoded));
170
171 // Decode the RGB to RGBA.
172 std::vector<unsigned char> decoded;
173 int outw, outh;
174 EXPECT_TRUE(PNGDecoder::Decode(&encoded[0], encoded.size(),
175 PNGDecoder::FORMAT_RGBA, &decoded,
176 &outw, &outh));
177
178 // Decoded and reference should be the same (opaque alpha).
179 ASSERT_EQ(w, outw);
180 ASSERT_EQ(h, outh);
181 ASSERT_EQ(original_rgba.size(), decoded.size());
182 ASSERT_TRUE(original_rgba == decoded);
183
184 // Encode RGBA to RGBA.
185 EXPECT_TRUE(PNGEncoder::Encode(&original_rgba[0], PNGEncoder::FORMAT_RGBA, w, h,
186 w * 4, false, &encoded));
187
188 // Decode the RGBA to RGB.
189 EXPECT_TRUE(PNGDecoder::Decode(&encoded[0], encoded.size(),
190 PNGDecoder::FORMAT_RGB, &decoded,
191 &outw, &outh));
192
193 // It should be the same as our non-alpha-channel reference.
194 ASSERT_EQ(w, outw);
195 ASSERT_EQ(h, outh);
196 ASSERT_EQ(original_rgb.size(), decoded.size());
197 ASSERT_TRUE(original_rgb == decoded);
198}
license.botf003cfe2008-08-24 09:55:55 +0900199