diff options
author | rbpotter <rbpotter@chromium.org> | 2017-01-06 08:10:18 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2017-01-06 08:10:19 -0800 |
commit | 8d94b6687f27e1238f352939434704f75b330c1d (patch) | |
tree | eec42ae295885acce22ed547359ead388ba17737 /core/fxcodec/codec/fx_codec_fax.cpp | |
parent | 469f6da247ffe77d0ae6089e5d93db0b0c0bb37e (diff) | |
download | pdfium-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.cpp | 212 |
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 |