blob: e2e03845cad5f2c9a18f9b9f64c4b0e149b7120d [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
14#include "SkBitmap.h"
15#include "SkData.h"
16#include "SkForceLinking.h"
halcanary@google.com29d4e632013-10-11 18:21:56 +000017#include "SkImage.h"
tfarina@chromium.orge4fafb12013-12-12 21:11:12 +000018#include "SkImageDecoder.h"
halcanary@google.com29d4e632013-10-11 18:21:56 +000019#include "SkStream.h"
tfarina@chromium.org8f6884a2014-01-24 20:56:26 +000020#include "Test.h"
halcanary@google.com29d4e632013-10-11 18:21:56 +000021
22__SK_FORCE_IMAGE_DECODER_LINKING;
23
tfarina@chromium.org58674812014-01-21 23:39:22 +000024static 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
34static 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
40static 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};
halcanary@google.com29d4e632013-10-11 18:21:56 +000050
51static void test_gif_data_no_colormap(skiatest::Reporter* r,
tfarina@chromium.org58674812014-01-21 23:39:22 +000052 void* data,
53 size_t size) {
halcanary@google.com29d4e632013-10-11 18:21:56 +000054 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}
65static 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}
85static 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
118static 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*/
tfarina@chromium.orge4fafb12013-12-12 21:11:12 +0000143DEF_TEST(Gif, reporter) {
halcanary@google.com29d4e632013-10-11 18:21:56 +0000144 // test perfectly good images.
tfarina@chromium.org58674812014-01-21 23:39:22 +0000145 test_gif_data(reporter, static_cast<void *>(gGIFData), sizeof(gGIFData));
146 test_interlaced_gif_data(reporter, static_cast<void *>(gInterlacedGIF),
147 sizeof(gInterlacedGIF));
halcanary@google.com29d4e632013-10-11 18:21:56 +0000148
tfarina@chromium.org58674812014-01-21 23:39:22 +0000149 unsigned char badData[sizeof(gGIFData)];
halcanary@google.com29d4e632013-10-11 18:21:56 +0000150
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
tfarina@chromium.org58674812014-01-21 23:39:22 +0000155 memcpy(badData, gGIFData, sizeof(gGIFData));
halcanary@google.com29d4e632013-10-11 18:21:56 +0000156 badData[6] = 0x01; // image too wide
tfarina@chromium.org58674812014-01-21 23:39:22 +0000157 test_gif_data(reporter, static_cast<void *>(badData), sizeof(gGIFData));
halcanary@google.com29d4e632013-10-11 18:21:56 +0000158 // "libgif warning [image too wide, expanding output to size]"
159
tfarina@chromium.org58674812014-01-21 23:39:22 +0000160 memcpy(badData, gGIFData, sizeof(gGIFData));
halcanary@google.com29d4e632013-10-11 18:21:56 +0000161 badData[8] = 0x01; // image too tall
tfarina@chromium.org58674812014-01-21 23:39:22 +0000162 test_gif_data(reporter, static_cast<void *>(badData), sizeof(gGIFData));
halcanary@google.com29d4e632013-10-11 18:21:56 +0000163 // "libgif warning [image too tall, expanding output to size]"
164
tfarina@chromium.org58674812014-01-21 23:39:22 +0000165 memcpy(badData, gGIFData, sizeof(gGIFData));
halcanary@google.com29d4e632013-10-11 18:21:56 +0000166 badData[62] = 0x01; // image shifted right
tfarina@chromium.org58674812014-01-21 23:39:22 +0000167 test_gif_data(reporter, static_cast<void *>(badData), sizeof(gGIFData));
halcanary@google.com29d4e632013-10-11 18:21:56 +0000168 // "libgif warning [shifting image left to fit]"
169
tfarina@chromium.org58674812014-01-21 23:39:22 +0000170 memcpy(badData, gGIFData, sizeof(gGIFData));
halcanary@google.com29d4e632013-10-11 18:21:56 +0000171 badData[64] = 0x01; // image shifted down
tfarina@chromium.org58674812014-01-21 23:39:22 +0000172 test_gif_data(reporter, static_cast<void *>(badData), sizeof(gGIFData));
halcanary@google.com29d4e632013-10-11 18:21:56 +0000173 // "libgif warning [shifting image up to fit]"
174
tfarina@chromium.org58674812014-01-21 23:39:22 +0000175 memcpy(badData, gGIFData, sizeof(gGIFData));
halcanary@google.com29d4e632013-10-11 18:21:56 +0000176 badData[62] = 0xff; // image shifted left
177 badData[63] = 0xff; // 2's complement -1 short
tfarina@chromium.org58674812014-01-21 23:39:22 +0000178 test_gif_data(reporter, static_cast<void *>(badData), sizeof(gGIFData));
halcanary@google.com29d4e632013-10-11 18:21:56 +0000179 // "libgif warning [shifting image left to fit]"
180
tfarina@chromium.org58674812014-01-21 23:39:22 +0000181 memcpy(badData, gGIFData, sizeof(gGIFData));
halcanary@google.com29d4e632013-10-11 18:21:56 +0000182 badData[64] = 0xff; // image shifted up
183 badData[65] = 0xff; // 2's complement -1 short
tfarina@chromium.org58674812014-01-21 23:39:22 +0000184 test_gif_data(reporter, static_cast<void *>(badData), sizeof(gGIFData));
halcanary@google.com29d4e632013-10-11 18:21:56 +0000185 // "libgif warning [shifting image up to fit]"
186
tfarina@chromium.org58674812014-01-21 23:39:22 +0000187 test_gif_data_no_colormap(reporter, static_cast<void *>(gGIFDataNoColormap),
188 sizeof(gGIFDataNoColormap));
halcanary@google.com29d4e632013-10-11 18:21:56 +0000189 // "libgif warning [missing colormap]"
190
191 // test short Gif. 80 is missing a few bytes.
tfarina@chromium.org58674812014-01-21 23:39:22 +0000192 test_gif_data_short(reporter, static_cast<void *>(gGIFData), 80);
halcanary@google.com29d4e632013-10-11 18:21:56 +0000193 // "libgif warning [DGifGetLine]"
194
tfarina@chromium.org58674812014-01-21 23:39:22 +0000195 test_interlaced_gif_data(reporter, static_cast<void *>(gInterlacedGIF),
halcanary@google.com29d4e632013-10-11 18:21:56 +0000196 100); // 100 is missing a few bytes
197 // "libgif warning [interlace DGifGetLine]"
198}
199
halcanary@google.com29d4e632013-10-11 18:21:56 +0000200#endif // !(SK_BUILD_FOR_WIN32||SK_BUILD_FOR_IOS||SK_BUILD_FOR_MAC)