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 "Resources.h" | |
9 #include "SkBitmap.h" | |
10 #include "SkData.h" | |
11 #include "SkImageGenerator.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 bm8888.allocN32Pixels(128, 128); | |
32 | |
33 uint8_t *pixels = reinterpret_cast<uint8_t*>(bm8888.getPixels()); | |
34 REPORTER_ASSERT(reporter, pixels); | |
35 | |
36 if (nullptr == pixels) { | |
37 return; | |
38 } | |
39 | |
40 uint8_t *row = pixels; | |
41 for (int y = 0; y < bm8888.height(); ++y) { | |
42 for (int x = 0; x < bm8888.width(); ++x) { | |
43 uint8_t a = rand.nextRangeU(0, 255); | |
44 uint8_t r = rand.nextRangeU(0, 255); | |
45 uint8_t g = rand.nextRangeU(0, 255); | |
46 uint8_t b = rand.nextRangeU(0, 255); | |
47 | |
48 SkPMColor &pixel = *(reinterpret_cast<SkPMColor*>(row + x*sizeof(SkP
MColor))); | |
49 pixel = SkPreMultiplyARGB(a, r, g, b); | |
50 } | |
51 row += bm8888.rowBytes(); | |
52 } | |
53 REPORTER_ASSERT(reporter, !(bm8888.empty())); | |
54 | |
55 SkAutoDataUnref encodedData(SkImageEncoder::EncodeData(bm8888, SkImageEncode
r::kKTX_Type, 0)); | |
56 if (nullptr == encodedData.get()) { | |
57 ERRORF(reporter, "failed to encode the bitmap to KTX"); | |
58 return; | |
59 } | |
60 | |
61 | |
62 SkAutoTDelete<SkMemoryStream> stream(new SkMemoryStream(encodedData)); | |
63 REPORTER_ASSERT(reporter, stream); | |
64 | |
65 SkBitmap decodedBitmap; | |
66 bool imageDecodeSuccess = SkImageDecoder::DecodeStream(stream, &decodedBitma
p); | |
67 if (!imageDecodeSuccess) { | |
68 ERRORF(reporter, "failed to decode the KTX stream"); | |
69 return; | |
70 } | |
71 | |
72 REPORTER_ASSERT(reporter, decodedBitmap.colorType() == bm8888.colorType()); | |
73 REPORTER_ASSERT(reporter, decodedBitmap.alphaType() == bm8888.alphaType()); | |
74 REPORTER_ASSERT(reporter, decodedBitmap.width() == bm8888.width()); | |
75 REPORTER_ASSERT(reporter, decodedBitmap.height() == bm8888.height()); | |
76 REPORTER_ASSERT(reporter, !(decodedBitmap.empty())); | |
77 | |
78 uint8_t *decodedPixels = reinterpret_cast<uint8_t*>(decodedBitmap.getPixels(
)); | |
79 REPORTER_ASSERT(reporter, decodedPixels); | |
80 REPORTER_ASSERT(reporter, decodedBitmap.getSize() == bm8888.getSize()); | |
81 | |
82 if (nullptr == decodedPixels) { | |
83 return; | |
84 } | |
85 | |
86 REPORTER_ASSERT(reporter, memcmp(decodedPixels, pixels, decodedBitmap.getSiz
e()) == 0); | |
87 } | |
88 | |
89 /** | |
90 * Next test is to see whether or not reading an unpremultiplied KTX file accura
tely | |
91 * creates a premultiplied buffer... | |
92 */ | |
93 DEF_TEST(KtxReadUnpremul, reporter) { | |
94 | |
95 static const uint8_t kHalfWhiteKTX[] = { | |
96 0xAB, 0x4B, 0x54, 0x58, 0x20, 0x31, // First twelve bytes is magic | |
97 0x31, 0xBB, 0x0D, 0x0A, 0x1A, 0x0A, // KTX identifier string | |
98 0x01, 0x02, 0x03, 0x04, // Then magic endian specifier | |
99 0x01, 0x14, 0x00, 0x00, // uint32_t fGLType; | |
100 0x01, 0x00, 0x00, 0x00, // uint32_t fGLTypeSize; | |
101 0x08, 0x19, 0x00, 0x00, // uint32_t fGLFormat; | |
102 0x58, 0x80, 0x00, 0x00, // uint32_t fGLInternalFormat; | |
103 0x08, 0x19, 0x00, 0x00, // uint32_t fGLBaseInternalFormat; | |
104 0x02, 0x00, 0x00, 0x00, // uint32_t fPixelWidth; | |
105 0x02, 0x00, 0x00, 0x00, // uint32_t fPixelHeight; | |
106 0x00, 0x00, 0x00, 0x00, // uint32_t fPixelDepth; | |
107 0x00, 0x00, 0x00, 0x00, // uint32_t fNumberOfArrayElements; | |
108 0x01, 0x00, 0x00, 0x00, // uint32_t fNumberOfFaces; | |
109 0x01, 0x00, 0x00, 0x00, // uint32_t fNumberOfMipmapLevels; | |
110 0x00, 0x00, 0x00, 0x00, // uint32_t fBytesOfKeyValueData; | |
111 0x10, 0x00, 0x00, 0x00, // image size: 2x2 image of RGBA = 4 * 4 = 16 by
tes | |
112 0xFF, 0xFF, 0xFF, 0x80, // Pixel 1 | |
113 0xFF, 0xFF, 0xFF, 0x80, // Pixel 2 | |
114 0xFF, 0xFF, 0xFF, 0x80, // Pixel 3 | |
115 0xFF, 0xFF, 0xFF, 0x80};// Pixel 4 | |
116 | |
117 SkAutoTDelete<SkMemoryStream> stream(new SkMemoryStream(kHalfWhiteKTX, sizeo
f(kHalfWhiteKTX))); | |
118 REPORTER_ASSERT(reporter, stream); | |
119 | |
120 SkBitmap decodedBitmap; | |
121 bool imageDecodeSuccess = SkImageDecoder::DecodeStream(stream, &decodedBitma
p); | |
122 if (!imageDecodeSuccess) { | |
123 ERRORF(reporter, "failed to decode the KTX stream"); | |
124 return; | |
125 } | |
126 | |
127 REPORTER_ASSERT(reporter, decodedBitmap.colorType() == kN32_SkColorType); | |
128 REPORTER_ASSERT(reporter, decodedBitmap.alphaType() == kPremul_SkAlphaType); | |
129 REPORTER_ASSERT(reporter, decodedBitmap.width() == 2); | |
130 REPORTER_ASSERT(reporter, decodedBitmap.height() == 2); | |
131 REPORTER_ASSERT(reporter, !(decodedBitmap.empty())); | |
132 | |
133 uint8_t *decodedPixels = reinterpret_cast<uint8_t*>(decodedBitmap.getPixels(
)); | |
134 REPORTER_ASSERT(reporter, decodedPixels); | |
135 | |
136 uint8_t *row = decodedPixels; | |
137 for (int j = 0; j < decodedBitmap.height(); ++j) { | |
138 for (int i = 0; i < decodedBitmap.width(); ++i) { | |
139 SkPMColor pixel = *(reinterpret_cast<SkPMColor*>(row + i*sizeof(SkPM
Color))); | |
140 REPORTER_ASSERT(reporter, SkPreMultiplyARGB(0x80, 0xFF, 0xFF, 0xFF)
== pixel); | |
141 } | |
142 row += decodedBitmap.rowBytes(); | |
143 } | |
144 } | |
OLD | NEW |