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

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

Issue 2608663003: Pdfium Patch to restore PS Path (Closed)
Patch Set: 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
« no previous file with comments | « core/fxcodec/codec/fx_codec.cpp ('k') | core/fxcodec/codec/fx_codec_flate.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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) {
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
614 const uint8_t kBlackRunTerminator[128] = {
615 0x37, 10, 0x02, 3, 0x03, 2, 0x02, 2, 0x03, 3, 0x03, 4, 0x02, 4,
616 0x03, 5, 0x05, 6, 0x04, 6, 0x04, 7, 0x05, 7, 0x07, 7, 0x04, 8,
617 0x07, 8, 0x18, 9, 0x17, 10, 0x18, 10, 0x08, 10, 0x67, 11, 0x68, 11,
618 0x6c, 11, 0x37, 11, 0x28, 11, 0x17, 11, 0x18, 11, 0xca, 12, 0xcb, 12,
619 0xcc, 12, 0xcd, 12, 0x68, 12, 0x69, 12, 0x6a, 12, 0x6b, 12, 0xd2, 12,
620 0xd3, 12, 0xd4, 12, 0xd5, 12, 0xd6, 12, 0xd7, 12, 0x6c, 12, 0x6d, 12,
621 0xda, 12, 0xdb, 12, 0x54, 12, 0x55, 12, 0x56, 12, 0x57, 12, 0x64, 12,
622 0x65, 12, 0x52, 12, 0x53, 12, 0x24, 12, 0x37, 12, 0x38, 12, 0x27, 12,
623 0x28, 12, 0x58, 12, 0x59, 12, 0x2b, 12, 0x2c, 12, 0x5a, 12, 0x66, 12,
624 0x67, 12,
625 };
626
627 const uint8_t kBlackRunMarkup[80] = {
628 0x0f, 10, 0xc8, 12, 0xc9, 12, 0x5b, 12, 0x33, 12, 0x34, 12, 0x35, 12,
629 0x6c, 13, 0x6d, 13, 0x4a, 13, 0x4b, 13, 0x4c, 13, 0x4d, 13, 0x72, 13,
630 0x73, 13, 0x74, 13, 0x75, 13, 0x76, 13, 0x77, 13, 0x52, 13, 0x53, 13,
631 0x54, 13, 0x55, 13, 0x5a, 13, 0x5b, 13, 0x64, 13, 0x65, 13, 0x08, 11,
632 0x0c, 11, 0x0d, 11, 0x12, 12, 0x13, 12, 0x14, 12, 0x15, 12, 0x16, 12,
633 0x17, 12, 0x1c, 12, 0x1d, 12, 0x1e, 12, 0x1f, 12,
634 };
635
636 const uint8_t kWhiteRunTerminator[128] = {
637 0x35, 8, 0x07, 6, 0x07, 4, 0x08, 4, 0x0B, 4, 0x0C, 4, 0x0E, 4, 0x0F, 4,
638 0x13, 5, 0x14, 5, 0x07, 5, 0x08, 5, 0x08, 6, 0x03, 6, 0x34, 6, 0x35, 6,
639 0x2a, 6, 0x2B, 6, 0x27, 7, 0x0c, 7, 0x08, 7, 0x17, 7, 0x03, 7, 0x04, 7,
640 0x28, 7, 0x2B, 7, 0x13, 7, 0x24, 7, 0x18, 7, 0x02, 8, 0x03, 8, 0x1a, 8,
641 0x1b, 8, 0x12, 8, 0x13, 8, 0x14, 8, 0x15, 8, 0x16, 8, 0x17, 8, 0x28, 8,
642 0x29, 8, 0x2a, 8, 0x2b, 8, 0x2c, 8, 0x2d, 8, 0x04, 8, 0x05, 8, 0x0a, 8,
643 0x0b, 8, 0x52, 8, 0x53, 8, 0x54, 8, 0x55, 8, 0x24, 8, 0x25, 8, 0x58, 8,
644 0x59, 8, 0x5a, 8, 0x5b, 8, 0x4a, 8, 0x4b, 8, 0x32, 8, 0x33, 8, 0x34, 8,
645 };
646
647 const uint8_t kWhiteRunMarkup[80] = {
648 0x1b, 5, 0x12, 5, 0x17, 6, 0x37, 7, 0x36, 8, 0x37, 8, 0x64, 8,
649 0x65, 8, 0x68, 8, 0x67, 8, 0xcc, 9, 0xcd, 9, 0xd2, 9, 0xd3, 9,
650 0xd4, 9, 0xd5, 9, 0xd6, 9, 0xd7, 9, 0xd8, 9, 0xd9, 9, 0xda, 9,
651 0xdb, 9, 0x98, 9, 0x99, 9, 0x9a, 9, 0x18, 6, 0x9b, 9, 0x08, 11,
652 0x0c, 11, 0x0d, 11, 0x12, 12, 0x13, 12, 0x14, 12, 0x15, 12, 0x16, 12,
653 0x17, 12, 0x1c, 12, 0x1d, 12, 0x1e, 12, 0x1f, 12,
654 };
655
656 void AddBitStream(uint8_t* dest_buf, int& dest_bitpos, int data, int bitlen) {
657 for (int i = bitlen - 1; i >= 0; i--) {
658 if (data & (1 << i)) {
659 dest_buf[dest_bitpos / 8] |= 1 << (7 - dest_bitpos % 8);
660 }
661 dest_bitpos++;
662 }
663 }
664
665 void FaxEncodeRun(uint8_t* dest_buf, int& dest_bitpos, int run, bool bWhite) {
666 while (run >= 2560) {
667 AddBitStream(dest_buf, dest_bitpos, 0x1f, 12);
668 run -= 2560;
669 }
670 if (run >= 64) {
671 int markup = run - run % 64;
672 const uint8_t* p = bWhite ? kWhiteRunMarkup : kBlackRunMarkup;
673 p += (markup / 64 - 1) * 2;
674 AddBitStream(dest_buf, dest_bitpos, *p, p[1]);
675 }
676 run %= 64;
677 const uint8_t* p = bWhite ? kWhiteRunTerminator : kBlackRunTerminator;
678 p += run * 2;
679 AddBitStream(dest_buf, dest_bitpos, *p, p[1]);
680 }
681
682 void FaxEncode2DLine(uint8_t* dest_buf,
683 int& dest_bitpos,
684 const uint8_t* src_buf,
685 const std::vector<uint8_t>& ref_buf,
686 int cols) {
687 int a0 = -1;
688 bool a0color = true;
689 while (1) {
690 int a1 = FindBit(src_buf, cols, a0 + 1, !a0color);
691 int b1;
692 int b2;
693 FaxG4FindB1B2(ref_buf, cols, a0, a0color, &b1, &b2);
694 if (b2 < a1) {
695 dest_bitpos += 3;
696 dest_buf[dest_bitpos / 8] |= 1 << (7 - dest_bitpos % 8);
697 dest_bitpos++;
698 a0 = b2;
699 } else if (a1 - b1 <= 3 && b1 - a1 <= 3) {
700 int delta = a1 - b1;
701 switch (delta) {
702 case 0:
703 dest_buf[dest_bitpos / 8] |= 1 << (7 - dest_bitpos % 8);
704 break;
705 case 1:
706 case 2:
707 case 3:
708 dest_bitpos += delta == 1 ? 1 : delta + 2;
709 dest_buf[dest_bitpos / 8] |= 1 << (7 - dest_bitpos % 8);
710 dest_bitpos++;
711 dest_buf[dest_bitpos / 8] |= 1 << (7 - dest_bitpos % 8);
712 break;
713 case -1:
714 case -2:
715 case -3:
716 dest_bitpos += delta == -1 ? 1 : -delta + 2;
717 dest_buf[dest_bitpos / 8] |= 1 << (7 - dest_bitpos % 8);
718 dest_bitpos++;
719 break;
720 }
721 dest_bitpos++;
722 a0 = a1;
723 a0color = !a0color;
724 } else {
725 int a2 = FindBit(src_buf, cols, a1 + 1, a0color);
726 dest_bitpos++;
727 dest_bitpos++;
728 dest_buf[dest_bitpos / 8] |= 1 << (7 - dest_bitpos % 8);
729 dest_bitpos++;
730 if (a0 < 0) {
731 a0 = 0;
732 }
733 FaxEncodeRun(dest_buf, dest_bitpos, a1 - a0, a0color);
734 FaxEncodeRun(dest_buf, dest_bitpos, a2 - a1, !a0color);
735 a0 = a2;
736 }
737 if (a0 >= cols) {
738 return;
739 }
740 }
741 }
742
743 class CCodec_FaxEncoder {
744 public:
745 CCodec_FaxEncoder(const uint8_t* src_buf, int width, int height, int pitch);
746 ~CCodec_FaxEncoder();
747
748 void Encode(std::unique_ptr<uint8_t, FxFreeDeleter>& dest_buf,
749 uint32_t& dest_size);
750
751 private:
752 CFX_BinaryBuf m_DestBuf;
753 std::vector<uint8_t> m_RefLine;
754 uint8_t* m_pLineBuf;
755 const int m_Cols;
756 const int m_Rows;
757 const int m_Pitch;
758 const uint8_t* const m_pSrcBuf;
759 };
760
761 CCodec_FaxEncoder::CCodec_FaxEncoder(const uint8_t* src_buf,
762 int width,
763 int height,
764 int pitch)
765 : m_pSrcBuf(src_buf), m_Cols(width), m_Rows(height), m_Pitch(pitch) {
766 m_RefLine.resize(m_Pitch);
767 FXSYS_memset(m_RefLine.data(), 0xff, m_Pitch);
768 m_pLineBuf = FX_Alloc2D(uint8_t, m_Pitch, 8);
769 m_DestBuf.EstimateSize(0, 10240);
770 }
771
772 CCodec_FaxEncoder::~CCodec_FaxEncoder() {
773 FX_Free(m_pLineBuf);
774 }
775
776 void CCodec_FaxEncoder::Encode(
777 std::unique_ptr<uint8_t, FxFreeDeleter>& dest_buf,
778 uint32_t& dest_size) {
779 int dest_bitpos = 0;
780 uint8_t last_byte = 0;
781 for (int i = 0; i < m_Rows; i++) {
782 const uint8_t* scan_line = m_pSrcBuf + i * m_Pitch;
783 FXSYS_memset(m_pLineBuf, 0, m_Pitch * 8);
784 m_pLineBuf[0] = last_byte;
785 FaxEncode2DLine(m_pLineBuf, dest_bitpos, scan_line, m_RefLine, m_Cols);
786 m_DestBuf.AppendBlock(m_pLineBuf, dest_bitpos / 8);
787 last_byte = m_pLineBuf[dest_bitpos / 8];
788 dest_bitpos %= 8;
789 FXSYS_memcpy(m_RefLine.data(), scan_line, m_Pitch);
790 }
791 if (dest_bitpos)
792 m_DestBuf.AppendByte(last_byte);
793
794 dest_size = m_DestBuf.GetSize();
795 dest_buf = m_DestBuf.DetachBuffer();
796 }
797
798 } // namespace
799
800 // static
801 void CCodec_FaxModule::FaxEncode(
802 const uint8_t* src_buf,
803 int width,
804 int height,
805 int pitch,
806 std::unique_ptr<uint8_t, FxFreeDeleter>& dest_buf,
807 uint32_t& dest_size) {
808 CCodec_FaxEncoder encoder(src_buf, width, height, pitch);
809 encoder.Encode(dest_buf, dest_size);
810 }
811
812 #endif
OLDNEW
« no previous file with comments | « core/fxcodec/codec/fx_codec.cpp ('k') | core/fxcodec/codec/fx_codec_flate.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698