Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(510)

Side by Side Diff: src/codec/SkCodec_wbmp.cpp

Issue 1254483004: Scanline decoding for wbmp (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright 2015 Google Inc. 2 * Copyright 2015 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 "SkCodec.h" 8 #include "SkCodec.h"
9 #include "SkColorPriv.h" 9 #include "SkColorPriv.h"
10 #include "SkStream.h" 10 #include "SkStream.h"
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
61 static uint8_t bit_to_bit(U8CPU bit) { return bit; } 61 static uint8_t bit_to_bit(U8CPU bit) { return bit; }
62 62
63 static uint8_t bit_to_grayscale(U8CPU bit) { 63 static uint8_t bit_to_grayscale(U8CPU bit) {
64 return bit ? GRAYSCALE_WHITE : GRAYSCALE_BLACK; 64 return bit ? GRAYSCALE_WHITE : GRAYSCALE_BLACK;
65 } 65 }
66 66
67 static uint16_t bit_to_rgb565(U8CPU bit) { 67 static uint16_t bit_to_rgb565(U8CPU bit) {
68 return bit ? RGB565_WHITE : RGB565_BLACK; 68 return bit ? RGB565_WHITE : RGB565_BLACK;
69 } 69 }
70 70
71 typedef void (*ExpandProc)(uint8_t*, const uint8_t*, int);
72
73 // TODO(halcanary): Add this functionality (grayscale and indexed output) to 71 // TODO(halcanary): Add this functionality (grayscale and indexed output) to
74 // SkSwizzler and use it here. 72 // SkSwizzler and use it here.
75 template <typename T, T (*TRANSFORM)(U8CPU)> 73 template <typename T, T (*TRANSFORM)(U8CPU)>
76 static void expand_bits_to_T(uint8_t* dstptr, const uint8_t* src, int bits) { 74 static void expand_bits_to_T(uint8_t* dstptr, const uint8_t* src, int bits) {
77 T* dst = reinterpret_cast<T*>(dstptr); 75 T* dst = reinterpret_cast<T*>(dstptr);
78 int bytes = bits >> 3; 76 int bytes = bits >> 3;
79 for (int i = 0; i < bytes; i++) { 77 for (int i = 0; i < bytes; i++) {
80 U8CPU mask = *src++; 78 U8CPU mask = *src++;
81 for (int j = 0; j < 8; j++) { 79 for (int j = 0; j < 8; j++) {
82 dst[j] = TRANSFORM((mask >> (7 - j)) & 1); 80 dst[j] = TRANSFORM((mask >> (7 - j)) & 1);
83 } 81 }
84 dst += 8; 82 dst += 8;
85 } 83 }
86 bits &= 7; 84 bits &= 7;
87 if (bits > 0) { 85 if (bits > 0) {
88 U8CPU mask = *src; 86 U8CPU mask = *src;
89 do { 87 do {
90 *dst++ = TRANSFORM((mask >> 7) & 1); 88 *dst++ = TRANSFORM((mask >> 7) & 1);
91 mask <<= 1; 89 mask <<= 1;
92 } while (--bits != 0); 90 } while (--bits != 0);
93 } 91 }
94 } 92 }
95 93
94 bool SkWbmpCodec::setExpandProc(SkColorType colorType, SkPMColor* ctable, int* c tableCount) {
95 switch (colorType) {
96 case kGray_8_SkColorType:
97 fProc = expand_bits_to_T<uint8_t, bit_to_grayscale>;
98 return true;
99 case kN32_SkColorType:
100 fProc = expand_bits_to_T<SkPMColor, bit_to_pmcolor>;
101 return true;
102 case kIndex_8_SkColorType:
103 ctable[0] = BLACK;
104 ctable[1] = WHITE;
105 *ctableCount = 2;
106 fProc = expand_bits_to_T<uint8_t, bit_to_bit>;
107 return true;
108 case kRGB_565_SkColorType:
109 fProc = expand_bits_to_T<uint16_t, bit_to_rgb565>;
110 return true;
111 default:
112 return false;
113 }
114 }
115
96 SkWbmpCodec::SkWbmpCodec(const SkImageInfo& info, SkStream* stream) 116 SkWbmpCodec::SkWbmpCodec(const SkImageInfo& info, SkStream* stream)
97 : INHERITED(info, stream) {} 117 : INHERITED(info, stream) {}
98 118
99 SkEncodedFormat SkWbmpCodec::onGetEncodedFormat() const { 119 SkEncodedFormat SkWbmpCodec::onGetEncodedFormat() const {
100 return kWBMP_SkEncodedFormat; 120 return kWBMP_SkEncodedFormat;
101 } 121 }
102 122
103 SkCodec::Result SkWbmpCodec::onGetPixels(const SkImageInfo& info, 123 SkCodec::Result SkWbmpCodec::onGetPixels(const SkImageInfo& info,
104 void* pixels, 124 void* pixels,
105 size_t rowBytes, 125 size_t rowBytes,
106 const Options& options, 126 const Options& options,
107 SkPMColor ctable[], 127 SkPMColor ctable[],
108 int* ctableCount) { 128 int* ctableCount) {
109 SkCodec::RewindState rewindState = this->rewindIfNeeded(); 129 SkCodec::RewindState rewindState = this->rewindIfNeeded();
110 if (rewindState == kCouldNotRewind_RewindState) { 130 if (rewindState == kCouldNotRewind_RewindState) {
111 return kCouldNotRewind; 131 return kCouldNotRewind;
112 } else if (rewindState == kRewound_RewindState) { 132 } else if (rewindState == kRewound_RewindState) {
113 (void)read_header(this->stream(), NULL); 133 (void)read_header(this->stream(), NULL);
114 } 134 }
115 if (options.fSubset) { 135 if (options.fSubset) {
116 // Subsets are not supported. 136 // Subsets are not supported.
117 return kUnimplemented; 137 return kUnimplemented;
118 } 138 }
119 if (info.dimensions() != this->getInfo().dimensions()) { 139 if (info.dimensions() != this->getInfo().dimensions()) {
120 return kInvalidScale; 140 return kInvalidScale;
121 } 141 }
122 ExpandProc proc = NULL; 142
123 switch (info.colorType()) { 143 // Choose the expand routine based on the requested color type
124 case kGray_8_SkColorType: 144 if (!setExpandProc(info.colorType(), ctable, ctableCount)) {
125 proc = expand_bits_to_T<uint8_t, bit_to_grayscale>; 145 return kInvalidConversion;
126 break;
127 case kN32_SkColorType:
128 proc = expand_bits_to_T<SkPMColor, bit_to_pmcolor>;
129 break;
130 case kIndex_8_SkColorType:
131 ctable[0] = BLACK;
132 ctable[1] = WHITE;
133 *ctableCount = 2;
134 proc = expand_bits_to_T<uint8_t, bit_to_bit>;
135 break;
136 case kRGB_565_SkColorType:
137 proc = expand_bits_to_T<uint16_t, bit_to_rgb565>;
138 break;
139 default:
140 return kInvalidConversion;
141 } 146 }
147
emmaleer 2015/07/27 14:41:37 nit: added extra line
msarett 2015/07/27 23:42:30 Acknowledged.
142 SkISize size = info.dimensions(); 148 SkISize size = info.dimensions();
143 uint8_t* dst = static_cast<uint8_t*>(pixels); 149 uint8_t* dst = static_cast<uint8_t*>(pixels);
144 size_t srcRowBytes = SkAlign8(size.width()) >> 3; 150 size_t srcRowBytes = SkAlign8(size.width()) >> 3;
145 SkAutoTMalloc<uint8_t> src(srcRowBytes); 151 SkAutoTMalloc<uint8_t> src(srcRowBytes);
146 for (int y = 0; y < size.height(); ++y) { 152 for (int y = 0; y < size.height(); ++y) {
147 if (this->stream()->read(src.get(), srcRowBytes) != srcRowBytes) { 153 if (this->stream()->read(src.get(), srcRowBytes) != srcRowBytes) {
148 return kIncompleteInput; 154 return kIncompleteInput;
149 } 155 }
150 proc(dst, src.get(), size.width()); 156 fProc(dst, src.get(), size.width());
151 dst += rowBytes; 157 dst += rowBytes;
152 } 158 }
153 return kSuccess; 159 return kSuccess;
154 } 160 }
155 161
156 bool SkWbmpCodec::IsWbmp(SkStream* stream) { 162 bool SkWbmpCodec::IsWbmp(SkStream* stream) {
157 return read_header(stream, NULL); 163 return read_header(stream, NULL);
158 } 164 }
159 165
160 SkCodec* SkWbmpCodec::NewFromStream(SkStream* stream) { 166 SkCodec* SkWbmpCodec::NewFromStream(SkStream* stream) {
161 SkAutoTDelete<SkStream> streamDeleter(stream); 167 SkAutoTDelete<SkStream> streamDeleter(stream);
162 SkISize size; 168 SkISize size;
163 if (!read_header(stream, &size)) { 169 if (!read_header(stream, &size)) {
164 return NULL; 170 return NULL;
165 } 171 }
166 SkImageInfo info = 172 SkImageInfo info =
167 SkImageInfo::Make(size.width(), size.height(), kGray_8_SkColorType, 173 SkImageInfo::Make(size.width(), size.height(), kGray_8_SkColorType,
168 kOpaque_SkAlphaType); 174 kOpaque_SkAlphaType);
169 return SkNEW_ARGS(SkWbmpCodec, (info, streamDeleter.detach())); 175 return SkNEW_ARGS(SkWbmpCodec, (info, streamDeleter.detach()));
170 } 176 }
177
178 class SkWbmpScanlineDecoder : public SkScanlineDecoder {
179 public:
180 SkWbmpScanlineDecoder(const SkImageInfo& dstInfo, SkWbmpCodec* codec)
181 : INHERITED(dstInfo)
182 , fCodec(codec)
183 , fSrcRowBytes(SkAlign8(fCodec->getInfo().width()) >> 3)
scroggo 2015/07/27 14:16:45 Maybe add a static helper function for this, to sh
emmaleer 2015/07/27 14:41:37 Could you add a comment describing why the rowByte
msarett 2015/07/27 23:42:30 Done.
184 , fSrcBuffer(fSrcRowBytes)
185 {}
186
187 SkCodec::Result onGetScanlines(void* dst, int count, size_t dstRowBytes) ove rride {
188 for (int y = 0; y < count; ++y) {
189 if (fCodec->stream()->read(fSrcBuffer.get(), fSrcRowBytes) != fSrcRo wBytes) {
190 return SkCodec::kIncompleteInput;
191 }
192 fCodec->fProc((uint8_t*) dst, fSrcBuffer.get(), dstInfo().width());
scroggo 2015/07/27 14:16:45 The scanline decoder will need to store fProc, but
emmaleer 2015/07/27 14:41:37 Why isn't the Swizzler being used? Does fProc do s
msarett 2015/07/27 23:42:30 fSwizzler is now a field of only the scanline deco
193 dst += dstRowBytes;
194 }
195 return SkCodec::kSuccess;
196 }
197
198 private:
199 SkAutoTDelete<SkWbmpCodec> fCodec;
200 const size_t fSrcRowBytes;
201 SkAutoTMalloc<uint8_t> fSrcBuffer;
202
203 typedef SkScanlineDecoder INHERITED;
204 };
205
206
207 SkScanlineDecoder* SkWbmpCodec::onGetScanlineDecoder(const SkImageInfo& dstInfo,
208 const Options& options, SkPMColor ctable[], int* ctableCount) {
209 if (options.fSubset) {
210 // Subsets are not supported.
211 return NULL;
212 }
213 if (dstInfo.dimensions() != this->getInfo().dimensions()) {
214 return NULL;
215 }
216 // Create a new SkWbmpCodec, to be owned by the scanline decoder.
217 SkStream* stream = this->stream()->duplicate();
218 if (!stream) {
219 return NULL;
220 }
221 SkAutoTDelete<SkWbmpCodec> codec(static_cast<SkWbmpCodec*>(SkWbmpCodec::NewF romStream(stream)));
222 if (!codec) {
223 return NULL;
224 }
225
226 // Choose the expand routine based on the requested color type
227 if (!codec->setExpandProc(dstInfo.colorType(), ctable, ctableCount)) {
228 return NULL;
229 }
230
231 return SkNEW_ARGS(SkWbmpScanlineDecoder, (dstInfo, codec.detach()));
232 }
OLDNEW
« src/codec/SkCodec_wbmp.h ('K') | « src/codec/SkCodec_wbmp.h ('k') | tests/CodexTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698