summaryrefslogtreecommitdiff
path: root/core/fxcodec/codec/fx_codec_fax.cpp
diff options
context:
space:
mode:
authorrbpotter <rbpotter@chromium.org>2017-01-06 08:10:18 -0800
committerCommit bot <commit-bot@chromium.org>2017-01-06 08:10:19 -0800
commit8d94b6687f27e1238f352939434704f75b330c1d (patch)
treeeec42ae295885acce22ed547359ead388ba17737 /core/fxcodec/codec/fx_codec_fax.cpp
parent469f6da247ffe77d0ae6089e5d93db0b0c0bb37e (diff)
downloadpdfium-8d94b6687f27e1238f352939434704f75b330c1d.tar.xz
Revert postscript code removal.
Revert CL http://crrev.com/2608663003 in preparation for adding postscript generation to Pdfium. Note postscript generation code will not be called until additional patches land. These patches will also include modifications needed to make this code functional (currently missing a few compression functions). BUG= Review-Url: https://codereview.chromium.org/2615703002
Diffstat (limited to 'core/fxcodec/codec/fx_codec_fax.cpp')
-rw-r--r--core/fxcodec/codec/fx_codec_fax.cpp212
1 files changed, 205 insertions, 7 deletions
diff --git a/core/fxcodec/codec/fx_codec_fax.cpp b/core/fxcodec/codec/fx_codec_fax.cpp
index 62ad38e19f..8a9c3efbc7 100644
--- a/core/fxcodec/codec/fx_codec_fax.cpp
+++ b/core/fxcodec/codec/fx_codec_fax.cpp
@@ -10,6 +10,7 @@
#include "core/fxcodec/codec/codec_int.h"
#include "core/fxcodec/fx_codec.h"
+#include "core/fxcrt/fx_memory.h"
#include "third_party/base/ptr_util.h"
namespace {
@@ -44,10 +45,7 @@ const uint8_t ZeroLeadPos[256] = {
// Limit of image dimension, an arbitrary large number.
const int kMaxImageDimension = 0x01FFFF;
-int FindBit(const std::vector<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) {
ASSERT(start_pos >= 0);
if (start_pos >= max_pos)
return max_pos;
@@ -88,20 +86,20 @@ void FaxG4FindB1B2(const std::vector<uint8_t>& ref_buf,
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.data(), 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.data(), 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.data(), columns, *b1 + 1, first_bit);
}
void FaxFillBits(uint8_t* dest_buf, int columns, int startpos, int endpos) {
@@ -609,3 +607,203 @@ std::unique_ptr<CCodec_ScanlineDecoder> CCodec_FaxModule::CreateDecoder(
src_buf, src_size, actual_width, actual_height, pitch, K, EndOfLine,
EncodedByteAlign, BlackIs1);
}
+
+#if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN64_DESKTOP_
+namespace {
+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);
+ }
+ (*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);
+ ~CCodec_FaxEncoder();
+ void Encode(std::unique_ptr<uint8_t, FxFreeDeleter>* dest_buf,
+ uint32_t* dest_size);
+
+ private:
+ CFX_BinaryBuf m_DestBuf;
+ std::vector<uint8_t> m_RefLine;
+ uint8_t* m_pLineBuf;
+ const int m_Cols;
+ const int m_Rows;
+ const int m_Pitch;
+ const uint8_t* m_pSrcBuf;
+};
+
+CCodec_FaxEncoder::CCodec_FaxEncoder(const uint8_t* src_buf,
+ int width,
+ int height,
+ int pitch)
+ : m_Cols(width), m_Rows(height), m_Pitch(pitch), m_pSrcBuf(src_buf) {
+ m_RefLine.resize(m_Pitch);
+ FXSYS_memset(m_RefLine.data(), 0xff, m_Pitch);
+ m_pLineBuf = FX_Alloc2D(uint8_t, m_Pitch, 8);
+ m_DestBuf.EstimateSize(0, 10240);
+}
+
+CCodec_FaxEncoder::~CCodec_FaxEncoder() {
+ FX_Free(m_pLineBuf);
+}
+
+void CCodec_FaxEncoder::Encode(
+ std::unique_ptr<uint8_t, FxFreeDeleter>* dest_buf,
+ uint32_t* dest_size) {
+ int dest_bitpos = 0;
+ uint8_t last_byte = 0;
+ for (int i = 0; i < m_Rows; i++) {
+ 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_RefLine, m_Cols);
+ m_DestBuf.AppendBlock(m_pLineBuf, dest_bitpos / 8);
+ last_byte = m_pLineBuf[dest_bitpos / 8];
+ dest_bitpos %= 8;
+ FXSYS_memcpy(m_RefLine.data(), scan_line, m_Pitch);
+ }
+ if (dest_bitpos) {
+ m_DestBuf.AppendByte(last_byte);
+ }
+ *dest_size = m_DestBuf.GetSize();
+ *dest_buf = m_DestBuf.DetachBuffer();
+}
+
+} // namespace
+
+void CCodec_FaxModule::FaxEncode(
+ const uint8_t* src_buf,
+ int width,
+ int height,
+ int pitch,
+ std::unique_ptr<uint8_t, FxFreeDeleter>* dest_buf,
+ uint32_t* dest_size) {
+ CCodec_FaxEncoder encoder(src_buf, width, height, pitch);
+ encoder.Encode(dest_buf, dest_size);
+}
+
+#endif