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