| Index: core/src/fpdfapi/fpdf_render/fpdf_render_loadimage.cpp
|
| diff --git a/core/src/fpdfapi/fpdf_render/fpdf_render_loadimage.cpp b/core/src/fpdfapi/fpdf_render/fpdf_render_loadimage.cpp
|
| index f6f41d9de11f000598c6858b726afa2a068650ac..bdd5e9aa9c04fbf694c0fd9a0a48385dd0ee6ee8 100644
|
| --- a/core/src/fpdfapi/fpdf_render/fpdf_render_loadimage.cpp
|
| +++ b/core/src/fpdfapi/fpdf_render/fpdf_render_loadimage.cpp
|
| @@ -19,7 +19,9 @@
|
|
|
| namespace {
|
|
|
| -unsigned int _GetBits8(const uint8_t* pData, int bitpos, int nbits) {
|
| +unsigned int GetBits8(const uint8_t* pData, uint64_t bitpos, size_t nbits) {
|
| + ASSERT(nbits == 1 || nbits == 2 || nbits == 4 || nbits == 8 || nbits == 16);
|
| + ASSERT((bitpos & (nbits - 1)) == 0);
|
| unsigned int byte = pData[bitpos / 8];
|
| if (nbits == 8) {
|
| return byte;
|
| @@ -993,11 +995,11 @@ void CPDF_DIBSource::TranslateScanline24bpp(uint8_t* dest_scan,
|
| int src_bit_pos = 0;
|
| int dest_byte_pos = 0;
|
| for (int column = 0; column < m_Width; column++) {
|
| - int R = _GetBits8(src_scan, src_bit_pos, m_bpc);
|
| + int R = GetBits8(src_scan, src_bit_pos, m_bpc);
|
| src_bit_pos += m_bpc;
|
| - int G = _GetBits8(src_scan, src_bit_pos, m_bpc);
|
| + int G = GetBits8(src_scan, src_bit_pos, m_bpc);
|
| src_bit_pos += m_bpc;
|
| - int B = _GetBits8(src_scan, src_bit_pos, m_bpc);
|
| + int B = GetBits8(src_scan, src_bit_pos, m_bpc);
|
| src_bit_pos += m_bpc;
|
| R = NORMALCOLOR_MAX(R, max_data);
|
| G = NORMALCOLOR_MAX(G, max_data);
|
| @@ -1051,7 +1053,7 @@ void CPDF_DIBSource::TranslateScanline24bpp(uint8_t* dest_scan,
|
| int dest_byte_pos = 0;
|
| for (int column = 0; column < m_Width; column++) {
|
| for (FX_DWORD color = 0; color < m_nComponents; color++) {
|
| - int data = _GetBits8(src_scan, src_bit_pos, m_bpc);
|
| + int data = GetBits8(src_scan, src_bit_pos, m_bpc);
|
| color_values[color] = m_pCompData[color].m_DecodeMin +
|
| m_pCompData[color].m_DecodeStep * data;
|
| src_bit_pos += m_bpc;
|
| @@ -1146,7 +1148,7 @@ const uint8_t* CPDF_DIBSource::GetScanline(int line) const {
|
| for (int col = 0; col < m_Width; col++) {
|
| int color_index = 0;
|
| for (FX_DWORD color = 0; color < m_nComponents; color++) {
|
| - int data = _GetBits8(pSrcLine, src_bit_pos, m_bpc);
|
| + int data = GetBits8(pSrcLine, src_bit_pos, m_bpc);
|
| color_index |= data << (color * m_bpc);
|
| src_bit_pos += m_bpc;
|
| }
|
| @@ -1368,7 +1370,7 @@ void CPDF_DIBSource::DownSampleScanline8Bit(int orig_Bpp,
|
| for (FX_DWORD col = 0; col < src_width; col++) {
|
| int color_index = 0;
|
| for (FX_DWORD color = 0; color < m_nComponents; color++) {
|
| - int data = _GetBits8(pSrcLine, src_bit_pos, m_bpc);
|
| + int data = GetBits8(pSrcLine, src_bit_pos, m_bpc);
|
| color_index |= data << (color * m_bpc);
|
| src_bit_pos += m_bpc;
|
| }
|
| @@ -1431,59 +1433,66 @@ void CPDF_DIBSource::DownSampleScanline32Bit(int orig_Bpp,
|
| int clip_width) const {
|
| int last_src_x = -1;
|
| FX_ARGB last_argb = FXARGB_MAKE(0xFF, 0xFF, 0xFF, 0xFF);
|
| - FX_FLOAT orig_Not8Bpp = (FX_FLOAT)m_bpc * (FX_FLOAT)m_nComponents / 8.0f;
|
| FX_FLOAT unit_To8Bpc = 255.0f / ((1 << m_bpc) - 1);
|
| for (int i = 0; i < clip_width; i++) {
|
| int dest_x = clip_left + i;
|
| FX_DWORD src_x = (bFlipX ? (dest_width - dest_x - 1) : dest_x) *
|
| (int64_t)src_width / dest_width;
|
| src_x %= src_width;
|
| +
|
| + // No need to check for 32-bit overflow, as |src_x| is bounded by
|
| + // |src_width| and DownSampleScanline already checked for overflow with the
|
| + // pitch calculation.
|
| const uint8_t* pSrcPixel = nullptr;
|
| + size_t bit_offset = 0;
|
| if (m_bpc % 8 == 0) {
|
| pSrcPixel = pSrcLine + src_x * orig_Bpp;
|
| } else {
|
| - pSrcPixel = pSrcLine + (int)(src_x * orig_Not8Bpp);
|
| + size_t num_bits = src_x * m_bpc * m_nComponents;
|
| + pSrcPixel = pSrcLine + num_bits / 8;
|
| + bit_offset = num_bits % 8;
|
| }
|
| +
|
| uint8_t* pDestPixel = dest_scan + i * dest_Bpp;
|
| FX_ARGB argb;
|
| if (src_x == last_src_x) {
|
| argb = last_argb;
|
| } else {
|
| + CFX_FixedBufGrow<uint8_t, 128> extracted_components(m_nComponents);
|
| + if (m_bpc % 8 != 0) {
|
| + uint64_t src_bit_pos = bit_offset;
|
| + for (FX_DWORD j = 0; j < m_nComponents; ++j) {
|
| + extracted_components[j] = static_cast<uint8_t>(
|
| + GetBits8(pSrcPixel, src_bit_pos, m_bpc) * unit_To8Bpc);
|
| + src_bit_pos += m_bpc;
|
| + }
|
| + pSrcPixel = extracted_components;
|
| + }
|
| +
|
| if (m_pColorSpace) {
|
| - CFX_FixedBufGrow<uint8_t, 128> temp(orig_Bpp);
|
| uint8_t color[4];
|
| const FX_BOOL bTransMask = TransMask();
|
| if (m_bDefaultDecode) {
|
| - if (m_bpc < 8) {
|
| - int src_bit_pos = 0;
|
| - if (src_x % 2) {
|
| - src_bit_pos = 4;
|
| - }
|
| - for (FX_DWORD j = 0; j < m_nComponents; ++j) {
|
| - temp[j] = (uint8_t)(_GetBits8(pSrcPixel, src_bit_pos, m_bpc) *
|
| - unit_To8Bpc);
|
| - src_bit_pos += m_bpc;
|
| - }
|
| - m_pColorSpace->TranslateImageLine(color, temp, 1, 0, 0, bTransMask);
|
| - } else {
|
| - m_pColorSpace->TranslateImageLine(color, pSrcPixel, 1, 0, 0,
|
| - bTransMask);
|
| - }
|
| + m_pColorSpace->TranslateImageLine(color, pSrcPixel, 1, 0, 0,
|
| + bTransMask);
|
| } else {
|
| for (FX_DWORD j = 0; j < m_nComponents; ++j) {
|
| + FX_FLOAT component_value =
|
| + static_cast<FX_FLOAT>(extracted_components[j]);
|
| int color_value =
|
| (int)((m_pCompData[j].m_DecodeMin +
|
| - m_pCompData[j].m_DecodeStep * (FX_FLOAT)pSrcPixel[j]) *
|
| + m_pCompData[j].m_DecodeStep * component_value) *
|
| 255.0f +
|
| 0.5f);
|
| - temp[j] =
|
| + extracted_components[j] =
|
| color_value > 255 ? 255 : (color_value < 0 ? 0 : color_value);
|
| }
|
| - m_pColorSpace->TranslateImageLine(color, temp, 1, 0, 0, bTransMask);
|
| + m_pColorSpace->TranslateImageLine(color, extracted_components, 1, 0,
|
| + 0, bTransMask);
|
| }
|
| argb = FXARGB_MAKE(0xFF, color[2], color[1], color[0]);
|
| } else {
|
| - argb = FXARGB_MAKE(0xFf, pSrcPixel[2], pSrcPixel[1], pSrcPixel[0]);
|
| + argb = FXARGB_MAKE(0xFF, pSrcPixel[2], pSrcPixel[1], pSrcPixel[0]);
|
| }
|
| if (m_bColorKey) {
|
| int alpha = 0xFF;
|
|
|