OLD | NEW |
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 "../../../include/fxcodec/fx_codec.h" | 7 #include "../../../include/fxcodec/fx_codec.h" |
8 #include "codec_int.h" | 8 #include "codec_int.h" |
| 9 |
| 10 namespace { |
| 11 |
9 const uint8_t OneLeadPos[256] = { | 12 const uint8_t OneLeadPos[256] = { |
10 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, | 13 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, |
11 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, | 14 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
12 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, | 15 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, |
13 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | 16 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
14 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | 17 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
15 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 18 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
16 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 19 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
17 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 20 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
18 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 21 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
19 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 22 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
20 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 23 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
21 }; | 24 }; |
22 const uint8_t ZeroLeadPos[256] = { | 25 const uint8_t ZeroLeadPos[256] = { |
23 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 26 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
24 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 27 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
25 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 28 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
26 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 29 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
27 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 30 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
28 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | 31 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
29 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | 32 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
30 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, | 33 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
31 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, | 34 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
32 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, | 35 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, |
33 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 7, 8, | 36 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 7, 8, |
34 }; | 37 }; |
35 | 38 |
36 int _FindBit(const uint8_t* data_buf, int max_pos, int start_pos, int bit) { | 39 int FindBit(const uint8_t* data_buf, int max_pos, int start_pos, int bit) { |
37 if (start_pos >= max_pos) { | 40 if (start_pos >= max_pos) { |
38 return max_pos; | 41 return max_pos; |
39 } | 42 } |
40 const uint8_t* leading_pos = bit ? OneLeadPos : ZeroLeadPos; | 43 const uint8_t* leading_pos = bit ? OneLeadPos : ZeroLeadPos; |
41 if (start_pos % 8) { | 44 if (start_pos % 8) { |
42 uint8_t data = data_buf[start_pos / 8]; | 45 uint8_t data = data_buf[start_pos / 8]; |
43 if (bit) { | 46 if (bit) { |
44 data &= 0xff >> (start_pos % 8); | 47 data &= 0xff >> (start_pos % 8); |
45 } else { | 48 } else { |
46 data |= 0xff << (8 - start_pos % 8); | 49 data |= 0xff << (8 - start_pos % 8); |
(...skipping 14 matching lines...) Expand all Loading... |
61 } | 64 } |
62 if (byte_pos == max_byte) { | 65 if (byte_pos == max_byte) { |
63 return max_pos; | 66 return max_pos; |
64 } | 67 } |
65 int pos = leading_pos[data_buf[byte_pos]] + byte_pos * 8; | 68 int pos = leading_pos[data_buf[byte_pos]] + byte_pos * 8; |
66 if (pos > max_pos) { | 69 if (pos > max_pos) { |
67 pos = max_pos; | 70 pos = max_pos; |
68 } | 71 } |
69 return pos; | 72 return pos; |
70 } | 73 } |
71 void _FaxG4FindB1B2(const uint8_t* ref_buf, | 74 |
72 int columns, | 75 void FaxG4FindB1B2(const uint8_t* ref_buf, |
73 int a0, | 76 int columns, |
74 FX_BOOL a0color, | 77 int a0, |
75 int& b1, | 78 bool a0color, |
76 int& b2) { | 79 int& b1, |
77 if (a0color) { | 80 int& b2) { |
78 a0color = 1; | |
79 } | |
80 uint8_t first_bit = | 81 uint8_t first_bit = |
81 (a0 < 0) ? 1 : ((ref_buf[a0 / 8] & (1 << (7 - a0 % 8))) != 0); | 82 (a0 < 0) ? 1 : ((ref_buf[a0 / 8] & (1 << (7 - a0 % 8))) != 0); |
82 b1 = _FindBit(ref_buf, columns, a0 + 1, !first_bit); | 83 b1 = FindBit(ref_buf, columns, a0 + 1, !first_bit); |
83 if (b1 >= columns) { | 84 if (b1 >= columns) { |
84 b1 = b2 = columns; | 85 b1 = b2 = columns; |
85 return; | 86 return; |
86 } | 87 } |
87 if (first_bit == !a0color) { | 88 if (first_bit == !a0color) { |
88 b1 = _FindBit(ref_buf, columns, b1 + 1, first_bit); | 89 b1 = FindBit(ref_buf, columns, b1 + 1, first_bit); |
89 first_bit = !first_bit; | 90 first_bit = !first_bit; |
90 } | 91 } |
91 if (b1 >= columns) { | 92 if (b1 >= columns) { |
92 b1 = b2 = columns; | 93 b1 = b2 = columns; |
93 return; | 94 return; |
94 } | 95 } |
95 b2 = _FindBit(ref_buf, columns, b1 + 1, first_bit); | 96 b2 = FindBit(ref_buf, columns, b1 + 1, first_bit); |
96 } | 97 } |
97 void _FaxFillBits(uint8_t* dest_buf, int columns, int startpos, int endpos) { | 98 |
| 99 void FaxFillBits(uint8_t* dest_buf, int columns, int startpos, int endpos) { |
98 if (startpos < 0) { | 100 if (startpos < 0) { |
99 startpos = 0; | 101 startpos = 0; |
100 } | 102 } |
101 if (endpos < 0) { | 103 if (endpos < 0) { |
102 endpos = 0; | 104 endpos = 0; |
103 } | 105 } |
104 if (endpos >= columns) { | 106 if (endpos >= columns) { |
105 endpos = columns; | 107 endpos = columns; |
106 } | 108 } |
107 if (startpos >= endpos) { | 109 if (startpos >= endpos) { |
(...skipping 11 matching lines...) Expand all Loading... |
119 for (i = startpos % 8; i < 8; i++) { | 121 for (i = startpos % 8; i < 8; i++) { |
120 dest_buf[first_byte] -= 1 << (7 - i); | 122 dest_buf[first_byte] -= 1 << (7 - i); |
121 } | 123 } |
122 for (i = 0; i <= (endpos - 1) % 8; i++) { | 124 for (i = 0; i <= (endpos - 1) % 8; i++) { |
123 dest_buf[last_byte] -= 1 << (7 - i); | 125 dest_buf[last_byte] -= 1 << (7 - i); |
124 } | 126 } |
125 if (last_byte > first_byte + 1) { | 127 if (last_byte > first_byte + 1) { |
126 FXSYS_memset(dest_buf + first_byte + 1, 0, last_byte - first_byte - 1); | 128 FXSYS_memset(dest_buf + first_byte + 1, 0, last_byte - first_byte - 1); |
127 } | 129 } |
128 } | 130 } |
| 131 |
129 #define NEXTBIT \ | 132 #define NEXTBIT \ |
130 src_buf[bitpos / 8] & (1 << (7 - bitpos % 8)); \ | 133 src_buf[bitpos / 8] & (1 << (7 - bitpos % 8)); \ |
131 bitpos++; | 134 bitpos++; |
132 #define ADDBIT(code, bit) \ | 135 #define ADDBIT(code, bit) \ |
133 code = code << 1; \ | 136 code = code << 1; \ |
134 if (bit) \ | 137 if (bit) \ |
135 code++; | 138 code++; |
136 #define GETBIT(bitpos) src_buf[bitpos / 8] & (1 << (7 - bitpos % 8)) | 139 #define GETBIT(bitpos) src_buf[bitpos / 8] & (1 << (7 - bitpos % 8)) |
137 static const uint8_t FaxBlackRunIns[] = { | 140 |
| 141 const uint8_t FaxBlackRunIns[] = { |
138 0, 2, 0x02, 3, 0, 0x03, | 142 0, 2, 0x02, 3, 0, 0x03, |
139 2, 0, 2, 0x02, 1, 0, | 143 2, 0, 2, 0x02, 1, 0, |
140 0x03, 4, 0, 2, 0x02, 6, | 144 0x03, 4, 0, 2, 0x02, 6, |
141 0, 0x03, 5, 0, 1, 0x03, | 145 0, 0x03, 5, 0, 1, 0x03, |
142 7, 0, 2, 0x04, 9, 0, | 146 7, 0, 2, 0x04, 9, 0, |
143 0x05, 8, 0, 3, 0x04, 10, | 147 0x05, 8, 0, 3, 0x04, 10, |
144 0, 0x05, 11, 0, 0x07, 12, | 148 0, 0x05, 11, 0, 0x07, 12, |
145 0, 2, 0x04, 13, 0, 0x07, | 149 0, 2, 0x04, 13, 0, 0x07, |
146 14, 0, 1, 0x18, 15, 0, | 150 14, 0, 1, 0x18, 15, 0, |
147 5, 0x08, 18, 0, 0x0f, 64, | 151 5, 0x08, 18, 0, 0x0f, 64, |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
183 704 / 256, 0x4c, 768 % 256, 768 / 256, 0x4d, 832 % 256, | 187 704 / 256, 0x4c, 768 % 256, 768 / 256, 0x4d, 832 % 256, |
184 832 / 256, 0x52, 1280 % 256, 1280 / 256, 0x53, 1344 % 256, | 188 832 / 256, 0x52, 1280 % 256, 1280 / 256, 0x53, 1344 % 256, |
185 1344 / 256, 0x54, 1408 % 256, 1408 / 256, 0x55, 1472 % 256, | 189 1344 / 256, 0x54, 1408 % 256, 1408 / 256, 0x55, 1472 % 256, |
186 1472 / 256, 0x5a, 1536 % 256, 1536 / 256, 0x5b, 1600 % 256, | 190 1472 / 256, 0x5a, 1536 % 256, 1536 / 256, 0x5b, 1600 % 256, |
187 1600 / 256, 0x64, 1664 % 256, 1664 / 256, 0x65, 1728 % 256, | 191 1600 / 256, 0x64, 1664 % 256, 1664 / 256, 0x65, 1728 % 256, |
188 1728 / 256, 0x6c, 512 % 256, 512 / 256, 0x6d, 576 % 256, | 192 1728 / 256, 0x6c, 512 % 256, 512 / 256, 0x6d, 576 % 256, |
189 576 / 256, 0x72, 896 % 256, 896 / 256, 0x73, 960 % 256, | 193 576 / 256, 0x72, 896 % 256, 896 / 256, 0x73, 960 % 256, |
190 960 / 256, 0x74, 1024 % 256, 1024 / 256, 0x75, 1088 % 256, | 194 960 / 256, 0x74, 1024 % 256, 1024 / 256, 0x75, 1088 % 256, |
191 1088 / 256, 0x76, 1152 % 256, 1152 / 256, 0x77, 1216 % 256, | 195 1088 / 256, 0x76, 1152 % 256, 1152 / 256, 0x77, 1216 % 256, |
192 1216 / 256, 0xff}; | 196 1216 / 256, 0xff}; |
193 static const uint8_t FaxWhiteRunIns[] = { | 197 |
| 198 const uint8_t FaxWhiteRunIns[] = { |
194 0, 0, 0, 6, 0x07, 2, | 199 0, 0, 0, 6, 0x07, 2, |
195 0, 0x08, 3, 0, 0x0B, 4, | 200 0, 0x08, 3, 0, 0x0B, 4, |
196 0, 0x0C, 5, 0, 0x0E, 6, | 201 0, 0x0C, 5, 0, 0x0E, 6, |
197 0, 0x0F, 7, 0, 6, 0x07, | 202 0, 0x0F, 7, 0, 6, 0x07, |
198 10, 0, 0x08, 11, 0, 0x12, | 203 10, 0, 0x08, 11, 0, 0x12, |
199 128, 0, 0x13, 8, 0, 0x14, | 204 128, 0, 0x13, 8, 0, 0x14, |
200 9, 0, 0x1b, 64, 0, 9, | 205 9, 0, 0x1b, 64, 0, 9, |
201 0x03, 13, 0, 0x07, 1, 0, | 206 0x03, 13, 0, 0x07, 1, 0, |
202 0x08, 12, 0, 0x17, 192, 0, | 207 0x08, 12, 0, 0x17, 192, 0, |
203 0x18, 1664 % 256, 1664 / 256, 0x2a, 16, 0, | 208 0x18, 1664 % 256, 1664 / 256, 0x2a, 16, 0, |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
240 0xda, 1344 % 256, 1344 / 256, 0xdb, 1408 % 256, 1408 / 256, | 245 0xda, 1344 % 256, 1344 / 256, 0xdb, 1408 % 256, 1408 / 256, |
241 0, 3, 0x08, 1792 % 256, 1792 / 256, 0x0c, | 246 0, 3, 0x08, 1792 % 256, 1792 / 256, 0x0c, |
242 1856 % 256, 1856 / 256, 0x0d, 1920 % 256, 1920 / 256, 10, | 247 1856 % 256, 1856 / 256, 0x0d, 1920 % 256, 1920 / 256, 10, |
243 0x12, 1984 % 256, 1984 / 256, 0x13, 2048 % 256, 2048 / 256, | 248 0x12, 1984 % 256, 1984 / 256, 0x13, 2048 % 256, 2048 / 256, |
244 0x14, 2112 % 256, 2112 / 256, 0x15, 2176 % 256, 2176 / 256, | 249 0x14, 2112 % 256, 2112 / 256, 0x15, 2176 % 256, 2176 / 256, |
245 0x16, 2240 % 256, 2240 / 256, 0x17, 2304 % 256, 2304 / 256, | 250 0x16, 2240 % 256, 2240 / 256, 0x17, 2304 % 256, 2304 / 256, |
246 0x1c, 2368 % 256, 2368 / 256, 0x1d, 2432 % 256, 2432 / 256, | 251 0x1c, 2368 % 256, 2368 / 256, 0x1d, 2432 % 256, 2432 / 256, |
247 0x1e, 2496 % 256, 2496 / 256, 0x1f, 2560 % 256, 2560 / 256, | 252 0x1e, 2496 % 256, 2496 / 256, 0x1f, 2560 % 256, 2560 / 256, |
248 0xff, | 253 0xff, |
249 }; | 254 }; |
250 int _FaxGetRun(const uint8_t* ins_array, | 255 |
251 const uint8_t* src_buf, | 256 int FaxGetRun(const uint8_t* ins_array, |
252 int& bitpos, | 257 const uint8_t* src_buf, |
253 int bitsize) { | 258 int& bitpos, |
| 259 int bitsize) { |
254 FX_DWORD code = 0; | 260 FX_DWORD code = 0; |
255 int ins_off = 0; | 261 int ins_off = 0; |
256 while (1) { | 262 while (1) { |
257 uint8_t ins = ins_array[ins_off++]; | 263 uint8_t ins = ins_array[ins_off++]; |
258 if (ins == 0xff) { | 264 if (ins == 0xff) { |
259 return -1; | 265 return -1; |
260 } | 266 } |
261 if (bitpos >= bitsize) { | 267 if (bitpos >= bitsize) { |
262 return -1; | 268 return -1; |
263 } | 269 } |
264 code <<= 1; | 270 code <<= 1; |
265 if (src_buf[bitpos / 8] & (1 << (7 - bitpos % 8))) { | 271 if (src_buf[bitpos / 8] & (1 << (7 - bitpos % 8))) { |
266 code++; | 272 code++; |
267 } | 273 } |
268 bitpos++; | 274 bitpos++; |
269 int next_off = ins_off + ins * 3; | 275 int next_off = ins_off + ins * 3; |
270 for (; ins_off < next_off; ins_off += 3) { | 276 for (; ins_off < next_off; ins_off += 3) { |
271 if (ins_array[ins_off] == code) { | 277 if (ins_array[ins_off] == code) { |
272 return ins_array[ins_off + 1] + ins_array[ins_off + 2] * 256; | 278 return ins_array[ins_off + 1] + ins_array[ins_off + 2] * 256; |
273 } | 279 } |
274 } | 280 } |
275 } | 281 } |
276 } | 282 } |
277 FX_BOOL _FaxG4GetRow(const uint8_t* src_buf, | 283 |
278 int bitsize, | 284 FX_BOOL FaxG4GetRow(const uint8_t* src_buf, |
279 int& bitpos, | 285 int bitsize, |
280 uint8_t* dest_buf, | 286 int& bitpos, |
281 const uint8_t* ref_buf, | 287 uint8_t* dest_buf, |
282 int columns) { | 288 const uint8_t* ref_buf, |
283 int a0 = -1, a0color = 1; | 289 int columns) { |
| 290 int a0 = -1; |
| 291 bool a0color = true; |
284 while (1) { | 292 while (1) { |
285 if (bitpos >= bitsize) { | 293 if (bitpos >= bitsize) { |
286 return FALSE; | 294 return FALSE; |
287 } | 295 } |
288 int a1, a2, b1, b2; | 296 int a1, a2, b1, b2; |
289 _FaxG4FindB1B2(ref_buf, columns, a0, a0color, b1, b2); | 297 FaxG4FindB1B2(ref_buf, columns, a0, a0color, b1, b2); |
290 FX_BOOL bit = NEXTBIT; | 298 FX_BOOL bit = NEXTBIT; |
291 int v_delta = 0; | 299 int v_delta = 0; |
292 if (bit) { | 300 if (bit) { |
293 } else { | 301 } else { |
294 if (bitpos >= bitsize) { | 302 if (bitpos >= bitsize) { |
295 return FALSE; | 303 return FALSE; |
296 } | 304 } |
297 FX_BOOL bit1 = NEXTBIT; | 305 FX_BOOL bit1 = NEXTBIT; |
298 if (bitpos >= bitsize) { | 306 if (bitpos >= bitsize) { |
299 return FALSE; | 307 return FALSE; |
300 } | 308 } |
301 FX_BOOL bit2 = NEXTBIT; | 309 FX_BOOL bit2 = NEXTBIT; |
302 if (bit1 && bit2) { | 310 if (bit1 && bit2) { |
303 v_delta = 1; | 311 v_delta = 1; |
304 } else if (bit1) { | 312 } else if (bit1) { |
305 v_delta = -1; | 313 v_delta = -1; |
306 } else if (bit2) { | 314 } else if (bit2) { |
307 int run_len1 = 0; | 315 int run_len1 = 0; |
308 while (1) { | 316 while (1) { |
309 int run = _FaxGetRun(a0color ? FaxWhiteRunIns : FaxBlackRunIns, | 317 int run = FaxGetRun(a0color ? FaxWhiteRunIns : FaxBlackRunIns, |
310 src_buf, bitpos, bitsize); | 318 src_buf, bitpos, bitsize); |
311 run_len1 += run; | 319 run_len1 += run; |
312 if (run < 64) { | 320 if (run < 64) { |
313 break; | 321 break; |
314 } | 322 } |
315 } | 323 } |
316 if (a0 < 0) { | 324 if (a0 < 0) { |
317 run_len1++; | 325 run_len1++; |
318 } | 326 } |
319 a1 = a0 + run_len1; | 327 a1 = a0 + run_len1; |
320 if (!a0color) { | 328 if (!a0color) { |
321 _FaxFillBits(dest_buf, columns, a0, a1); | 329 FaxFillBits(dest_buf, columns, a0, a1); |
322 } | 330 } |
323 int run_len2 = 0; | 331 int run_len2 = 0; |
324 while (1) { | 332 while (1) { |
325 int run = _FaxGetRun(a0color ? FaxBlackRunIns : FaxWhiteRunIns, | 333 int run = FaxGetRun(a0color ? FaxBlackRunIns : FaxWhiteRunIns, |
326 src_buf, bitpos, bitsize); | 334 src_buf, bitpos, bitsize); |
327 run_len2 += run; | 335 run_len2 += run; |
328 if (run < 64) { | 336 if (run < 64) { |
329 break; | 337 break; |
330 } | 338 } |
331 } | 339 } |
332 a2 = a1 + run_len2; | 340 a2 = a1 + run_len2; |
333 if (a0color) { | 341 if (a0color) { |
334 _FaxFillBits(dest_buf, columns, a1, a2); | 342 FaxFillBits(dest_buf, columns, a1, a2); |
335 } | 343 } |
336 a0 = a2; | 344 a0 = a2; |
337 if (a0 < columns) { | 345 if (a0 < columns) { |
338 continue; | 346 continue; |
339 } | 347 } |
340 return TRUE; | 348 return TRUE; |
341 } else { | 349 } else { |
342 if (bitpos >= bitsize) { | 350 if (bitpos >= bitsize) { |
343 return FALSE; | 351 return FALSE; |
344 } | 352 } |
345 bit = NEXTBIT; | 353 bit = NEXTBIT; |
346 if (bit) { | 354 if (bit) { |
347 if (!a0color) { | 355 if (!a0color) { |
348 _FaxFillBits(dest_buf, columns, a0, b2); | 356 FaxFillBits(dest_buf, columns, a0, b2); |
349 } | 357 } |
350 if (b2 >= columns) { | 358 if (b2 >= columns) { |
351 return TRUE; | 359 return TRUE; |
352 } | 360 } |
353 a0 = b2; | 361 a0 = b2; |
354 continue; | 362 continue; |
355 } else { | 363 } else { |
356 if (bitpos >= bitsize) { | 364 if (bitpos >= bitsize) { |
357 return FALSE; | 365 return FALSE; |
358 } | 366 } |
(...skipping 27 matching lines...) Expand all Loading... |
386 } else { | 394 } else { |
387 bitpos += 5; | 395 bitpos += 5; |
388 return TRUE; | 396 return TRUE; |
389 } | 397 } |
390 } | 398 } |
391 } | 399 } |
392 } | 400 } |
393 } | 401 } |
394 a1 = b1 + v_delta; | 402 a1 = b1 + v_delta; |
395 if (!a0color) { | 403 if (!a0color) { |
396 _FaxFillBits(dest_buf, columns, a0, a1); | 404 FaxFillBits(dest_buf, columns, a0, a1); |
397 } | 405 } |
398 if (a1 >= columns) { | 406 if (a1 >= columns) { |
399 return TRUE; | 407 return TRUE; |
400 } | 408 } |
401 a0 = a1; | 409 a0 = a1; |
402 a0color = !a0color; | 410 a0color = !a0color; |
403 } | 411 } |
404 } | 412 } |
405 FX_BOOL _FaxSkipEOL(const uint8_t* src_buf, int bitsize, int& bitpos) { | 413 |
| 414 FX_BOOL FaxSkipEOL(const uint8_t* src_buf, int bitsize, int& bitpos) { |
406 int startbit = bitpos; | 415 int startbit = bitpos; |
407 while (bitpos < bitsize) { | 416 while (bitpos < bitsize) { |
408 int bit = NEXTBIT; | 417 int bit = NEXTBIT; |
409 if (bit) { | 418 if (bit) { |
410 if (bitpos - startbit <= 11) { | 419 if (bitpos - startbit <= 11) { |
411 bitpos = startbit; | 420 bitpos = startbit; |
412 } | 421 } |
413 return TRUE; | 422 return TRUE; |
414 } | 423 } |
415 } | 424 } |
416 return FALSE; | 425 return FALSE; |
417 } | 426 } |
418 FX_BOOL _FaxGet1DLine(const uint8_t* src_buf, | 427 |
419 int bitsize, | 428 FX_BOOL FaxGet1DLine(const uint8_t* src_buf, |
420 int& bitpos, | 429 int bitsize, |
421 uint8_t* dest_buf, | 430 int& bitpos, |
422 int columns) { | 431 uint8_t* dest_buf, |
423 int color = TRUE; | 432 int columns) { |
| 433 bool color = true; |
424 int startpos = 0; | 434 int startpos = 0; |
425 while (1) { | 435 while (1) { |
426 if (bitpos >= bitsize) { | 436 if (bitpos >= bitsize) { |
427 return FALSE; | 437 return FALSE; |
428 } | 438 } |
429 int run_len = 0; | 439 int run_len = 0; |
430 while (1) { | 440 while (1) { |
431 int run = _FaxGetRun(color ? FaxWhiteRunIns : FaxBlackRunIns, src_buf, | 441 int run = FaxGetRun(color ? FaxWhiteRunIns : FaxBlackRunIns, src_buf, |
432 bitpos, bitsize); | 442 bitpos, bitsize); |
433 if (run < 0) { | 443 if (run < 0) { |
434 while (bitpos < bitsize) { | 444 while (bitpos < bitsize) { |
435 int bit = NEXTBIT; | 445 int bit = NEXTBIT; |
436 if (bit) { | 446 if (bit) { |
437 return TRUE; | 447 return TRUE; |
438 } | 448 } |
439 } | 449 } |
440 return FALSE; | 450 return FALSE; |
441 } | 451 } |
442 run_len += run; | 452 run_len += run; |
443 if (run < 64) { | 453 if (run < 64) { |
444 break; | 454 break; |
445 } | 455 } |
446 } | 456 } |
447 if (!color) { | 457 if (!color) { |
448 _FaxFillBits(dest_buf, columns, startpos, startpos + run_len); | 458 FaxFillBits(dest_buf, columns, startpos, startpos + run_len); |
449 } | 459 } |
450 startpos += run_len; | 460 startpos += run_len; |
451 if (startpos >= columns) { | 461 if (startpos >= columns) { |
452 break; | 462 break; |
453 } | 463 } |
454 color = !color; | 464 color = !color; |
455 } | 465 } |
456 return TRUE; | 466 return TRUE; |
457 } | 467 } |
458 | 468 |
| 469 const uint8_t BlackRunTerminator[128] = { |
| 470 0x37, 10, 0x02, 3, 0x03, 2, 0x02, 2, 0x03, 3, 0x03, 4, 0x02, 4, |
| 471 0x03, 5, 0x05, 6, 0x04, 6, 0x04, 7, 0x05, 7, 0x07, 7, 0x04, 8, |
| 472 0x07, 8, 0x18, 9, 0x17, 10, 0x18, 10, 0x08, 10, 0x67, 11, 0x68, 11, |
| 473 0x6c, 11, 0x37, 11, 0x28, 11, 0x17, 11, 0x18, 11, 0xca, 12, 0xcb, 12, |
| 474 0xcc, 12, 0xcd, 12, 0x68, 12, 0x69, 12, 0x6a, 12, 0x6b, 12, 0xd2, 12, |
| 475 0xd3, 12, 0xd4, 12, 0xd5, 12, 0xd6, 12, 0xd7, 12, 0x6c, 12, 0x6d, 12, |
| 476 0xda, 12, 0xdb, 12, 0x54, 12, 0x55, 12, 0x56, 12, 0x57, 12, 0x64, 12, |
| 477 0x65, 12, 0x52, 12, 0x53, 12, 0x24, 12, 0x37, 12, 0x38, 12, 0x27, 12, |
| 478 0x28, 12, 0x58, 12, 0x59, 12, 0x2b, 12, 0x2c, 12, 0x5a, 12, 0x66, 12, |
| 479 0x67, 12, |
| 480 }; |
| 481 |
| 482 const uint8_t BlackRunMarkup[80] = { |
| 483 0x0f, 10, 0xc8, 12, 0xc9, 12, 0x5b, 12, 0x33, 12, 0x34, 12, 0x35, 12, |
| 484 0x6c, 13, 0x6d, 13, 0x4a, 13, 0x4b, 13, 0x4c, 13, 0x4d, 13, 0x72, 13, |
| 485 0x73, 13, 0x74, 13, 0x75, 13, 0x76, 13, 0x77, 13, 0x52, 13, 0x53, 13, |
| 486 0x54, 13, 0x55, 13, 0x5a, 13, 0x5b, 13, 0x64, 13, 0x65, 13, 0x08, 11, |
| 487 0x0c, 11, 0x0d, 11, 0x12, 12, 0x13, 12, 0x14, 12, 0x15, 12, 0x16, 12, |
| 488 0x17, 12, 0x1c, 12, 0x1d, 12, 0x1e, 12, 0x1f, 12, |
| 489 }; |
| 490 |
| 491 const uint8_t WhiteRunTerminator[128] = { |
| 492 0x35, 8, 0x07, 6, 0x07, 4, 0x08, 4, 0x0B, 4, 0x0C, 4, 0x0E, 4, 0x0F, 4, |
| 493 0x13, 5, 0x14, 5, 0x07, 5, 0x08, 5, 0x08, 6, 0x03, 6, 0x34, 6, 0x35, 6, |
| 494 0x2a, 6, 0x2B, 6, 0x27, 7, 0x0c, 7, 0x08, 7, 0x17, 7, 0x03, 7, 0x04, 7, |
| 495 0x28, 7, 0x2B, 7, 0x13, 7, 0x24, 7, 0x18, 7, 0x02, 8, 0x03, 8, 0x1a, 8, |
| 496 0x1b, 8, 0x12, 8, 0x13, 8, 0x14, 8, 0x15, 8, 0x16, 8, 0x17, 8, 0x28, 8, |
| 497 0x29, 8, 0x2a, 8, 0x2b, 8, 0x2c, 8, 0x2d, 8, 0x04, 8, 0x05, 8, 0x0a, 8, |
| 498 0x0b, 8, 0x52, 8, 0x53, 8, 0x54, 8, 0x55, 8, 0x24, 8, 0x25, 8, 0x58, 8, |
| 499 0x59, 8, 0x5a, 8, 0x5b, 8, 0x4a, 8, 0x4b, 8, 0x32, 8, 0x33, 8, 0x34, 8, |
| 500 }; |
| 501 |
| 502 const uint8_t WhiteRunMarkup[80] = { |
| 503 0x1b, 5, 0x12, 5, 0x17, 6, 0x37, 7, 0x36, 8, 0x37, 8, 0x64, 8, |
| 504 0x65, 8, 0x68, 8, 0x67, 8, 0xcc, 9, 0xcd, 9, 0xd2, 9, 0xd3, 9, |
| 505 0xd4, 9, 0xd5, 9, 0xd6, 9, 0xd7, 9, 0xd8, 9, 0xd9, 9, 0xda, 9, |
| 506 0xdb, 9, 0x98, 9, 0x99, 9, 0x9a, 9, 0x18, 6, 0x9b, 9, 0x08, 11, |
| 507 0x0c, 11, 0x0d, 11, 0x12, 12, 0x13, 12, 0x14, 12, 0x15, 12, 0x16, 12, |
| 508 0x17, 12, 0x1c, 12, 0x1d, 12, 0x1e, 12, 0x1f, 12, |
| 509 }; |
| 510 |
| 511 void AddBitStream(uint8_t* dest_buf, int& dest_bitpos, int data, int bitlen) { |
| 512 for (int i = bitlen - 1; i >= 0; i--) { |
| 513 if (data & (1 << i)) { |
| 514 dest_buf[dest_bitpos / 8] |= 1 << (7 - dest_bitpos % 8); |
| 515 } |
| 516 dest_bitpos++; |
| 517 } |
| 518 } |
| 519 |
| 520 void FaxEncodeRun(uint8_t* dest_buf, int& dest_bitpos, int run, bool bWhite) { |
| 521 while (run >= 2560) { |
| 522 AddBitStream(dest_buf, dest_bitpos, 0x1f, 12); |
| 523 run -= 2560; |
| 524 } |
| 525 if (run >= 64) { |
| 526 int markup = run - run % 64; |
| 527 const uint8_t* p = bWhite ? WhiteRunMarkup : BlackRunMarkup; |
| 528 p += (markup / 64 - 1) * 2; |
| 529 AddBitStream(dest_buf, dest_bitpos, *p, p[1]); |
| 530 } |
| 531 run %= 64; |
| 532 const uint8_t* p = bWhite ? WhiteRunTerminator : BlackRunTerminator; |
| 533 p += run * 2; |
| 534 AddBitStream(dest_buf, dest_bitpos, *p, p[1]); |
| 535 } |
| 536 |
| 537 void FaxEncode2DLine(uint8_t* dest_buf, |
| 538 int& dest_bitpos, |
| 539 const uint8_t* src_buf, |
| 540 const uint8_t* ref_buf, |
| 541 int cols) { |
| 542 int a0 = -1; |
| 543 bool a0color = true; |
| 544 while (1) { |
| 545 int a1 = FindBit(src_buf, cols, a0 + 1, !a0color); |
| 546 int b1, b2; |
| 547 FaxG4FindB1B2(ref_buf, cols, a0, a0color, b1, b2); |
| 548 if (b2 < a1) { |
| 549 dest_bitpos += 3; |
| 550 dest_buf[dest_bitpos / 8] |= 1 << (7 - dest_bitpos % 8); |
| 551 dest_bitpos++; |
| 552 a0 = b2; |
| 553 } else if (a1 - b1 <= 3 && b1 - a1 <= 3) { |
| 554 int delta = a1 - b1; |
| 555 switch (delta) { |
| 556 case 0: |
| 557 dest_buf[dest_bitpos / 8] |= 1 << (7 - dest_bitpos % 8); |
| 558 break; |
| 559 case 1: |
| 560 case 2: |
| 561 case 3: |
| 562 dest_bitpos += delta == 1 ? 1 : delta + 2; |
| 563 dest_buf[dest_bitpos / 8] |= 1 << (7 - dest_bitpos % 8); |
| 564 dest_bitpos++; |
| 565 dest_buf[dest_bitpos / 8] |= 1 << (7 - dest_bitpos % 8); |
| 566 break; |
| 567 case -1: |
| 568 case -2: |
| 569 case -3: |
| 570 dest_bitpos += delta == -1 ? 1 : -delta + 2; |
| 571 dest_buf[dest_bitpos / 8] |= 1 << (7 - dest_bitpos % 8); |
| 572 dest_bitpos++; |
| 573 break; |
| 574 } |
| 575 dest_bitpos++; |
| 576 a0 = a1; |
| 577 a0color = !a0color; |
| 578 } else { |
| 579 int a2 = FindBit(src_buf, cols, a1 + 1, a0color); |
| 580 dest_bitpos++; |
| 581 dest_bitpos++; |
| 582 dest_buf[dest_bitpos / 8] |= 1 << (7 - dest_bitpos % 8); |
| 583 dest_bitpos++; |
| 584 if (a0 < 0) { |
| 585 a0 = 0; |
| 586 } |
| 587 FaxEncodeRun(dest_buf, dest_bitpos, a1 - a0, a0color); |
| 588 FaxEncodeRun(dest_buf, dest_bitpos, a2 - a1, !a0color); |
| 589 a0 = a2; |
| 590 } |
| 591 if (a0 >= cols) { |
| 592 return; |
| 593 } |
| 594 } |
| 595 } |
| 596 |
| 597 } // namespace |
| 598 |
459 class CCodec_FaxDecoder : public CCodec_ScanlineDecoder { | 599 class CCodec_FaxDecoder : public CCodec_ScanlineDecoder { |
460 public: | 600 public: |
461 CCodec_FaxDecoder(); | 601 CCodec_FaxDecoder(); |
462 ~CCodec_FaxDecoder() override; | 602 ~CCodec_FaxDecoder() override; |
463 | 603 |
464 FX_BOOL Create(const uint8_t* src_buf, | 604 FX_BOOL Create(const uint8_t* src_buf, |
465 FX_DWORD src_size, | 605 FX_DWORD src_size, |
466 int width, | 606 int width, |
467 int height, | 607 int height, |
468 int K, | 608 int K, |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
528 m_bColorTransformed = FALSE; | 668 m_bColorTransformed = FALSE; |
529 return TRUE; | 669 return TRUE; |
530 } | 670 } |
531 FX_BOOL CCodec_FaxDecoder::v_Rewind() { | 671 FX_BOOL CCodec_FaxDecoder::v_Rewind() { |
532 FXSYS_memset(m_pRefBuf, 0xff, m_Pitch); | 672 FXSYS_memset(m_pRefBuf, 0xff, m_Pitch); |
533 bitpos = 0; | 673 bitpos = 0; |
534 return TRUE; | 674 return TRUE; |
535 } | 675 } |
536 uint8_t* CCodec_FaxDecoder::v_GetNextLine() { | 676 uint8_t* CCodec_FaxDecoder::v_GetNextLine() { |
537 int bitsize = m_SrcSize * 8; | 677 int bitsize = m_SrcSize * 8; |
538 _FaxSkipEOL(m_pSrcBuf, bitsize, bitpos); | 678 FaxSkipEOL(m_pSrcBuf, bitsize, bitpos); |
539 if (bitpos >= bitsize) { | 679 if (bitpos >= bitsize) { |
540 return NULL; | 680 return NULL; |
541 } | 681 } |
542 FXSYS_memset(m_pScanlineBuf, 0xff, m_Pitch); | 682 FXSYS_memset(m_pScanlineBuf, 0xff, m_Pitch); |
543 if (m_Encoding < 0) { | 683 if (m_Encoding < 0) { |
544 _FaxG4GetRow(m_pSrcBuf, bitsize, bitpos, m_pScanlineBuf, m_pRefBuf, | 684 FaxG4GetRow(m_pSrcBuf, bitsize, bitpos, m_pScanlineBuf, m_pRefBuf, |
545 m_OrigWidth); | 685 m_OrigWidth); |
546 FXSYS_memcpy(m_pRefBuf, m_pScanlineBuf, m_Pitch); | 686 FXSYS_memcpy(m_pRefBuf, m_pScanlineBuf, m_Pitch); |
547 } else if (m_Encoding == 0) { | 687 } else if (m_Encoding == 0) { |
548 _FaxGet1DLine(m_pSrcBuf, bitsize, bitpos, m_pScanlineBuf, m_OrigWidth); | 688 FaxGet1DLine(m_pSrcBuf, bitsize, bitpos, m_pScanlineBuf, m_OrigWidth); |
549 } else { | 689 } else { |
550 FX_BOOL bNext1D = m_pSrcBuf[bitpos / 8] & (1 << (7 - bitpos % 8)); | 690 FX_BOOL bNext1D = m_pSrcBuf[bitpos / 8] & (1 << (7 - bitpos % 8)); |
551 bitpos++; | 691 bitpos++; |
552 if (bNext1D) { | 692 if (bNext1D) { |
553 _FaxGet1DLine(m_pSrcBuf, bitsize, bitpos, m_pScanlineBuf, m_OrigWidth); | 693 FaxGet1DLine(m_pSrcBuf, bitsize, bitpos, m_pScanlineBuf, m_OrigWidth); |
554 } else { | 694 } else { |
555 _FaxG4GetRow(m_pSrcBuf, bitsize, bitpos, m_pScanlineBuf, m_pRefBuf, | 695 FaxG4GetRow(m_pSrcBuf, bitsize, bitpos, m_pScanlineBuf, m_pRefBuf, |
556 m_OrigWidth); | 696 m_OrigWidth); |
557 } | 697 } |
558 FXSYS_memcpy(m_pRefBuf, m_pScanlineBuf, m_Pitch); | 698 FXSYS_memcpy(m_pRefBuf, m_pScanlineBuf, m_Pitch); |
559 } | 699 } |
560 if (m_bEndOfLine) { | 700 if (m_bEndOfLine) { |
561 _FaxSkipEOL(m_pSrcBuf, bitsize, bitpos); | 701 FaxSkipEOL(m_pSrcBuf, bitsize, bitpos); |
562 } | 702 } |
563 if (m_bByteAlign && bitpos < bitsize) { | 703 if (m_bByteAlign && bitpos < bitsize) { |
564 int bitpos0 = bitpos; | 704 int bitpos0 = bitpos; |
565 int bitpos1 = (bitpos + 7) / 8 * 8; | 705 int bitpos1 = (bitpos + 7) / 8 * 8; |
566 while (m_bByteAlign && bitpos0 < bitpos1) { | 706 while (m_bByteAlign && bitpos0 < bitpos1) { |
567 int bit = m_pSrcBuf[bitpos0 / 8] & (1 << (7 - bitpos0 % 8)); | 707 int bit = m_pSrcBuf[bitpos0 / 8] & (1 << (7 - bitpos0 % 8)); |
568 if (bit != 0) { | 708 if (bit != 0) { |
569 m_bByteAlign = FALSE; | 709 m_bByteAlign = FALSE; |
570 } else { | 710 } else { |
571 bitpos0++; | 711 bitpos0++; |
(...skipping 10 matching lines...) Expand all Loading... |
582 } | 722 } |
583 return m_pScanlineBuf; | 723 return m_pScanlineBuf; |
584 } | 724 } |
585 FX_DWORD CCodec_FaxDecoder::GetSrcOffset() { | 725 FX_DWORD CCodec_FaxDecoder::GetSrcOffset() { |
586 FX_DWORD ret = (bitpos + 7) / 8; | 726 FX_DWORD ret = (bitpos + 7) / 8; |
587 if (ret > m_SrcSize) { | 727 if (ret > m_SrcSize) { |
588 ret = m_SrcSize; | 728 ret = m_SrcSize; |
589 } | 729 } |
590 return ret; | 730 return ret; |
591 } | 731 } |
592 extern "C" { | 732 |
593 void _FaxG4Decode(const uint8_t* src_buf, | 733 void FaxG4Decode(const uint8_t* src_buf, |
594 FX_DWORD src_size, | 734 FX_DWORD src_size, |
595 int* pbitpos, | 735 int* pbitpos, |
596 uint8_t* dest_buf, | 736 uint8_t* dest_buf, |
597 int width, | 737 int width, |
598 int height, | 738 int height, |
599 int pitch) { | 739 int pitch) { |
600 if (pitch == 0) { | 740 if (pitch == 0) { |
601 pitch = (width + 7) / 8; | 741 pitch = (width + 7) / 8; |
602 } | 742 } |
603 uint8_t* ref_buf = FX_Alloc(uint8_t, pitch); | 743 uint8_t* ref_buf = FX_Alloc(uint8_t, pitch); |
604 FXSYS_memset(ref_buf, 0xff, pitch); | 744 FXSYS_memset(ref_buf, 0xff, pitch); |
605 int bitpos = *pbitpos; | 745 int bitpos = *pbitpos; |
606 for (int iRow = 0; iRow < height; iRow++) { | 746 for (int iRow = 0; iRow < height; iRow++) { |
607 uint8_t* line_buf = dest_buf + iRow * pitch; | 747 uint8_t* line_buf = dest_buf + iRow * pitch; |
608 FXSYS_memset(line_buf, 0xff, pitch); | 748 FXSYS_memset(line_buf, 0xff, pitch); |
609 _FaxG4GetRow(src_buf, src_size << 3, bitpos, line_buf, ref_buf, width); | 749 FaxG4GetRow(src_buf, src_size << 3, bitpos, line_buf, ref_buf, width); |
610 FXSYS_memcpy(ref_buf, line_buf, pitch); | 750 FXSYS_memcpy(ref_buf, line_buf, pitch); |
611 } | 751 } |
612 FX_Free(ref_buf); | 752 FX_Free(ref_buf); |
613 *pbitpos = bitpos; | 753 *pbitpos = bitpos; |
614 } | 754 } |
615 }; | 755 |
616 static const uint8_t BlackRunTerminator[128] = { | |
617 0x37, 10, 0x02, 3, 0x03, 2, 0x02, 2, 0x03, 3, 0x03, 4, 0x02, 4, | |
618 0x03, 5, 0x05, 6, 0x04, 6, 0x04, 7, 0x05, 7, 0x07, 7, 0x04, 8, | |
619 0x07, 8, 0x18, 9, 0x17, 10, 0x18, 10, 0x08, 10, 0x67, 11, 0x68, 11, | |
620 0x6c, 11, 0x37, 11, 0x28, 11, 0x17, 11, 0x18, 11, 0xca, 12, 0xcb, 12, | |
621 0xcc, 12, 0xcd, 12, 0x68, 12, 0x69, 12, 0x6a, 12, 0x6b, 12, 0xd2, 12, | |
622 0xd3, 12, 0xd4, 12, 0xd5, 12, 0xd6, 12, 0xd7, 12, 0x6c, 12, 0x6d, 12, | |
623 0xda, 12, 0xdb, 12, 0x54, 12, 0x55, 12, 0x56, 12, 0x57, 12, 0x64, 12, | |
624 0x65, 12, 0x52, 12, 0x53, 12, 0x24, 12, 0x37, 12, 0x38, 12, 0x27, 12, | |
625 0x28, 12, 0x58, 12, 0x59, 12, 0x2b, 12, 0x2c, 12, 0x5a, 12, 0x66, 12, | |
626 0x67, 12, | |
627 }; | |
628 static const uint8_t BlackRunMarkup[80] = { | |
629 0x0f, 10, 0xc8, 12, 0xc9, 12, 0x5b, 12, 0x33, 12, 0x34, 12, 0x35, 12, | |
630 0x6c, 13, 0x6d, 13, 0x4a, 13, 0x4b, 13, 0x4c, 13, 0x4d, 13, 0x72, 13, | |
631 0x73, 13, 0x74, 13, 0x75, 13, 0x76, 13, 0x77, 13, 0x52, 13, 0x53, 13, | |
632 0x54, 13, 0x55, 13, 0x5a, 13, 0x5b, 13, 0x64, 13, 0x65, 13, 0x08, 11, | |
633 0x0c, 11, 0x0d, 11, 0x12, 12, 0x13, 12, 0x14, 12, 0x15, 12, 0x16, 12, | |
634 0x17, 12, 0x1c, 12, 0x1d, 12, 0x1e, 12, 0x1f, 12, | |
635 }; | |
636 static const uint8_t WhiteRunTerminator[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 static 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 static void _AddBitStream(uint8_t* dest_buf, | |
655 int& dest_bitpos, | |
656 int data, | |
657 int bitlen) { | |
658 for (int i = bitlen - 1; i >= 0; i--) { | |
659 if (data & (1 << i)) { | |
660 dest_buf[dest_bitpos / 8] |= 1 << (7 - dest_bitpos % 8); | |
661 } | |
662 dest_bitpos++; | |
663 } | |
664 } | |
665 static void _FaxEncodeRun(uint8_t* dest_buf, | |
666 int& dest_bitpos, | |
667 int run, | |
668 FX_BOOL bWhite) { | |
669 while (run >= 2560) { | |
670 _AddBitStream(dest_buf, dest_bitpos, 0x1f, 12); | |
671 run -= 2560; | |
672 } | |
673 if (run >= 64) { | |
674 int markup = run - run % 64; | |
675 const uint8_t* p = bWhite ? WhiteRunMarkup : BlackRunMarkup; | |
676 p += (markup / 64 - 1) * 2; | |
677 _AddBitStream(dest_buf, dest_bitpos, *p, p[1]); | |
678 } | |
679 run %= 64; | |
680 const uint8_t* p = bWhite ? WhiteRunTerminator : BlackRunTerminator; | |
681 p += run * 2; | |
682 _AddBitStream(dest_buf, dest_bitpos, *p, p[1]); | |
683 } | |
684 static void _FaxEncode2DLine(uint8_t* dest_buf, | |
685 int& dest_bitpos, | |
686 const uint8_t* src_buf, | |
687 const uint8_t* ref_buf, | |
688 int cols) { | |
689 int a0 = -1, a0color = 1; | |
690 while (1) { | |
691 int a1 = _FindBit(src_buf, cols, a0 + 1, 1 - a0color); | |
692 int b1, 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 = 1 - 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, 1 - a0color); | |
735 a0 = a2; | |
736 } | |
737 if (a0 >= cols) { | |
738 return; | |
739 } | |
740 } | |
741 } | |
742 class CCodec_FaxEncoder { | 756 class CCodec_FaxEncoder { |
743 public: | 757 public: |
744 CCodec_FaxEncoder(const uint8_t* src_buf, int width, int height, int pitch); | 758 CCodec_FaxEncoder(const uint8_t* src_buf, int width, int height, int pitch); |
745 ~CCodec_FaxEncoder(); | 759 ~CCodec_FaxEncoder(); |
746 void Encode(uint8_t*& dest_buf, FX_DWORD& dest_size); | 760 void Encode(uint8_t*& dest_buf, FX_DWORD& dest_size); |
747 void Encode2DLine(const uint8_t* scan_line); | 761 void Encode2DLine(const uint8_t* scan_line); |
748 CFX_BinaryBuf m_DestBuf; | 762 CFX_BinaryBuf m_DestBuf; |
749 uint8_t* m_pRefLine; | 763 uint8_t* m_pRefLine; |
750 uint8_t* m_pLineBuf; | 764 uint8_t* m_pLineBuf; |
751 int m_Cols, m_Rows, m_Pitch; | 765 int m_Cols, m_Rows, m_Pitch; |
(...skipping 16 matching lines...) Expand all Loading... |
768 FX_Free(m_pRefLine); | 782 FX_Free(m_pRefLine); |
769 FX_Free(m_pLineBuf); | 783 FX_Free(m_pLineBuf); |
770 } | 784 } |
771 void CCodec_FaxEncoder::Encode(uint8_t*& dest_buf, FX_DWORD& dest_size) { | 785 void CCodec_FaxEncoder::Encode(uint8_t*& dest_buf, FX_DWORD& dest_size) { |
772 int dest_bitpos = 0; | 786 int dest_bitpos = 0; |
773 uint8_t last_byte = 0; | 787 uint8_t last_byte = 0; |
774 for (int i = 0; i < m_Rows; i++) { | 788 for (int i = 0; i < m_Rows; i++) { |
775 const uint8_t* scan_line = m_pSrcBuf + i * m_Pitch; | 789 const uint8_t* scan_line = m_pSrcBuf + i * m_Pitch; |
776 FXSYS_memset(m_pLineBuf, 0, m_Pitch * 8); | 790 FXSYS_memset(m_pLineBuf, 0, m_Pitch * 8); |
777 m_pLineBuf[0] = last_byte; | 791 m_pLineBuf[0] = last_byte; |
778 _FaxEncode2DLine(m_pLineBuf, dest_bitpos, scan_line, m_pRefLine, m_Cols); | 792 FaxEncode2DLine(m_pLineBuf, dest_bitpos, scan_line, m_pRefLine, m_Cols); |
779 m_DestBuf.AppendBlock(m_pLineBuf, dest_bitpos / 8); | 793 m_DestBuf.AppendBlock(m_pLineBuf, dest_bitpos / 8); |
780 last_byte = m_pLineBuf[dest_bitpos / 8]; | 794 last_byte = m_pLineBuf[dest_bitpos / 8]; |
781 dest_bitpos %= 8; | 795 dest_bitpos %= 8; |
782 FXSYS_memcpy(m_pRefLine, scan_line, m_Pitch); | 796 FXSYS_memcpy(m_pRefLine, scan_line, m_Pitch); |
783 } | 797 } |
784 if (dest_bitpos) { | 798 if (dest_bitpos) { |
785 m_DestBuf.AppendByte(last_byte); | 799 m_DestBuf.AppendByte(last_byte); |
786 } | 800 } |
787 dest_buf = m_DestBuf.GetBuffer(); | 801 dest_buf = m_DestBuf.GetBuffer(); |
788 dest_size = m_DestBuf.GetSize(); | 802 dest_size = m_DestBuf.GetSize(); |
(...skipping 18 matching lines...) Expand all Loading... |
807 FX_BOOL EndOfLine, | 821 FX_BOOL EndOfLine, |
808 FX_BOOL EncodedByteAlign, | 822 FX_BOOL EncodedByteAlign, |
809 FX_BOOL BlackIs1, | 823 FX_BOOL BlackIs1, |
810 int Columns, | 824 int Columns, |
811 int Rows) { | 825 int Rows) { |
812 CCodec_FaxDecoder* pDecoder = new CCodec_FaxDecoder; | 826 CCodec_FaxDecoder* pDecoder = new CCodec_FaxDecoder; |
813 pDecoder->Create(src_buf, src_size, width, height, K, EndOfLine, | 827 pDecoder->Create(src_buf, src_size, width, height, K, EndOfLine, |
814 EncodedByteAlign, BlackIs1, Columns, Rows); | 828 EncodedByteAlign, BlackIs1, Columns, Rows); |
815 return pDecoder; | 829 return pDecoder; |
816 } | 830 } |
OLD | NEW |