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

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

Issue 1498903004: Revert of Make SkAndroidCodec support ico (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 5 years 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
« no previous file with comments | « src/codec/SkBmpStandardCodec.h ('k') | src/codec/SkCodec_libico.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 "SkBmpStandardCodec.h" 8 #include "SkBmpStandardCodec.h"
9 #include "SkCodecPriv.h" 9 #include "SkCodecPriv.h"
10 #include "SkColorPriv.h" 10 #include "SkColorPriv.h"
11 #include "SkStream.h" 11 #include "SkStream.h"
12 12
13 /* 13 /*
14 * Creates an instance of the decoder 14 * Creates an instance of the decoder
15 * Called only by NewFromStream 15 * Called only by NewFromStream
16 */ 16 */
17 SkBmpStandardCodec::SkBmpStandardCodec(const SkImageInfo& info, SkStream* stream , 17 SkBmpStandardCodec::SkBmpStandardCodec(const SkImageInfo& info, SkStream* stream ,
18 uint16_t bitsPerPixel, uint32_t numColors , 18 uint16_t bitsPerPixel, uint32_t numColors ,
19 uint32_t bytesPerColor, uint32_t offset, 19 uint32_t bytesPerColor, uint32_t offset,
20 SkCodec::SkScanlineOrder rowOrder, bool i nIco) 20 SkCodec::SkScanlineOrder rowOrder, bool i nIco)
21 : INHERITED(info, stream, bitsPerPixel, rowOrder) 21 : INHERITED(info, stream, bitsPerPixel, rowOrder)
22 , fColorTable(nullptr) 22 , fColorTable(nullptr)
23 , fNumColors(this->computeNumColors(numColors)) 23 , fNumColors(this->computeNumColors(numColors))
24 , fBytesPerColor(bytesPerColor) 24 , fBytesPerColor(bytesPerColor)
25 , fOffset(offset) 25 , fOffset(offset)
26 , fSwizzler(nullptr) 26 , fSwizzler(nullptr)
27 , fSrcRowBytes(SkAlign4(compute_row_bytes(this->getInfo().width(), this->bit sPerPixel()))) 27 , fSrcRowBytes(SkAlign4(compute_row_bytes(this->getInfo().width(), this->bit sPerPixel())))
28 , fSrcBuffer(new uint8_t [fSrcRowBytes]) 28 , fSrcBuffer(new uint8_t [fSrcRowBytes])
29 , fInIco(inIco) 29 , fInIco(inIco)
30 , fAndMaskRowBytes(fInIco ? SkAlign4(compute_row_bytes(this->getInfo().width (), 1)) : 0)
31 {} 30 {}
32 31
33 /* 32 /*
34 * Initiates the bitmap decode 33 * Initiates the bitmap decode
35 */ 34 */
36 SkCodec::Result SkBmpStandardCodec::onGetPixels(const SkImageInfo& dstInfo, 35 SkCodec::Result SkBmpStandardCodec::onGetPixels(const SkImageInfo& dstInfo,
37 void* dst, size_t dstRowBytes, 36 void* dst, size_t dstRowBytes,
38 const Options& opts, 37 const Options& opts,
39 SkPMColor* inputColorPtr, 38 SkPMColor* inputColorPtr,
40 int* inputColorCount, 39 int* inputColorCount,
(...skipping 13 matching lines...) Expand all
54 53
55 Result result = this->prepareToDecode(dstInfo, opts, inputColorPtr, inputCol orCount); 54 Result result = this->prepareToDecode(dstInfo, opts, inputColorPtr, inputCol orCount);
56 if (kSuccess != result) { 55 if (kSuccess != result) {
57 return result; 56 return result;
58 } 57 }
59 int rows = this->decodeRows(dstInfo, dst, dstRowBytes, opts); 58 int rows = this->decodeRows(dstInfo, dst, dstRowBytes, opts);
60 if (rows != dstInfo.height()) { 59 if (rows != dstInfo.height()) {
61 *rowsDecoded = rows; 60 *rowsDecoded = rows;
62 return kIncompleteInput; 61 return kIncompleteInput;
63 } 62 }
63 if (fInIco) {
64 return this->decodeIcoMask(dstInfo, dst, dstRowBytes);
65 }
64 return kSuccess; 66 return kSuccess;
65 } 67 }
66 68
67 /* 69 /*
68 * Process the color table for the bmp input 70 * Process the color table for the bmp input
69 */ 71 */
70 bool SkBmpStandardCodec::createColorTable(SkAlphaType alphaType, int* numColors ) { 72 bool SkBmpStandardCodec::createColorTable(SkAlphaType alphaType, int* numColors ) {
71 // Allocate memory for color table 73 // Allocate memory for color table
72 uint32_t colorBytes = 0; 74 uint32_t colorBytes = 0;
73 SkPMColor colorTable[256]; 75 SkPMColor colorTable[256];
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
218 if (!this->initializeSwizzler(dstInfo, options)) { 220 if (!this->initializeSwizzler(dstInfo, options)) {
219 SkCodecPrintf("Error: cannot initialize swizzler.\n"); 221 SkCodecPrintf("Error: cannot initialize swizzler.\n");
220 return SkCodec::kInvalidConversion; 222 return SkCodec::kInvalidConversion;
221 } 223 }
222 return SkCodec::kSuccess; 224 return SkCodec::kSuccess;
223 } 225 }
224 226
225 /* 227 /*
226 * Performs the bitmap decoding for standard input format 228 * Performs the bitmap decoding for standard input format
227 */ 229 */
228 int SkBmpStandardCodec::decodeRows(const SkImageInfo& dstInfo, void* dst, size_t dstRowBytes, 230 int SkBmpStandardCodec::decodeRows(const SkImageInfo& dstInfo,
229 const Options& opts) { 231 void* dst, size_t dstRowBytes,
232 const Options& opts) {
230 // Iterate over rows of the image 233 // Iterate over rows of the image
231 const int height = dstInfo.height(); 234 const int height = dstInfo.height();
232 for (int y = 0; y < height; y++) { 235 for (int y = 0; y < height; y++) {
233 // Read a row of the input 236 // Read a row of the input
234 if (this->stream()->read(fSrcBuffer.get(), fSrcRowBytes) != fSrcRowBytes ) { 237 if (this->stream()->read(fSrcBuffer.get(), fSrcRowBytes) != fSrcRowBytes ) {
235 SkCodecPrintf("Warning: incomplete input stream.\n"); 238 SkCodecPrintf("Warning: incomplete input stream.\n");
236 return y; 239 return y;
237 } 240 }
238 241
239 // Decode the row in destination format 242 // Decode the row in destination format
240 uint32_t row = this->getDstRow(y, dstInfo.height()); 243 uint32_t row = this->getDstRow(y, dstInfo.height());
241 244
242 void* dstRow = SkTAddOffset<void>(dst, row * dstRowBytes); 245 void* dstRow = SkTAddOffset<void>(dst, row * dstRowBytes);
243 fSwizzler->swizzle(dstRow, fSrcBuffer.get()); 246 fSwizzler->swizzle(dstRow, fSrcBuffer.get());
244 } 247 }
245 248
246 if (fInIco) { 249 // Finished decoding the entire image
247 const int startScanline = this->currScanline();
248 if (startScanline < 0) {
249 // We are not performing a scanline decode.
250 // Just decode the entire ICO mask and return.
251 decodeIcoMask(this->stream(), dstInfo, dst, dstRowBytes);
252 return height;
253 }
254
255 // In order to perform a scanline ICO decode, we must be able
256 // to skip ahead in the stream in order to apply the AND mask
257 // to the requested scanlines.
258 // We will do this by taking advantage of the fact that
259 // SkIcoCodec always uses a SkMemoryStream as its underlying
260 // representation of the stream.
261 const void* memoryBase = this->stream()->getMemoryBase();
262 SkASSERT(nullptr != memoryBase);
263 SkASSERT(this->stream()->hasLength());
264 SkASSERT(this->stream()->hasPosition());
265
266 const size_t length = this->stream()->getLength();
267 const size_t currPosition = this->stream()->getPosition();
268
269 // Calculate how many bytes we must skip to reach the AND mask.
270 const int remainingScanlines = this->getInfo().height() - startScanline - height;
271 const size_t bytesToSkip = remainingScanlines * fSrcRowBytes +
272 startScanline * fAndMaskRowBytes;
273 const size_t subStreamStartPosition = currPosition + bytesToSkip;
274 if (subStreamStartPosition >= length) {
275 // FIXME: How can we indicate that this decode was actually incomple te?
276 return height;
277 }
278
279 // Create a subStream to pass to decodeIcoMask(). It is useful to encap sulate
280 // the memory base into a stream in order to safely handle incomplete im ages
281 // without reading out of bounds memory.
282 const void* subStreamMemoryBase = SkTAddOffset<const void>(memoryBase,
283 subStreamStartPosition);
284 const size_t subStreamLength = length - subStreamStartPosition;
285 // This call does not transfer ownership of the subStreamMemoryBase.
286 SkMemoryStream subStream(subStreamMemoryBase, subStreamLength, false);
287
288 // FIXME: If decodeIcoMask does not succeed, is there a way that we can
289 // indicate the decode was incomplete?
290 decodeIcoMask(&subStream, dstInfo, dst, dstRowBytes);
291 }
292
293 return height; 250 return height;
294 } 251 }
295 252
296 void SkBmpStandardCodec::decodeIcoMask(SkStream* stream, const SkImageInfo& dstI nfo, 253 // TODO (msarett): This function will need to be modified in order to perform ro w by row decodes
254 // when the Ico scanline decoder is implemented.
255 SkCodec::Result SkBmpStandardCodec::decodeIcoMask(const SkImageInfo& dstInfo,
297 void* dst, size_t dstRowBytes) { 256 void* dst, size_t dstRowBytes) {
298 // BMP in ICO have transparency, so this cannot be 565, and this mask 257 // BMP in ICO have transparency, so this cannot be 565, and this mask
299 // prevents us from using kIndex8. The below code depends on the output 258 // prevents us from using kIndex8. The below code depends on the output
300 // being an SkPMColor. 259 // being an SkPMColor.
301 SkASSERT(dstInfo.colorType() == kN32_SkColorType); 260 SkASSERT(dstInfo.colorType() == kN32_SkColorType);
302 261
303 // If we are sampling, make sure that we only mask the sampled pixels. 262 // The AND mask is always 1 bit per pixel
304 // We do not need to worry about sampling in the y-dimension because that 263 const int width = this->getInfo().width();
305 // should be handled by SkSampledCodec. 264 const size_t rowBytes = SkAlign4(compute_row_bytes(width, 1));
306 int sampleX = fSwizzler->sampleX();
307 int startX = get_start_coord(sampleX);
308 265
309 SkPMColor* dstPtr = (SkPMColor*) dst; 266 SkPMColor* dstPtr = (SkPMColor*) dst;
310 for (int y = 0; y < dstInfo.height(); y++) { 267 for (int y = 0; y < dstInfo.height(); y++) {
311 // The srcBuffer will at least be large enough 268 // The srcBuffer will at least be large enough
312 if (stream->read(fSrcBuffer.get(), fAndMaskRowBytes) != fAndMaskRowBytes ) { 269 if (stream()->read(fSrcBuffer.get(), rowBytes) != rowBytes) {
313 SkCodecPrintf("Warning: incomplete AND mask for bmp-in-ico.\n"); 270 SkCodecPrintf("Warning: incomplete AND mask for bmp-in-ico.\n");
314 return; 271 return kIncompleteInput;
315 } 272 }
316 273
317 int row = this->getDstRow(y, dstInfo.height()); 274 int row = this->getDstRow(y, dstInfo.height());
318 275
319 SkPMColor* dstRow = 276 SkPMColor* dstRow =
320 SkTAddOffset<SkPMColor>(dstPtr, row * dstRowBytes); 277 SkTAddOffset<SkPMColor>(dstPtr, row * dstRowBytes);
321 278
322 for (int x = startX; x < this->getInfo().width(); x += sampleX) { 279 for (int x = 0; x < width; x++) {
323 int quotient; 280 int quotient;
324 int modulus; 281 int modulus;
325 SkTDivMod(x, 8, &quotient, &modulus); 282 SkTDivMod(x, 8, &quotient, &modulus);
326 uint32_t shift = 7 - modulus; 283 uint32_t shift = 7 - modulus;
327 uint32_t alphaBit = (fSrcBuffer.get()[quotient] >> shift) & 0x1; 284 uint32_t alphaBit =
328 dstRow[get_dst_coord(x, sampleX)] &= alphaBit - 1; 285 (fSrcBuffer.get()[quotient] >> shift) & 0x1;
286 dstRow[x] &= alphaBit - 1;
329 } 287 }
330 } 288 }
289 return kSuccess;
331 } 290 }
332 291
333 uint32_t SkBmpStandardCodec::onGetFillValue(SkColorType colorType, SkAlphaType a lphaType) const { 292 uint32_t SkBmpStandardCodec::onGetFillValue(SkColorType colorType, SkAlphaType a lphaType) const {
334 const SkPMColor* colorPtr = get_color_ptr(fColorTable.get()); 293 const SkPMColor* colorPtr = get_color_ptr(fColorTable.get());
335 if (colorPtr) { 294 if (colorPtr) {
336 return get_color_table_fill_value(colorType, colorPtr, 0); 295 return get_color_table_fill_value(colorType, colorPtr, 0);
337 } 296 }
338 return INHERITED::onGetFillValue(colorType, alphaType); 297 return INHERITED::onGetFillValue(colorType, alphaType);
339 } 298 }
OLDNEW
« no previous file with comments | « src/codec/SkBmpStandardCodec.h ('k') | src/codec/SkCodec_libico.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698