34 std::unique_ptr<SkStream> stream,
35 uint16_t bitsPerPixel, uint32_t numColors,
36 uint32_t bytesPerColor, uint32_t
offset,
39 , fColorTable(nullptr)
40 , fNumColors(numColors)
41 , fBytesPerColor(bytesPerColor)
52 void* dst,
size_t dstRowBytes,
66 int rows = this->
decodeRows(dstInfo, dst, dstRowBytes, opts);
81 bool SkBmpRLECodec::createColorTable(
SkColorType dstColorType) {
83 uint32_t colorBytes = 0;
89 const uint32_t numColorsToRead =
90 fNumColors == 0 ? maxColors : std::min(fNumColors, maxColors);
93 colorBytes = numColorsToRead * fBytesPerColor;
94 std::unique_ptr<uint8_t[]> cBuffer(
new uint8_t[colorBytes]);
95 if (
stream()->
read(cBuffer.get(), colorBytes) != colorBytes) {
103 for (; i < numColorsToRead; i++) {
104 uint8_t blue =
get_byte(cBuffer.get(), i*fBytesPerColor);
105 uint8_t green =
get_byte(cBuffer.get(), i*fBytesPerColor + 1);
106 uint8_t red =
get_byte(cBuffer.get(), i*fBytesPerColor + 2);
107 colorTable[i] = packARGB(0xFF, red, green, blue);
113 for (; i < maxColors; i++) {
122 if(fOffset < colorBytes) {
128 SkCodecPrintf(
"Error: pixel data offset less than color table size.\n");
133 if (
stream()->
skip(fOffset - colorBytes) != fOffset - colorBytes) {
142bool SkBmpRLECodec::initializeStreamBuffer() {
143 fBytesBuffered = this->
stream()->
read(fStreamBuffer, kBufferSize);
144 if (fBytesBuffered == 0) {
156size_t SkBmpRLECodec::checkForMoreData() {
157 const size_t remainingBytes = fBytesBuffered - fCurrRLEByte;
158 uint8_t*
buffer = fStreamBuffer;
164 memmove(
buffer, SkTAddOffset<uint8_t>(
buffer, fCurrRLEByte), remainingBytes);
172 size_t additionalBytes = this->
stream()->
read(buffer, fCurrRLEByte);
177 fBytesBuffered = remainingBytes + additionalBytes;
178 return fBytesBuffered;
184void SkBmpRLECodec::setPixel(
void* dst,
size_t dstRowBytes,
196 SkPMColor* dstRow = SkTAddOffset<SkPMColor>(dst, row * (
int) dstRowBytes);
197 dstRow[dstX] = fColorTable->operator[](index);
201 uint16_t* dstRow = SkTAddOffset<uint16_t>(dst, row * (
int) dstRowBytes);
217void SkBmpRLECodec::setRGBPixel(
void* dst,
size_t dstRowBytes,
219 uint32_t
y, uint8_t red, uint8_t green,
229 SkPMColor* dstRow = SkTAddOffset<SkPMColor>(dst, row * (
int) dstRowBytes);
234 SkPMColor* dstRow = SkTAddOffset<SkPMColor>(dst, row * (
int) dstRowBytes);
239 uint16_t* dstRow = SkTAddOffset<uint16_t>(dst, row * (
int) dstRowBytes);
274 if (!this->createColorTable(colorTableColorType)) {
280 if (!this->initializeStreamBuffer()) {
307 if (
height > fLinesToSkip) {
310 dst = SkTAddOffset<void>(dst, fLinesToSkip * dstRowBytes);
320 void* decodeDst = dst;
321 size_t decodeRowBytes = dstRowBytes;
336 int decodedHeight = this->decodeRLE(decodeInfo, decodeDst, decodeRowBytes);
338 for (
int y = 0;
y < decodedHeight;
y++) {
340 decodeDst = SkTAddOffset<void>(decodeDst, decodeRowBytes);
341 dst = SkTAddOffset<void>(dst, dstRowBytes);
345 return decodedHeight;
348int SkBmpRLECodec::decodeRLE(
const SkImageInfo& dstInfo,
void* dst,
size_t dstRowBytes) {
356 constexpr uint8_t RLE_ESCAPE = 0;
357 constexpr uint8_t RLE_EOL = 0;
358 constexpr uint8_t RLE_EOF = 1;
359 constexpr uint8_t RLE_DELTA = 2;
376 if ((
int) fBytesBuffered - fCurrRLEByte < 2) {
377 if (this->checkForMoreData() < 2) {
386 const uint8_t
flag = fStreamBuffer[fCurrRLEByte++];
387 const uint8_t task = fStreamBuffer[fCurrRLEByte++];
390 if (RLE_ESCAPE ==
flag) {
400 if ((
int) fBytesBuffered - fCurrRLEByte < 2) {
401 if (this->checkForMoreData() < 2) {
406 const uint8_t
dx = fStreamBuffer[fCurrRLEByte++];
407 const uint8_t dy = fStreamBuffer[fCurrRLEByte++];
424 uint8_t numPixels = task;
427 if (x + numPixels >
width) {
438 static_assert(255 * 3 + 1 < kBufferSize,
439 "kBufferSize needs to be larger!");
440 const size_t alignedRowBytes =
SkAlign2(rowBytes);
441 if ((
int) fBytesBuffered - fCurrRLEByte < alignedRowBytes) {
442 SkASSERT(alignedRowBytes < kBufferSize);
443 if (this->checkForMoreData() < alignedRowBytes) {
448 while ((numPixels > 0) && (
x <
width)) {
451 SkASSERT(fCurrRLEByte < fBytesBuffered);
452 uint8_t val = fStreamBuffer[fCurrRLEByte++];
453 setPixel(dst, dstRowBytes,
dstInfo,
x++,
456 if (numPixels != 0) {
457 setPixel(dst, dstRowBytes,
dstInfo,
464 SkASSERT(fCurrRLEByte < fBytesBuffered);
465 setPixel(dst, dstRowBytes,
dstInfo,
x++,
466 y, fStreamBuffer[fCurrRLEByte++]);
470 SkASSERT(fCurrRLEByte + 2 < fBytesBuffered);
471 uint8_t blue = fStreamBuffer[fCurrRLEByte++];
472 uint8_t green = fStreamBuffer[fCurrRLEByte++];
473 uint8_t red = fStreamBuffer[fCurrRLEByte++];
474 setRGBPixel(dst, dstRowBytes,
dstInfo,
475 x++,
y, red, green, blue);
494 const uint8_t numPixels =
flag;
495 const int endX = std::min<int>(
x + numPixels,
width);
501 if ((
int) fBytesBuffered - fCurrRLEByte < 2) {
502 if (this->checkForMoreData() < 2) {
509 uint8_t green = fStreamBuffer[fCurrRLEByte++];
510 uint8_t red = fStreamBuffer[fCurrRLEByte++];
512 setRGBPixel(dst, dstRowBytes,
dstInfo,
x++,
y, red, green, blue);
520 uint8_t indices[2] = { task, task };
527 for (
int which = 0;
x < endX;
x++) {
528 setPixel(dst, dstRowBytes,
dstInfo,
x,
y, indices[which]);
567 if (!fSampler && createIfNecessary) {
568 fSampler = std::make_unique<SkBmpRLESampler>(
this);
571 return fSampler.get();
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
static constexpr bool SkIsAlign2(T x)
static constexpr T SkAlign2(T x)
static bool is_coord_necessary(int srcCoord, int sampleFactor, int scaledDim)
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 int get_dst_coord(int srcCoord, int sampleFactor)
static int get_scaled_dimension(int srcDimension, int sampleSize)
#define SkCodecPrintf(...)
static uint32_t SkPackARGB_as_RGBA(U8CPU a, U8CPU r, U8CPU g, U8CPU b)
static U16CPU SkPack888ToRGB16(U8CPU r, U8CPU g, U8CPU b)
static U16CPU SkPixel32ToPixel16(SkPMColor c)
static uint32_t SkPackARGB_as_BGRA(U8CPU a, U8CPU r, U8CPU g, U8CPU b)
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;
@ kRGB_565_SkColorType
pixel with 5 bits red, 6 bits green, 5 bits blue, in 16-bit word
@ 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)
static void sk_bzero(void *buffer, size_t size)
void resetXformBuffer(int count)
int32_t getDstRow(int32_t y, int32_t height) const
SkCodec::Result prepareToDecode(const SkImageInfo &dstInfo, const SkCodec::Options &options)
uint32_t * xformBuffer() const
static constexpr SkColorType kXformSrcColorType
uint16_t bitsPerPixel() const
Result onGetPixels(const SkImageInfo &dstInfo, void *dst, size_t dstRowBytes, const Options &, int *) override
SkCodec::Result onPrepareToDecode(const SkImageInfo &dstInfo, const SkCodec::Options &options) override
SkSampler * getSampler(bool createIfNecessary) override
bool skipRows(int count) override
SkBmpRLECodec(SkEncodedInfo &&info, std::unique_ptr< SkStream >, uint16_t bitsPerPixel, uint32_t numColors, uint32_t bytesPerColor, uint32_t offset, SkCodec::SkScanlineOrder rowOrder)
int decodeRows(const SkImageInfo &dstInfo, void *dst, size_t dstRowBytes, const Options &opts) override
SkBmpRLESampler(SkBmpRLECodec *codec)
int onSetSampleX(int sampleX) override
int fillWidth() const override
SkISize dimensions() const
const SkImageInfo & dstInfo() const
void applyColorXform(void *dst, const void *src, int count) const
const Options & options() const
static void Fill(const SkImageInfo &info, void *dst, size_t rowBytes, SkCodec::ZeroInitialized zeroInit)
virtual size_t read(void *buffer, size_t size)=0
void reset(T *ptr=nullptr)
FlutterSemanticsFlag flag
static const uint8_t buffer[]
skia_private::AutoTArray< sk_sp< SkImageFilter > > filters TypedMatrix matrix TypedMatrix matrix SkScalar dx
ZeroInitialized fZeroInitialized
constexpr int32_t width() const
SkImageInfo makeWH(int newWidth, int newHeight) const
static SkImageInfo Make(int width, int height, SkColorType ct, SkAlphaType at)
SkColorType colorType() const
SkImageInfo makeColorType(SkColorType newColorType) const