OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright 2014 Google Inc. | 2 * Copyright 2014 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "gm.h" | 8 #include "gm.h" |
9 #include "SkCanvas.h" | 9 #include "SkCanvas.h" |
10 #include "SkData.h" | 10 #include "SkData.h" |
11 #include "SkDecodingImageGenerator.h" | 11 #include "SkDecodingImageGenerator.h" |
12 #include "SkImageDecoder.h" | 12 #include "SkImageDecoder.h" |
13 #include "SkOSFile.h" | 13 #include "SkOSFile.h" |
14 | 14 |
robertphillips
2014/06/04 14:36:50
Do we have to guard this for builds w/o etc1 ?
krajcevski
2014/06/04 14:52:17
Well, I don't know if our gms go with our other so
| |
15 #include "etc1.h" | |
16 | |
17 /** | |
18 * Remove the last row and column of ETC1 blocks, effectively | |
19 * making a texture that started as power of two into a texture | |
20 * that is no longer power of two... | |
21 */ | |
22 bool slice_etc1_data(void *data, int* width, int* height) { | |
23 | |
24 // First, parse the data and get to it... | |
25 etc1_byte *etc1data = reinterpret_cast<etc1_byte *>(data); | |
26 if (!etc1_pkm_is_valid(etc1data)) { | |
27 return false; | |
28 } | |
29 | |
30 int encW = etc1_pkm_get_width(etc1data); | |
31 int encH = etc1_pkm_get_height(etc1data); | |
32 | |
33 int blockWidth = (encW + 3) >> 2; | |
34 int blockHeight = (encH + 3) >> 2; | |
35 | |
36 // Make sure that we have blocks to trim off.. | |
37 if (blockWidth < 2 || blockHeight < 2) { | |
38 return false; | |
39 } | |
40 | |
41 int newWidth = (blockWidth - 1) << 2; | |
42 int newHeight = (blockHeight - 1) << 2; | |
43 | |
44 size_t newDataSz = etc1_get_encoded_data_size(newWidth, newHeight) + ETC_PKM _HEADER_SIZE; | |
45 SkAutoMalloc am(newDataSz); | |
46 | |
47 etc1_byte *amData = reinterpret_cast<etc1_byte *>(am.get()); | |
48 | |
49 etc1_pkm_format_header(amData, newWidth, newHeight); | |
50 amData += ETC_PKM_HEADER_SIZE; | |
51 etc1data += ETC_PKM_HEADER_SIZE; | |
52 | |
53 for (int j = 0; j < blockHeight - 1; ++j) { | |
54 memcpy(amData, etc1data, (blockWidth - 1)*ETC1_ENCODED_BLOCK_SIZE); | |
55 etc1data += blockWidth*ETC1_ENCODED_BLOCK_SIZE; | |
56 amData += (blockWidth - 1)*ETC1_ENCODED_BLOCK_SIZE; | |
57 } | |
58 | |
59 // Stick the data back whence it came | |
60 memcpy(data, am.get(), newDataSz); | |
61 *width = newWidth; | |
62 *height = newHeight; | |
63 | |
64 return true; | |
65 } | |
66 | |
15 namespace skiagm { | 67 namespace skiagm { |
16 | 68 |
17 /** | 69 /** |
18 * Test decoding an image from a PKM or KTX file and then | 70 * Test decoding an image from a PKM or KTX file and then |
19 * from compressed ETC1 data. | 71 * from compressed ETC1 data. |
20 */ | 72 */ |
21 class ETC1BitmapGM : public GM { | 73 class ETC1BitmapGM : public GM { |
22 public: | 74 public: |
23 ETC1BitmapGM() { } | 75 ETC1BitmapGM() { } |
24 virtual ~ETC1BitmapGM() { } | 76 virtual ~ETC1BitmapGM() { } |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
83 virtual ~ETC1Bitmap_KTX_GM() { } | 135 virtual ~ETC1Bitmap_KTX_GM() { } |
84 | 136 |
85 protected: | 137 protected: |
86 | 138 |
87 virtual SkString fileExtension() const SK_OVERRIDE { return SkString("ktx"); } | 139 virtual SkString fileExtension() const SK_OVERRIDE { return SkString("ktx"); } |
88 | 140 |
89 private: | 141 private: |
90 typedef ETC1BitmapGM INHERITED; | 142 typedef ETC1BitmapGM INHERITED; |
91 }; | 143 }; |
92 | 144 |
145 /** | |
146 * Test decoding an image from a PKM file and then | |
147 * from non-power-of-two compressed ETC1 data. First slice | |
148 * off a row and column of blocks in order to make it non-power | |
149 * of two. | |
150 */ | |
151 class ETC1Bitmap_NPOT_GM : public GM { | |
152 public: | |
153 ETC1Bitmap_NPOT_GM() { } | |
154 virtual ~ETC1Bitmap_NPOT_GM() { } | |
155 | |
156 protected: | |
157 virtual SkString onShortName() SK_OVERRIDE { | |
158 return SkString("etc1bitmap_npot"); | |
159 } | |
160 | |
161 virtual SkISize onISize() SK_OVERRIDE { | |
162 return make_isize(508, 508); | |
163 } | |
164 | |
165 virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE { | |
166 | |
167 SkBitmap bm; | |
168 SkString filename = SkOSPath::SkPathJoin( | |
169 INHERITED::gResourcePath.c_str(), "mandrill_128.pkm"); | |
170 | |
171 SkAutoDataUnref fileData(SkData::NewFromFileName(filename.c_str())); | |
172 if (NULL == fileData) { | |
173 SkDebugf("Could not open the file. Did you forget to set the resourc ePath?\n"); | |
174 return; | |
175 } | |
176 | |
177 SkAutoMalloc am(fileData->size()); | |
178 memcpy(am.get(), fileData->data(), fileData->size()); | |
179 | |
180 int width, height; | |
181 if (!slice_etc1_data(am.get(), &width, &height)) { | |
182 SkDebugf("ETC1 Data is poorly formatted.\n"); | |
183 return; | |
184 } | |
185 | |
186 SkASSERT(124 == width); | |
187 SkASSERT(124 == height); | |
188 | |
189 size_t dataSz = etc1_get_encoded_data_size(width, height) + ETC_PKM_HEAD ER_SIZE; | |
190 SkAutoDataUnref nonPOTData(SkData::NewWithCopy(am.get(), dataSz)); | |
191 | |
192 if (!SkInstallDiscardablePixelRef( | |
193 SkDecodingImageGenerator::Create( | |
194 nonPOTData, SkDecodingImageGenerator::Options()), &bm)) { | |
195 SkDebugf("Could not install discardable pixel ref.\n"); | |
196 return; | |
197 } | |
198 | |
199 canvas->drawBitmap(bm, 0, 0); | |
200 } | |
201 | |
202 private: | |
203 typedef GM INHERITED; | |
204 }; | |
205 | |
93 } // namespace skiagm | 206 } // namespace skiagm |
94 | 207 |
95 ////////////////////////////////////////////////////////////////////////////// | 208 ////////////////////////////////////////////////////////////////////////////// |
96 | 209 |
97 DEF_GM( return SkNEW(skiagm::ETC1Bitmap_PKM_GM); ) | 210 DEF_GM( return SkNEW(skiagm::ETC1Bitmap_PKM_GM); ) |
98 DEF_GM( return SkNEW(skiagm::ETC1Bitmap_KTX_GM); ) | 211 DEF_GM( return SkNEW(skiagm::ETC1Bitmap_KTX_GM); ) |
212 DEF_GM( return SkNEW(skiagm::ETC1Bitmap_NPOT_GM); ) | |
OLD | NEW |