summaryrefslogtreecommitdiff
path: root/core/fxcodec
diff options
context:
space:
mode:
Diffstat (limited to 'core/fxcodec')
-rw-r--r--core/fxcodec/codec/fx_codec_flate.cpp235
1 files changed, 141 insertions, 94 deletions
diff --git a/core/fxcodec/codec/fx_codec_flate.cpp b/core/fxcodec/codec/fx_codec_flate.cpp
index 2270de5eb3..f0cbd6732a 100644
--- a/core/fxcodec/codec/fx_codec_flate.cpp
+++ b/core/fxcodec/codec/fx_codec_flate.cpp
@@ -573,35 +573,19 @@ class CCodec_FlateScanlineDecoder : public CCodec_ScanlineDecoder {
int width,
int height,
int nComps,
- int bpc,
- int predictor,
- int Colors,
- int BitsPerComponent,
- int Columns);
+ int bpc);
~CCodec_FlateScanlineDecoder() override;
- // CCodec_ScanlineDecoder
+ // CCodec_ScanlineDecoder:
bool v_Rewind() override;
uint8_t* v_GetNextLine() override;
uint32_t GetSrcOffset() override;
- private:
+ protected:
void* m_pFlate = nullptr;
const uint8_t* const m_SrcBuf;
const uint32_t m_SrcSize;
uint8_t* const m_pScanline;
- uint8_t* m_pLastLine = nullptr;
- uint8_t* m_pPredictBuffer = nullptr;
- uint8_t* m_pPredictRaw = nullptr;
-
- const PredictorType m_Predictor;
-
- // These are only used if |m_Predictor| != |kNone|.
- int m_Colors = 0;
- int m_BitsPerComponent = 0;
- int m_Columns = 0;
- uint32_t m_PredictPitch = 0;
- size_t m_LeftOver = 0;
};
CCodec_FlateScanlineDecoder::CCodec_FlateScanlineDecoder(const uint8_t* src_buf,
@@ -609,11 +593,7 @@ CCodec_FlateScanlineDecoder::CCodec_FlateScanlineDecoder(const uint8_t* src_buf,
int width,
int height,
int nComps,
- int bpc,
- int predictor,
- int Colors,
- int BitsPerComponent,
- int Columns)
+ int bpc)
: CCodec_ScanlineDecoder(width,
height,
width,
@@ -623,30 +603,10 @@ CCodec_FlateScanlineDecoder::CCodec_FlateScanlineDecoder(const uint8_t* src_buf,
CalculatePitch8(bpc, nComps, width).ValueOrDie()),
m_SrcBuf(src_buf),
m_SrcSize(src_size),
- m_pScanline(FX_Alloc(uint8_t, m_Pitch)),
- m_Predictor(GetPredictor(predictor)) {
- if (m_Predictor != PredictorType::kNone) {
- if (BitsPerComponent * Colors * Columns == 0) {
- BitsPerComponent = m_bpc;
- Colors = m_nComps;
- Columns = m_OrigWidth;
- }
- m_Colors = Colors;
- m_BitsPerComponent = BitsPerComponent;
- m_Columns = Columns;
- m_PredictPitch =
- CalculatePitch8(m_BitsPerComponent, m_Colors, m_Columns).ValueOrDie();
- m_pLastLine = FX_Alloc(uint8_t, m_PredictPitch);
- m_pPredictRaw = FX_Alloc(uint8_t, m_PredictPitch + 1);
- m_pPredictBuffer = FX_Alloc(uint8_t, m_PredictPitch);
- }
-}
+ m_pScanline(FX_Alloc(uint8_t, m_Pitch)) {}
CCodec_FlateScanlineDecoder::~CCodec_FlateScanlineDecoder() {
FX_Free(m_pScanline);
- FX_Free(m_pLastLine);
- FX_Free(m_pPredictBuffer);
- FX_Free(m_pPredictRaw);
if (m_pFlate)
FlateEnd(m_pFlate);
}
@@ -660,57 +620,11 @@ bool CCodec_FlateScanlineDecoder::v_Rewind() {
return false;
FlateInput(m_pFlate, m_SrcBuf, m_SrcSize);
- m_LeftOver = 0;
return true;
}
uint8_t* CCodec_FlateScanlineDecoder::v_GetNextLine() {
- if (m_Predictor != PredictorType::kNone) {
- if (m_Pitch == m_PredictPitch) {
- if (m_Predictor == PredictorType::kPng) {
- FlateOutput(m_pFlate, m_pPredictRaw, m_PredictPitch + 1);
- PNG_PredictLine(m_pScanline, m_pPredictRaw, m_pLastLine,
- m_BitsPerComponent, m_Colors, m_Columns);
- memcpy(m_pLastLine, m_pScanline, m_PredictPitch);
- } else {
- ASSERT(m_Predictor == PredictorType::kFlate);
- FlateOutput(m_pFlate, m_pScanline, m_Pitch);
- TIFF_PredictLine(m_pScanline, m_PredictPitch, m_bpc, m_nComps,
- m_OutputWidth);
- }
- } else {
- size_t bytes_to_go = m_Pitch;
- size_t read_leftover =
- m_LeftOver > bytes_to_go ? bytes_to_go : m_LeftOver;
- if (read_leftover) {
- memcpy(m_pScanline, m_pPredictBuffer + m_PredictPitch - m_LeftOver,
- read_leftover);
- m_LeftOver -= read_leftover;
- bytes_to_go -= read_leftover;
- }
- while (bytes_to_go) {
- if (m_Predictor == PredictorType::kPng) {
- FlateOutput(m_pFlate, m_pPredictRaw, m_PredictPitch + 1);
- PNG_PredictLine(m_pPredictBuffer, m_pPredictRaw, m_pLastLine,
- m_BitsPerComponent, m_Colors, m_Columns);
- memcpy(m_pLastLine, m_pPredictBuffer, m_PredictPitch);
- } else {
- ASSERT(m_Predictor == PredictorType::kFlate);
- FlateOutput(m_pFlate, m_pPredictBuffer, m_PredictPitch);
- TIFF_PredictLine(m_pPredictBuffer, m_PredictPitch, m_BitsPerComponent,
- m_Colors, m_Columns);
- }
- size_t read_bytes =
- m_PredictPitch > bytes_to_go ? bytes_to_go : m_PredictPitch;
- memcpy(m_pScanline + m_Pitch - bytes_to_go, m_pPredictBuffer,
- read_bytes);
- m_LeftOver += m_PredictPitch - read_bytes;
- bytes_to_go -= read_bytes;
- }
- }
- } else {
- FlateOutput(m_pFlate, m_pScanline, m_Pitch);
- }
+ FlateOutput(m_pFlate, m_pScanline, m_Pitch);
return m_pScanline;
}
@@ -718,6 +632,134 @@ uint32_t CCodec_FlateScanlineDecoder::GetSrcOffset() {
return FlateGetPossiblyTruncatedTotalIn(m_pFlate);
}
+class CCodec_FlatePredictorScanlineDecoder
+ : public CCodec_FlateScanlineDecoder {
+ public:
+ CCodec_FlatePredictorScanlineDecoder(const uint8_t* src_buf,
+ uint32_t src_size,
+ int width,
+ int height,
+ int comps,
+ int bpc,
+ PredictorType predictor,
+ int Colors,
+ int BitsPerComponent,
+ int Columns);
+ ~CCodec_FlatePredictorScanlineDecoder() override;
+
+ // CCodec_ScanlineDecoder:
+ bool v_Rewind() override;
+ uint8_t* v_GetNextLine() override;
+
+ protected:
+ void GetNextLineWithPredictedPitch();
+ void GetNextLineWithoutPredictedPitch();
+
+ const PredictorType m_Predictor;
+ int m_Colors = 0;
+ int m_BitsPerComponent = 0;
+ int m_Columns = 0;
+ uint32_t m_PredictPitch = 0;
+ size_t m_LeftOver = 0;
+ uint8_t* m_pLastLine = nullptr;
+ uint8_t* m_pPredictBuffer = nullptr;
+ uint8_t* m_pPredictRaw = nullptr;
+};
+
+CCodec_FlatePredictorScanlineDecoder::CCodec_FlatePredictorScanlineDecoder(
+ const uint8_t* src_buf,
+ uint32_t src_size,
+ int width,
+ int height,
+ int comps,
+ int bpc,
+ PredictorType predictor,
+ int Colors,
+ int BitsPerComponent,
+ int Columns)
+ : CCodec_FlateScanlineDecoder(src_buf, src_size, width, height, comps, bpc),
+ m_Predictor(predictor) {
+ ASSERT(m_Predictor != PredictorType::kNone);
+ if (BitsPerComponent * Colors * Columns == 0) {
+ BitsPerComponent = m_bpc;
+ Colors = m_nComps;
+ Columns = m_OrigWidth;
+ }
+ m_Colors = Colors;
+ m_BitsPerComponent = BitsPerComponent;
+ m_Columns = Columns;
+ m_PredictPitch =
+ CalculatePitch8(m_BitsPerComponent, m_Colors, m_Columns).ValueOrDie();
+ m_pLastLine = FX_Alloc(uint8_t, m_PredictPitch);
+ m_pPredictBuffer = FX_Alloc(uint8_t, m_PredictPitch);
+ m_pPredictRaw = FX_Alloc(uint8_t, m_PredictPitch + 1);
+}
+
+CCodec_FlatePredictorScanlineDecoder::~CCodec_FlatePredictorScanlineDecoder() {
+ FX_Free(m_pLastLine);
+ FX_Free(m_pPredictBuffer);
+ FX_Free(m_pPredictRaw);
+}
+
+bool CCodec_FlatePredictorScanlineDecoder::v_Rewind() {
+ if (!CCodec_FlateScanlineDecoder::v_Rewind())
+ return false;
+
+ m_LeftOver = 0;
+ return true;
+}
+
+uint8_t* CCodec_FlatePredictorScanlineDecoder::v_GetNextLine() {
+ if (m_Pitch == m_PredictPitch)
+ GetNextLineWithPredictedPitch();
+ else
+ GetNextLineWithoutPredictedPitch();
+ return m_pScanline;
+}
+
+void CCodec_FlatePredictorScanlineDecoder::GetNextLineWithPredictedPitch() {
+ if (m_Predictor == PredictorType::kPng) {
+ FlateOutput(m_pFlate, m_pPredictRaw, m_PredictPitch + 1);
+ PNG_PredictLine(m_pScanline, m_pPredictRaw, m_pLastLine, m_BitsPerComponent,
+ m_Colors, m_Columns);
+ memcpy(m_pLastLine, m_pScanline, m_PredictPitch);
+ } else {
+ ASSERT(m_Predictor == PredictorType::kFlate);
+ FlateOutput(m_pFlate, m_pScanline, m_Pitch);
+ TIFF_PredictLine(m_pScanline, m_PredictPitch, m_bpc, m_nComps,
+ m_OutputWidth);
+ }
+}
+
+void CCodec_FlatePredictorScanlineDecoder::GetNextLineWithoutPredictedPitch() {
+ size_t bytes_to_go = m_Pitch;
+ size_t read_leftover = m_LeftOver > bytes_to_go ? bytes_to_go : m_LeftOver;
+ if (read_leftover) {
+ memcpy(m_pScanline, m_pPredictBuffer + m_PredictPitch - m_LeftOver,
+ read_leftover);
+ m_LeftOver -= read_leftover;
+ bytes_to_go -= read_leftover;
+ }
+ while (bytes_to_go) {
+ if (m_Predictor == PredictorType::kPng) {
+ FlateOutput(m_pFlate, m_pPredictRaw, m_PredictPitch + 1);
+ PNG_PredictLine(m_pPredictBuffer, m_pPredictRaw, m_pLastLine,
+ m_BitsPerComponent, m_Colors, m_Columns);
+ memcpy(m_pLastLine, m_pPredictBuffer, m_PredictPitch);
+ } else {
+ ASSERT(m_Predictor == PredictorType::kFlate);
+ FlateOutput(m_pFlate, m_pPredictBuffer, m_PredictPitch);
+ TIFF_PredictLine(m_pPredictBuffer, m_PredictPitch, m_BitsPerComponent,
+ m_Colors, m_Columns);
+ }
+ size_t read_bytes =
+ m_PredictPitch > bytes_to_go ? bytes_to_go : m_PredictPitch;
+ memcpy(m_pScanline + m_Pitch - bytes_to_go, m_pPredictBuffer, read_bytes);
+ m_LeftOver += m_PredictPitch - read_bytes;
+ bytes_to_go -= read_bytes;
+ }
+}
+
} // namespace
std::unique_ptr<CCodec_ScanlineDecoder> CCodec_FlateModule::CreateDecoder(
@@ -731,8 +773,13 @@ std::unique_ptr<CCodec_ScanlineDecoder> CCodec_FlateModule::CreateDecoder(
int Colors,
int BitsPerComponent,
int Columns) {
- return pdfium::MakeUnique<CCodec_FlateScanlineDecoder>(
- src_buf, src_size, width, height, nComps, bpc, predictor, Colors,
+ PredictorType predictor_type = GetPredictor(predictor);
+ if (predictor_type == PredictorType::kNone) {
+ return pdfium::MakeUnique<CCodec_FlateScanlineDecoder>(
+ src_buf, src_size, width, height, nComps, bpc);
+ }
+ return pdfium::MakeUnique<CCodec_FlatePredictorScanlineDecoder>(
+ src_buf, src_size, width, height, nComps, bpc, predictor_type, Colors,
BitsPerComponent, Columns);
}