diff options
Diffstat (limited to 'core/fxcodec/lbmp')
-rw-r--r-- | core/fxcodec/lbmp/fx_bmp.cpp | 180 | ||||
-rw-r--r-- | core/fxcodec/lbmp/fx_bmp.h | 31 |
2 files changed, 102 insertions, 109 deletions
diff --git a/core/fxcodec/lbmp/fx_bmp.cpp b/core/fxcodec/lbmp/fx_bmp.cpp index 1febce63eb..62ae681b2a 100644 --- a/core/fxcodec/lbmp/fx_bmp.cpp +++ b/core/fxcodec/lbmp/fx_bmp.cpp @@ -30,24 +30,40 @@ uint16_t GetWord_LSBFirst(uint8_t* p) { return p[0] | (p[1] << 8); } -BMPDecompressor* bmp_create_decompress() { - BMPDecompressor* bmp_ptr = FX_Alloc(BMPDecompressor, 1); - memset(bmp_ptr, 0, sizeof(BMPDecompressor)); - bmp_ptr->decode_status = BMP_D_STATUS_HEADER; - bmp_ptr->bmp_header_ptr = FX_Alloc(BmpFileHeader, 1); - return bmp_ptr; -} - -void bmp_destroy_decompress(BMPDecompressor** bmp_ptr_ptr) { - if (!bmp_ptr_ptr || !*bmp_ptr_ptr) - return; - - BMPDecompressor* bmp_ptr = *bmp_ptr_ptr; - *bmp_ptr_ptr = nullptr; - FX_Free(bmp_ptr->out_row_buffer); - FX_Free(bmp_ptr->pal_ptr); - FX_Free(bmp_ptr->bmp_header_ptr); - FX_Free(bmp_ptr); +BMPDecompressor::BMPDecompressor() + : err_ptr(nullptr), + context_ptr(nullptr), + bmp_header_ptr(FX_Alloc(BmpFileHeader, 1)), + bmp_infoheader_ptr(nullptr), + width(0), + height(0), + compress_flag(0), + components(0), + src_row_bytes(0), + out_row_bytes(0), + bitCounts(0), + color_used(0), + pal_num(0), + pal_type(0), + pal_ptr(nullptr), + data_size(0), + img_data_offset(0), + img_ifh_size(0), + row_num(0), + col_num(0), + dpi_x(0), + dpi_y(0), + mask_red(0), + mask_green(0), + mask_blue(0), + next_in(nullptr), + avail_in(0), + skip_size(0), + decode_status(BMP_D_STATUS_HEADER) {} + +BMPDecompressor::~BMPDecompressor() { + FX_Free(pal_ptr); + FX_Free(bmp_header_ptr); } void BMPDecompressor::Error(const char* err_msg) { @@ -55,7 +71,8 @@ void BMPDecompressor::Error(const char* err_msg) { longjmp(jmpbuf, 1); } -void BMPDecompressor::ReadScanline(int32_t row_num, uint8_t* row_buf) { +void BMPDecompressor::ReadScanline(uint32_t row_num, + const std::vector<uint8_t>& row_buf) { auto* p = reinterpret_cast<CBmpContext*>(context_ptr); p->m_pDelegate->BmpReadScanline(row_num, row_buf); } @@ -108,7 +125,6 @@ int32_t BMPDecompressor::ReadHeader() { bitCounts = GetWord_LSBFirst( reinterpret_cast<uint8_t*>(&bmp_core_header_ptr->bcBitCount)); compress_flag = BMP_RGB; - imgTB_flag = false; } break; case kBmpInfoHeaderSize: { BmpInfoHeaderPtr bmp_info_header_ptr = nullptr; @@ -128,14 +144,6 @@ int32_t BMPDecompressor::ReadHeader() { (uint8_t*)&bmp_info_header_ptr->biXPelsPerMeter); dpi_y = (int32_t)GetDWord_LSBFirst( (uint8_t*)&bmp_info_header_ptr->biYPelsPerMeter); - if (height < 0) { - if (height == std::numeric_limits<int>::min()) { - Error("Unsupported height"); - NOTREACHED(); - } - height = -height; - imgTB_flag = true; - } } break; default: { if (img_ifh_size > @@ -159,23 +167,14 @@ int32_t BMPDecompressor::ReadHeader() { (uint8_t*)&bmp_info_header_ptr->biXPelsPerMeter); dpi_y = GetDWord_LSBFirst( (uint8_t*)&bmp_info_header_ptr->biYPelsPerMeter); - if (height < 0) { - if (height == std::numeric_limits<int>::min()) { - Error("Unsupported height"); - NOTREACHED(); - } - height = -height; - imgTB_flag = true; - } - if (compress_flag == BMP_RGB && biPlanes == 1 && color_used == 0) { + if (compress_flag == BMP_RGB && biPlanes == 1 && color_used == 0) break; - } } Error("Unsupported Bmp File"); NOTREACHED(); } } - if (width <= 0 || width > BMP_MAX_WIDTH || compress_flag > BMP_BITFIELDS) { + if (width > BMP_MAX_WIDTH || compress_flag > BMP_BITFIELDS) { Error("The Bmp File Is Corrupt"); NOTREACHED(); } @@ -214,16 +213,14 @@ int32_t BMPDecompressor::ReadHeader() { components = 4; break; } - FX_Free(out_row_buffer); - out_row_buffer = nullptr; + out_row_buffer.clear(); if (out_row_bytes <= 0) { Error("The Bmp File Is Corrupt"); NOTREACHED(); } - out_row_buffer = FX_Alloc(uint8_t, out_row_bytes); - memset(out_row_buffer, 0, out_row_bytes); + out_row_buffer.resize(out_row_bytes); SaveDecodingStatus(BMP_D_STATUS_PAL); } if (decode_status == BMP_D_STATUS_PAL) { @@ -346,20 +343,22 @@ bool BMPDecompressor::ValidateColorIndex(uint8_t val) { int32_t BMPDecompressor::DecodeRGB() { uint8_t* des_buf = nullptr; while (row_num < height) { - uint8_t* row_buf = out_row_buffer; + size_t idx = 0; if (!ReadData(&des_buf, src_row_bytes)) return 2; SaveDecodingStatus(BMP_D_STATUS_DATA); switch (bitCounts) { case 1: { - for (int32_t col = 0; col < width; ++col) - *row_buf++ = des_buf[col >> 3] & (0x80 >> (col % 8)) ? 0x01 : 0x00; + for (uint32_t col = 0; col < width; ++col) + out_row_buffer[idx++] = + des_buf[col >> 3] & (0x80 >> (col % 8)) ? 0x01 : 0x00; } break; case 4: { - for (int32_t col = 0; col < width; ++col) { - *row_buf++ = (col & 0x01) ? (des_buf[col >> 1] & 0x0F) - : ((des_buf[col >> 1] & 0xF0) >> 4); + for (uint32_t col = 0; col < width; ++col) { + out_row_buffer[idx++] = (col & 0x01) + ? (des_buf[col >> 1] & 0x0F) + : ((des_buf[col >> 1] & 0xF0) >> 4); } } break; case 16: { @@ -382,26 +381,28 @@ int32_t BMPDecompressor::DecodeRGB() { blue_bits = 8 - blue_bits; green_bits -= 8; red_bits -= 8; - for (int32_t col = 0; col < width; ++col) { + for (uint32_t col = 0; col < width; ++col) { *buf = GetWord_LSBFirst((uint8_t*)buf); - *row_buf++ = static_cast<uint8_t>((*buf & mask_blue) << blue_bits); - *row_buf++ = static_cast<uint8_t>((*buf & mask_green) >> green_bits); - *row_buf++ = static_cast<uint8_t>((*buf++ & mask_red) >> red_bits); + out_row_buffer[idx++] = + static_cast<uint8_t>((*buf & mask_blue) << blue_bits); + out_row_buffer[idx++] = + static_cast<uint8_t>((*buf & mask_green) >> green_bits); + out_row_buffer[idx++] = + static_cast<uint8_t>((*buf++ & mask_red) >> red_bits); } } break; case 8: case 24: case 32: - memcpy(out_row_buffer, des_buf, src_row_bytes); - row_buf += src_row_bytes; + std::copy(des_buf, des_buf + src_row_bytes, out_row_buffer.begin()); + idx += src_row_bytes; break; } - for (uint8_t* buf = out_row_buffer; buf < row_buf; ++buf) { - if (!ValidateColorIndex(*buf)) + for (uint8_t byte : out_row_buffer) { + if (!ValidateColorIndex(byte)) return 0; } - ReadScanline(imgTB_flag ? row_num++ : (height - 1 - row_num++), - out_row_buffer); + ReadScanline(height - 1 - row_num++, out_row_buffer); } SaveDecodingStatus(BMP_D_STATUS_TAIL); return 1; @@ -429,17 +430,15 @@ int32_t BMPDecompressor::DecodeRLE8() { Error("The Bmp File Is Corrupt"); NOTREACHED(); } - ReadScanline(imgTB_flag ? row_num++ : (height - 1 - row_num++), - out_row_buffer); + ReadScanline(height - 1 - row_num++, out_row_buffer); col_num = 0; - memset(out_row_buffer, 0, out_row_bytes); + std::fill(out_row_buffer.begin(), out_row_buffer.end(), 0); SaveDecodingStatus(BMP_D_STATUS_DATA); continue; } case RLE_EOI: { if (row_num < height) { - ReadScanline(imgTB_flag ? row_num++ : (height - 1 - row_num++), - out_row_buffer); + ReadScanline(height - 1 - row_num++, out_row_buffer); } SaveDecodingStatus(BMP_D_STATUS_TAIL); return 1; @@ -450,16 +449,15 @@ int32_t BMPDecompressor::DecodeRLE8() { skip_size = skip_size_org; return 2; } - col_num += (int32_t)delta_ptr[0]; - int32_t bmp_row_num_next = row_num + (int32_t)delta_ptr[1]; + col_num += delta_ptr[0]; + size_t bmp_row_num_next = row_num + delta_ptr[1]; if (col_num >= out_row_bytes || bmp_row_num_next >= height) { Error("The Bmp File Is Corrupt Or Not Supported"); NOTREACHED(); } while (row_num < bmp_row_num_next) { - memset(out_row_buffer, 0, out_row_bytes); - ReadScanline(imgTB_flag ? row_num++ : (height - 1 - row_num++), - out_row_buffer); + std::fill(out_row_buffer.begin(), out_row_buffer.end(), 0); + ReadScanline(height - 1 - row_num++, out_row_buffer); } } break; default: { @@ -475,13 +473,13 @@ int32_t BMPDecompressor::DecodeRLE8() { skip_size = skip_size_org; return 2; } - uint8_t* first_buf = out_row_buffer + col_num; - memcpy(out_row_buffer + col_num, second_byte_ptr, *first_byte_ptr); - for (size_t i = 0; i < *first_byte_ptr; ++i) { - if (!ValidateColorIndex(first_buf[i])) + std::copy(second_byte_ptr, second_byte_ptr + *first_byte_ptr, + out_row_buffer.begin() + col_num); + for (size_t i = col_num; i < col_num + *first_byte_ptr; ++i) { + if (!ValidateColorIndex(out_row_buffer[i])) return 0; } - col_num += (int32_t)(*first_byte_ptr); + col_num += *first_byte_ptr; } } } break; @@ -495,13 +493,12 @@ int32_t BMPDecompressor::DecodeRLE8() { skip_size = skip_size_org; return 2; } - uint8_t* first_buf = out_row_buffer + col_num; - memset(out_row_buffer + col_num, *second_byte_ptr, *first_byte_ptr); - for (size_t i = 0; i < *first_byte_ptr; ++i) { - if (!ValidateColorIndex(first_buf[i])) - return 0; - } - col_num += (int32_t)(*first_byte_ptr); + std::fill(out_row_buffer.begin() + col_num, + out_row_buffer.begin() + col_num + *first_byte_ptr, + *second_byte_ptr); + if (!ValidateColorIndex(out_row_buffer[col_num])) + return 0; + col_num += *first_byte_ptr; } } } @@ -531,17 +528,15 @@ int32_t BMPDecompressor::DecodeRLE4() { Error("The Bmp File Is Corrupt"); NOTREACHED(); } - ReadScanline(imgTB_flag ? row_num++ : (height - 1 - row_num++), - out_row_buffer); + ReadScanline(height - 1 - row_num++, out_row_buffer); col_num = 0; - memset(out_row_buffer, 0, out_row_bytes); + std::fill(out_row_buffer.begin(), out_row_buffer.end(), 0); SaveDecodingStatus(BMP_D_STATUS_DATA); continue; } case RLE_EOI: { if (row_num < height) { - ReadScanline(imgTB_flag ? row_num++ : (height - 1 - row_num++), - out_row_buffer); + ReadScanline(height - 1 - row_num++, out_row_buffer); } SaveDecodingStatus(BMP_D_STATUS_TAIL); return 1; @@ -552,16 +547,15 @@ int32_t BMPDecompressor::DecodeRLE4() { skip_size = skip_size_org; return 2; } - col_num += (int32_t)delta_ptr[0]; - int32_t bmp_row_num_next = row_num + (int32_t)delta_ptr[1]; + col_num += delta_ptr[0]; + size_t bmp_row_num_next = row_num + delta_ptr[1]; if (col_num >= out_row_bytes || bmp_row_num_next >= height) { Error("The Bmp File Is Corrupt Or Not Supported"); NOTREACHED(); } while (row_num < bmp_row_num_next) { - memset(out_row_buffer, 0, out_row_bytes); - ReadScanline(imgTB_flag ? row_num++ : (height - 1 - row_num++), - out_row_buffer); + std::fill(out_row_buffer.begin(), out_row_buffer.end(), 0); + ReadScanline(height - 1 - row_num++, out_row_buffer); } } break; default: { @@ -588,7 +582,7 @@ int32_t BMPDecompressor::DecodeRLE4() { if (!ValidateColorIndex(color)) return 0; - *(out_row_buffer + col_num++) = color; + out_row_buffer[col_num++] = color; } } } @@ -617,7 +611,7 @@ int32_t BMPDecompressor::DecodeRLE4() { i & 0x01 ? (second_byte & 0x0F) : (second_byte & 0xF0) >> 4; if (!ValidateColorIndex(second_byte)) return 0; - *(out_row_buffer + col_num++) = second_byte; + out_row_buffer[col_num++] = second_byte; } } } diff --git a/core/fxcodec/lbmp/fx_bmp.h b/core/fxcodec/lbmp/fx_bmp.h index 2612d7eb8c..bf5e94fc23 100644 --- a/core/fxcodec/lbmp/fx_bmp.h +++ b/core/fxcodec/lbmp/fx_bmp.h @@ -8,6 +8,7 @@ #define CORE_FXCODEC_LBMP_FX_BMP_H_ #include <setjmp.h> +#include <vector> #include "core/fxcodec/codec/ccodec_bmpmodule.h" #include "core/fxcrt/fx_basic.h" @@ -68,6 +69,9 @@ typedef struct tagBmpInfoHeader { class BMPDecompressor { public: + BMPDecompressor(); + ~BMPDecompressor(); + void Error(const char* err_msg); int32_t DecodeImage(); int32_t ReadHeader(); @@ -81,24 +85,24 @@ class BMPDecompressor { BmpFileHeaderPtr bmp_header_ptr; BmpInfoHeaderPtr bmp_infoheader_ptr; - int32_t width; - int32_t height; + std::vector<uint8_t> out_row_buffer; + + uint32_t width; + uint32_t height; uint32_t compress_flag; int32_t components; - int32_t src_row_bytes; - int32_t out_row_bytes; - uint8_t* out_row_buffer; + size_t src_row_bytes; + size_t out_row_bytes; uint16_t bitCounts; uint32_t color_used; - bool imgTB_flag; int32_t pal_num; int32_t pal_type; uint32_t* pal_ptr; uint32_t data_size; uint32_t img_data_offset; uint32_t img_ifh_size; - int32_t row_num; - int32_t col_num; + size_t row_num; + size_t col_num; int32_t dpi_x; int32_t dpi_y; uint32_t mask_red; @@ -112,7 +116,7 @@ class BMPDecompressor { private: bool GetDataPosition(uint32_t cur_pos); - void ReadScanline(int32_t row_num, uint8_t* row_buf); + void ReadScanline(uint32_t row_num, const std::vector<uint8_t>& row_buf); int32_t DecodeRGB(); int32_t DecodeRLE8(); int32_t DecodeRLE4(); @@ -122,17 +126,12 @@ class BMPDecompressor { bool ValidateFlag() const; }; -BMPDecompressor* bmp_create_decompress(); -void bmp_destroy_decompress(BMPDecompressor** bmp_ptr_ptr); - class CBmpContext : public CCodec_BmpModule::Context { public: - CBmpContext(BMPDecompressor* pBmp, - CCodec_BmpModule* pModule, - CCodec_BmpModule::Delegate* pDelegate); + CBmpContext(CCodec_BmpModule* pModule, CCodec_BmpModule::Delegate* pDelegate); ~CBmpContext() override; - BMPDecompressor* m_pBmp; + BMPDecompressor m_Bmp; CFX_UnownedPtr<CCodec_BmpModule> const m_pModule; CFX_UnownedPtr<CCodec_BmpModule::Delegate> const m_pDelegate; char m_szLastError[256]; |