1 /*
2 * Copyright 2013 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8 // This tests out GIF decoder (SkImageDecoder_libgif.cpp)
9 // It is not used on these platforms:
10 #if (!defined(SK_BUILD_FOR_WIN32)) && \
11 (!defined(SK_BUILD_FOR_IOS)) && \
12 (!defined(SK_BUILD_FOR_MAC))
13
14 #include "SkBitmap.h"
15 #include "SkData.h"
16 #include "SkForceLinking.h"
17 #include "SkImage.h"
18 #include "SkImageDecoder.h"
19 #include "SkStream.h"
20 #include "Test.h"
21
22 __SK_FORCE_IMAGE_DECODER_LINKING;
23
24 static unsigned char gGIFData[] = {
25 0x47, 0x49, 0x46, 0x38, 0x37, 0x61, 0x03, 0x00, 0x03, 0x00, 0xe3, 0x08,
26 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0x00,
27 0xff, 0x80, 0x80, 0x80, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
28 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
29 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
30 0xff, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00, 0x00, 0x04,
31 0x07, 0x50, 0x1c, 0x43, 0x40, 0x41, 0x23, 0x44, 0x00, 0x3b
32 };
33
34 static unsigned char gGIFDataNoColormap[] = {
35 0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
36 0x21, 0xf9, 0x04, 0x01, 0x0a, 0x00, 0x01, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x00,
37 0x01, 0x00, 0x01, 0x00, 0x00, 0x02, 0x02, 0x4c, 0x01, 0x00, 0x3b
38 };
39
40 static unsigned char gInterlacedGIF[] = {
41 0x47, 0x49, 0x46, 0x38, 0x37, 0x61, 0x09, 0x00, 0x09, 0x00, 0xe3, 0x08, 0x00,
42 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0x00, 0xff, 0x80,
43 0x80, 0x80, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff,
44 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
45 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x2c, 0x00, 0x00, 0x00,
46 0x00, 0x09, 0x00, 0x09, 0x00, 0x40, 0x04, 0x1b, 0x50, 0x1c, 0x23, 0xe9, 0x44,
47 0x23, 0x60, 0x9d, 0x09, 0x28, 0x1e, 0xf8, 0x6d, 0x64, 0x56, 0x9d, 0x53, 0xa8,
48 0x7e, 0xa8, 0x65, 0x94, 0x5c, 0xb0, 0x8a, 0x45, 0x04, 0x00, 0x3b
49 };
50
test_gif_data_no_colormap(skiatest::Reporter * r,void * data,size_t size)51 static void test_gif_data_no_colormap(skiatest::Reporter* r,
52 void* data,
53 size_t size) {
54 SkBitmap bm;
55 bool imageDecodeSuccess = SkImageDecoder::DecodeMemory(
56 data, size, &bm);
57 REPORTER_ASSERT(r, imageDecodeSuccess);
58 REPORTER_ASSERT(r, bm.width() == 1);
59 REPORTER_ASSERT(r, bm.height() == 1);
60 REPORTER_ASSERT(r, !(bm.empty()));
61 if (!(bm.empty())) {
62 REPORTER_ASSERT(r, bm.getColor(0, 0) == 0x00000000);
63 }
64 }
test_gif_data(skiatest::Reporter * r,void * data,size_t size)65 static void test_gif_data(skiatest::Reporter* r, void* data, size_t size) {
66 SkBitmap bm;
67 bool imageDecodeSuccess = SkImageDecoder::DecodeMemory(
68 data, size, &bm);
69 REPORTER_ASSERT(r, imageDecodeSuccess);
70 REPORTER_ASSERT(r, bm.width() == 3);
71 REPORTER_ASSERT(r, bm.height() == 3);
72 REPORTER_ASSERT(r, !(bm.empty()));
73 if (!(bm.empty())) {
74 REPORTER_ASSERT(r, bm.getColor(0, 0) == 0xffff0000);
75 REPORTER_ASSERT(r, bm.getColor(1, 0) == 0xffffff00);
76 REPORTER_ASSERT(r, bm.getColor(2, 0) == 0xff00ffff);
77 REPORTER_ASSERT(r, bm.getColor(0, 1) == 0xff808080);
78 REPORTER_ASSERT(r, bm.getColor(1, 1) == 0xff000000);
79 REPORTER_ASSERT(r, bm.getColor(2, 1) == 0xff00ff00);
80 REPORTER_ASSERT(r, bm.getColor(0, 2) == 0xffffffff);
81 REPORTER_ASSERT(r, bm.getColor(1, 2) == 0xffff00ff);
82 REPORTER_ASSERT(r, bm.getColor(2, 2) == 0xff0000ff);
83 }
84 }
test_interlaced_gif_data(skiatest::Reporter * r,void * data,size_t size)85 static void test_interlaced_gif_data(skiatest::Reporter* r,
86 void* data,
87 size_t size) {
88 SkBitmap bm;
89 bool imageDecodeSuccess = SkImageDecoder::DecodeMemory(
90 data, size, &bm);
91 REPORTER_ASSERT(r, imageDecodeSuccess);
92 REPORTER_ASSERT(r, bm.width() == 9);
93 REPORTER_ASSERT(r, bm.height() == 9);
94 REPORTER_ASSERT(r, !(bm.empty()));
95 if (!(bm.empty())) {
96 REPORTER_ASSERT(r, bm.getColor(0, 0) == 0xffff0000);
97 REPORTER_ASSERT(r, bm.getColor(1, 0) == 0xffffff00);
98 REPORTER_ASSERT(r, bm.getColor(2, 0) == 0xff00ffff);
99
100 REPORTER_ASSERT(r, bm.getColor(0, 2) == 0xffffffff);
101 REPORTER_ASSERT(r, bm.getColor(1, 2) == 0xffff00ff);
102 REPORTER_ASSERT(r, bm.getColor(2, 2) == 0xff0000ff);
103
104 REPORTER_ASSERT(r, bm.getColor(0, 4) == 0xff808080);
105 REPORTER_ASSERT(r, bm.getColor(1, 4) == 0xff000000);
106 REPORTER_ASSERT(r, bm.getColor(2, 4) == 0xff00ff00);
107
108 REPORTER_ASSERT(r, bm.getColor(0, 6) == 0xffff0000);
109 REPORTER_ASSERT(r, bm.getColor(1, 6) == 0xffffff00);
110 REPORTER_ASSERT(r, bm.getColor(2, 6) == 0xff00ffff);
111
112 REPORTER_ASSERT(r, bm.getColor(0, 8) == 0xffffffff);
113 REPORTER_ASSERT(r, bm.getColor(1, 8) == 0xffff00ff);
114 REPORTER_ASSERT(r, bm.getColor(2, 8) == 0xff0000ff);
115 }
116 }
117
test_gif_data_short(skiatest::Reporter * r,void * data,size_t size)118 static void test_gif_data_short(skiatest::Reporter* r,
119 void* data,
120 size_t size) {
121 SkBitmap bm;
122 bool imageDecodeSuccess = SkImageDecoder::DecodeMemory(
123 data, size, &bm);
124 REPORTER_ASSERT(r, imageDecodeSuccess);
125 REPORTER_ASSERT(r, bm.width() == 3);
126 REPORTER_ASSERT(r, bm.height() == 3);
127 REPORTER_ASSERT(r, !(bm.empty()));
128 if (!(bm.empty())) {
129 REPORTER_ASSERT(r, bm.getColor(0, 0) == 0xffff0000);
130 REPORTER_ASSERT(r, bm.getColor(1, 0) == 0xffffff00);
131 REPORTER_ASSERT(r, bm.getColor(2, 0) == 0xff00ffff);
132 REPORTER_ASSERT(r, bm.getColor(0, 1) == 0xff808080);
133 REPORTER_ASSERT(r, bm.getColor(1, 1) == 0xff000000);
134 REPORTER_ASSERT(r, bm.getColor(2, 1) == 0xff00ff00);
135 }
136 }
137
138 /**
139 This test will test the ability of the SkImageDecoder to deal with
140 GIF files which have been mangled somehow. We want to display as
141 much of the GIF as possible.
142 */
DEF_TEST(Gif,reporter)143 DEF_TEST(Gif, reporter) {
144 // test perfectly good images.
145 test_gif_data(reporter, static_cast<void *>(gGIFData), sizeof(gGIFData));
146 test_interlaced_gif_data(reporter, static_cast<void *>(gInterlacedGIF),
147 sizeof(gInterlacedGIF));
148
149 unsigned char badData[sizeof(gGIFData)];
150
151 /* If you set the environment variable
152 skia_images_gif_suppressDecoderWarnings to 'false', you will
153 see warnings on stderr. This is a feature. */
154
155 memcpy(badData, gGIFData, sizeof(gGIFData));
156 badData[6] = 0x01; // image too wide
157 test_gif_data(reporter, static_cast<void *>(badData), sizeof(gGIFData));
158 // "libgif warning [image too wide, expanding output to size]"
159
160 memcpy(badData, gGIFData, sizeof(gGIFData));
161 badData[8] = 0x01; // image too tall
162 test_gif_data(reporter, static_cast<void *>(badData), sizeof(gGIFData));
163 // "libgif warning [image too tall, expanding output to size]"
164
165 memcpy(badData, gGIFData, sizeof(gGIFData));
166 badData[62] = 0x01; // image shifted right
167 test_gif_data(reporter, static_cast<void *>(badData), sizeof(gGIFData));
168 // "libgif warning [shifting image left to fit]"
169
170 memcpy(badData, gGIFData, sizeof(gGIFData));
171 badData[64] = 0x01; // image shifted down
172 test_gif_data(reporter, static_cast<void *>(badData), sizeof(gGIFData));
173 // "libgif warning [shifting image up to fit]"
174
175 memcpy(badData, gGIFData, sizeof(gGIFData));
176 badData[62] = 0xff; // image shifted left
177 badData[63] = 0xff; // 2's complement -1 short
178 test_gif_data(reporter, static_cast<void *>(badData), sizeof(gGIFData));
179 // "libgif warning [shifting image left to fit]"
180
181 memcpy(badData, gGIFData, sizeof(gGIFData));
182 badData[64] = 0xff; // image shifted up
183 badData[65] = 0xff; // 2's complement -1 short
184 test_gif_data(reporter, static_cast<void *>(badData), sizeof(gGIFData));
185 // "libgif warning [shifting image up to fit]"
186
187 test_gif_data_no_colormap(reporter, static_cast<void *>(gGIFDataNoColormap),
188 sizeof(gGIFDataNoColormap));
189 // "libgif warning [missing colormap]"
190
191 // test short Gif. 80 is missing a few bytes.
192 test_gif_data_short(reporter, static_cast<void *>(gGIFData), 80);
193 // "libgif warning [DGifGetLine]"
194
195 test_interlaced_gif_data(reporter, static_cast<void *>(gInterlacedGIF),
196 100); // 100 is missing a few bytes
197 // "libgif warning [interlace DGifGetLine]"
198 }
199
200 #endif // !(SK_BUILD_FOR_WIN32||SK_BUILD_FOR_IOS||SK_BUILD_FOR_MAC)
201