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 "SkColorPriv.h" | |
9 #include "SkImageDecoder.h" | |
10 #include "SkScaledBitmapSampler.h" | |
11 #include "SkStream.h" | |
12 #include "SkStreamHelpers.h" | |
13 #include "SkTypes.h" | |
14 | |
15 #include "SkKTXFile.h" | |
16 | |
17 #include "etc1.h" | |
18 | |
19 //////////////////////////////////////////////////////////////////////////////// ///////// | |
20 | |
21 | |
22 //////////////////////////////////////////////////////////////////////////////// ///////// | |
23 | |
robertphillips
2014/06/03 13:27:41
Comment on what KTX is ?
krajcevski
2014/06/03 14:46:27
Done.
| |
24 class SkKTXImageDecoder : public SkImageDecoder { | |
25 public: | |
26 SkKTXImageDecoder() { } | |
27 | |
28 virtual Format getFormat() const SK_OVERRIDE { | |
29 return kKTX_Format; | |
30 } | |
31 | |
32 protected: | |
33 virtual bool onDecode(SkStream* stream, SkBitmap* bm, Mode) SK_OVERRIDE; | |
34 | |
35 private: | |
36 typedef SkImageDecoder INHERITED; | |
37 }; | |
38 | |
39 bool SkKTXImageDecoder::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { | |
40 SkAutoMalloc autoMal; | |
41 const size_t length = CopyStreamToStorage(&autoMal, stream); | |
42 if (0 == length) { | |
43 return false; | |
44 } | |
45 | |
46 SkKTXFile ktxFile(reinterpret_cast<const uint8_t *>(autoMal.get()), length); | |
47 if (!ktxFile.valid()) { | |
48 return false; | |
49 } | |
50 | |
51 const unsigned short width = ktxFile.width(); | |
52 const unsigned short height = ktxFile.height(); | |
53 | |
robertphillips
2014/06/03 13:27:41
Won't we (in the future) need to support A8 ? Use
krajcevski
2014/06/03 14:46:27
We will, but I don't think isRGBA8() is the correc
| |
54 // should we allow the Chooser (if present) to pick a config for us??? | |
55 if (!this->chooseFromOneChoice(SkBitmap::kARGB_8888_Config, width, height)) { | |
56 return false; | |
57 } | |
58 | |
59 // Setup the sampler... | |
60 SkScaledBitmapSampler sampler(width, height, this->getSampleSize()); | |
61 | |
62 // Set the config... | |
63 bm->setConfig(SkBitmap::kARGB_8888_Config, | |
64 sampler.scaledWidth(), sampler.scaledHeight(), | |
65 0, | |
66 ktxFile.isRGBA8()? kUnpremul_SkAlphaType : kOpaque_SkAlphaType ); | |
67 if (SkImageDecoder::kDecodeBounds_Mode == mode) { | |
68 return true; | |
69 } | |
70 | |
71 // If we've made it this far, then we know how to grok the data. | |
72 if (!this->allocPixelRef(bm, NULL)) { | |
73 return false; | |
74 } | |
75 | |
76 // Lock the pixels, since we're about to write to them... | |
77 SkAutoLockPixels alp(*bm); | |
78 | |
79 if (ktxFile.isETC1()) { | |
80 if (!sampler.begin(bm, SkScaledBitmapSampler::kRGB, *this)) { | |
81 return false; | |
82 } | |
83 | |
84 // ETC1 Data is encoded as RGB pixels, so we should extract it as such | |
85 int nPixels = width * height; | |
86 SkAutoMalloc outRGBData(nPixels * 3); | |
87 etc1_byte *outRGBDataPtr = reinterpret_cast<etc1_byte *>(outRGBData.get( )); | |
88 | |
89 // Decode ETC1 | |
90 const etc1_byte *buf = reinterpret_cast<const etc1_byte *>(ktxFile.pixel Data()); | |
91 if (etc1_decode_image(buf, outRGBDataPtr, width, height, 3, width*3)) { | |
92 return false; | |
93 } | |
94 | |
95 // Set each of the pixels... | |
96 const int srcRowBytes = width * 3; | |
97 const int dstHeight = sampler.scaledHeight(); | |
98 const uint8_t *srcRow = reinterpret_cast<uint8_t *>(outRGBDataPtr); | |
99 srcRow += sampler.srcY0() * srcRowBytes; | |
100 for (int y = 0; y < dstHeight; ++y) { | |
101 sampler.next(srcRow); | |
102 srcRow += sampler.srcDY() * srcRowBytes; | |
103 } | |
104 | |
105 return true; | |
106 | |
107 } else if (ktxFile.isRGB8()) { | |
108 | |
robertphillips
2014/06/03 13:27:41
// Uncompressed RGB data ?
krajcevski
2014/06/03 14:46:27
Done.
| |
109 if (!sampler.begin(bm, SkScaledBitmapSampler::kRGB, *this)) { | |
110 return false; | |
111 } | |
112 | |
113 // Just need to read RGB pixels | |
114 const int srcRowBytes = width * 3; | |
115 const int dstHeight = sampler.scaledHeight(); | |
116 const uint8_t *srcRow = reinterpret_cast<const uint8_t *>(ktxFile.pixelD ata()); | |
117 srcRow += sampler.srcY0() * srcRowBytes; | |
118 for (int y = 0; y < dstHeight; ++y) { | |
119 sampler.next(srcRow); | |
120 srcRow += sampler.srcDY() * srcRowBytes; | |
121 } | |
122 | |
123 return true; | |
124 | |
125 } else if (ktxFile.isRGBA8()) { | |
126 | |
robertphillips
2014/06/03 13:27:41
// Uncompressed RGBA data ?
krajcevski
2014/06/03 14:46:27
Done.
| |
127 if (!sampler.begin(bm, SkScaledBitmapSampler::kRGBA, *this)) { | |
128 return false; | |
129 } | |
130 | |
robertphillips
2014/06/03 13:27:41
RGBA ?
krajcevski
2014/06/03 14:46:27
Done.
| |
131 // Just need to read RGB pixels | |
132 const int srcRowBytes = width * 4; | |
133 const int dstHeight = sampler.scaledHeight(); | |
134 const uint8_t *srcRow = reinterpret_cast<const uint8_t *>(ktxFile.pixelD ata()); | |
135 srcRow += sampler.srcY0() * srcRowBytes; | |
136 for (int y = 0; y < dstHeight; ++y) { | |
137 sampler.next(srcRow); | |
138 srcRow += sampler.srcDY() * srcRowBytes; | |
139 } | |
140 | |
141 return true; | |
142 } | |
143 | |
144 return false; | |
145 } | |
146 | |
147 //////////////////////////////////////////////////////////////////////////////// ///////// | |
148 DEFINE_DECODER_CREATOR(KTXImageDecoder); | |
149 //////////////////////////////////////////////////////////////////////////////// ///////// | |
150 | |
151 static SkImageDecoder* sk_libktx_dfactory(SkStreamRewindable* stream) { | |
152 if (SkKTXFile::is_ktx(stream)) { | |
153 return SkNEW(SkKTXImageDecoder); | |
154 } | |
155 return NULL; | |
156 } | |
157 | |
158 static SkImageDecoder_DecodeReg gReg(sk_libktx_dfactory); | |
159 | |
160 static SkImageDecoder::Format get_format_ktx(SkStreamRewindable* stream) { | |
161 if (SkKTXFile::is_ktx(stream)) { | |
162 return SkImageDecoder::kKTX_Format; | |
163 } | |
164 return SkImageDecoder::kUnknown_Format; | |
165 } | |
166 | |
167 static SkImageDecoder_FormatReg gFormatReg(get_format_ktx); | |
OLD | NEW |