Home | History | Annotate | Download | only in tests
      1 /*
      2  * Copyright 2014 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 #include "Resources.h"
      9 #include "SkBitmap.h"
     10 #include "SkData.h"
     11 #include "SkDecodingImageGenerator.h"
     12 #include "SkForceLinking.h"
     13 #include "SkImageDecoder.h"
     14 #include "SkOSFile.h"
     15 #include "SkRandom.h"
     16 #include "SkStream.h"
     17 #include "Test.h"
     18 
     19 __SK_FORCE_IMAGE_DECODER_LINKING;
     20 
     21 /**
     22  * First, make sure that writing an 8-bit RGBA KTX file and then
     23  * reading it produces the same bitmap.
     24  */
     25 DEF_TEST(KtxReadWrite, reporter) {
     26 
     27     // Random number generator with explicit seed for reproducibility
     28     SkRandom rand(0x1005cbad);
     29 
     30     SkBitmap bm8888;
     31     bool pixelsAllocated = bm8888.allocN32Pixels(128, 128);
     32     REPORTER_ASSERT(reporter, pixelsAllocated);
     33 
     34     uint8_t *pixels = reinterpret_cast<uint8_t*>(bm8888.getPixels());
     35     REPORTER_ASSERT(reporter, NULL != pixels);
     36 
     37     if (NULL == pixels) {
     38         return;
     39     }
     40 
     41     uint8_t *row = pixels;
     42     for (int y = 0; y < bm8888.height(); ++y) {
     43         for (int x = 0; x < bm8888.width(); ++x) {
     44             uint8_t a = rand.nextRangeU(0, 255);
     45             uint8_t r = rand.nextRangeU(0, 255);
     46             uint8_t g = rand.nextRangeU(0, 255);
     47             uint8_t b = rand.nextRangeU(0, 255);
     48 
     49             SkPMColor &pixel = *(reinterpret_cast<SkPMColor*>(row + x*sizeof(SkPMColor)));
     50             pixel = SkPreMultiplyARGB(a, r, g, b);
     51         }
     52         row += bm8888.rowBytes();
     53     }
     54     REPORTER_ASSERT(reporter, !(bm8888.empty()));
     55 
     56     SkAutoDataUnref encodedData(SkImageEncoder::EncodeData(bm8888, SkImageEncoder::kKTX_Type, 0));
     57     REPORTER_ASSERT(reporter, NULL != encodedData);
     58 
     59     SkAutoTUnref<SkMemoryStream> stream(SkNEW_ARGS(SkMemoryStream, (encodedData)));
     60     REPORTER_ASSERT(reporter, NULL != stream);
     61 
     62     SkBitmap decodedBitmap;
     63     bool imageDecodeSuccess = SkImageDecoder::DecodeStream(stream, &decodedBitmap);
     64     REPORTER_ASSERT(reporter, imageDecodeSuccess);
     65 
     66     REPORTER_ASSERT(reporter, decodedBitmap.colorType() == bm8888.colorType());
     67     REPORTER_ASSERT(reporter, decodedBitmap.alphaType() == bm8888.alphaType());
     68     REPORTER_ASSERT(reporter, decodedBitmap.width() == bm8888.width());
     69     REPORTER_ASSERT(reporter, decodedBitmap.height() == bm8888.height());
     70     REPORTER_ASSERT(reporter, !(decodedBitmap.empty()));
     71 
     72     uint8_t *decodedPixels = reinterpret_cast<uint8_t*>(decodedBitmap.getPixels());
     73     REPORTER_ASSERT(reporter, NULL != decodedPixels);
     74     REPORTER_ASSERT(reporter, decodedBitmap.getSize() == bm8888.getSize());
     75 
     76     if (NULL == decodedPixels) {
     77         return;
     78     }
     79 
     80     REPORTER_ASSERT(reporter, memcmp(decodedPixels, pixels, decodedBitmap.getSize()) == 0);
     81 }
     82 
     83 /**
     84  * Next test is to see whether or not reading an unpremultiplied KTX file accurately
     85  * creates a premultiplied buffer...
     86  */
     87 DEF_TEST(KtxReadUnpremul, reporter) {
     88 
     89     static const uint8_t kHalfWhiteKTX[] = {
     90         0xAB, 0x4B, 0x54, 0x58, 0x20, 0x31, // First twelve bytes is magic
     91         0x31, 0xBB, 0x0D, 0x0A, 0x1A, 0x0A, // KTX identifier string
     92         0x01, 0x02, 0x03, 0x04, // Then magic endian specifier
     93         0x01, 0x14, 0x00, 0x00, // uint32_t fGLType;
     94         0x01, 0x00, 0x00, 0x00, // uint32_t fGLTypeSize;
     95         0x08, 0x19, 0x00, 0x00, // uint32_t fGLFormat;
     96         0x58, 0x80, 0x00, 0x00, // uint32_t fGLInternalFormat;
     97         0x08, 0x19, 0x00, 0x00, // uint32_t fGLBaseInternalFormat;
     98         0x02, 0x00, 0x00, 0x00, // uint32_t fPixelWidth;
     99         0x02, 0x00, 0x00, 0x00, // uint32_t fPixelHeight;
    100         0x00, 0x00, 0x00, 0x00, // uint32_t fPixelDepth;
    101         0x00, 0x00, 0x00, 0x00, // uint32_t fNumberOfArrayElements;
    102         0x01, 0x00, 0x00, 0x00, // uint32_t fNumberOfFaces;
    103         0x01, 0x00, 0x00, 0x00, // uint32_t fNumberOfMipmapLevels;
    104         0x00, 0x00, 0x00, 0x00, // uint32_t fBytesOfKeyValueData;
    105         0x10, 0x00, 0x00, 0x00, // image size: 2x2 image of RGBA = 4 * 4 = 16 bytes
    106         0xFF, 0xFF, 0xFF, 0x80, // Pixel 1
    107         0xFF, 0xFF, 0xFF, 0x80, // Pixel 2
    108         0xFF, 0xFF, 0xFF, 0x80, // Pixel 3
    109         0xFF, 0xFF, 0xFF, 0x80};// Pixel 4
    110 
    111     SkAutoTUnref<SkMemoryStream> stream(
    112         SkNEW_ARGS(SkMemoryStream, (kHalfWhiteKTX, sizeof(kHalfWhiteKTX))));
    113     REPORTER_ASSERT(reporter, NULL != stream);
    114 
    115     SkBitmap decodedBitmap;
    116     bool imageDecodeSuccess = SkImageDecoder::DecodeStream(stream, &decodedBitmap);
    117     REPORTER_ASSERT(reporter, imageDecodeSuccess);
    118 
    119     REPORTER_ASSERT(reporter, decodedBitmap.colorType() == kN32_SkColorType);
    120     REPORTER_ASSERT(reporter, decodedBitmap.alphaType() == kPremul_SkAlphaType);
    121     REPORTER_ASSERT(reporter, decodedBitmap.width() == 2);
    122     REPORTER_ASSERT(reporter, decodedBitmap.height() == 2);
    123     REPORTER_ASSERT(reporter, !(decodedBitmap.empty()));
    124 
    125     uint8_t *decodedPixels = reinterpret_cast<uint8_t*>(decodedBitmap.getPixels());
    126     REPORTER_ASSERT(reporter, NULL != decodedPixels);
    127 
    128     uint8_t *row = decodedPixels;
    129     for (int j = 0; j < decodedBitmap.height(); ++j) {
    130         for (int i = 0; i < decodedBitmap.width(); ++i) {
    131             SkPMColor pixel = *(reinterpret_cast<SkPMColor*>(row + i*sizeof(SkPMColor)));
    132             REPORTER_ASSERT(reporter, SkPreMultiplyARGB(0x80, 0xFF, 0xFF, 0xFF) == pixel);
    133         }
    134         row += decodedBitmap.rowBytes();
    135     }
    136 }
    137 
    138 /**
    139  * Finally, make sure that if we get ETC1 data from a PKM file that we can then
    140  * accurately write it out into a KTX file (i.e. transferring the ETC1 data from
    141  * the PKM to the KTX should produce an identical KTX to the one we have on file)
    142  */
    143 DEF_TEST(KtxReexportPKM, reporter) {
    144     SkString resourcePath = GetResourcePath();
    145     SkString filename = SkOSPath::SkPathJoin(resourcePath.c_str(), "mandrill_128.pkm");
    146 
    147     // Load PKM file into a bitmap
    148     SkBitmap etcBitmap;
    149     SkAutoTUnref<SkData> fileData(SkData::NewFromFileName(filename.c_str()));
    150     REPORTER_ASSERT(reporter, NULL != fileData);
    151     if (NULL == fileData) {
    152         return;
    153     }
    154 
    155     bool installDiscardablePixelRefSuccess =
    156         SkInstallDiscardablePixelRef(
    157             SkDecodingImageGenerator::Create(
    158                 fileData, SkDecodingImageGenerator::Options()), &etcBitmap);
    159     REPORTER_ASSERT(reporter, installDiscardablePixelRefSuccess);
    160 
    161     // Write the bitmap out to a KTX file.
    162     SkData *ktxDataPtr = SkImageEncoder::EncodeData(etcBitmap, SkImageEncoder::kKTX_Type, 0);
    163     SkAutoDataUnref newKtxData(ktxDataPtr);
    164     REPORTER_ASSERT(reporter, NULL != ktxDataPtr);
    165 
    166     // See is this data is identical to data in existing ktx file.
    167     SkString ktxFilename = SkOSPath::SkPathJoin(resourcePath.c_str(), "mandrill_128.ktx");
    168     SkAutoDataUnref oldKtxData(SkData::NewFromFileName(ktxFilename.c_str()));
    169     REPORTER_ASSERT(reporter, oldKtxData->equals(newKtxData));
    170 }
    171