summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/fxcodec/bmp/cfx_bmpdecompressor.cpp291
-rw-r--r--core/fxcodec/bmp/cfx_bmpdecompressor.h9
-rw-r--r--core/fxcrt/cfx_memorystream.cpp8
-rw-r--r--core/fxcrt/cfx_memorystream.h3
4 files changed, 162 insertions, 149 deletions
diff --git a/core/fxcodec/bmp/cfx_bmpdecompressor.cpp b/core/fxcodec/bmp/cfx_bmpdecompressor.cpp
index 191df8e29a..56f11fd4cb 100644
--- a/core/fxcodec/bmp/cfx_bmpdecompressor.cpp
+++ b/core/fxcodec/bmp/cfx_bmpdecompressor.cpp
@@ -29,7 +29,6 @@ uint8_t HalfRoundUp(uint8_t value) {
CFX_BmpDecompressor::CFX_BmpDecompressor()
: context_ptr_(nullptr),
- next_in_(nullptr),
header_offset_(0),
width_(0),
height_(0),
@@ -52,8 +51,6 @@ CFX_BmpDecompressor::CFX_BmpDecompressor()
mask_red_(0),
mask_green_(0),
mask_blue_(0),
- avail_in_(0),
- skip_size_(0),
decode_status_(BMP_D_STATUS_HEADER) {}
CFX_BmpDecompressor::~CFX_BmpDecompressor() {}
@@ -74,30 +71,31 @@ bool CFX_BmpDecompressor::GetDataPosition(uint32_t rcd_pos) {
}
int32_t CFX_BmpDecompressor::ReadHeader() {
- uint32_t skip_size_org = skip_size_;
if (decode_status_ == BMP_D_STATUS_HEADER) {
- BmpFileHeader* pBmp_header = nullptr;
- if (!ReadData(reinterpret_cast<uint8_t**>(&pBmp_header),
+ BmpFileHeader bmp_header;
+ if (!ReadData(reinterpret_cast<uint8_t*>(&bmp_header),
sizeof(BmpFileHeader))) {
return 2;
}
- pBmp_header->bfType =
- FXWORD_GET_LSBFIRST(reinterpret_cast<uint8_t*>(&pBmp_header->bfType));
- pBmp_header->bfOffBits = FXDWORD_GET_LSBFIRST(
- reinterpret_cast<uint8_t*>(&pBmp_header->bfOffBits));
+ bmp_header.bfType =
+ FXWORD_GET_LSBFIRST(reinterpret_cast<uint8_t*>(&bmp_header.bfType));
+ bmp_header.bfOffBits =
+ FXDWORD_GET_LSBFIRST(reinterpret_cast<uint8_t*>(&bmp_header.bfOffBits));
data_size_ =
- FXDWORD_GET_LSBFIRST(reinterpret_cast<uint8_t*>(&pBmp_header->bfSize));
- if (pBmp_header->bfType != BMP_SIGNATURE) {
+ FXDWORD_GET_LSBFIRST(reinterpret_cast<uint8_t*>(&bmp_header.bfSize));
+ if (bmp_header.bfType != BMP_SIGNATURE) {
Error();
NOTREACHED();
}
- if (avail_in_ < skip_size_ + sizeof(uint32_t)) {
- skip_size_ = skip_size_org;
+
+ if (!ReadData(reinterpret_cast<uint8_t*>(&img_ifh_size_),
+ sizeof(img_ifh_size_))) {
return 2;
}
+
img_ifh_size_ =
- FXDWORD_GET_LSBFIRST(static_cast<uint8_t*>(next_in_ + skip_size_));
+ FXDWORD_GET_LSBFIRST(reinterpret_cast<uint8_t*>(&img_ifh_size_));
pal_type_ = 0;
static_assert(sizeof(BmpCoreHeader) == kBmpCoreHeaderSize,
"BmpCoreHeader has wrong size");
@@ -106,71 +104,71 @@ int32_t CFX_BmpDecompressor::ReadHeader() {
switch (img_ifh_size_) {
case kBmpCoreHeaderSize: {
pal_type_ = 1;
- BmpCoreHeader* pBmp_core_header = nullptr;
- if (!ReadData(reinterpret_cast<uint8_t**>(&pBmp_core_header),
+ BmpCoreHeader bmp_core_header;
+ if (!ReadData(reinterpret_cast<uint8_t*>(&bmp_core_header),
img_ifh_size_)) {
- skip_size_ = skip_size_org;
return 2;
}
+
width_ = FXWORD_GET_LSBFIRST(
- reinterpret_cast<uint8_t*>(&pBmp_core_header->bcWidth));
+ reinterpret_cast<uint8_t*>(&bmp_core_header.bcWidth));
height_ = FXWORD_GET_LSBFIRST(
- reinterpret_cast<uint8_t*>(&pBmp_core_header->bcHeight));
+ reinterpret_cast<uint8_t*>(&bmp_core_header.bcHeight));
bit_counts_ = FXWORD_GET_LSBFIRST(
- reinterpret_cast<uint8_t*>(&pBmp_core_header->bcBitCount));
+ reinterpret_cast<uint8_t*>(&bmp_core_header.bcBitCount));
compress_flag_ = BMP_RGB;
imgTB_flag_ = false;
} break;
case kBmpInfoHeaderSize: {
- BmpInfoHeader* pBmp_info_header = nullptr;
- if (!ReadData(reinterpret_cast<uint8_t**>(&pBmp_info_header),
+ BmpInfoHeader bmp_info_header;
+ if (!ReadData(reinterpret_cast<uint8_t*>(&bmp_info_header),
img_ifh_size_)) {
- skip_size_ = skip_size_org;
return 2;
}
+
width_ = FXDWORD_GET_LSBFIRST(
- reinterpret_cast<uint8_t*>(&pBmp_info_header->biWidth));
+ reinterpret_cast<uint8_t*>(&bmp_info_header.biWidth));
int32_t signed_height = FXDWORD_GET_LSBFIRST(
- reinterpret_cast<uint8_t*>(&pBmp_info_header->biHeight));
+ reinterpret_cast<uint8_t*>(&bmp_info_header.biHeight));
bit_counts_ = FXWORD_GET_LSBFIRST(
- reinterpret_cast<uint8_t*>(&pBmp_info_header->biBitCount));
+ reinterpret_cast<uint8_t*>(&bmp_info_header.biBitCount));
compress_flag_ = FXDWORD_GET_LSBFIRST(
- reinterpret_cast<uint8_t*>(&pBmp_info_header->biCompression));
+ reinterpret_cast<uint8_t*>(&bmp_info_header.biCompression));
color_used_ = FXDWORD_GET_LSBFIRST(
- reinterpret_cast<uint8_t*>(&pBmp_info_header->biClrUsed));
+ reinterpret_cast<uint8_t*>(&bmp_info_header.biClrUsed));
dpi_x_ = static_cast<int32_t>(FXDWORD_GET_LSBFIRST(
- reinterpret_cast<uint8_t*>(&pBmp_info_header->biXPelsPerMeter)));
+ reinterpret_cast<uint8_t*>(&bmp_info_header.biXPelsPerMeter)));
dpi_y_ = static_cast<int32_t>(FXDWORD_GET_LSBFIRST(
- reinterpret_cast<uint8_t*>(&pBmp_info_header->biYPelsPerMeter)));
+ reinterpret_cast<uint8_t*>(&bmp_info_header.biYPelsPerMeter)));
SetHeight(signed_height);
} break;
default: {
if (img_ifh_size_ >
std::min(kBmpInfoHeaderSize,
static_cast<size_t>(sizeof(BmpInfoHeader)))) {
- BmpInfoHeader* pBmp_info_header = nullptr;
- if (!ReadData(reinterpret_cast<uint8_t**>(&pBmp_info_header),
+ BmpInfoHeader bmp_info_header;
+ if (!ReadData(reinterpret_cast<uint8_t*>(&bmp_info_header),
img_ifh_size_)) {
- skip_size_ = skip_size_org;
return 2;
}
+
uint16_t biPlanes;
width_ = FXDWORD_GET_LSBFIRST(
- reinterpret_cast<uint8_t*>(&pBmp_info_header->biWidth));
+ reinterpret_cast<uint8_t*>(&bmp_info_header.biWidth));
int32_t signed_height = FXDWORD_GET_LSBFIRST(
- reinterpret_cast<uint8_t*>(&pBmp_info_header->biHeight));
+ reinterpret_cast<uint8_t*>(&bmp_info_header.biHeight));
bit_counts_ = FXWORD_GET_LSBFIRST(
- reinterpret_cast<uint8_t*>(&pBmp_info_header->biBitCount));
+ reinterpret_cast<uint8_t*>(&bmp_info_header.biBitCount));
compress_flag_ = FXDWORD_GET_LSBFIRST(
- reinterpret_cast<uint8_t*>(&pBmp_info_header->biCompression));
+ reinterpret_cast<uint8_t*>(&bmp_info_header.biCompression));
color_used_ = FXDWORD_GET_LSBFIRST(
- reinterpret_cast<uint8_t*>(&pBmp_info_header->biClrUsed));
+ reinterpret_cast<uint8_t*>(&bmp_info_header.biClrUsed));
biPlanes = FXWORD_GET_LSBFIRST(
- reinterpret_cast<uint8_t*>(&pBmp_info_header->biPlanes));
+ reinterpret_cast<uint8_t*>(&bmp_info_header.biPlanes));
dpi_x_ = FXDWORD_GET_LSBFIRST(
- reinterpret_cast<uint8_t*>(&pBmp_info_header->biXPelsPerMeter));
+ reinterpret_cast<uint8_t*>(&bmp_info_header.biXPelsPerMeter));
dpi_y_ = FXDWORD_GET_LSBFIRST(
- reinterpret_cast<uint8_t*>(&pBmp_info_header->biYPelsPerMeter));
+ reinterpret_cast<uint8_t*>(&bmp_info_header.biYPelsPerMeter));
SetHeight(signed_height);
if (compress_flag_ == BMP_RGB && biPlanes == 1 && color_used_ == 0)
break;
@@ -229,21 +227,19 @@ int32_t CFX_BmpDecompressor::ReadHeader() {
SaveDecodingStatus(BMP_D_STATUS_PAL);
}
if (decode_status_ == BMP_D_STATUS_PAL) {
- skip_size_org = skip_size_;
if (compress_flag_ == BMP_BITFIELDS) {
if (bit_counts_ != 16 && bit_counts_ != 32) {
Error();
NOTREACHED();
}
- uint32_t* mask;
- if (ReadData(reinterpret_cast<uint8_t**>(&mask), 3 * sizeof(uint32_t)) ==
- nullptr) {
- skip_size_ = skip_size_org;
+
+ uint32_t masks[3];
+ if (!ReadData(reinterpret_cast<uint8_t*>(masks), sizeof(masks)))
return 2;
- }
- mask_red_ = FXDWORD_GET_LSBFIRST(reinterpret_cast<uint8_t*>(&mask[0]));
- mask_green_ = FXDWORD_GET_LSBFIRST(reinterpret_cast<uint8_t*>(&mask[1]));
- mask_blue_ = FXDWORD_GET_LSBFIRST(reinterpret_cast<uint8_t*>(&mask[2]));
+
+ mask_red_ = FXDWORD_GET_LSBFIRST(reinterpret_cast<uint8_t*>(&masks[0]));
+ mask_green_ = FXDWORD_GET_LSBFIRST(reinterpret_cast<uint8_t*>(&masks[1]));
+ mask_blue_ = FXDWORD_GET_LSBFIRST(reinterpret_cast<uint8_t*>(&masks[2]));
if (mask_red_ & mask_green_ || mask_red_ & mask_blue_ ||
mask_green_ & mask_blue_) {
Error();
@@ -262,25 +258,27 @@ int32_t CFX_BmpDecompressor::ReadHeader() {
pal_num_ = 1 << bit_counts_;
if (color_used_ != 0)
pal_num_ = color_used_;
- uint8_t* src_pal_ptr = nullptr;
uint32_t src_pal_size = pal_num_ * (pal_type_ ? 3 : 4);
- if (ReadData(&src_pal_ptr, src_pal_size) == nullptr) {
- skip_size_ = skip_size_org;
+ std::vector<uint8_t> src_pal(src_pal_size);
+ uint8_t* src_pal_data = src_pal.data();
+ if (!ReadData(src_pal_data, src_pal_size)) {
return 2;
}
+
palette_.resize(pal_num_);
int32_t src_pal_index = 0;
if (pal_type_ == BMP_PAL_OLD) {
while (src_pal_index < pal_num_) {
palette_[src_pal_index++] = BMP_PAL_ENCODE(
- 0x00, src_pal_ptr[2], src_pal_ptr[1], src_pal_ptr[0]);
- src_pal_ptr += 3;
+ 0x00, src_pal_data[2], src_pal_data[1], src_pal_data[0]);
+ src_pal_data += 3;
}
} else {
while (src_pal_index < pal_num_) {
- palette_[src_pal_index++] = BMP_PAL_ENCODE(
- src_pal_ptr[3], src_pal_ptr[2], src_pal_ptr[1], src_pal_ptr[0]);
- src_pal_ptr += 4;
+ palette_[src_pal_index++] =
+ BMP_PAL_ENCODE(src_pal_data[3], src_pal_data[2], src_pal_data[1],
+ src_pal_data[0]);
+ src_pal_data += 4;
}
}
}
@@ -305,12 +303,13 @@ bool CFX_BmpDecompressor::ValidateFlag() const {
int32_t CFX_BmpDecompressor::DecodeImage() {
if (decode_status_ == BMP_D_STATUS_DATA_PRE) {
- avail_in_ = 0;
+ input_buffer_->Seek(0);
if (!GetDataPosition(header_offset_)) {
decode_status_ = BMP_D_STATUS_TAIL;
Error();
NOTREACHED();
}
+
row_num_ = 0;
SaveDecodingStatus(BMP_D_STATUS_DATA);
}
@@ -318,6 +317,7 @@ int32_t CFX_BmpDecompressor::DecodeImage() {
Error();
NOTREACHED();
}
+
switch (compress_flag_) {
case BMP_RGB:
case BMP_BITFIELDS:
@@ -336,14 +336,15 @@ bool CFX_BmpDecompressor::ValidateColorIndex(uint8_t val) {
Error();
NOTREACHED();
}
+
return true;
}
int32_t CFX_BmpDecompressor::DecodeRGB() {
- uint8_t* des_buf = nullptr;
+ std::vector<uint8_t> des_buf(src_row_bytes_);
while (row_num_ < height_) {
size_t idx = 0;
- if (!ReadData(&des_buf, src_row_bytes_))
+ if (!ReadData(des_buf.data(), src_row_bytes_))
return 2;
SaveDecodingStatus(BMP_D_STATUS_DATA);
@@ -361,7 +362,7 @@ int32_t CFX_BmpDecompressor::DecodeRGB() {
}
} break;
case 16: {
- uint16_t* buf = (uint16_t*)des_buf;
+ uint16_t* buf = reinterpret_cast<uint16_t*>(des_buf.data());
uint8_t blue_bits = 0;
uint8_t green_bits = 0;
uint8_t red_bits = 0;
@@ -393,7 +394,9 @@ int32_t CFX_BmpDecompressor::DecodeRGB() {
case 8:
case 24:
case 32:
- std::copy(des_buf, des_buf + src_row_bytes_, out_row_buffer_.begin());
+ uint8_t* des_buf_data = des_buf.data();
+ std::copy(des_buf_data, des_buf_data + src_row_bytes_,
+ out_row_buffer_.begin());
idx += src_row_bytes_;
break;
}
@@ -409,27 +412,25 @@ int32_t CFX_BmpDecompressor::DecodeRGB() {
}
int32_t CFX_BmpDecompressor::DecodeRLE8() {
- uint8_t* first_byte_ptr = nullptr;
- uint8_t* second_byte_ptr = nullptr;
+ uint8_t first_part;
col_num_ = 0;
while (true) {
- uint32_t skip_size_org = skip_size_;
- if (!ReadData(&first_byte_ptr, 1))
+ if (!ReadData(&first_part, sizeof(first_part)))
return 2;
- switch (*first_byte_ptr) {
+ switch (first_part) {
case RLE_MARKER: {
- if (!ReadData(&first_byte_ptr, 1)) {
- skip_size_ = skip_size_org;
+ if (!ReadData(&first_part, sizeof(first_part)))
return 2;
- }
- switch (*first_byte_ptr) {
+
+ switch (first_part) {
case RLE_EOL: {
if (row_num_ >= height_) {
SaveDecodingStatus(BMP_D_STATUS_TAIL);
Error();
NOTREACHED();
}
+
ReadScanline(imgTB_flag_ ? row_num_++ : (height_ - 1 - row_num_++),
out_row_buffer_);
col_num_ = 0;
@@ -447,17 +448,17 @@ int32_t CFX_BmpDecompressor::DecodeRLE8() {
return 1;
}
case RLE_DELTA: {
- uint8_t* delta_ptr;
- if (!ReadData(&delta_ptr, 2)) {
- skip_size_ = skip_size_org;
+ uint8_t delta[2];
+ if (!ReadData(delta, sizeof(delta)))
return 2;
- }
- col_num_ += delta_ptr[0];
- size_t bmp_row_num__next = row_num_ + delta_ptr[1];
+
+ col_num_ += delta[0];
+ size_t bmp_row_num__next = row_num_ + delta[1];
if (col_num_ >= out_row_bytes_ || bmp_row_num__next >= height_) {
Error();
NOTREACHED();
}
+
while (row_num_ < bmp_row_num__next) {
std::fill(out_row_buffer_.begin(), out_row_buffer_.end(), 0);
ReadScanline(
@@ -467,43 +468,44 @@ int32_t CFX_BmpDecompressor::DecodeRLE8() {
} break;
default: {
int32_t avail_size = out_row_bytes_ - col_num_;
- if (!avail_size ||
- static_cast<int32_t>(*first_byte_ptr) > avail_size) {
+ if (!avail_size || static_cast<int32_t>(first_part) > avail_size) {
Error();
NOTREACHED();
}
- if (!ReadData(&second_byte_ptr, *first_byte_ptr & 1
- ? *first_byte_ptr + 1
- : *first_byte_ptr)) {
- skip_size_ = skip_size_org;
+
+ size_t second_part_size =
+ first_part & 1 ? first_part + 1 : first_part;
+ std::vector<uint8_t> second_part(second_part_size);
+ uint8_t* second_part_data = second_part.data();
+ if (!ReadData(second_part_data, second_part_size))
return 2;
- }
- std::copy(second_byte_ptr, second_byte_ptr + *first_byte_ptr,
+
+ std::copy(second_part_data, second_part_data + first_part,
out_row_buffer_.begin() + col_num_);
- for (size_t i = col_num_; i < col_num_ + *first_byte_ptr; ++i) {
+ for (size_t i = col_num_; i < col_num_ + first_part; ++i) {
if (!ValidateColorIndex(out_row_buffer_[i]))
return 0;
}
- col_num_ += *first_byte_ptr;
+ col_num_ += first_part;
}
}
} break;
default: {
int32_t avail_size = out_row_bytes_ - col_num_;
- if (!avail_size || static_cast<int32_t>(*first_byte_ptr) > avail_size) {
+ if (!avail_size || static_cast<int32_t>(first_part) > avail_size) {
Error();
NOTREACHED();
}
- if (!ReadData(&second_byte_ptr, 1)) {
- skip_size_ = skip_size_org;
+
+ uint8_t second_part;
+ if (!ReadData(&second_part, sizeof(second_part)))
return 2;
- }
+
std::fill(out_row_buffer_.begin() + col_num_,
- out_row_buffer_.begin() + col_num_ + *first_byte_ptr,
- *second_byte_ptr);
+ out_row_buffer_.begin() + col_num_ + first_part, second_part);
if (!ValidateColorIndex(out_row_buffer_[col_num_]))
return 0;
- col_num_ += *first_byte_ptr;
+ col_num_ += first_part;
}
}
}
@@ -512,27 +514,25 @@ int32_t CFX_BmpDecompressor::DecodeRLE8() {
}
int32_t CFX_BmpDecompressor::DecodeRLE4() {
- uint8_t* first_byte_ptr = nullptr;
- uint8_t* second_byte_ptr = nullptr;
+ uint8_t first_part;
col_num_ = 0;
while (true) {
- uint32_t skip_size_org = skip_size_;
- if (!ReadData(&first_byte_ptr, 1))
+ if (!ReadData(&first_part, sizeof(first_part)))
return 2;
- switch (*first_byte_ptr) {
+ switch (first_part) {
case RLE_MARKER: {
- if (!ReadData(&first_byte_ptr, 1)) {
- skip_size_ = skip_size_org;
+ if (!ReadData(&first_part, sizeof(first_part))) {
return 2;
}
- switch (*first_byte_ptr) {
+ switch (first_part) {
case RLE_EOL: {
if (row_num_ >= height_) {
SaveDecodingStatus(BMP_D_STATUS_TAIL);
Error();
NOTREACHED();
}
+
ReadScanline(imgTB_flag_ ? row_num_++ : (height_ - 1 - row_num_++),
out_row_buffer_);
col_num_ = 0;
@@ -550,17 +550,17 @@ int32_t CFX_BmpDecompressor::DecodeRLE4() {
return 1;
}
case RLE_DELTA: {
- uint8_t* delta_ptr;
- if (!ReadData(&delta_ptr, 2)) {
- skip_size_ = skip_size_org;
+ uint8_t delta[2];
+ if (!ReadData(delta, sizeof(delta)))
return 2;
- }
- col_num_ += delta_ptr[0];
- size_t bmp_row_num__next = row_num_ + delta_ptr[1];
+
+ col_num_ += delta[0];
+ size_t bmp_row_num__next = row_num_ + delta[1];
if (col_num_ >= out_row_bytes_ || bmp_row_num__next >= height_) {
Error();
NOTREACHED();
}
+
while (row_num_ < bmp_row_num__next) {
std::fill(out_row_buffer_.begin(), out_row_buffer_.end(), 0);
ReadScanline(
@@ -574,21 +574,24 @@ int32_t CFX_BmpDecompressor::DecodeRLE4() {
Error();
NOTREACHED();
}
- uint8_t size = HalfRoundUp(*first_byte_ptr);
- if (static_cast<int32_t>(*first_byte_ptr) > avail_size) {
+ uint8_t size = HalfRoundUp(first_part);
+ if (static_cast<int32_t>(first_part) > avail_size) {
if (size + (col_num_ >> 1) > src_row_bytes_) {
Error();
NOTREACHED();
}
- *first_byte_ptr = avail_size - 1;
+
+ first_part = avail_size - 1;
}
- if (!ReadData(&second_byte_ptr, size & 1 ? size + 1 : size)) {
- skip_size_ = skip_size_org;
+ size_t second_part_size = size & 1 ? size + 1 : size;
+ std::vector<uint8_t> second_part(second_part_size);
+ uint8_t* second_part_data = second_part.data();
+ if (!ReadData(second_part_data, second_part_size))
return 2;
- }
- for (uint8_t i = 0; i < *first_byte_ptr; i++) {
- uint8_t color = (i & 0x01) ? (*second_byte_ptr++ & 0x0F)
- : (*second_byte_ptr & 0xF0) >> 4;
+
+ for (uint8_t i = 0; i < first_part; i++) {
+ uint8_t color = (i & 0x01) ? (*second_part_data++ & 0x0F)
+ : (*second_part_data & 0xF0) >> 4;
if (!ValidateColorIndex(color))
return 0;
@@ -603,24 +606,27 @@ int32_t CFX_BmpDecompressor::DecodeRLE4() {
Error();
NOTREACHED();
}
- if (static_cast<int32_t>(*first_byte_ptr) > avail_size) {
- uint8_t size = HalfRoundUp(*first_byte_ptr);
+
+ if (static_cast<int32_t>(first_part) > avail_size) {
+ uint8_t size = HalfRoundUp(first_part);
if (size + (col_num_ >> 1) > src_row_bytes_) {
Error();
NOTREACHED();
}
- *first_byte_ptr = avail_size - 1;
+
+ first_part = avail_size - 1;
}
- if (!ReadData(&second_byte_ptr, 1)) {
- skip_size_ = skip_size_org;
+ uint8_t second_part;
+ if (!ReadData(&second_part, sizeof(second_part)))
return 2;
- }
- for (uint8_t i = 0; i < *first_byte_ptr; i++) {
- uint8_t second_byte = *second_byte_ptr;
+
+ for (uint8_t i = 0; i < first_part; i++) {
+ uint8_t second_byte = second_part;
second_byte =
i & 0x01 ? (second_byte & 0x0F) : (second_byte & 0xF0) >> 4;
if (!ValidateColorIndex(second_byte))
return 0;
+
out_row_buffer_[col_num_++] = second_byte;
}
}
@@ -630,37 +636,32 @@ int32_t CFX_BmpDecompressor::DecodeRLE4() {
NOTREACHED();
}
-uint8_t* CFX_BmpDecompressor::ReadData(uint8_t** des_buf, uint32_t data_size) {
- pdfium::base::CheckedNumeric<uint32_t> request_size = data_size;
- request_size += skip_size_;
- if (!request_size.IsValid() || avail_in_ < request_size.ValueOrDie())
- return nullptr;
-
- *des_buf = next_in_ + skip_size_;
- skip_size_ += data_size;
- return *des_buf;
+bool CFX_BmpDecompressor::ReadData(uint8_t* destination, uint32_t size) {
+ return input_buffer_ && input_buffer_->ReadBlock(destination, size);
}
void CFX_BmpDecompressor::SaveDecodingStatus(int32_t status) {
decode_status_ = status;
- next_in_ += skip_size_;
- avail_in_ -= skip_size_;
- skip_size_ = 0;
}
void CFX_BmpDecompressor::SetInputBuffer(uint8_t* src_buf, uint32_t src_size) {
- next_in_ = src_buf;
- avail_in_ = src_size;
- skip_size_ = 0;
+ input_buffer_ =
+ pdfium::MakeRetain<CFX_MemoryStream>(src_buf, src_size, false);
}
uint32_t CFX_BmpDecompressor::GetAvailInput(uint8_t** avail_buf) {
+ if (!input_buffer_)
+ return 0;
+
+ FX_FILESIZE available =
+ input_buffer_->GetSize() - input_buffer_->GetPosition();
if (avail_buf) {
*avail_buf = nullptr;
- if (avail_in_ > 0)
- *avail_buf = next_in_;
+ if (available > 0)
+ *avail_buf = input_buffer_->GetBuffer() + available;
}
- return avail_in_;
+
+ return available;
}
void CFX_BmpDecompressor::SetHeight(int32_t signed_height) {
diff --git a/core/fxcodec/bmp/cfx_bmpdecompressor.h b/core/fxcodec/bmp/cfx_bmpdecompressor.h
index 499d559637..eece78c7ca 100644
--- a/core/fxcodec/bmp/cfx_bmpdecompressor.h
+++ b/core/fxcodec/bmp/cfx_bmpdecompressor.h
@@ -14,6 +14,8 @@
#include <memory>
#include <vector>
+#include "core/fxcrt/cfx_memorystream.h"
+
class CFX_BmpDecompressor {
public:
CFX_BmpDecompressor();
@@ -31,7 +33,6 @@ class CFX_BmpDecompressor {
std::vector<uint8_t> out_row_buffer_;
std::vector<uint32_t> palette_;
- uint8_t* next_in_;
uint32_t header_offset_;
uint32_t width_;
@@ -56,8 +57,6 @@ class CFX_BmpDecompressor {
uint32_t mask_green_;
uint32_t mask_blue_;
- uint32_t avail_in_;
- uint32_t skip_size_;
int32_t decode_status_;
private:
@@ -66,11 +65,13 @@ class CFX_BmpDecompressor {
int32_t DecodeRGB();
int32_t DecodeRLE8();
int32_t DecodeRLE4();
- uint8_t* ReadData(uint8_t** des_buf, uint32_t data_size);
+ bool ReadData(uint8_t* destination, uint32_t size);
void SaveDecodingStatus(int32_t status);
bool ValidateColorIndex(uint8_t val);
bool ValidateFlag() const;
void SetHeight(int32_t signed_height);
+
+ RetainPtr<CFX_MemoryStream> input_buffer_;
};
#endif // CORE_FXCODEC_BMP_CFX_BMPDECOMPRESSOR_H_
diff --git a/core/fxcrt/cfx_memorystream.cpp b/core/fxcrt/cfx_memorystream.cpp
index 345b381226..dcd21f073f 100644
--- a/core/fxcrt/cfx_memorystream.cpp
+++ b/core/fxcrt/cfx_memorystream.cpp
@@ -148,6 +148,14 @@ bool CFX_MemoryStream::WriteBlock(const void* buffer,
return true;
}
+bool CFX_MemoryStream::Seek(size_t pos) {
+ if (pos > m_nCurSize)
+ return false;
+
+ m_nCurPos = pos;
+ return true;
+}
+
void CFX_MemoryStream::EstimateSize(size_t nInitSize, size_t nGrowSize) {
if (m_dwFlags & Type::kConsecutive) {
if (m_Blocks.empty()) {
diff --git a/core/fxcrt/cfx_memorystream.h b/core/fxcrt/cfx_memorystream.h
index ef66080420..a56a2dbe2c 100644
--- a/core/fxcrt/cfx_memorystream.h
+++ b/core/fxcrt/cfx_memorystream.h
@@ -28,6 +28,9 @@ class CFX_MemoryStream : public IFX_SeekableStream {
bool WriteBlock(const void* buffer, FX_FILESIZE offset, size_t size) override;
bool Flush() override;
+ // Sets the cursor position to |pos| if possible
+ bool Seek(size_t pos);
+
bool IsConsecutive() const { return !!(m_dwFlags & Type::kConsecutive); }
uint8_t* GetBuffer() const {