summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/include/fxcodec/fx_codec.h20
-rw-r--r--core/src/fpdfapi/fpdf_parser/fpdf_parser_filters.cpp29
-rw-r--r--core/src/fxcodec/codec/fx_codec_fax.cpp682
-rw-r--r--core/src/fxcodec/jbig2/JBig2_Define.h10
-rw-r--r--core/src/fxcodec/jbig2/JBig2_GrdProc.cpp5
5 files changed, 380 insertions, 366 deletions
diff --git a/core/include/fxcodec/fx_codec.h b/core/include/fxcodec/fx_codec.h
index 06eaf85063..796fbf0c11 100644
--- a/core/include/fxcodec/fx_codec.h
+++ b/core/include/fxcodec/fx_codec.h
@@ -530,4 +530,24 @@ class IFX_DIBAttributeExif {
virtual FX_BOOL GetInfo(FX_WORD tag, void* val) = 0;
};
+FX_BOOL FaxSkipEOL(const uint8_t* src_buf, int bitsize, int& bitpos);
+FX_BOOL FaxGet1DLine(const uint8_t* src_buf,
+ int bitsize,
+ int& bitpos,
+ uint8_t* dest_buf,
+ int columns);
+FX_BOOL FaxG4GetRow(const uint8_t* src_buf,
+ int bitsize,
+ int& bitpos,
+ uint8_t* dest_buf,
+ const uint8_t* ref_buf,
+ int columns);
+void FaxG4Decode(const uint8_t* src_buf,
+ FX_DWORD src_size,
+ int* pbitpos,
+ uint8_t* dest_buf,
+ int width,
+ int height,
+ int pitch);
+
#endif // CORE_INCLUDE_FXCODEC_FX_CODEC_H_
diff --git a/core/src/fpdfapi/fpdf_parser/fpdf_parser_filters.cpp b/core/src/fpdfapi/fpdf_parser/fpdf_parser_filters.cpp
index 8cb432029c..28f95adf31 100644
--- a/core/src/fpdfapi/fpdf_parser/fpdf_parser_filters.cpp
+++ b/core/src/fpdfapi/fpdf_parser/fpdf_parser_filters.cpp
@@ -846,18 +846,7 @@ void CPDF_FaxFilter::v_FilterFinish(CFX_BinaryBuf& dest_buf) {
ProcessData(m_InputBuf.GetBuffer(), m_InputBuf.GetSize(), m_InputBitPos, TRUE,
dest_buf);
}
-FX_BOOL _FaxSkipEOL(const uint8_t* src_buf, int bitsize, int& bitpos);
-FX_BOOL _FaxG4GetRow(const uint8_t* src_buf,
- int bitsize,
- int& bitpos,
- uint8_t* dest_buf,
- const uint8_t* ref_buf,
- int columns);
-FX_BOOL _FaxGet1DLine(const uint8_t* src_buf,
- int bitsize,
- int& bitpos,
- uint8_t* dest_buf,
- int columns);
+
void CPDF_FaxFilter::ProcessData(const uint8_t* src_buf,
FX_DWORD src_size,
int& bitpos,
@@ -893,15 +882,15 @@ void CPDF_FaxFilter::ProcessData(const uint8_t* src_buf,
FX_BOOL CPDF_FaxFilter::ReadLine(const uint8_t* src_buf,
int bitsize,
int& bitpos) {
- if (!_FaxSkipEOL(src_buf, bitsize, bitpos)) {
+ if (!FaxSkipEOL(src_buf, bitsize, bitpos)) {
return FALSE;
}
FX_BOOL ret;
if (m_Encoding < 0) {
- ret = _FaxG4GetRow(src_buf, bitsize, bitpos, m_pScanlineBuf, m_pRefBuf,
- m_nColumns);
+ ret = FaxG4GetRow(src_buf, bitsize, bitpos, m_pScanlineBuf, m_pRefBuf,
+ m_nColumns);
} else if (m_Encoding == 0) {
- ret = _FaxGet1DLine(src_buf, bitsize, bitpos, m_pScanlineBuf, m_nColumns);
+ ret = FaxGet1DLine(src_buf, bitsize, bitpos, m_pScanlineBuf, m_nColumns);
} else {
if (bitpos == bitsize) {
return FALSE;
@@ -909,17 +898,17 @@ FX_BOOL CPDF_FaxFilter::ReadLine(const uint8_t* src_buf,
FX_BOOL bNext1D = src_buf[bitpos / 8] & (1 << (7 - bitpos % 8));
bitpos++;
if (bNext1D) {
- ret = _FaxGet1DLine(src_buf, bitsize, bitpos, m_pScanlineBuf, m_nColumns);
+ ret = FaxGet1DLine(src_buf, bitsize, bitpos, m_pScanlineBuf, m_nColumns);
} else {
- ret = _FaxG4GetRow(src_buf, bitsize, bitpos, m_pScanlineBuf, m_pRefBuf,
- m_nColumns);
+ ret = FaxG4GetRow(src_buf, bitsize, bitpos, m_pScanlineBuf, m_pRefBuf,
+ m_nColumns);
}
}
if (!ret) {
return FALSE;
}
if (m_bEndOfLine)
- if (!_FaxSkipEOL(src_buf, bitsize, bitpos)) {
+ if (!FaxSkipEOL(src_buf, bitsize, bitpos)) {
return FALSE;
}
if (m_bByteAlign) {
diff --git a/core/src/fxcodec/codec/fx_codec_fax.cpp b/core/src/fxcodec/codec/fx_codec_fax.cpp
index 394e22b013..ff9d45d256 100644
--- a/core/src/fxcodec/codec/fx_codec_fax.cpp
+++ b/core/src/fxcodec/codec/fx_codec_fax.cpp
@@ -6,6 +6,9 @@
#include "../../../include/fxcodec/fx_codec.h"
#include "codec_int.h"
+
+namespace {
+
const uint8_t OneLeadPos[256] = {
8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
@@ -33,7 +36,7 @@ const uint8_t ZeroLeadPos[256] = {
4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 7, 8,
};
-int _FindBit(const uint8_t* data_buf, int max_pos, int start_pos, int bit) {
+int FindBit(const uint8_t* data_buf, int max_pos, int start_pos, int bit) {
if (start_pos >= max_pos) {
return max_pos;
}
@@ -68,33 +71,32 @@ int _FindBit(const uint8_t* data_buf, int max_pos, int start_pos, int bit) {
}
return pos;
}
-void _FaxG4FindB1B2(const uint8_t* ref_buf,
- int columns,
- int a0,
- FX_BOOL a0color,
- int& b1,
- int& b2) {
- if (a0color) {
- a0color = 1;
- }
+
+void FaxG4FindB1B2(const uint8_t* ref_buf,
+ int columns,
+ int a0,
+ bool a0color,
+ int& b1,
+ int& b2) {
uint8_t first_bit =
(a0 < 0) ? 1 : ((ref_buf[a0 / 8] & (1 << (7 - a0 % 8))) != 0);
- b1 = _FindBit(ref_buf, columns, a0 + 1, !first_bit);
+ b1 = FindBit(ref_buf, columns, a0 + 1, !first_bit);
if (b1 >= columns) {
b1 = b2 = columns;
return;
}
if (first_bit == !a0color) {
- b1 = _FindBit(ref_buf, columns, b1 + 1, first_bit);
+ b1 = FindBit(ref_buf, columns, b1 + 1, first_bit);
first_bit = !first_bit;
}
if (b1 >= columns) {
b1 = b2 = columns;
return;
}
- b2 = _FindBit(ref_buf, columns, b1 + 1, first_bit);
+ b2 = FindBit(ref_buf, columns, b1 + 1, first_bit);
}
-void _FaxFillBits(uint8_t* dest_buf, int columns, int startpos, int endpos) {
+
+void FaxFillBits(uint8_t* dest_buf, int columns, int startpos, int endpos) {
if (startpos < 0) {
startpos = 0;
}
@@ -126,6 +128,7 @@ void _FaxFillBits(uint8_t* dest_buf, int columns, int startpos, int endpos) {
FXSYS_memset(dest_buf + first_byte + 1, 0, last_byte - first_byte - 1);
}
}
+
#define NEXTBIT \
src_buf[bitpos / 8] & (1 << (7 - bitpos % 8)); \
bitpos++;
@@ -134,7 +137,8 @@ void _FaxFillBits(uint8_t* dest_buf, int columns, int startpos, int endpos) {
if (bit) \
code++;
#define GETBIT(bitpos) src_buf[bitpos / 8] & (1 << (7 - bitpos % 8))
-static const uint8_t FaxBlackRunIns[] = {
+
+const uint8_t FaxBlackRunIns[] = {
0, 2, 0x02, 3, 0, 0x03,
2, 0, 2, 0x02, 1, 0,
0x03, 4, 0, 2, 0x02, 6,
@@ -190,7 +194,8 @@ static const uint8_t FaxBlackRunIns[] = {
960 / 256, 0x74, 1024 % 256, 1024 / 256, 0x75, 1088 % 256,
1088 / 256, 0x76, 1152 % 256, 1152 / 256, 0x77, 1216 % 256,
1216 / 256, 0xff};
-static const uint8_t FaxWhiteRunIns[] = {
+
+const uint8_t FaxWhiteRunIns[] = {
0, 0, 0, 6, 0x07, 2,
0, 0x08, 3, 0, 0x0B, 4,
0, 0x0C, 5, 0, 0x0E, 6,
@@ -247,10 +252,11 @@ static const uint8_t FaxWhiteRunIns[] = {
0x1e, 2496 % 256, 2496 / 256, 0x1f, 2560 % 256, 2560 / 256,
0xff,
};
-int _FaxGetRun(const uint8_t* ins_array,
- const uint8_t* src_buf,
- int& bitpos,
- int bitsize) {
+
+int FaxGetRun(const uint8_t* ins_array,
+ const uint8_t* src_buf,
+ int& bitpos,
+ int bitsize) {
FX_DWORD code = 0;
int ins_off = 0;
while (1) {
@@ -274,188 +280,137 @@ int _FaxGetRun(const uint8_t* ins_array,
}
}
}
-FX_BOOL _FaxG4GetRow(const uint8_t* src_buf,
- int bitsize,
- int& bitpos,
- uint8_t* dest_buf,
- const uint8_t* ref_buf,
- int columns) {
- int a0 = -1, a0color = 1;
- while (1) {
- if (bitpos >= bitsize) {
- return FALSE;
- }
- int a1, a2, b1, b2;
- _FaxG4FindB1B2(ref_buf, columns, a0, a0color, b1, b2);
- FX_BOOL bit = NEXTBIT;
- int v_delta = 0;
- if (bit) {
- } else {
- if (bitpos >= bitsize) {
- return FALSE;
- }
- FX_BOOL bit1 = NEXTBIT;
- if (bitpos >= bitsize) {
- return FALSE;
- }
- FX_BOOL bit2 = NEXTBIT;
- if (bit1 && bit2) {
- v_delta = 1;
- } else if (bit1) {
- v_delta = -1;
- } else if (bit2) {
- int run_len1 = 0;
- while (1) {
- int run = _FaxGetRun(a0color ? FaxWhiteRunIns : FaxBlackRunIns,
- src_buf, bitpos, bitsize);
- run_len1 += run;
- if (run < 64) {
- break;
- }
- }
- if (a0 < 0) {
- run_len1++;
- }
- a1 = a0 + run_len1;
- if (!a0color) {
- _FaxFillBits(dest_buf, columns, a0, a1);
- }
- int run_len2 = 0;
- while (1) {
- int run = _FaxGetRun(a0color ? FaxBlackRunIns : FaxWhiteRunIns,
- src_buf, bitpos, bitsize);
- run_len2 += run;
- if (run < 64) {
- break;
- }
- }
- a2 = a1 + run_len2;
- if (a0color) {
- _FaxFillBits(dest_buf, columns, a1, a2);
- }
- a0 = a2;
- if (a0 < columns) {
- continue;
- }
- return TRUE;
- } else {
- if (bitpos >= bitsize) {
- return FALSE;
- }
- bit = NEXTBIT;
- if (bit) {
- if (!a0color) {
- _FaxFillBits(dest_buf, columns, a0, b2);
- }
- if (b2 >= columns) {
- return TRUE;
- }
- a0 = b2;
- continue;
- } else {
- if (bitpos >= bitsize) {
- return FALSE;
- }
- FX_BOOL bit1 = NEXTBIT;
- if (bitpos >= bitsize) {
- return FALSE;
- }
- FX_BOOL bit2 = NEXTBIT;
- if (bit1 && bit2) {
- v_delta = 2;
- } else if (bit1) {
- v_delta = -2;
- } else if (bit2) {
- if (bitpos >= bitsize) {
- return FALSE;
- }
- bit = NEXTBIT;
- if (bit) {
- v_delta = 3;
- } else {
- v_delta = -3;
- }
- } else {
- if (bitpos >= bitsize) {
- return FALSE;
- }
- bit = NEXTBIT;
- if (bit) {
- bitpos += 3;
- continue;
- } else {
- bitpos += 5;
- return TRUE;
- }
- }
- }
- }
- }
- a1 = b1 + v_delta;
- if (!a0color) {
- _FaxFillBits(dest_buf, columns, a0, a1);
- }
- if (a1 >= columns) {
- return TRUE;
+
+const uint8_t BlackRunTerminator[128] = {
+ 0x37, 10, 0x02, 3, 0x03, 2, 0x02, 2, 0x03, 3, 0x03, 4, 0x02, 4,
+ 0x03, 5, 0x05, 6, 0x04, 6, 0x04, 7, 0x05, 7, 0x07, 7, 0x04, 8,
+ 0x07, 8, 0x18, 9, 0x17, 10, 0x18, 10, 0x08, 10, 0x67, 11, 0x68, 11,
+ 0x6c, 11, 0x37, 11, 0x28, 11, 0x17, 11, 0x18, 11, 0xca, 12, 0xcb, 12,
+ 0xcc, 12, 0xcd, 12, 0x68, 12, 0x69, 12, 0x6a, 12, 0x6b, 12, 0xd2, 12,
+ 0xd3, 12, 0xd4, 12, 0xd5, 12, 0xd6, 12, 0xd7, 12, 0x6c, 12, 0x6d, 12,
+ 0xda, 12, 0xdb, 12, 0x54, 12, 0x55, 12, 0x56, 12, 0x57, 12, 0x64, 12,
+ 0x65, 12, 0x52, 12, 0x53, 12, 0x24, 12, 0x37, 12, 0x38, 12, 0x27, 12,
+ 0x28, 12, 0x58, 12, 0x59, 12, 0x2b, 12, 0x2c, 12, 0x5a, 12, 0x66, 12,
+ 0x67, 12,
+};
+
+const uint8_t BlackRunMarkup[80] = {
+ 0x0f, 10, 0xc8, 12, 0xc9, 12, 0x5b, 12, 0x33, 12, 0x34, 12, 0x35, 12,
+ 0x6c, 13, 0x6d, 13, 0x4a, 13, 0x4b, 13, 0x4c, 13, 0x4d, 13, 0x72, 13,
+ 0x73, 13, 0x74, 13, 0x75, 13, 0x76, 13, 0x77, 13, 0x52, 13, 0x53, 13,
+ 0x54, 13, 0x55, 13, 0x5a, 13, 0x5b, 13, 0x64, 13, 0x65, 13, 0x08, 11,
+ 0x0c, 11, 0x0d, 11, 0x12, 12, 0x13, 12, 0x14, 12, 0x15, 12, 0x16, 12,
+ 0x17, 12, 0x1c, 12, 0x1d, 12, 0x1e, 12, 0x1f, 12,
+};
+
+const uint8_t WhiteRunTerminator[128] = {
+ 0x35, 8, 0x07, 6, 0x07, 4, 0x08, 4, 0x0B, 4, 0x0C, 4, 0x0E, 4, 0x0F, 4,
+ 0x13, 5, 0x14, 5, 0x07, 5, 0x08, 5, 0x08, 6, 0x03, 6, 0x34, 6, 0x35, 6,
+ 0x2a, 6, 0x2B, 6, 0x27, 7, 0x0c, 7, 0x08, 7, 0x17, 7, 0x03, 7, 0x04, 7,
+ 0x28, 7, 0x2B, 7, 0x13, 7, 0x24, 7, 0x18, 7, 0x02, 8, 0x03, 8, 0x1a, 8,
+ 0x1b, 8, 0x12, 8, 0x13, 8, 0x14, 8, 0x15, 8, 0x16, 8, 0x17, 8, 0x28, 8,
+ 0x29, 8, 0x2a, 8, 0x2b, 8, 0x2c, 8, 0x2d, 8, 0x04, 8, 0x05, 8, 0x0a, 8,
+ 0x0b, 8, 0x52, 8, 0x53, 8, 0x54, 8, 0x55, 8, 0x24, 8, 0x25, 8, 0x58, 8,
+ 0x59, 8, 0x5a, 8, 0x5b, 8, 0x4a, 8, 0x4b, 8, 0x32, 8, 0x33, 8, 0x34, 8,
+};
+
+const uint8_t WhiteRunMarkup[80] = {
+ 0x1b, 5, 0x12, 5, 0x17, 6, 0x37, 7, 0x36, 8, 0x37, 8, 0x64, 8,
+ 0x65, 8, 0x68, 8, 0x67, 8, 0xcc, 9, 0xcd, 9, 0xd2, 9, 0xd3, 9,
+ 0xd4, 9, 0xd5, 9, 0xd6, 9, 0xd7, 9, 0xd8, 9, 0xd9, 9, 0xda, 9,
+ 0xdb, 9, 0x98, 9, 0x99, 9, 0x9a, 9, 0x18, 6, 0x9b, 9, 0x08, 11,
+ 0x0c, 11, 0x0d, 11, 0x12, 12, 0x13, 12, 0x14, 12, 0x15, 12, 0x16, 12,
+ 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);
}
- a0 = a1;
- a0color = !a0color;
+ dest_bitpos++;
}
}
-FX_BOOL _FaxSkipEOL(const uint8_t* src_buf, int bitsize, int& bitpos) {
- int startbit = bitpos;
- while (bitpos < bitsize) {
- int bit = NEXTBIT;
- if (bit) {
- if (bitpos - startbit <= 11) {
- bitpos = startbit;
- }
- return TRUE;
- }
+
+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;
}
- return FALSE;
+ 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]);
}
-FX_BOOL _FaxGet1DLine(const uint8_t* src_buf,
- int bitsize,
- int& bitpos,
- uint8_t* dest_buf,
- int columns) {
- int color = TRUE;
- int startpos = 0;
+
+void FaxEncode2DLine(uint8_t* dest_buf,
+ int& dest_bitpos,
+ const uint8_t* src_buf,
+ const uint8_t* ref_buf,
+ int cols) {
+ int a0 = -1;
+ bool a0color = true;
while (1) {
- if (bitpos >= bitsize) {
- return FALSE;
- }
- int run_len = 0;
- while (1) {
- int run = _FaxGetRun(color ? FaxWhiteRunIns : FaxBlackRunIns, src_buf,
- bitpos, bitsize);
- if (run < 0) {
- while (bitpos < bitsize) {
- int bit = NEXTBIT;
- if (bit) {
- return TRUE;
- }
- }
- return FALSE;
+ int a1 = FindBit(src_buf, cols, a0 + 1, !a0color);
+ int b1, 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;
}
- run_len += run;
- if (run < 64) {
- 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 (!color) {
- _FaxFillBits(dest_buf, columns, startpos, startpos + run_len);
- }
- startpos += run_len;
- if (startpos >= columns) {
- break;
+ if (a0 >= cols) {
+ return;
}
- color = !color;
}
- return TRUE;
}
+} // namespace
+
class CCodec_FaxDecoder : public CCodec_ScanlineDecoder {
public:
CCodec_FaxDecoder();
@@ -535,30 +490,30 @@ FX_BOOL CCodec_FaxDecoder::v_Rewind() {
}
uint8_t* CCodec_FaxDecoder::v_GetNextLine() {
int bitsize = m_SrcSize * 8;
- _FaxSkipEOL(m_pSrcBuf, bitsize, bitpos);
+ FaxSkipEOL(m_pSrcBuf, bitsize, bitpos);
if (bitpos >= bitsize) {
return NULL;
}
FXSYS_memset(m_pScanlineBuf, 0xff, m_Pitch);
if (m_Encoding < 0) {
- _FaxG4GetRow(m_pSrcBuf, bitsize, bitpos, m_pScanlineBuf, m_pRefBuf,
- m_OrigWidth);
+ FaxG4GetRow(m_pSrcBuf, bitsize, bitpos, m_pScanlineBuf, m_pRefBuf,
+ m_OrigWidth);
FXSYS_memcpy(m_pRefBuf, m_pScanlineBuf, m_Pitch);
} else if (m_Encoding == 0) {
- _FaxGet1DLine(m_pSrcBuf, bitsize, bitpos, m_pScanlineBuf, m_OrigWidth);
+ FaxGet1DLine(m_pSrcBuf, bitsize, bitpos, m_pScanlineBuf, m_OrigWidth);
} else {
FX_BOOL bNext1D = m_pSrcBuf[bitpos / 8] & (1 << (7 - bitpos % 8));
bitpos++;
if (bNext1D) {
- _FaxGet1DLine(m_pSrcBuf, bitsize, bitpos, m_pScanlineBuf, m_OrigWidth);
+ FaxGet1DLine(m_pSrcBuf, bitsize, bitpos, m_pScanlineBuf, m_OrigWidth);
} else {
- _FaxG4GetRow(m_pSrcBuf, bitsize, bitpos, m_pScanlineBuf, m_pRefBuf,
- m_OrigWidth);
+ FaxG4GetRow(m_pSrcBuf, bitsize, bitpos, m_pScanlineBuf, m_pRefBuf,
+ m_OrigWidth);
}
FXSYS_memcpy(m_pRefBuf, m_pScanlineBuf, m_Pitch);
}
if (m_bEndOfLine) {
- _FaxSkipEOL(m_pSrcBuf, bitsize, bitpos);
+ FaxSkipEOL(m_pSrcBuf, bitsize, bitpos);
}
if (m_bByteAlign && bitpos < bitsize) {
int bitpos0 = bitpos;
@@ -589,14 +544,199 @@ FX_DWORD CCodec_FaxDecoder::GetSrcOffset() {
}
return ret;
}
-extern "C" {
-void _FaxG4Decode(const uint8_t* src_buf,
- FX_DWORD src_size,
- int* pbitpos,
- uint8_t* dest_buf,
- int width,
- int height,
- int pitch) {
+
+FX_BOOL FaxSkipEOL(const uint8_t* src_buf, int bitsize, int& bitpos) {
+ int startbit = bitpos;
+ while (bitpos < bitsize) {
+ int bit = NEXTBIT;
+ if (bit) {
+ if (bitpos - startbit <= 11) {
+ bitpos = startbit;
+ }
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+FX_BOOL FaxGet1DLine(const uint8_t* src_buf,
+ int bitsize,
+ int& bitpos,
+ uint8_t* dest_buf,
+ int columns) {
+ bool color = true;
+ int startpos = 0;
+ while (1) {
+ if (bitpos >= bitsize) {
+ return FALSE;
+ }
+ int run_len = 0;
+ while (1) {
+ int run = FaxGetRun(color ? FaxWhiteRunIns : FaxBlackRunIns, src_buf,
+ bitpos, bitsize);
+ if (run < 0) {
+ while (bitpos < bitsize) {
+ int bit = NEXTBIT;
+ if (bit) {
+ return TRUE;
+ }
+ }
+ return FALSE;
+ }
+ run_len += run;
+ if (run < 64) {
+ break;
+ }
+ }
+ if (!color) {
+ FaxFillBits(dest_buf, columns, startpos, startpos + run_len);
+ }
+ startpos += run_len;
+ if (startpos >= columns) {
+ break;
+ }
+ color = !color;
+ }
+ return TRUE;
+}
+
+FX_BOOL FaxG4GetRow(const uint8_t* src_buf,
+ int bitsize,
+ int& bitpos,
+ uint8_t* dest_buf,
+ const uint8_t* ref_buf,
+ int columns) {
+ int a0 = -1;
+ bool a0color = true;
+ while (1) {
+ if (bitpos >= bitsize) {
+ return FALSE;
+ }
+ int a1, a2, b1, b2;
+ FaxG4FindB1B2(ref_buf, columns, a0, a0color, b1, b2);
+ FX_BOOL bit = NEXTBIT;
+ int v_delta = 0;
+ if (bit) {
+ } else {
+ if (bitpos >= bitsize) {
+ return FALSE;
+ }
+ FX_BOOL bit1 = NEXTBIT;
+ if (bitpos >= bitsize) {
+ return FALSE;
+ }
+ FX_BOOL bit2 = NEXTBIT;
+ if (bit1 && bit2) {
+ v_delta = 1;
+ } else if (bit1) {
+ v_delta = -1;
+ } else if (bit2) {
+ int run_len1 = 0;
+ while (1) {
+ int run = FaxGetRun(a0color ? FaxWhiteRunIns : FaxBlackRunIns,
+ src_buf, bitpos, bitsize);
+ run_len1 += run;
+ if (run < 64) {
+ break;
+ }
+ }
+ if (a0 < 0) {
+ run_len1++;
+ }
+ a1 = a0 + run_len1;
+ if (!a0color) {
+ FaxFillBits(dest_buf, columns, a0, a1);
+ }
+ int run_len2 = 0;
+ while (1) {
+ int run = FaxGetRun(a0color ? FaxBlackRunIns : FaxWhiteRunIns,
+ src_buf, bitpos, bitsize);
+ run_len2 += run;
+ if (run < 64) {
+ break;
+ }
+ }
+ a2 = a1 + run_len2;
+ if (a0color) {
+ FaxFillBits(dest_buf, columns, a1, a2);
+ }
+ a0 = a2;
+ if (a0 < columns) {
+ continue;
+ }
+ return TRUE;
+ } else {
+ if (bitpos >= bitsize) {
+ return FALSE;
+ }
+ bit = NEXTBIT;
+ if (bit) {
+ if (!a0color) {
+ FaxFillBits(dest_buf, columns, a0, b2);
+ }
+ if (b2 >= columns) {
+ return TRUE;
+ }
+ a0 = b2;
+ continue;
+ } else {
+ if (bitpos >= bitsize) {
+ return FALSE;
+ }
+ FX_BOOL bit1 = NEXTBIT;
+ if (bitpos >= bitsize) {
+ return FALSE;
+ }
+ FX_BOOL bit2 = NEXTBIT;
+ if (bit1 && bit2) {
+ v_delta = 2;
+ } else if (bit1) {
+ v_delta = -2;
+ } else if (bit2) {
+ if (bitpos >= bitsize) {
+ return FALSE;
+ }
+ bit = NEXTBIT;
+ if (bit) {
+ v_delta = 3;
+ } else {
+ v_delta = -3;
+ }
+ } else {
+ if (bitpos >= bitsize) {
+ return FALSE;
+ }
+ bit = NEXTBIT;
+ if (bit) {
+ bitpos += 3;
+ continue;
+ } else {
+ bitpos += 5;
+ return TRUE;
+ }
+ }
+ }
+ }
+ }
+ a1 = b1 + v_delta;
+ if (!a0color) {
+ FaxFillBits(dest_buf, columns, a0, a1);
+ }
+ if (a1 >= columns) {
+ return TRUE;
+ }
+ a0 = a1;
+ a0color = !a0color;
+ }
+}
+
+void FaxG4Decode(const uint8_t* src_buf,
+ FX_DWORD src_size,
+ int* pbitpos,
+ uint8_t* dest_buf,
+ int width,
+ int height,
+ int pitch) {
if (pitch == 0) {
pitch = (width + 7) / 8;
}
@@ -606,139 +746,13 @@ void _FaxG4Decode(const uint8_t* src_buf,
for (int iRow = 0; iRow < height; iRow++) {
uint8_t* line_buf = dest_buf + iRow * pitch;
FXSYS_memset(line_buf, 0xff, pitch);
- _FaxG4GetRow(src_buf, src_size << 3, bitpos, line_buf, ref_buf, width);
+ FaxG4GetRow(src_buf, src_size << 3, bitpos, line_buf, ref_buf, width);
FXSYS_memcpy(ref_buf, line_buf, pitch);
}
FX_Free(ref_buf);
*pbitpos = bitpos;
}
-};
-static const uint8_t BlackRunTerminator[128] = {
- 0x37, 10, 0x02, 3, 0x03, 2, 0x02, 2, 0x03, 3, 0x03, 4, 0x02, 4,
- 0x03, 5, 0x05, 6, 0x04, 6, 0x04, 7, 0x05, 7, 0x07, 7, 0x04, 8,
- 0x07, 8, 0x18, 9, 0x17, 10, 0x18, 10, 0x08, 10, 0x67, 11, 0x68, 11,
- 0x6c, 11, 0x37, 11, 0x28, 11, 0x17, 11, 0x18, 11, 0xca, 12, 0xcb, 12,
- 0xcc, 12, 0xcd, 12, 0x68, 12, 0x69, 12, 0x6a, 12, 0x6b, 12, 0xd2, 12,
- 0xd3, 12, 0xd4, 12, 0xd5, 12, 0xd6, 12, 0xd7, 12, 0x6c, 12, 0x6d, 12,
- 0xda, 12, 0xdb, 12, 0x54, 12, 0x55, 12, 0x56, 12, 0x57, 12, 0x64, 12,
- 0x65, 12, 0x52, 12, 0x53, 12, 0x24, 12, 0x37, 12, 0x38, 12, 0x27, 12,
- 0x28, 12, 0x58, 12, 0x59, 12, 0x2b, 12, 0x2c, 12, 0x5a, 12, 0x66, 12,
- 0x67, 12,
-};
-static const uint8_t BlackRunMarkup[80] = {
- 0x0f, 10, 0xc8, 12, 0xc9, 12, 0x5b, 12, 0x33, 12, 0x34, 12, 0x35, 12,
- 0x6c, 13, 0x6d, 13, 0x4a, 13, 0x4b, 13, 0x4c, 13, 0x4d, 13, 0x72, 13,
- 0x73, 13, 0x74, 13, 0x75, 13, 0x76, 13, 0x77, 13, 0x52, 13, 0x53, 13,
- 0x54, 13, 0x55, 13, 0x5a, 13, 0x5b, 13, 0x64, 13, 0x65, 13, 0x08, 11,
- 0x0c, 11, 0x0d, 11, 0x12, 12, 0x13, 12, 0x14, 12, 0x15, 12, 0x16, 12,
- 0x17, 12, 0x1c, 12, 0x1d, 12, 0x1e, 12, 0x1f, 12,
-};
-static const uint8_t WhiteRunTerminator[128] = {
- 0x35, 8, 0x07, 6, 0x07, 4, 0x08, 4, 0x0B, 4, 0x0C, 4, 0x0E, 4, 0x0F, 4,
- 0x13, 5, 0x14, 5, 0x07, 5, 0x08, 5, 0x08, 6, 0x03, 6, 0x34, 6, 0x35, 6,
- 0x2a, 6, 0x2B, 6, 0x27, 7, 0x0c, 7, 0x08, 7, 0x17, 7, 0x03, 7, 0x04, 7,
- 0x28, 7, 0x2B, 7, 0x13, 7, 0x24, 7, 0x18, 7, 0x02, 8, 0x03, 8, 0x1a, 8,
- 0x1b, 8, 0x12, 8, 0x13, 8, 0x14, 8, 0x15, 8, 0x16, 8, 0x17, 8, 0x28, 8,
- 0x29, 8, 0x2a, 8, 0x2b, 8, 0x2c, 8, 0x2d, 8, 0x04, 8, 0x05, 8, 0x0a, 8,
- 0x0b, 8, 0x52, 8, 0x53, 8, 0x54, 8, 0x55, 8, 0x24, 8, 0x25, 8, 0x58, 8,
- 0x59, 8, 0x5a, 8, 0x5b, 8, 0x4a, 8, 0x4b, 8, 0x32, 8, 0x33, 8, 0x34, 8,
-};
-static const uint8_t WhiteRunMarkup[80] = {
- 0x1b, 5, 0x12, 5, 0x17, 6, 0x37, 7, 0x36, 8, 0x37, 8, 0x64, 8,
- 0x65, 8, 0x68, 8, 0x67, 8, 0xcc, 9, 0xcd, 9, 0xd2, 9, 0xd3, 9,
- 0xd4, 9, 0xd5, 9, 0xd6, 9, 0xd7, 9, 0xd8, 9, 0xd9, 9, 0xda, 9,
- 0xdb, 9, 0x98, 9, 0x99, 9, 0x9a, 9, 0x18, 6, 0x9b, 9, 0x08, 11,
- 0x0c, 11, 0x0d, 11, 0x12, 12, 0x13, 12, 0x14, 12, 0x15, 12, 0x16, 12,
- 0x17, 12, 0x1c, 12, 0x1d, 12, 0x1e, 12, 0x1f, 12,
-};
-static 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++;
- }
-}
-static void _FaxEncodeRun(uint8_t* dest_buf,
- int& dest_bitpos,
- int run,
- FX_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]);
-}
-static void _FaxEncode2DLine(uint8_t* dest_buf,
- int& dest_bitpos,
- const uint8_t* src_buf,
- const uint8_t* ref_buf,
- int cols) {
- int a0 = -1, a0color = 1;
- while (1) {
- int a1 = _FindBit(src_buf, cols, a0 + 1, 1 - a0color);
- int b1, 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 = 1 - 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, 1 - a0color);
- a0 = a2;
- }
- if (a0 >= cols) {
- return;
- }
- }
-}
+
class CCodec_FaxEncoder {
public:
CCodec_FaxEncoder(const uint8_t* src_buf, int width, int height, int pitch);
@@ -775,7 +789,7 @@ void CCodec_FaxEncoder::Encode(uint8_t*& dest_buf, FX_DWORD& dest_size) {
const uint8_t* scan_line = m_pSrcBuf + i * m_Pitch;
FXSYS_memset(m_pLineBuf, 0, m_Pitch * 8);
m_pLineBuf[0] = last_byte;
- _FaxEncode2DLine(m_pLineBuf, dest_bitpos, scan_line, m_pRefLine, m_Cols);
+ FaxEncode2DLine(m_pLineBuf, dest_bitpos, scan_line, m_pRefLine, m_Cols);
m_DestBuf.AppendBlock(m_pLineBuf, dest_bitpos / 8);
last_byte = m_pLineBuf[dest_bitpos / 8];
dest_bitpos %= 8;
diff --git a/core/src/fxcodec/jbig2/JBig2_Define.h b/core/src/fxcodec/jbig2/JBig2_Define.h
index 50516f5798..d1a19c5d61 100644
--- a/core/src/fxcodec/jbig2/JBig2_Define.h
+++ b/core/src/fxcodec/jbig2/JBig2_Define.h
@@ -26,16 +26,6 @@ struct JBig2HuffmanCode {
int32_t code;
};
-extern "C" {
-void _FaxG4Decode(const uint8_t* src_buf,
- FX_DWORD src_size,
- int* pbitpos,
- uint8_t* dest_buf,
- int width,
- int height,
- int pitch = 0);
-};
-
#define JBIG2_MAX_REFERRED_SEGMENT_COUNT 64
#define JBIG2_MAX_EXPORT_SYSMBOLS 65535
#define JBIG2_MAX_NEW_SYSMBOLS 65535
diff --git a/core/src/fxcodec/jbig2/JBig2_GrdProc.cpp b/core/src/fxcodec/jbig2/JBig2_GrdProc.cpp
index 5eb0570e72..eda76bbce9 100644
--- a/core/src/fxcodec/jbig2/JBig2_GrdProc.cpp
+++ b/core/src/fxcodec/jbig2/JBig2_GrdProc.cpp
@@ -7,6 +7,7 @@
#include "JBig2_GrdProc.h"
#include "../../../../third_party/base/nonstd_unique_ptr.h"
+#include "../../../include/fxcodec/fx_codec.h"
#include "JBig2_ArithDecoder.h"
#include "JBig2_BitStream.h"
#include "JBig2_Image.h"
@@ -668,8 +669,8 @@ FXCODEC_STATUS CJBig2_GRDProc::Start_decode_MMR(CJBig2_Image** pImage,
return m_ProssiveStatus;
}
bitpos = (int)pStream->getBitPos();
- _FaxG4Decode(pStream->getBuf(), pStream->getLength(), &bitpos,
- (*pImage)->m_pData, GBW, GBH, (*pImage)->m_nStride);
+ FaxG4Decode(pStream->getBuf(), pStream->getLength(), &bitpos,
+ (*pImage)->m_pData, GBW, GBH, (*pImage)->m_nStride);
pStream->setBitPos(bitpos);
for (i = 0; (FX_DWORD)i < (*pImage)->m_nStride * GBH; i++) {
(*pImage)->m_pData[i] = ~(*pImage)->m_pData[i];