2 * Copyright 2013 Google Inc.
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
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))
16 #include "SkForceLinking.h"
18 #include "SkImageDecoder.h"
22 __SK_FORCE_IMAGE_DECODER_LINKING;
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
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
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
51 static void test_gif_data_no_colormap(skiatest::Reporter* r,
55 bool imageDecodeSuccess = SkImageDecoder::DecodeMemory(
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()));
62 REPORTER_ASSERT(r, bm.getColor(0, 0) == 0x00000000);
65 static void test_gif_data(skiatest::Reporter* r, void* data, size_t size) {
67 bool imageDecodeSuccess = SkImageDecoder::DecodeMemory(
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()));
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);
85 static void test_interlaced_gif_data(skiatest::Reporter* r,
89 bool imageDecodeSuccess = SkImageDecoder::DecodeMemory(
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()));
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);
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);
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);
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);
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);
118 static void test_gif_data_short(skiatest::Reporter* r,
122 bool imageDecodeSuccess = SkImageDecoder::DecodeMemory(
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()));
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);
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.
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));
149 unsigned char badData[sizeof(gGIFData)];
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. */
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]"
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]"
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]"
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]"
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]"
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]"
187 test_gif_data_no_colormap(reporter, static_cast<void *>(gGIFDataNoColormap),
188 sizeof(gGIFDataNoColormap));
189 // "libgif warning [missing colormap]"
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]"
195 test_interlaced_gif_data(reporter, static_cast<void *>(gInterlacedGIF),
196 100); // 100 is missing a few bytes
197 // "libgif warning [interlace DGifGetLine]"
200 #endif // !(SK_BUILD_FOR_WIN32||SK_BUILD_FOR_IOS||SK_BUILD_FOR_MAC)