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 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 } 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 } 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 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 */ 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