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