• 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 // 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