Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(93)

Side by Side Diff: core/fxcodec/codec/fx_codec_fax.cpp

Issue 2615703002: Revert postscript code removal. (Closed)
Patch Set: Fix Compile Errors Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 PDFium Authors. All rights reserved. 1 // Copyright 2014 PDFium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <memory> 8 #include <memory>
9 #include <vector> 9 #include <vector>
10 10
11 #include "core/fxcodec/codec/codec_int.h" 11 #include "core/fxcodec/codec/codec_int.h"
12 #include "core/fxcodec/fx_codec.h" 12 #include "core/fxcodec/fx_codec.h"
13 #include "core/fxcrt/fx_memory.h"
13 #include "third_party/base/ptr_util.h" 14 #include "third_party/base/ptr_util.h"
14 15
15 namespace { 16 namespace {
16 17
17 const uint8_t OneLeadPos[256] = { 18 const uint8_t OneLeadPos[256] = {
18 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 19 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3,
19 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 20 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
20 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 21 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1,
21 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 22 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
22 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 23 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
(...skipping 14 matching lines...) Expand all
37 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 38 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
38 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 39 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
39 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 40 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
40 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 41 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
41 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 7, 8, 42 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 7, 8,
42 }; 43 };
43 44
44 // Limit of image dimension, an arbitrary large number. 45 // Limit of image dimension, an arbitrary large number.
45 const int kMaxImageDimension = 0x01FFFF; 46 const int kMaxImageDimension = 0x01FFFF;
46 47
47 int FindBit(const std::vector<uint8_t>& data_buf, 48 int FindBit(const uint8_t* data_buf, int max_pos, int start_pos, int bit) {
dsinclair 2017/01/05 17:13:43 This one's a bit weird. Why do we change from a ve
rbpotter 2017/01/05 22:58:18 The encoder needs to call this function on rows of
48 int max_pos,
49 int start_pos,
50 int bit) {
51 ASSERT(start_pos >= 0); 49 ASSERT(start_pos >= 0);
52 if (start_pos >= max_pos) 50 if (start_pos >= max_pos)
53 return max_pos; 51 return max_pos;
54 52
55 const uint8_t* leading_pos = bit ? OneLeadPos : ZeroLeadPos; 53 const uint8_t* leading_pos = bit ? OneLeadPos : ZeroLeadPos;
56 if (start_pos % 8) { 54 if (start_pos % 8) {
57 uint8_t data = data_buf[start_pos / 8]; 55 uint8_t data = data_buf[start_pos / 8];
58 if (bit) 56 if (bit)
59 data &= 0xff >> (start_pos % 8); 57 data &= 0xff >> (start_pos % 8);
60 else 58 else
(...skipping 20 matching lines...) Expand all
81 } 79 }
82 80
83 void FaxG4FindB1B2(const std::vector<uint8_t>& ref_buf, 81 void FaxG4FindB1B2(const std::vector<uint8_t>& ref_buf,
84 int columns, 82 int columns,
85 int a0, 83 int a0,
86 bool a0color, 84 bool a0color,
87 int* b1, 85 int* b1,
88 int* b2) { 86 int* b2) {
89 uint8_t first_bit = 87 uint8_t first_bit =
90 (a0 < 0) ? 1 : ((ref_buf[a0 / 8] & (1 << (7 - a0 % 8))) != 0); 88 (a0 < 0) ? 1 : ((ref_buf[a0 / 8] & (1 << (7 - a0 % 8))) != 0);
91 *b1 = FindBit(ref_buf, columns, a0 + 1, !first_bit); 89 *b1 = FindBit(ref_buf.data(), columns, a0 + 1, !first_bit);
92 if (*b1 >= columns) { 90 if (*b1 >= columns) {
93 *b1 = *b2 = columns; 91 *b1 = *b2 = columns;
94 return; 92 return;
95 } 93 }
96 if (first_bit == !a0color) { 94 if (first_bit == !a0color) {
97 *b1 = FindBit(ref_buf, columns, *b1 + 1, first_bit); 95 *b1 = FindBit(ref_buf.data(), columns, *b1 + 1, first_bit);
98 first_bit = !first_bit; 96 first_bit = !first_bit;
99 } 97 }
100 if (*b1 >= columns) { 98 if (*b1 >= columns) {
101 *b1 = *b2 = columns; 99 *b1 = *b2 = columns;
102 return; 100 return;
103 } 101 }
104 *b2 = FindBit(ref_buf, columns, *b1 + 1, first_bit); 102 *b2 = FindBit(ref_buf.data(), columns, *b1 + 1, first_bit);
105 } 103 }
106 104
107 void FaxFillBits(uint8_t* dest_buf, int columns, int startpos, int endpos) { 105 void FaxFillBits(uint8_t* dest_buf, int columns, int startpos, int endpos) {
108 startpos = std::max(startpos, 0); 106 startpos = std::max(startpos, 0);
109 endpos = std::min(std::max(endpos, 0), columns); 107 endpos = std::min(std::max(endpos, 0), columns);
110 if (startpos >= endpos) 108 if (startpos >= endpos)
111 return; 109 return;
112 110
113 int first_byte = startpos / 8; 111 int first_byte = startpos / 8;
114 int last_byte = (endpos - 1) / 8; 112 int last_byte = (endpos - 1) / 8;
(...skipping 487 matching lines...) Expand 10 before | Expand all | Expand 10 after
602 600
603 // Reject unreasonable large input. 601 // Reject unreasonable large input.
604 if (actual_width > kMaxImageDimension || actual_height > kMaxImageDimension) 602 if (actual_width > kMaxImageDimension || actual_height > kMaxImageDimension)
605 return nullptr; 603 return nullptr;
606 604
607 uint32_t pitch = (static_cast<uint32_t>(actual_width) + 31) / 32 * 4; 605 uint32_t pitch = (static_cast<uint32_t>(actual_width) + 31) / 32 * 4;
608 return pdfium::MakeUnique<CCodec_FaxDecoder>( 606 return pdfium::MakeUnique<CCodec_FaxDecoder>(
609 src_buf, src_size, actual_width, actual_height, pitch, K, EndOfLine, 607 src_buf, src_size, actual_width, actual_height, pitch, K, EndOfLine,
610 EncodedByteAlign, BlackIs1); 608 EncodedByteAlign, BlackIs1);
611 } 609 }
610
611 #if _FX_OS_ == _FX_WIN32_DESKTOP_ || _FX_OS_ == _FX_WIN64_DESKTOP_
612 namespace {
613 const uint8_t BlackRunTerminator[128] = {
614 0x37, 10, 0x02, 3, 0x03, 2, 0x02, 2, 0x03, 3, 0x03, 4, 0x02, 4,
615 0x03, 5, 0x05, 6, 0x04, 6, 0x04, 7, 0x05, 7, 0x07, 7, 0x04, 8,
616 0x07, 8, 0x18, 9, 0x17, 10, 0x18, 10, 0x08, 10, 0x67, 11, 0x68, 11,
617 0x6c, 11, 0x37, 11, 0x28, 11, 0x17, 11, 0x18, 11, 0xca, 12, 0xcb, 12,
618 0xcc, 12, 0xcd, 12, 0x68, 12, 0x69, 12, 0x6a, 12, 0x6b, 12, 0xd2, 12,
619 0xd3, 12, 0xd4, 12, 0xd5, 12, 0xd6, 12, 0xd7, 12, 0x6c, 12, 0x6d, 12,
620 0xda, 12, 0xdb, 12, 0x54, 12, 0x55, 12, 0x56, 12, 0x57, 12, 0x64, 12,
621 0x65, 12, 0x52, 12, 0x53, 12, 0x24, 12, 0x37, 12, 0x38, 12, 0x27, 12,
622 0x28, 12, 0x58, 12, 0x59, 12, 0x2b, 12, 0x2c, 12, 0x5a, 12, 0x66, 12,
623 0x67, 12,
624 };
625
626 const uint8_t BlackRunMarkup[80] = {
627 0x0f, 10, 0xc8, 12, 0xc9, 12, 0x5b, 12, 0x33, 12, 0x34, 12, 0x35, 12,
628 0x6c, 13, 0x6d, 13, 0x4a, 13, 0x4b, 13, 0x4c, 13, 0x4d, 13, 0x72, 13,
629 0x73, 13, 0x74, 13, 0x75, 13, 0x76, 13, 0x77, 13, 0x52, 13, 0x53, 13,
630 0x54, 13, 0x55, 13, 0x5a, 13, 0x5b, 13, 0x64, 13, 0x65, 13, 0x08, 11,
631 0x0c, 11, 0x0d, 11, 0x12, 12, 0x13, 12, 0x14, 12, 0x15, 12, 0x16, 12,
632 0x17, 12, 0x1c, 12, 0x1d, 12, 0x1e, 12, 0x1f, 12,
633 };
634
635 const uint8_t WhiteRunTerminator[128] = {
636 0x35, 8, 0x07, 6, 0x07, 4, 0x08, 4, 0x0B, 4, 0x0C, 4, 0x0E, 4, 0x0F, 4,
637 0x13, 5, 0x14, 5, 0x07, 5, 0x08, 5, 0x08, 6, 0x03, 6, 0x34, 6, 0x35, 6,
638 0x2a, 6, 0x2B, 6, 0x27, 7, 0x0c, 7, 0x08, 7, 0x17, 7, 0x03, 7, 0x04, 7,
639 0x28, 7, 0x2B, 7, 0x13, 7, 0x24, 7, 0x18, 7, 0x02, 8, 0x03, 8, 0x1a, 8,
640 0x1b, 8, 0x12, 8, 0x13, 8, 0x14, 8, 0x15, 8, 0x16, 8, 0x17, 8, 0x28, 8,
641 0x29, 8, 0x2a, 8, 0x2b, 8, 0x2c, 8, 0x2d, 8, 0x04, 8, 0x05, 8, 0x0a, 8,
642 0x0b, 8, 0x52, 8, 0x53, 8, 0x54, 8, 0x55, 8, 0x24, 8, 0x25, 8, 0x58, 8,
643 0x59, 8, 0x5a, 8, 0x5b, 8, 0x4a, 8, 0x4b, 8, 0x32, 8, 0x33, 8, 0x34, 8,
644 };
645
646 const uint8_t WhiteRunMarkup[80] = {
647 0x1b, 5, 0x12, 5, 0x17, 6, 0x37, 7, 0x36, 8, 0x37, 8, 0x64, 8,
648 0x65, 8, 0x68, 8, 0x67, 8, 0xcc, 9, 0xcd, 9, 0xd2, 9, 0xd3, 9,
649 0xd4, 9, 0xd5, 9, 0xd6, 9, 0xd7, 9, 0xd8, 9, 0xd9, 9, 0xda, 9,
650 0xdb, 9, 0x98, 9, 0x99, 9, 0x9a, 9, 0x18, 6, 0x9b, 9, 0x08, 11,
651 0x0c, 11, 0x0d, 11, 0x12, 12, 0x13, 12, 0x14, 12, 0x15, 12, 0x16, 12,
652 0x17, 12, 0x1c, 12, 0x1d, 12, 0x1e, 12, 0x1f, 12,
653 };
654
655 void AddBitStream(uint8_t* dest_buf, int& dest_bitpos, int data, int bitlen) {
656 for (int i = bitlen - 1; i >= 0; i--) {
657 if (data & (1 << i)) {
658 dest_buf[dest_bitpos / 8] |= 1 << (7 - dest_bitpos % 8);
659 }
660 dest_bitpos++;
661 }
662 }
663
664 void FaxEncodeRun(uint8_t* dest_buf, int& dest_bitpos, int run, bool bWhite) {
665 while (run >= 2560) {
666 AddBitStream(dest_buf, dest_bitpos, 0x1f, 12);
667 run -= 2560;
668 }
669 if (run >= 64) {
670 int markup = run - run % 64;
671 const uint8_t* p = bWhite ? WhiteRunMarkup : BlackRunMarkup;
672 p += (markup / 64 - 1) * 2;
673 AddBitStream(dest_buf, dest_bitpos, *p, p[1]);
674 }
675 run %= 64;
676 const uint8_t* p = bWhite ? WhiteRunTerminator : BlackRunTerminator;
677 p += run * 2;
678 AddBitStream(dest_buf, dest_bitpos, *p, p[1]);
679 }
680
681 void FaxEncode2DLine(uint8_t* dest_buf,
682 int& dest_bitpos,
683 const uint8_t* src_buf,
684 const std::vector<uint8_t>& ref_buf,
685 int cols) {
686 int a0 = -1;
687 bool a0color = true;
688 while (1) {
689 int a1 = FindBit(src_buf, cols, a0 + 1, !a0color);
690 int b1;
691 int b2;
692 FaxG4FindB1B2(ref_buf, cols, a0, a0color, &b1, &b2);
693 if (b2 < a1) {
694 dest_bitpos += 3;
695 dest_buf[dest_bitpos / 8] |= 1 << (7 - dest_bitpos % 8);
696 dest_bitpos++;
697 a0 = b2;
698 } else if (a1 - b1 <= 3 && b1 - a1 <= 3) {
699 int delta = a1 - b1;
700 switch (delta) {
701 case 0:
702 dest_buf[dest_bitpos / 8] |= 1 << (7 - dest_bitpos % 8);
703 break;
704 case 1:
705 case 2:
706 case 3:
707 dest_bitpos += delta == 1 ? 1 : delta + 2;
708 dest_buf[dest_bitpos / 8] |= 1 << (7 - dest_bitpos % 8);
709 dest_bitpos++;
710 dest_buf[dest_bitpos / 8] |= 1 << (7 - dest_bitpos % 8);
711 break;
712 case -1:
713 case -2:
714 case -3:
715 dest_bitpos += delta == -1 ? 1 : -delta + 2;
716 dest_buf[dest_bitpos / 8] |= 1 << (7 - dest_bitpos % 8);
717 dest_bitpos++;
718 break;
719 }
720 dest_bitpos++;
721 a0 = a1;
722 a0color = !a0color;
723 } else {
724 int a2 = FindBit(src_buf, cols, a1 + 1, a0color);
725 dest_bitpos++;
726 dest_bitpos++;
727 dest_buf[dest_bitpos / 8] |= 1 << (7 - dest_bitpos % 8);
728 dest_bitpos++;
729 if (a0 < 0) {
730 a0 = 0;
731 }
732 FaxEncodeRun(dest_buf, dest_bitpos, a1 - a0, a0color);
733 FaxEncodeRun(dest_buf, dest_bitpos, a2 - a1, !a0color);
734 a0 = a2;
735 }
736 if (a0 >= cols) {
737 return;
738 }
739 }
740 }
741
742 class CCodec_FaxEncoder {
743 public:
744 CCodec_FaxEncoder(const uint8_t* src_buf, int width, int height, int pitch);
745 ~CCodec_FaxEncoder();
746 void Encode(std::unique_ptr<uint8_t, FxFreeDeleter>& dest_buf,
747 uint32_t& dest_size);
748
749 private:
750 CFX_BinaryBuf m_DestBuf;
751 std::vector<uint8_t> m_RefLine;
752 uint8_t* m_pLineBuf;
753 const int m_Cols;
754 const int m_Rows;
755 const int m_Pitch;
756 const uint8_t* m_pSrcBuf;
757 };
758
759 CCodec_FaxEncoder::CCodec_FaxEncoder(const uint8_t* src_buf,
760 int width,
761 int height,
762 int pitch)
763 : m_Cols(width), m_Rows(height), m_Pitch(pitch), m_pSrcBuf(src_buf) {
764 m_RefLine.resize(m_Pitch);
765 FXSYS_memset(m_RefLine.data(), 0xff, m_Pitch);
766 m_pLineBuf = FX_Alloc2D(uint8_t, m_Pitch, 8);
767 m_DestBuf.EstimateSize(0, 10240);
768 }
769
770 CCodec_FaxEncoder::~CCodec_FaxEncoder() {
771 FX_Free(m_pLineBuf);
772 }
773
774 void CCodec_FaxEncoder::Encode(
775 std::unique_ptr<uint8_t, FxFreeDeleter>& dest_buf,
776 uint32_t& dest_size) {
777 int dest_bitpos = 0;
778 uint8_t last_byte = 0;
779 for (int i = 0; i < m_Rows; i++) {
780 const uint8_t* scan_line = m_pSrcBuf + i * m_Pitch;
781 FXSYS_memset(m_pLineBuf, 0, m_Pitch * 8);
782 m_pLineBuf[0] = last_byte;
783 FaxEncode2DLine(m_pLineBuf, dest_bitpos, scan_line, m_RefLine, m_Cols);
784 m_DestBuf.AppendBlock(m_pLineBuf, dest_bitpos / 8);
785 last_byte = m_pLineBuf[dest_bitpos / 8];
786 dest_bitpos %= 8;
787 FXSYS_memcpy(m_RefLine.data(), scan_line, m_Pitch);
788 }
789 if (dest_bitpos) {
790 m_DestBuf.AppendByte(last_byte);
791 }
792 dest_size = m_DestBuf.GetSize();
793 dest_buf = m_DestBuf.DetachBuffer();
794 }
795
796 } // namespace
797
798 void CCodec_FaxModule::FaxEncode(
799 const uint8_t* src_buf,
800 int width,
801 int height,
802 int pitch,
803 std::unique_ptr<uint8_t, FxFreeDeleter>& dest_buf,
804 uint32_t& dest_size) {
805 CCodec_FaxEncoder encoder(src_buf, width, height, pitch);
806 encoder.Encode(dest_buf, dest_size);
807 }
808
809 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698