| OLD | NEW |
| 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, | 20 SkCodec::SkScanlineOrder rowOrder, |
| 21 bool isOpaque, bool inIco) | 21 bool isOpaque, bool inIco) |
| 22 : INHERITED(info, stream, bitsPerPixel, rowOrder) | 22 : INHERITED(info, stream, bitsPerPixel, rowOrder) |
| 23 , fColorTable(nullptr) | 23 , fColorTable(nullptr) |
| 24 , fNumColors(numColors) | 24 , fNumColors(numColors) |
| 25 , fBytesPerColor(bytesPerColor) | 25 , fBytesPerColor(bytesPerColor) |
| 26 , fOffset(offset) | 26 , fOffset(offset) |
| 27 , fSwizzler(nullptr) | 27 , fSwizzler(nullptr) |
| 28 , fSrcRowBytes(SkAlign4(compute_row_bytes(this->getInfo().width(), this->bit
sPerPixel()))) | 28 , fSrcBuffer(new uint8_t [this->srcRowBytes()]) |
| 29 , fSrcBuffer(new uint8_t [fSrcRowBytes]) | |
| 30 , fIsOpaque(isOpaque) | 29 , fIsOpaque(isOpaque) |
| 31 , fInIco(inIco) | 30 , fInIco(inIco) |
| 32 , fAndMaskRowBytes(fInIco ? SkAlign4(compute_row_bytes(this->getInfo().width
(), 1)) : 0) | 31 , fAndMaskRowBytes(fInIco ? SkAlign4(compute_row_bytes(this->getInfo().width
(), 1)) : 0) |
| 33 {} | 32 {} |
| 34 | 33 |
| 35 /* | 34 /* |
| 36 * Initiates the bitmap decode | 35 * Initiates the bitmap decode |
| 37 */ | 36 */ |
| 38 SkCodec::Result SkBmpStandardCodec::onGetPixels(const SkImageInfo& dstInfo, | 37 SkCodec::Result SkBmpStandardCodec::onGetPixels(const SkImageInfo& dstInfo, |
| 39 void* dst, size_t dstRowBytes, | 38 void* dst, size_t dstRowBytes, |
| (...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 218 | 217 |
| 219 /* | 218 /* |
| 220 * Performs the bitmap decoding for standard input format | 219 * Performs the bitmap decoding for standard input format |
| 221 */ | 220 */ |
| 222 int SkBmpStandardCodec::decodeRows(const SkImageInfo& dstInfo, void* dst, size_t
dstRowBytes, | 221 int SkBmpStandardCodec::decodeRows(const SkImageInfo& dstInfo, void* dst, size_t
dstRowBytes, |
| 223 const Options& opts) { | 222 const Options& opts) { |
| 224 // Iterate over rows of the image | 223 // Iterate over rows of the image |
| 225 const int height = dstInfo.height(); | 224 const int height = dstInfo.height(); |
| 226 for (int y = 0; y < height; y++) { | 225 for (int y = 0; y < height; y++) { |
| 227 // Read a row of the input | 226 // Read a row of the input |
| 228 if (this->stream()->read(fSrcBuffer.get(), fSrcRowBytes) != fSrcRowBytes
) { | 227 if (this->stream()->read(fSrcBuffer.get(), this->srcRowBytes()) != this-
>srcRowBytes()) { |
| 229 SkCodecPrintf("Warning: incomplete input stream.\n"); | 228 SkCodecPrintf("Warning: incomplete input stream.\n"); |
| 230 return y; | 229 return y; |
| 231 } | 230 } |
| 232 | 231 |
| 233 // Decode the row in destination format | 232 // Decode the row in destination format |
| 234 uint32_t row = this->getDstRow(y, dstInfo.height()); | 233 uint32_t row = this->getDstRow(y, dstInfo.height()); |
| 235 | 234 |
| 236 void* dstRow = SkTAddOffset<void>(dst, row * dstRowBytes); | 235 void* dstRow = SkTAddOffset<void>(dst, row * dstRowBytes); |
| 237 fSwizzler->swizzle(dstRow, fSrcBuffer.get()); | 236 fSwizzler->swizzle(dstRow, fSrcBuffer.get()); |
| 238 } | 237 } |
| (...skipping 16 matching lines...) Expand all Loading... |
| 255 const void* memoryBase = this->stream()->getMemoryBase(); | 254 const void* memoryBase = this->stream()->getMemoryBase(); |
| 256 SkASSERT(nullptr != memoryBase); | 255 SkASSERT(nullptr != memoryBase); |
| 257 SkASSERT(this->stream()->hasLength()); | 256 SkASSERT(this->stream()->hasLength()); |
| 258 SkASSERT(this->stream()->hasPosition()); | 257 SkASSERT(this->stream()->hasPosition()); |
| 259 | 258 |
| 260 const size_t length = this->stream()->getLength(); | 259 const size_t length = this->stream()->getLength(); |
| 261 const size_t currPosition = this->stream()->getPosition(); | 260 const size_t currPosition = this->stream()->getPosition(); |
| 262 | 261 |
| 263 // Calculate how many bytes we must skip to reach the AND mask. | 262 // Calculate how many bytes we must skip to reach the AND mask. |
| 264 const int remainingScanlines = this->getInfo().height() - startScanline
- height; | 263 const int remainingScanlines = this->getInfo().height() - startScanline
- height; |
| 265 const size_t bytesToSkip = remainingScanlines * fSrcRowBytes + | 264 const size_t bytesToSkip = remainingScanlines * this->srcRowBytes() + |
| 266 startScanline * fAndMaskRowBytes; | 265 startScanline * fAndMaskRowBytes; |
| 267 const size_t subStreamStartPosition = currPosition + bytesToSkip; | 266 const size_t subStreamStartPosition = currPosition + bytesToSkip; |
| 268 if (subStreamStartPosition >= length) { | 267 if (subStreamStartPosition >= length) { |
| 269 // FIXME: How can we indicate that this decode was actually incomple
te? | 268 // FIXME: How can we indicate that this decode was actually incomple
te? |
| 270 return height; | 269 return height; |
| 271 } | 270 } |
| 272 | 271 |
| 273 // Create a subStream to pass to decodeIcoMask(). It is useful to encap
sulate | 272 // Create a subStream to pass to decodeIcoMask(). It is useful to encap
sulate |
| 274 // the memory base into a stream in order to safely handle incomplete im
ages | 273 // the memory base into a stream in order to safely handle incomplete im
ages |
| 275 // without reading out of bounds memory. | 274 // without reading out of bounds memory. |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 328 } | 327 } |
| 329 } | 328 } |
| 330 | 329 |
| 331 uint32_t SkBmpStandardCodec::onGetFillValue(SkColorType colorType) const { | 330 uint32_t SkBmpStandardCodec::onGetFillValue(SkColorType colorType) const { |
| 332 const SkPMColor* colorPtr = get_color_ptr(fColorTable.get()); | 331 const SkPMColor* colorPtr = get_color_ptr(fColorTable.get()); |
| 333 if (colorPtr) { | 332 if (colorPtr) { |
| 334 return get_color_table_fill_value(colorType, colorPtr, 0); | 333 return get_color_table_fill_value(colorType, colorPtr, 0); |
| 335 } | 334 } |
| 336 return INHERITED::onGetFillValue(colorType); | 335 return INHERITED::onGetFillValue(colorType); |
| 337 } | 336 } |
| OLD | NEW |