30 uint16_t bitsPerPixel, uint32_t numColors,
31 uint32_t bytesPerColor, uint32_t
offset,
33 bool isOpaque,
bool inIco)
35 , fColorTable(nullptr)
36 , fNumColors(numColors)
37 , fBytesPerColor(bytesPerColor)
49 void*
dst,
size_t dstRowBytes,
65 int rows = this->decodeRows(
dstInfo,
dst, dstRowBytes, opts);
78 uint32_t colorBytes = 0;
84 const uint32_t numColorsToRead =
85 fNumColors == 0 ? maxColors :
std::min(fNumColors, maxColors);
88 colorBytes = numColorsToRead * fBytesPerColor;
89 std::unique_ptr<uint8_t[]> cBuffer(
new uint8_t[colorBytes]);
90 if (
stream()->
read(cBuffer.get(), colorBytes) != colorBytes) {
108 for (;
i < numColorsToRead;
i++) {
109 uint8_t blue =
get_byte(cBuffer.get(),
i*fBytesPerColor);
110 uint8_t green =
get_byte(cBuffer.get(),
i*fBytesPerColor + 1);
111 uint8_t red =
get_byte(cBuffer.get(),
i*fBytesPerColor + 2);
116 alpha =
get_byte(cBuffer.get(),
i*fBytesPerColor + 3);
118 colorTable[
i] = packARGB(alpha, red, green, blue);
124 for (;
i < maxColors;
i++) {
140 if(fOffset < colorBytes) {
146 SkCodecPrintf(
"Error: pixel data offset less than color table size.\n");
151 if (
stream()->
skip(fOffset - colorBytes) != fOffset - colorBytes) {
172 info.alpha(), this->bitsPerPixel());
183void SkBmpStandardCodec::initializeSwizzler(
const SkImageInfo& dstInfo,
const Options& opts) {
203 fSwizzler =
SkSwizzler::Make(encodedInfo, colorPtr, swizzlerInfo, swizzlerOptions);
228int SkBmpStandardCodec::decodeRows(
const SkImageInfo& dstInfo,
void*
dst,
size_t dstRowBytes,
229 const Options& opts) {
242 void* dstRow = SkTAddOffset<void>(
dst, row * dstRowBytes);
249 fSwizzler->swizzle(dstRow, this->
srcBuffer());
253 if (fInIco && fIsOpaque) {
255 if (startScanline < 0) {
258 decodeIcoMask(this->
stream(), dstInfo,
dst, dstRowBytes);
278 const size_t bytesToSkip = remainingScanlines * this->
srcRowBytes() +
279 startScanline * fAndMaskRowBytes;
280 const size_t subStreamStartPosition = currPosition + bytesToSkip;
281 if (subStreamStartPosition >=
length) {
289 const void* subStreamMemoryBase = SkTAddOffset<const void>(memoryBase,
290 subStreamStartPosition);
291 const size_t subStreamLength =
length - subStreamStartPosition;
293 SkMemoryStream subStream(subStreamMemoryBase, subStreamLength,
false);
297 decodeIcoMask(&subStream,
dstInfo,
dst, dstRowBytes);
304 void*
dst,
size_t dstRowBytes) {
314 const int sampleX = fSwizzler->sampleX();
322 if (
stream->
read(this->srcBuffer(), fAndMaskRowBytes) != fAndMaskRowBytes) {
323 SkCodecPrintf(
"Warning: incomplete AND mask for bmp-in-ico.\n");
327 auto applyMask = [
dstInfo](
void* dstRow,
int x, uint64_t bit) {
329 uint64_t* dst64 = (uint64_t*) dstRow;
332 uint32_t* dst32 = (uint32_t*) dstRow;
339 void* dstRow = SkTAddOffset<SkPMColor>(dstPtr, row * dstRowBytes);
341 int srcX = srcStartX;
342 for (
int dstX = 0; dstX < sampledWidth; dstX++) {
346 uint32_t shift = 7 - modulus;
347 uint64_t alphaBit = (this->
srcBuffer()[quotient] >> shift) & 0x1;
348 applyMask(dstRow, dstX, alphaBit);
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
static constexpr T SkAlign4(T x)
@ kPremul_SkAlphaType
pixel components are premultiplied by alpha
static SkEncodedInfo make_info(SkEncodedInfo::Color color, SkEncodedInfo::Alpha alpha, int bitsPerPixel)
static uint8_t get_byte(const uint8_t *buffer, uint32_t i)
uint32_t(* PackColorProc)(U8CPU a, U8CPU r, U8CPU g, U8CPU b)
static PackColorProc choose_pack_color_proc(bool isPremul, SkColorType colorType)
static size_t compute_row_bytes(int width, uint32_t bitsPerPixel)
static const SkPMColor * get_color_ptr(SkColorPalette *colorTable)
static int get_scaled_dimension(int srcDimension, int sampleSize)
#define SkCodecPrintf(...)
static int get_start_coord(int sampleFactor)
static SkPMColor SkPackARGB32NoCheck(U8CPU a, U8CPU r, U8CPU g, U8CPU b)
@ kBGRA_8888_SkColorType
pixel with 8 bits for blue, green, red, alpha; in 32-bit word
@ kRGBA_F16_SkColorType
pixel with half floats for red, green, blue, alpha;
@ kRGBA_8888_SkColorType
pixel with 8 bits for red, green, blue, alpha; in 32-bit word
static bool read(SkStream *stream, void *buffer, size_t amount)
static bool skip(SkStream *stream, size_t amount)
void SkTDivMod(In numer, In denom, Out *div, Out *mod)
void resetXformBuffer(int count)
int32_t getDstRow(int32_t y, int32_t height) const
SkCodec::Result prepareToDecode(const SkImageInfo &dstInfo, const SkCodec::Options &options)
size_t srcRowBytes() const
uint32_t * xformBuffer() const
static constexpr SkColorType kXformSrcColorType
uint16_t bitsPerPixel() const
SkBmpStandardCodec(SkEncodedInfo &&info, std::unique_ptr< SkStream > stream, uint16_t bitsPerPixel, uint32_t numColors, uint32_t bytesPerColor, uint32_t offset, SkCodec::SkScanlineOrder rowOrder, bool isOpaque, bool inIco)
SkCodec::Result onPrepareToDecode(const SkImageInfo &dstInfo, const SkCodec::Options &options) override
Result onGetPixels(const SkImageInfo &dstInfo, void *dst, size_t dstRowBytes, const Options &, int *) override
SkISize dimensions() const
const SkImageInfo & dstInfo() const
bool xformOnDecode() const
void applyColorXform(void *dst, const void *src, int count) const
const SkEncodedInfo & getEncodedInfo() const
const Options & options() const
virtual size_t getPosition() const
virtual size_t getLength() const
virtual const void * getMemoryBase()
virtual size_t read(void *buffer, size_t size)=0
static std::unique_ptr< SkSwizzler > Make(const SkEncodedInfo &encodedInfo, const SkPMColor *ctable, const SkImageInfo &dstInfo, const SkCodec::Options &, const SkIRect *frame=nullptr)
void reset(T *ptr=nullptr)
static float min(float r, float g, float b)
ZeroInitialized fZeroInitialized
static SkEncodedInfo Make(int width, int height, Color color, Alpha alpha, int bitsPerComponent)
constexpr int32_t height() const
SkImageInfo makeAlphaType(SkAlphaType newAlphaType) const
SkISize dimensions() const
SkAlphaType alphaType() const
SkColorType colorType() const
SkImageInfo makeColorType(SkColorType newColorType) const