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