Index: tests/KtxTest.cpp |
diff --git a/tests/KtxTest.cpp b/tests/KtxTest.cpp |
new file mode 100644 |
index 0000000000000000000000000000000000000000..ee6a17dabde3f118d78f3e4c09a09979067da275 |
--- /dev/null |
+++ b/tests/KtxTest.cpp |
@@ -0,0 +1,168 @@ |
+/* |
+ * Copyright 2014 Google Inc. |
+ * |
+ * Use of this source code is governed by a BSD-style license that can be |
+ * found in the LICENSE file. |
+ */ |
+ |
+#include "SkBitmap.h" |
+#include "SkData.h" |
+#include "SkDecodingImageGenerator.h" |
+#include "SkForceLinking.h" |
+#include "SkImageDecoder.h" |
+#include "SkOSFile.h" |
+#include "SkRandom.h" |
+#include "SkStream.h" |
+#include "Test.h" |
+ |
+__SK_FORCE_IMAGE_DECODER_LINKING; |
+ |
+/** |
+ * First, make sure that writing an 8-bit RGBA KTX file and then |
+ * reading it produces the same bitmap. |
+ */ |
+DEF_TEST(KtxReadWrite, reporter) { |
+ |
+ // Random number generator with explicit seed for reproducibility |
+ SkRandom rand(0x1005cbad); |
+ |
+ SkBitmap bm8888; |
+ bm8888.setConfig(SkBitmap::kARGB_8888_Config, 128, 128); |
+ |
+ bool pixelsAllocated = bm8888.allocPixels(); |
+ REPORTER_ASSERT(reporter, pixelsAllocated); |
+ |
+ uint8_t *pixels = reinterpret_cast<uint8_t*>(bm8888.getPixels()); |
+ REPORTER_ASSERT(reporter, NULL != pixels); |
+ |
+ if (NULL == pixels) { |
+ return; |
+ } |
+ |
+ uint8_t *row = pixels; |
+ for (int y = 0; y < bm8888.height(); ++y) { |
+ for (int x = 0; x < bm8888.width(); ++x) { |
+ uint8_t a = rand.nextRangeU(0, 255); |
+ uint8_t r = rand.nextRangeU(0, 255); |
+ uint8_t g = rand.nextRangeU(0, 255); |
+ uint8_t b = rand.nextRangeU(0, 255); |
+ |
+ SkPMColor &pixel = *(reinterpret_cast<SkPMColor*>(row + x*sizeof(SkPMColor))); |
+ pixel = SkPreMultiplyARGB(a, r, g, b); |
+ } |
+ row += bm8888.rowBytes(); |
+ } |
+ REPORTER_ASSERT(reporter, !(bm8888.empty())); |
+ |
+ SkAutoDataUnref encodedData(SkImageEncoder::EncodeData(bm8888, SkImageEncoder::kKTX_Type, 0)); |
+ REPORTER_ASSERT(reporter, NULL != encodedData); |
+ |
+ SkAutoTUnref<SkMemoryStream> stream(SkNEW_ARGS(SkMemoryStream, (encodedData))); |
+ REPORTER_ASSERT(reporter, NULL != stream); |
+ |
+ SkBitmap decodedBitmap; |
+ bool imageDecodeSuccess = SkImageDecoder::DecodeStream(stream, &decodedBitmap); |
+ REPORTER_ASSERT(reporter, imageDecodeSuccess); |
+ |
+ REPORTER_ASSERT(reporter, decodedBitmap.config() == bm8888.config()); |
+ REPORTER_ASSERT(reporter, decodedBitmap.alphaType() == bm8888.alphaType()); |
+ REPORTER_ASSERT(reporter, decodedBitmap.width() == bm8888.width()); |
+ REPORTER_ASSERT(reporter, decodedBitmap.height() == bm8888.height()); |
+ REPORTER_ASSERT(reporter, !(decodedBitmap.empty())); |
+ |
+ uint8_t *decodedPixels = reinterpret_cast<uint8_t*>(decodedBitmap.getPixels()); |
+ REPORTER_ASSERT(reporter, NULL != decodedPixels); |
+ REPORTER_ASSERT(reporter, decodedBitmap.getSize() == bm8888.getSize()); |
+ |
+ if (NULL == decodedPixels) { |
+ return; |
+ } |
+ |
+ REPORTER_ASSERT(reporter, memcmp(decodedPixels, pixels, decodedBitmap.getSize()) == 0); |
+} |
+ |
+/** |
+ * Next test is to see whether or not reading an unpremultiplied KTX file accurately |
+ * creates a premultiplied buffer... |
+ */ |
+DEF_TEST(KtxReadUnpremul, reporter) { |
+ |
+ static const uint8_t kHalfWhiteKTX[] = { |
+ 0xAB, 0x4B, 0x54, 0x58, 0x20, 0x31, // First twelve bytes is magic |
+ 0x31, 0xBB, 0x0D, 0x0A, 0x1A, 0x0A, // KTX identifier string |
+ 0x01, 0x02, 0x03, 0x04, // Then magic endian specifier |
+ 0x01, 0x14, 0x00, 0x00, // uint32_t fGLType; |
+ 0x01, 0x00, 0x00, 0x00, // uint32_t fGLTypeSize; |
+ 0x08, 0x19, 0x00, 0x00, // uint32_t fGLFormat; |
+ 0x58, 0x80, 0x00, 0x00, // uint32_t fGLInternalFormat; |
+ 0x08, 0x19, 0x00, 0x00, // uint32_t fGLBaseInternalFormat; |
+ 0x02, 0x00, 0x00, 0x00, // uint32_t fPixelWidth; |
+ 0x02, 0x00, 0x00, 0x00, // uint32_t fPixelHeight; |
+ 0x00, 0x00, 0x00, 0x00, // uint32_t fPixelDepth; |
+ 0x00, 0x00, 0x00, 0x00, // uint32_t fNumberOfArrayElements; |
+ 0x01, 0x00, 0x00, 0x00, // uint32_t fNumberOfFaces; |
+ 0x01, 0x00, 0x00, 0x00, // uint32_t fNumberOfMipmapLevels; |
+ 0x00, 0x00, 0x00, 0x00, // uint32_t fBytesOfKeyValueData; |
+ 0x10, 0x00, 0x00, 0x00, // image size: 2x2 image of RGBA = 4 * 4 = 16 bytes |
+ 0xFF, 0xFF, 0xFF, 0x80, // Pixel 1 |
+ 0xFF, 0xFF, 0xFF, 0x80, // Pixel 2 |
+ 0xFF, 0xFF, 0xFF, 0x80, // Pixel 3 |
+ 0xFF, 0xFF, 0xFF, 0x80};// Pixel 4 |
+ |
+ SkAutoTUnref<SkMemoryStream> stream( |
+ SkNEW_ARGS(SkMemoryStream, (kHalfWhiteKTX, sizeof(kHalfWhiteKTX)))); |
+ REPORTER_ASSERT(reporter, NULL != stream); |
+ |
+ SkBitmap decodedBitmap; |
+ bool imageDecodeSuccess = SkImageDecoder::DecodeStream(stream, &decodedBitmap); |
+ REPORTER_ASSERT(reporter, imageDecodeSuccess); |
+ |
+ REPORTER_ASSERT(reporter, decodedBitmap.config() == SkBitmap::kARGB_8888_Config); |
+ REPORTER_ASSERT(reporter, decodedBitmap.alphaType() == kPremul_SkAlphaType); |
+ REPORTER_ASSERT(reporter, decodedBitmap.width() == 2); |
+ REPORTER_ASSERT(reporter, decodedBitmap.height() == 2); |
+ REPORTER_ASSERT(reporter, !(decodedBitmap.empty())); |
+ |
+ uint8_t *decodedPixels = reinterpret_cast<uint8_t*>(decodedBitmap.getPixels()); |
+ REPORTER_ASSERT(reporter, NULL != decodedPixels); |
+ |
+ uint8_t *row = decodedPixels; |
+ for (int j = 0; j < decodedBitmap.height(); ++j) { |
+ for (int i = 0; i < decodedBitmap.width(); ++i) { |
+ SkPMColor pixel = *(reinterpret_cast<SkPMColor*>(row + i*sizeof(SkPMColor))); |
+ REPORTER_ASSERT(reporter, SkPreMultiplyARGB(0x80, 0xFF, 0xFF, 0xFF) == pixel); |
+ } |
+ row += decodedBitmap.rowBytes(); |
+ } |
+} |
+ |
+/** |
+ * Finally, make sure that if we get ETC1 data from a PKM file that we can then |
+ * accurately write it out into a KTX file (i.e. transferring the ETC1 data from |
+ * the PKM to the KTX should produce an identical KTX to the one we have on file) |
+ */ |
+DEF_TEST(KtxReexportPKM, reporter) { |
+ SkString resourcePath = skiatest::Test::GetResourcePath(); |
+ SkString filename = SkOSPath::SkPathJoin(resourcePath.c_str(), "mandrill_128.pkm"); |
+ |
+ // Load PKM file into a bitmap |
+ SkBitmap etcBitmap; |
+ SkAutoTUnref<SkData> fileData(SkData::NewFromFileName(filename.c_str())); |
+ REPORTER_ASSERT(reporter, NULL != fileData); |
+ |
+ bool installDiscardablePixelRefSuccess = |
+ SkInstallDiscardablePixelRef( |
+ SkDecodingImageGenerator::Create( |
+ fileData, SkDecodingImageGenerator::Options()), &etcBitmap); |
+ REPORTER_ASSERT(reporter, installDiscardablePixelRefSuccess); |
+ |
+ // Write the bitmap out to a KTX file. |
+ SkData *ktxDataPtr = SkImageEncoder::EncodeData(etcBitmap, SkImageEncoder::kKTX_Type, 0); |
+ SkAutoDataUnref newKtxData(ktxDataPtr); |
+ REPORTER_ASSERT(reporter, NULL != ktxDataPtr); |
+ |
+ // See is this data is identical to data in existing ktx file. |
+ SkString ktxFilename = SkOSPath::SkPathJoin(resourcePath.c_str(), "mandrill_128.ktx"); |
+ SkAutoDataUnref oldKtxData(SkData::NewFromFileName(ktxFilename.c_str())); |
+ REPORTER_ASSERT(reporter, oldKtxData->equals(newKtxData)); |
+} |