Cleanup in CCodec_FaxModule
This CL moves FaxG4Decode to the class where it's implemented. It should
remain there because it calls FaxG4GetRow, declared and used in the cpp
file. Do some ++ cleanup while at it.
This CL also makes CCodec_FaxModule own some methods that were
namespaced since doing so allows removing a bunch of parameters.
Change-Id: I24787f5668c7273b9bdb4009c3d0b29590c5552f
Reviewed-on: https://pdfium-review.googlesource.com/42950
Commit-Queue: Nicolás Peña Moreno <npm@chromium.org>
Reviewed-by: Tom Sepez <tsepez@chromium.org>
diff --git a/core/fxcodec/codec/ccodec_faxmodule.cpp b/core/fxcodec/codec/ccodec_faxmodule.cpp
index faa40da..423dfe6 100644
--- a/core/fxcodec/codec/ccodec_faxmodule.cpp
+++ b/core/fxcodec/codec/ccodec_faxmodule.cpp
@@ -555,25 +555,26 @@
return std::min(static_cast<size_t>((m_bitpos + 7) / 8), m_SrcSpan.size());
}
-void FaxG4Decode(const uint8_t* src_buf,
- uint32_t src_size,
- int* pbitpos,
- uint8_t* dest_buf,
- int width,
- int height,
- int pitch) {
+// static
+int CCodec_FaxModule::FaxG4Decode(const uint8_t* src_buf,
+ uint32_t src_size,
+ int starting_bitpos,
+ int width,
+ int height,
+ int pitch,
+ uint8_t* dest_buf) {
if (pitch == 0)
pitch = (width + 7) / 8;
std::vector<uint8_t> ref_buf(pitch, 0xff);
- int bitpos = *pbitpos;
- for (int iRow = 0; iRow < height; iRow++) {
+ int bitpos = starting_bitpos;
+ for (int iRow = 0; iRow < height; ++iRow) {
uint8_t* line_buf = dest_buf + iRow * pitch;
memset(line_buf, 0xff, pitch);
FaxG4GetRow(src_buf, src_size << 3, &bitpos, line_buf, ref_buf, width);
memcpy(ref_buf.data(), line_buf, pitch);
}
- *pbitpos = bitpos;
+ return bitpos;
}
std::unique_ptr<CCodec_ScanlineDecoder> CCodec_FaxModule::CreateDecoder(
@@ -647,90 +648,6 @@
0x17, 12, 0x1c, 12, 0x1d, 12, 0x1e, 12, 0x1f, 12,
};
-void AddBitStream(uint8_t* dest_buf, int* dest_bitpos, int data, int bitlen) {
- for (int i = bitlen - 1; i >= 0; i--) {
- if (data & (1 << i))
- dest_buf[*dest_bitpos / 8] |= 1 << (7 - *dest_bitpos % 8);
- (*dest_bitpos)++;
- }
-}
-
-void FaxEncodeRun(uint8_t* dest_buf, int* dest_bitpos, int run, bool bWhite) {
- while (run >= 2560) {
- AddBitStream(dest_buf, dest_bitpos, 0x1f, 12);
- run -= 2560;
- }
- if (run >= 64) {
- int markup = run - run % 64;
- const uint8_t* p = bWhite ? WhiteRunMarkup : BlackRunMarkup;
- p += (markup / 64 - 1) * 2;
- AddBitStream(dest_buf, dest_bitpos, *p, p[1]);
- }
- run %= 64;
- const uint8_t* p = bWhite ? WhiteRunTerminator : BlackRunTerminator;
- p += run * 2;
- AddBitStream(dest_buf, dest_bitpos, *p, p[1]);
-}
-
-void FaxEncode2DLine(uint8_t* dest_buf,
- int* dest_bitpos,
- const uint8_t* src_buf,
- const std::vector<uint8_t>& ref_buf,
- int cols) {
- int a0 = -1;
- bool a0color = true;
- while (1) {
- int a1 = FindBit(src_buf, cols, a0 + 1, !a0color);
- int b1;
- int b2;
- FaxG4FindB1B2(ref_buf, cols, a0, a0color, &b1, &b2);
- if (b2 < a1) {
- *dest_bitpos += 3;
- dest_buf[*dest_bitpos / 8] |= 1 << (7 - *dest_bitpos % 8);
- (*dest_bitpos)++;
- a0 = b2;
- } else if (a1 - b1 <= 3 && b1 - a1 <= 3) {
- int delta = a1 - b1;
- switch (delta) {
- case 0:
- dest_buf[*dest_bitpos / 8] |= 1 << (7 - *dest_bitpos % 8);
- break;
- case 1:
- case 2:
- case 3:
- *dest_bitpos += delta == 1 ? 1 : delta + 2;
- dest_buf[*dest_bitpos / 8] |= 1 << (7 - *dest_bitpos % 8);
- (*dest_bitpos)++;
- dest_buf[*dest_bitpos / 8] |= 1 << (7 - *dest_bitpos % 8);
- break;
- case -1:
- case -2:
- case -3:
- *dest_bitpos += delta == -1 ? 1 : -delta + 2;
- dest_buf[*dest_bitpos / 8] |= 1 << (7 - *dest_bitpos % 8);
- (*dest_bitpos)++;
- break;
- }
- (*dest_bitpos)++;
- a0 = a1;
- a0color = !a0color;
- } else {
- int a2 = FindBit(src_buf, cols, a1 + 1, a0color);
- (*dest_bitpos)++;
- (*dest_bitpos)++;
- dest_buf[*dest_bitpos / 8] |= 1 << (7 - *dest_bitpos % 8);
- (*dest_bitpos)++;
- if (a0 < 0)
- a0 = 0;
- FaxEncodeRun(dest_buf, dest_bitpos, a1 - a0, a0color);
- FaxEncodeRun(dest_buf, dest_bitpos, a2 - a1, !a0color);
- a0 = a2;
- }
- if (a0 >= cols)
- return;
- }
-}
-
class CCodec_FaxEncoder {
public:
CCodec_FaxEncoder(const uint8_t* src_buf, int width, int height, int pitch);
@@ -739,9 +656,14 @@
uint32_t* dest_size);
private:
+ void FaxEncode2DLine(const uint8_t* src_buf);
+ void FaxEncodeRun(int run, bool bWhite);
+ void AddBitStream(int data, int bitlen);
+
CFX_BinaryBuf m_DestBuf;
std::vector<uint8_t> m_RefLine;
uint8_t* m_pLineBuf;
+ int m_DestBitpos;
const int m_Cols;
const int m_Rows;
const int m_Pitch;
@@ -763,22 +685,101 @@
FX_Free(m_pLineBuf);
}
+void CCodec_FaxEncoder::AddBitStream(int data, int bitlen) {
+ for (int i = bitlen - 1; i >= 0; --i, ++m_DestBitpos) {
+ if (data & (1 << i))
+ m_pLineBuf[m_DestBitpos / 8] |= 1 << (7 - m_DestBitpos % 8);
+ }
+}
+
+void CCodec_FaxEncoder::FaxEncodeRun(int run, bool bWhite) {
+ while (run >= 2560) {
+ AddBitStream(0x1f, 12);
+ run -= 2560;
+ }
+ if (run >= 64) {
+ int markup = run - run % 64;
+ const uint8_t* p = bWhite ? WhiteRunMarkup : BlackRunMarkup;
+ p += (markup / 64 - 1) * 2;
+ AddBitStream(*p, p[1]);
+ }
+ run %= 64;
+ const uint8_t* p = bWhite ? WhiteRunTerminator : BlackRunTerminator;
+ p += run * 2;
+ AddBitStream(*p, p[1]);
+}
+
+void CCodec_FaxEncoder::FaxEncode2DLine(const uint8_t* src_buf) {
+ int a0 = -1;
+ bool a0color = true;
+ while (1) {
+ int a1 = FindBit(src_buf, m_Cols, a0 + 1, !a0color);
+ int b1;
+ int b2;
+ FaxG4FindB1B2(m_RefLine, m_Cols, a0, a0color, &b1, &b2);
+ if (b2 < a1) {
+ m_DestBitpos += 3;
+ m_pLineBuf[m_DestBitpos / 8] |= 1 << (7 - m_DestBitpos % 8);
+ ++m_DestBitpos;
+ a0 = b2;
+ } else if (a1 - b1 <= 3 && b1 - a1 <= 3) {
+ int delta = a1 - b1;
+ switch (delta) {
+ case 0:
+ m_pLineBuf[m_DestBitpos / 8] |= 1 << (7 - m_DestBitpos % 8);
+ break;
+ case 1:
+ case 2:
+ case 3:
+ m_DestBitpos += delta == 1 ? 1 : delta + 2;
+ m_pLineBuf[m_DestBitpos / 8] |= 1 << (7 - m_DestBitpos % 8);
+ ++m_DestBitpos;
+ m_pLineBuf[m_DestBitpos / 8] |= 1 << (7 - m_DestBitpos % 8);
+ break;
+ case -1:
+ case -2:
+ case -3:
+ m_DestBitpos += delta == -1 ? 1 : -delta + 2;
+ m_pLineBuf[m_DestBitpos / 8] |= 1 << (7 - m_DestBitpos % 8);
+ ++m_DestBitpos;
+ break;
+ }
+ ++m_DestBitpos;
+ a0 = a1;
+ a0color = !a0color;
+ } else {
+ int a2 = FindBit(src_buf, m_Cols, a1 + 1, a0color);
+ ++m_DestBitpos;
+ ++m_DestBitpos;
+ m_pLineBuf[m_DestBitpos / 8] |= 1 << (7 - m_DestBitpos % 8);
+ ++m_DestBitpos;
+ if (a0 < 0)
+ a0 = 0;
+ FaxEncodeRun(a1 - a0, a0color);
+ FaxEncodeRun(a2 - a1, !a0color);
+ a0 = a2;
+ }
+ if (a0 >= m_Cols)
+ return;
+ }
+}
+
void CCodec_FaxEncoder::Encode(
std::unique_ptr<uint8_t, FxFreeDeleter>* dest_buf,
uint32_t* dest_size) {
- int dest_bitpos = 0;
+ m_DestBitpos = 0;
uint8_t last_byte = 0;
- for (int i = 0; i < m_Rows; i++) {
+ for (int i = 0; i < m_Rows; ++i) {
const uint8_t* scan_line = m_pSrcBuf + i * m_Pitch;
memset(m_pLineBuf, 0, m_Pitch * 8);
m_pLineBuf[0] = last_byte;
- FaxEncode2DLine(m_pLineBuf, &dest_bitpos, scan_line, m_RefLine, m_Cols);
- m_DestBuf.AppendBlock(m_pLineBuf, dest_bitpos / 8);
- last_byte = m_pLineBuf[dest_bitpos / 8];
- dest_bitpos %= 8;
+ FaxEncode2DLine(scan_line);
+ m_DestBuf.AppendBlock(m_pLineBuf, m_DestBitpos / 8);
+ last_byte = m_pLineBuf[m_DestBitpos / 8];
+ m_DestBitpos %= 8;
memcpy(m_RefLine.data(), scan_line, m_Pitch);
}
- if (dest_bitpos)
+ if (m_DestBitpos)
m_DestBuf.AppendByte(last_byte);
*dest_size = m_DestBuf.GetSize();
*dest_buf = m_DestBuf.DetachBuffer();
diff --git a/core/fxcodec/codec/ccodec_faxmodule.h b/core/fxcodec/codec/ccodec_faxmodule.h
index 3d546d7..e43aea3 100644
--- a/core/fxcodec/codec/ccodec_faxmodule.h
+++ b/core/fxcodec/codec/ccodec_faxmodule.h
@@ -36,6 +36,15 @@
std::unique_ptr<uint8_t, FxFreeDeleter>* dest_buf,
uint32_t* dest_size);
#endif // _FX_PLATFORM_ == _FX_PLATFORM_WINDOWS_
+
+ // Return the ending bit position.
+ static int FaxG4Decode(const uint8_t* src_buf,
+ uint32_t src_size,
+ int starting_bitpos,
+ int width,
+ int height,
+ int pitch,
+ uint8_t* dest_buf);
};
#endif // CORE_FXCODEC_CODEC_CCODEC_FAXMODULE_H_
diff --git a/core/fxcodec/fx_codec.h b/core/fxcodec/fx_codec.h
index 8e96676..3b15fd7 100644
--- a/core/fxcodec/fx_codec.h
+++ b/core/fxcodec/fx_codec.h
@@ -151,13 +151,6 @@
uint8_t m,
uint8_t y,
uint8_t k);
-void FaxG4Decode(const uint8_t* src_buf,
- uint32_t src_size,
- int* pbitpos,
- uint8_t* dest_buf,
- int width,
- int height,
- int pitch);
FX_SAFE_UINT32 CalculatePitch8(uint32_t bpc, uint32_t components, int width);
FX_SAFE_UINT32 CalculatePitch32(int bpp, int width);
diff --git a/core/fxcodec/jbig2/JBig2_GrdProc.cpp b/core/fxcodec/jbig2/JBig2_GrdProc.cpp
index d0fe440..278b5c0 100644
--- a/core/fxcodec/jbig2/JBig2_GrdProc.cpp
+++ b/core/fxcodec/jbig2/JBig2_GrdProc.cpp
@@ -10,6 +10,7 @@
#include <memory>
#include <utility>
+#include "core/fxcodec/codec/ccodec_faxmodule.h"
#include "core/fxcodec/fx_codec.h"
#include "core/fxcodec/jbig2/JBig2_ArithDecoder.h"
#include "core/fxcodec/jbig2/JBig2_BitStream.h"
@@ -451,18 +452,18 @@
FXCODEC_STATUS CJBig2_GRDProc::StartDecodeMMR(
std::unique_ptr<CJBig2_Image>* pImage,
CJBig2_BitStream* pStream) {
- int bitpos, i;
auto image = pdfium::MakeUnique<CJBig2_Image>(GBW, GBH);
if (!image->data()) {
*pImage = nullptr;
m_ProssiveStatus = FXCODEC_STATUS_ERROR;
return m_ProssiveStatus;
}
- bitpos = static_cast<int>(pStream->getBitPos());
- FaxG4Decode(pStream->getBuf(), pStream->getLength(), &bitpos, image->data(),
- GBW, GBH, image->stride());
+ int bitpos = static_cast<int>(pStream->getBitPos());
+ bitpos = CCodec_FaxModule::FaxG4Decode(pStream->getBuf(),
+ pStream->getLength(), bitpos, GBW, GBH,
+ image->stride(), image->data());
pStream->setBitPos(bitpos);
- for (i = 0; (uint32_t)i < image->stride() * GBH; ++i)
+ for (uint32_t i = 0; i < image->stride() * GBH; ++i)
image->data()[i] = ~image->data()[i];
m_ProssiveStatus = FXCODEC_STATUS_DECODE_FINISH;
*pImage = std::move(image);