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; | |
robertphillips
2014/06/05 19:12:20
i & j are okay but I usually use x & y.
krajcevski
2014/06/05 19:29:44
Done.
| |
43 for (int j = 0; j < bm8888.height(); ++j) { | |
44 for (int i = 0; i < bm8888.width(); ++i) { | |
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 + i*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 | |
robertphillips
2014/06/05 19:12:20
_s -> memStream ? Do we even need _s ?
krajcevski
2014/06/05 19:29:44
No, this is my (poor) attempt at trying to manage
| |
112 SkMemoryStream *_s = SkNEW_ARGS(SkMemoryStream, (kHalfWhiteKTX, sizeof(kHalf WhiteKTX))); | |
113 SkAutoTUnref<SkMemoryStream> stream(_s); | |
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 |