summaryrefslogtreecommitdiff
path: root/core/src/fxcodec/codec/fx_codec_flate.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'core/src/fxcodec/codec/fx_codec_flate.cpp')
-rw-r--r--core/src/fxcodec/codec/fx_codec_flate.cpp306
1 files changed, 162 insertions, 144 deletions
diff --git a/core/src/fxcodec/codec/fx_codec_flate.cpp b/core/src/fxcodec/codec/fx_codec_flate.cpp
index 37aecf106d..519ff00522 100644
--- a/core/src/fxcodec/codec/fx_codec_flate.cpp
+++ b/core/src/fxcodec/codec/fx_codec_flate.cpp
@@ -75,6 +75,8 @@ void FPDFAPI_FlateEnd(void* context) {
}
} // extern "C"
+namespace {
+
class CLZWDecoder {
public:
int Decode(uint8_t* output,
@@ -222,7 +224,8 @@ int CLZWDecoder::Decode(uint8_t* dest_buf,
src_size = (m_InPos + 7) / 8;
return 0;
}
-static uint8_t PaethPredictor(int a, int b, int c) {
+
+uint8_t PaethPredictor(int a, int b, int c) {
int p = a + b - c;
int pa = FXSYS_abs(p - a);
int pb = FXSYS_abs(p - b);
@@ -235,12 +238,13 @@ static uint8_t PaethPredictor(int a, int b, int c) {
}
return (uint8_t)c;
}
-static FX_BOOL PNG_PredictorEncode(uint8_t*& data_buf,
- FX_DWORD& data_size,
- int predictor,
- int Colors,
- int BitsPerComponent,
- int Columns) {
+
+FX_BOOL PNG_PredictorEncode(uint8_t*& data_buf,
+ FX_DWORD& data_size,
+ int predictor,
+ int Colors,
+ int BitsPerComponent,
+ int Columns) {
const int BytesPerPixel = (Colors * BitsPerComponent + 7) / 8;
const int row_size = (Colors * BitsPerComponent * Columns + 7) / 8;
if (row_size <= 0)
@@ -324,12 +328,13 @@ static FX_BOOL PNG_PredictorEncode(uint8_t*& data_buf,
(last_row_size > 0 ? (row_size - last_row_size) : 0);
return TRUE;
}
-static void PNG_PredictLine(uint8_t* pDestData,
- const uint8_t* pSrcData,
- const uint8_t* pLastLine,
- int bpc,
- int nColors,
- int nPixels) {
+
+void PNG_PredictLine(uint8_t* pDestData,
+ const uint8_t* pSrcData,
+ const uint8_t* pLastLine,
+ int bpc,
+ int nColors,
+ int nPixels) {
int row_size = (nPixels * bpc * nColors + 7) / 8;
int BytesPerPixel = (bpc * nColors + 7) / 8;
uint8_t tag = pSrcData[0];
@@ -390,11 +395,12 @@ static void PNG_PredictLine(uint8_t* pDestData,
}
}
}
-static FX_BOOL PNG_Predictor(uint8_t*& data_buf,
- FX_DWORD& data_size,
- int Colors,
- int BitsPerComponent,
- int Columns) {
+
+FX_BOOL PNG_Predictor(uint8_t*& data_buf,
+ FX_DWORD& data_size,
+ int Colors,
+ int BitsPerComponent,
+ int Columns) {
const int BytesPerPixel = (Colors * BitsPerComponent + 7) / 8;
const int row_size = (Colors * BitsPerComponent * Columns + 7) / 8;
if (row_size <= 0)
@@ -483,11 +489,12 @@ static FX_BOOL PNG_Predictor(uint8_t*& data_buf,
(last_row_size > 0 ? (row_size + 1 - last_row_size) : 0);
return TRUE;
}
-static void TIFF_PredictorEncodeLine(uint8_t* dest_buf,
- int row_size,
- int BitsPerComponent,
- int Colors,
- int Columns) {
+
+void TIFF_PredictorEncodeLine(uint8_t* dest_buf,
+ int row_size,
+ int BitsPerComponent,
+ int Colors,
+ int Columns) {
int BytesPerPixel = BitsPerComponent * Colors / 8;
if (BitsPerComponent < 8) {
uint8_t mask = 0x01;
@@ -528,11 +535,12 @@ static void TIFF_PredictorEncodeLine(uint8_t* dest_buf,
}
}
}
-static FX_BOOL TIFF_PredictorEncode(uint8_t*& data_buf,
- FX_DWORD& data_size,
- int Colors,
- int BitsPerComponent,
- int Columns) {
+
+FX_BOOL TIFF_PredictorEncode(uint8_t*& data_buf,
+ FX_DWORD& data_size,
+ int Colors,
+ int BitsPerComponent,
+ int Columns) {
int row_size = (Colors * BitsPerComponent * Columns + 7) / 8;
if (row_size == 0)
return FALSE;
@@ -548,11 +556,12 @@ static FX_BOOL TIFF_PredictorEncode(uint8_t*& data_buf,
}
return TRUE;
}
-static void TIFF_PredictLine(uint8_t* dest_buf,
- int row_size,
- int BitsPerComponent,
- int Colors,
- int Columns) {
+
+void TIFF_PredictLine(uint8_t* dest_buf,
+ int row_size,
+ int BitsPerComponent,
+ int Colors,
+ int Columns) {
if (BitsPerComponent == 1) {
int row_bits = FX_MIN(BitsPerComponent * Colors * Columns, row_size * 8);
int index_pre = 0;
@@ -586,11 +595,12 @@ static void TIFF_PredictLine(uint8_t* dest_buf,
}
}
}
-static FX_BOOL TIFF_Predictor(uint8_t*& data_buf,
- FX_DWORD& data_size,
- int Colors,
- int BitsPerComponent,
- int Columns) {
+
+FX_BOOL TIFF_Predictor(uint8_t*& data_buf,
+ FX_DWORD& data_size,
+ int Colors,
+ int BitsPerComponent,
+ int Columns) {
int row_size = (Colors * BitsPerComponent * Columns + 7) / 8;
if (row_size == 0)
return FALSE;
@@ -606,6 +616,120 @@ static FX_BOOL TIFF_Predictor(uint8_t*& data_buf,
return TRUE;
}
+void FlateUncompress(const uint8_t* src_buf,
+ FX_DWORD src_size,
+ FX_DWORD orig_size,
+ uint8_t*& dest_buf,
+ FX_DWORD& dest_size,
+ FX_DWORD& offset) {
+ FX_DWORD guess_size = orig_size ? orig_size : src_size * 2;
+ const FX_DWORD kStepSize = 10240;
+ FX_DWORD alloc_step = orig_size ? kStepSize : std::min(src_size, kStepSize);
+ static const FX_DWORD kMaxInitialAllocSize = 10000000;
+ if (guess_size > kMaxInitialAllocSize) {
+ guess_size = kMaxInitialAllocSize;
+ alloc_step = kMaxInitialAllocSize;
+ }
+ FX_DWORD buf_size = guess_size;
+ FX_DWORD last_buf_size = buf_size;
+
+ dest_buf = nullptr;
+ dest_size = 0;
+ void* context = FPDFAPI_FlateInit(my_alloc_func, my_free_func);
+ if (!context)
+ return;
+
+ nonstd::unique_ptr<uint8_t, FxFreeDeleter> guess_buf(
+ FX_Alloc(uint8_t, guess_size + 1));
+ guess_buf.get()[guess_size] = '\0';
+
+ FPDFAPI_FlateInput(context, src_buf, src_size);
+
+ if (src_size < kStepSize) {
+ // This is the old implementation.
+ uint8_t* cur_buf = guess_buf.get();
+ while (1) {
+ int32_t ret = FPDFAPI_FlateOutput(context, cur_buf, buf_size);
+ if (ret != Z_OK)
+ break;
+ int32_t avail_buf_size = FPDFAPI_FlateGetAvailOut(context);
+ if (avail_buf_size != 0)
+ break;
+
+ FX_DWORD old_size = guess_size;
+ guess_size += alloc_step;
+ if (guess_size < old_size || guess_size + 1 < guess_size) {
+ FPDFAPI_FlateEnd(context);
+ return;
+ }
+
+ {
+ uint8_t* new_buf =
+ FX_Realloc(uint8_t, guess_buf.release(), guess_size + 1);
+ guess_buf.reset(new_buf);
+ }
+ guess_buf.get()[guess_size] = '\0';
+ cur_buf = guess_buf.get() + old_size;
+ buf_size = guess_size - old_size;
+ }
+ dest_size = FPDFAPI_FlateGetTotalOut(context);
+ offset = FPDFAPI_FlateGetTotalIn(context);
+ if (guess_size / 2 > dest_size) {
+ {
+ uint8_t* new_buf =
+ FX_Realloc(uint8_t, guess_buf.release(), dest_size + 1);
+ guess_buf.reset(new_buf);
+ }
+ guess_size = dest_size;
+ guess_buf.get()[guess_size] = '\0';
+ }
+ dest_buf = guess_buf.release();
+ } else {
+ CFX_ArrayTemplate<uint8_t*> result_tmp_bufs;
+ uint8_t* cur_buf = guess_buf.release();
+ while (1) {
+ int32_t ret = FPDFAPI_FlateOutput(context, cur_buf, buf_size);
+ int32_t avail_buf_size = FPDFAPI_FlateGetAvailOut(context);
+ if (ret != Z_OK) {
+ last_buf_size = buf_size - avail_buf_size;
+ result_tmp_bufs.Add(cur_buf);
+ break;
+ }
+ if (avail_buf_size != 0) {
+ last_buf_size = buf_size - avail_buf_size;
+ result_tmp_bufs.Add(cur_buf);
+ break;
+ }
+
+ result_tmp_bufs.Add(cur_buf);
+ cur_buf = FX_Alloc(uint8_t, buf_size + 1);
+ cur_buf[buf_size] = '\0';
+ }
+ dest_size = FPDFAPI_FlateGetTotalOut(context);
+ offset = FPDFAPI_FlateGetTotalIn(context);
+ if (result_tmp_bufs.GetSize() == 1) {
+ dest_buf = result_tmp_bufs[0];
+ } else {
+ uint8_t* result_buf = FX_Alloc(uint8_t, dest_size);
+ FX_DWORD result_pos = 0;
+ for (int32_t i = 0; i < result_tmp_bufs.GetSize(); i++) {
+ uint8_t* tmp_buf = result_tmp_bufs[i];
+ FX_DWORD tmp_buf_size = buf_size;
+ if (i == result_tmp_bufs.GetSize() - 1) {
+ tmp_buf_size = last_buf_size;
+ }
+ FXSYS_memcpy(result_buf + result_pos, tmp_buf, tmp_buf_size);
+ result_pos += tmp_buf_size;
+ FX_Free(result_tmp_bufs[i]);
+ }
+ dest_buf = result_buf;
+ }
+ }
+ FPDFAPI_FlateEnd(context);
+}
+
+} // namespace
+
class CCodec_FlateScanlineDecoder : public CCodec_ScanlineDecoder {
public:
CCodec_FlateScanlineDecoder();
@@ -761,113 +885,7 @@ uint8_t* CCodec_FlateScanlineDecoder::v_GetNextLine() {
FX_DWORD CCodec_FlateScanlineDecoder::GetSrcOffset() {
return FPDFAPI_FlateGetTotalIn(m_pFlate);
}
-static void FlateUncompress(const uint8_t* src_buf,
- FX_DWORD src_size,
- FX_DWORD orig_size,
- uint8_t*& dest_buf,
- FX_DWORD& dest_size,
- FX_DWORD& offset) {
- const FX_BOOL useOldImpl = src_size < 10240;
- FX_DWORD guess_size = orig_size ? orig_size : src_size * 2;
- FX_DWORD alloc_step =
- orig_size ? 10240 : (src_size < 10240 ? 10240 : src_size);
- static const FX_DWORD kMaxInitialAllocSize = 10000000;
- if (guess_size > kMaxInitialAllocSize) {
- guess_size = kMaxInitialAllocSize;
- alloc_step = kMaxInitialAllocSize;
- }
- FX_DWORD buf_size = guess_size;
- FX_DWORD last_buf_size = buf_size;
- void* context = nullptr;
- uint8_t* guess_buf = FX_Alloc(uint8_t, guess_size + 1);
- uint8_t* cur_buf = guess_buf;
- guess_buf[guess_size] = '\0';
- context = FPDFAPI_FlateInit(my_alloc_func, my_free_func);
- if (!context)
- goto fail;
- FPDFAPI_FlateInput(context, src_buf, src_size);
- if (useOldImpl) {
- while (1) {
- int32_t ret = FPDFAPI_FlateOutput(context, cur_buf, buf_size);
- if (ret != Z_OK)
- break;
- int32_t avail_buf_size = FPDFAPI_FlateGetAvailOut(context);
- if (avail_buf_size != 0)
- break;
-
- // |avail_buf_size| == 0 case.
- FX_DWORD old_size = guess_size;
- guess_size += alloc_step;
- if (guess_size < old_size || guess_size + 1 < guess_size)
- goto fail;
- guess_buf = FX_Realloc(uint8_t, guess_buf, guess_size + 1);
- if (!guess_buf)
- goto fail;
- guess_buf[guess_size] = '\0';
- cur_buf = guess_buf + old_size;
- buf_size = guess_size - old_size;
- }
- dest_size = FPDFAPI_FlateGetTotalOut(context);
- offset = FPDFAPI_FlateGetTotalIn(context);
- if (guess_size / 2 > dest_size) {
- guess_buf = FX_Realloc(uint8_t, guess_buf, dest_size + 1);
- if (!guess_buf)
- goto fail;
- guess_size = dest_size;
- guess_buf[guess_size] = '\0';
- }
- dest_buf = guess_buf;
- } else {
- CFX_ArrayTemplate<uint8_t*> result_tmp_bufs;
- while (1) {
- int32_t ret = FPDFAPI_FlateOutput(context, cur_buf, buf_size);
- int32_t avail_buf_size = FPDFAPI_FlateGetAvailOut(context);
- if (ret != Z_OK) {
- last_buf_size = buf_size - avail_buf_size;
- result_tmp_bufs.Add(cur_buf);
- break;
- }
- if (avail_buf_size != 0) {
- last_buf_size = buf_size - avail_buf_size;
- result_tmp_bufs.Add(cur_buf);
- break;
- }
-
- // |avail_buf_size| == 0 case.
- result_tmp_bufs.Add(cur_buf);
- cur_buf = FX_Alloc(uint8_t, buf_size + 1);
- cur_buf[buf_size] = '\0';
- }
- dest_size = FPDFAPI_FlateGetTotalOut(context);
- offset = FPDFAPI_FlateGetTotalIn(context);
- if (result_tmp_bufs.GetSize() == 1) {
- dest_buf = result_tmp_bufs[0];
- } else {
- uint8_t* result_buf = FX_Alloc(uint8_t, dest_size);
- FX_DWORD result_pos = 0;
- for (int32_t i = 0; i < result_tmp_bufs.GetSize(); i++) {
- uint8_t* tmp_buf = result_tmp_bufs[i];
- FX_DWORD tmp_buf_size = buf_size;
- if (i == result_tmp_bufs.GetSize() - 1) {
- tmp_buf_size = last_buf_size;
- }
- FXSYS_memcpy(result_buf + result_pos, tmp_buf, tmp_buf_size);
- result_pos += tmp_buf_size;
- FX_Free(result_tmp_bufs[i]);
- }
- dest_buf = result_buf;
- }
- }
- FPDFAPI_FlateEnd(context);
- return;
-
-fail:
- FX_Free(guess_buf);
- dest_buf = nullptr;
- dest_size = 0;
- return;
-}
ICodec_ScanlineDecoder* CCodec_FlateModule::CreateDecoder(
const uint8_t* src_buf,
FX_DWORD src_size,