Home | History | Annotate | Download | only in tests
      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