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

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

Issue 1265503005: clang-format all pdfium code. (Closed) Base URL: https://pdfium.googlesource.com/pdfium.git@master
Patch Set: sigh Created 5 years, 4 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 "../../../include/fxcodec/fx_codec.h" 7 #include "../../../include/fxcodec/fx_codec.h"
8 #include "codec_int.h" 8 #include "codec_int.h"
9 const uint8_t OneLeadPos[256] = { 9 const uint8_t OneLeadPos[256] = {
10 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 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,
11 3, 3, 3, 3, 3, 3, 3, 3, 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,
12 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,
13 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 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,
14 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,
15 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,
16 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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,
17 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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,
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,
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,
18 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,
19 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,
21 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,
23 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,
25 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
26 }; 21 };
27 const uint8_t ZeroLeadPos[256] = { 22 const uint8_t ZeroLeadPos[256] = {
28 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, 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, 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,
30 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,
31 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,
32 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,
33 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,
34 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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,
35 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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,
36 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,
37 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 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,
38 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,
40 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
41 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
42 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
43 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 7, 8, 33 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 7, 8,
44 }; 34 };
45 35
46 int _FindBit(const uint8_t* data_buf, int max_pos, int start_pos, int bit) 36 int _FindBit(const uint8_t* data_buf, int max_pos, int start_pos, int bit) {
47 { 37 if (start_pos >= max_pos) {
48 if (start_pos >= max_pos) { 38 return max_pos;
49 return max_pos; 39 }
50 } 40 const uint8_t* leading_pos = bit ? OneLeadPos : ZeroLeadPos;
51 const uint8_t* leading_pos = bit ? OneLeadPos : ZeroLeadPos; 41 if (start_pos % 8) {
52 if (start_pos % 8) { 42 uint8_t data = data_buf[start_pos / 8];
53 uint8_t data = data_buf[start_pos / 8]; 43 if (bit) {
44 data &= 0xff >> (start_pos % 8);
45 } else {
46 data |= 0xff << (8 - start_pos % 8);
47 }
48 if (leading_pos[data] < 8) {
49 return start_pos / 8 * 8 + leading_pos[data];
50 }
51 start_pos += 7;
52 }
53 uint8_t skip = bit ? 0x00 : 0xff;
54 int byte_pos = start_pos / 8;
55 int max_byte = (max_pos + 7) / 8;
56 while (byte_pos < max_byte) {
57 if (data_buf[byte_pos] != skip) {
58 break;
59 }
60 byte_pos++;
61 }
62 if (byte_pos == max_byte) {
63 return max_pos;
64 }
65 int pos = leading_pos[data_buf[byte_pos]] + byte_pos * 8;
66 if (pos > max_pos) {
67 pos = max_pos;
68 }
69 return pos;
70 }
71 void _FaxG4FindB1B2(const uint8_t* ref_buf,
72 int columns,
73 int a0,
74 FX_BOOL a0color,
75 int& b1,
76 int& b2) {
77 if (a0color) {
78 a0color = 1;
79 }
80 uint8_t first_bit =
81 (a0 < 0) ? 1 : ((ref_buf[a0 / 8] & (1 << (7 - a0 % 8))) != 0);
82 b1 = _FindBit(ref_buf, columns, a0 + 1, !first_bit);
83 if (b1 >= columns) {
84 b1 = b2 = columns;
85 return;
86 }
87 if (first_bit == !a0color) {
88 b1 = _FindBit(ref_buf, columns, b1 + 1, first_bit);
89 first_bit = !first_bit;
90 }
91 if (b1 >= columns) {
92 b1 = b2 = columns;
93 return;
94 }
95 b2 = _FindBit(ref_buf, columns, b1 + 1, first_bit);
96 }
97 void _FaxFillBits(uint8_t* dest_buf, int columns, int startpos, int endpos) {
98 if (startpos < 0) {
99 startpos = 0;
100 }
101 if (endpos < 0) {
102 endpos = 0;
103 }
104 if (endpos >= columns) {
105 endpos = columns;
106 }
107 if (startpos >= endpos) {
108 return;
109 }
110 int first_byte = startpos / 8;
111 int last_byte = (endpos - 1) / 8;
112 if (first_byte == last_byte) {
113 for (int i = startpos % 8; i <= (endpos - 1) % 8; i++) {
114 dest_buf[first_byte] -= 1 << (7 - i);
115 }
116 return;
117 }
118 int i;
119 for (i = startpos % 8; i < 8; i++) {
120 dest_buf[first_byte] -= 1 << (7 - i);
121 }
122 for (i = 0; i <= (endpos - 1) % 8; i++) {
123 dest_buf[last_byte] -= 1 << (7 - i);
124 }
125 if (last_byte > first_byte + 1) {
126 FXSYS_memset(dest_buf + first_byte + 1, 0, last_byte - first_byte - 1);
127 }
128 }
129 #define NEXTBIT \
130 src_buf[bitpos / 8] & (1 << (7 - bitpos % 8)); \
131 bitpos++;
132 #define ADDBIT(code, bit) \
133 code = code << 1; \
134 if (bit) \
135 code++;
136 #define GETBIT(bitpos) src_buf[bitpos / 8] & (1 << (7 - bitpos % 8))
137 static const uint8_t FaxBlackRunIns[] = {
138 0, 2, 0x02, 3, 0, 0x03,
139 2, 0, 2, 0x02, 1, 0,
140 0x03, 4, 0, 2, 0x02, 6,
141 0, 0x03, 5, 0, 1, 0x03,
142 7, 0, 2, 0x04, 9, 0,
143 0x05, 8, 0, 3, 0x04, 10,
144 0, 0x05, 11, 0, 0x07, 12,
145 0, 2, 0x04, 13, 0, 0x07,
146 14, 0, 1, 0x18, 15, 0,
147 5, 0x08, 18, 0, 0x0f, 64,
148 0, 0x17, 16, 0, 0x18, 17,
149 0, 0x37, 0, 0, 10, 0x08,
150 0x00, 0x07, 0x0c, 0x40, 0x07, 0x0d,
151 0x80, 0x07, 0x17, 24, 0, 0x18,
152 25, 0, 0x28, 23, 0, 0x37,
153 22, 0, 0x67, 19, 0, 0x68,
154 20, 0, 0x6c, 21, 0, 54,
155 0x12, 1984 % 256, 1984 / 256, 0x13, 2048 % 256, 2048 / 256,
156 0x14, 2112 % 256, 2112 / 256, 0x15, 2176 % 256, 2176 / 256,
157 0x16, 2240 % 256, 2240 / 256, 0x17, 2304 % 256, 2304 / 256,
158 0x1c, 2368 % 256, 2368 / 256, 0x1d, 2432 % 256, 2432 / 256,
159 0x1e, 2496 % 256, 2496 / 256, 0x1f, 2560 % 256, 2560 / 256,
160 0x24, 52, 0, 0x27, 55, 0,
161 0x28, 56, 0, 0x2b, 59, 0,
162 0x2c, 60, 0, 0x33, 320 % 256, 320 / 256,
163 0x34, 384 % 256, 384 / 256, 0x35, 448 % 256, 448 / 256,
164 0x37, 53, 0, 0x38, 54, 0,
165 0x52, 50, 0, 0x53, 51, 0,
166 0x54, 44, 0, 0x55, 45, 0,
167 0x56, 46, 0, 0x57, 47, 0,
168 0x58, 57, 0, 0x59, 58, 0,
169 0x5a, 61, 0, 0x5b, 256 % 256, 256 / 256,
170 0x64, 48, 0, 0x65, 49, 0,
171 0x66, 62, 0, 0x67, 63, 0,
172 0x68, 30, 0, 0x69, 31, 0,
173 0x6a, 32, 0, 0x6b, 33, 0,
174 0x6c, 40, 0, 0x6d, 41, 0,
175 0xc8, 128, 0, 0xc9, 192, 0,
176 0xca, 26, 0, 0xcb, 27, 0,
177 0xcc, 28, 0, 0xcd, 29, 0,
178 0xd2, 34, 0, 0xd3, 35, 0,
179 0xd4, 36, 0, 0xd5, 37, 0,
180 0xd6, 38, 0, 0xd7, 39, 0,
181 0xda, 42, 0, 0xdb, 43, 0,
182 20, 0x4a, 640 % 256, 640 / 256, 0x4b, 704 % 256,
183 704 / 256, 0x4c, 768 % 256, 768 / 256, 0x4d, 832 % 256,
184 832 / 256, 0x52, 1280 % 256, 1280 / 256, 0x53, 1344 % 256,
185 1344 / 256, 0x54, 1408 % 256, 1408 / 256, 0x55, 1472 % 256,
186 1472 / 256, 0x5a, 1536 % 256, 1536 / 256, 0x5b, 1600 % 256,
187 1600 / 256, 0x64, 1664 % 256, 1664 / 256, 0x65, 1728 % 256,
188 1728 / 256, 0x6c, 512 % 256, 512 / 256, 0x6d, 576 % 256,
189 576 / 256, 0x72, 896 % 256, 896 / 256, 0x73, 960 % 256,
190 960 / 256, 0x74, 1024 % 256, 1024 / 256, 0x75, 1088 % 256,
191 1088 / 256, 0x76, 1152 % 256, 1152 / 256, 0x77, 1216 % 256,
192 1216 / 256, 0xff};
193 static const uint8_t FaxWhiteRunIns[] = {
194 0, 0, 0, 6, 0x07, 2,
195 0, 0x08, 3, 0, 0x0B, 4,
196 0, 0x0C, 5, 0, 0x0E, 6,
197 0, 0x0F, 7, 0, 6, 0x07,
198 10, 0, 0x08, 11, 0, 0x12,
199 128, 0, 0x13, 8, 0, 0x14,
200 9, 0, 0x1b, 64, 0, 9,
201 0x03, 13, 0, 0x07, 1, 0,
202 0x08, 12, 0, 0x17, 192, 0,
203 0x18, 1664 % 256, 1664 / 256, 0x2a, 16, 0,
204 0x2B, 17, 0, 0x34, 14, 0,
205 0x35, 15, 0, 12, 0x03, 22,
206 0, 0x04, 23, 0, 0x08, 20,
207 0, 0x0c, 19, 0, 0x13, 26,
208 0, 0x17, 21, 0, 0x18, 28,
209 0, 0x24, 27, 0, 0x27, 18,
210 0, 0x28, 24, 0, 0x2B, 25,
211 0, 0x37, 256 % 256, 256 / 256, 42, 0x02,
212 29, 0, 0x03, 30, 0, 0x04,
213 45, 0, 0x05, 46, 0, 0x0a,
214 47, 0, 0x0b, 48, 0, 0x12,
215 33, 0, 0x13, 34, 0, 0x14,
216 35, 0, 0x15, 36, 0, 0x16,
217 37, 0, 0x17, 38, 0, 0x1a,
218 31, 0, 0x1b, 32, 0, 0x24,
219 53, 0, 0x25, 54, 0, 0x28,
220 39, 0, 0x29, 40, 0, 0x2a,
221 41, 0, 0x2b, 42, 0, 0x2c,
222 43, 0, 0x2d, 44, 0, 0x32,
223 61, 0, 0x33, 62, 0, 0x34,
224 63, 0, 0x35, 0, 0, 0x36,
225 320 % 256, 320 / 256, 0x37, 384 % 256, 384 / 256, 0x4a,
226 59, 0, 0x4b, 60, 0, 0x52,
227 49, 0, 0x53, 50, 0, 0x54,
228 51, 0, 0x55, 52, 0, 0x58,
229 55, 0, 0x59, 56, 0, 0x5a,
230 57, 0, 0x5b, 58, 0, 0x64,
231 448 % 256, 448 / 256, 0x65, 512 % 256, 512 / 256, 0x67,
232 640 % 256, 640 / 256, 0x68, 576 % 256, 576 / 256, 16,
233 0x98, 1472 % 256, 1472 / 256, 0x99, 1536 % 256, 1536 / 256,
234 0x9a, 1600 % 256, 1600 / 256, 0x9b, 1728 % 256, 1728 / 256,
235 0xcc, 704 % 256, 704 / 256, 0xcd, 768 % 256, 768 / 256,
236 0xd2, 832 % 256, 832 / 256, 0xd3, 896 % 256, 896 / 256,
237 0xd4, 960 % 256, 960 / 256, 0xd5, 1024 % 256, 1024 / 256,
238 0xd6, 1088 % 256, 1088 / 256, 0xd7, 1152 % 256, 1152 / 256,
239 0xd8, 1216 % 256, 1216 / 256, 0xd9, 1280 % 256, 1280 / 256,
240 0xda, 1344 % 256, 1344 / 256, 0xdb, 1408 % 256, 1408 / 256,
241 0, 3, 0x08, 1792 % 256, 1792 / 256, 0x0c,
242 1856 % 256, 1856 / 256, 0x0d, 1920 % 256, 1920 / 256, 10,
243 0x12, 1984 % 256, 1984 / 256, 0x13, 2048 % 256, 2048 / 256,
244 0x14, 2112 % 256, 2112 / 256, 0x15, 2176 % 256, 2176 / 256,
245 0x16, 2240 % 256, 2240 / 256, 0x17, 2304 % 256, 2304 / 256,
246 0x1c, 2368 % 256, 2368 / 256, 0x1d, 2432 % 256, 2432 / 256,
247 0x1e, 2496 % 256, 2496 / 256, 0x1f, 2560 % 256, 2560 / 256,
248 0xff,
249 };
250 int _FaxGetRun(const uint8_t* ins_array,
251 const uint8_t* src_buf,
252 int& bitpos,
253 int bitsize) {
254 FX_DWORD code = 0;
255 int ins_off = 0;
256 while (1) {
257 uint8_t ins = ins_array[ins_off++];
258 if (ins == 0xff) {
259 return -1;
260 }
261 if (bitpos >= bitsize) {
262 return -1;
263 }
264 code <<= 1;
265 if (src_buf[bitpos / 8] & (1 << (7 - bitpos % 8))) {
266 code++;
267 }
268 bitpos++;
269 int next_off = ins_off + ins * 3;
270 for (; ins_off < next_off; ins_off += 3) {
271 if (ins_array[ins_off] == code) {
272 return ins_array[ins_off + 1] + ins_array[ins_off + 2] * 256;
273 }
274 }
275 }
276 }
277 FX_BOOL _FaxG4GetRow(const uint8_t* src_buf,
278 int bitsize,
279 int& bitpos,
280 uint8_t* dest_buf,
281 const uint8_t* ref_buf,
282 int columns) {
283 int a0 = -1, a0color = 1;
284 while (1) {
285 if (bitpos >= bitsize) {
286 return FALSE;
287 }
288 int a1, a2, b1, b2;
289 _FaxG4FindB1B2(ref_buf, columns, a0, a0color, b1, b2);
290 FX_BOOL bit = NEXTBIT;
291 int v_delta = 0;
292 if (bit) {
293 } else {
294 if (bitpos >= bitsize) {
295 return FALSE;
296 }
297 FX_BOOL bit1 = NEXTBIT;
298 if (bitpos >= bitsize) {
299 return FALSE;
300 }
301 FX_BOOL bit2 = NEXTBIT;
302 if (bit1 && bit2) {
303 v_delta = 1;
304 } else if (bit1) {
305 v_delta = -1;
306 } else if (bit2) {
307 int run_len1 = 0;
308 while (1) {
309 int run = _FaxGetRun(a0color ? FaxWhiteRunIns : FaxBlackRunIns,
310 src_buf, bitpos, bitsize);
311 run_len1 += run;
312 if (run < 64) {
313 break;
314 }
315 }
316 if (a0 < 0) {
317 run_len1++;
318 }
319 a1 = a0 + run_len1;
320 if (!a0color) {
321 _FaxFillBits(dest_buf, columns, a0, a1);
322 }
323 int run_len2 = 0;
324 while (1) {
325 int run = _FaxGetRun(a0color ? FaxBlackRunIns : FaxWhiteRunIns,
326 src_buf, bitpos, bitsize);
327 run_len2 += run;
328 if (run < 64) {
329 break;
330 }
331 }
332 a2 = a1 + run_len2;
333 if (a0color) {
334 _FaxFillBits(dest_buf, columns, a1, a2);
335 }
336 a0 = a2;
337 if (a0 < columns) {
338 continue;
339 }
340 return TRUE;
341 } else {
342 if (bitpos >= bitsize) {
343 return FALSE;
344 }
345 bit = NEXTBIT;
54 if (bit) { 346 if (bit) {
55 data &= 0xff >> (start_pos % 8); 347 if (!a0color) {
348 _FaxFillBits(dest_buf, columns, a0, b2);
349 }
350 if (b2 >= columns) {
351 return TRUE;
352 }
353 a0 = b2;
354 continue;
56 } else { 355 } else {
57 data |= 0xff << (8 - start_pos % 8); 356 if (bitpos >= bitsize) {
357 return FALSE;
358 }
359 FX_BOOL bit1 = NEXTBIT;
360 if (bitpos >= bitsize) {
361 return FALSE;
362 }
363 FX_BOOL bit2 = NEXTBIT;
364 if (bit1 && bit2) {
365 v_delta = 2;
366 } else if (bit1) {
367 v_delta = -2;
368 } else if (bit2) {
369 if (bitpos >= bitsize) {
370 return FALSE;
371 }
372 bit = NEXTBIT;
373 if (bit) {
374 v_delta = 3;
375 } else {
376 v_delta = -3;
377 }
378 } else {
379 if (bitpos >= bitsize) {
380 return FALSE;
381 }
382 bit = NEXTBIT;
383 if (bit) {
384 bitpos += 3;
385 continue;
386 } else {
387 bitpos += 5;
388 return TRUE;
389 }
390 }
58 } 391 }
59 if (leading_pos[data] < 8) { 392 }
60 return start_pos / 8 * 8 + leading_pos[data]; 393 }
394 a1 = b1 + v_delta;
395 if (!a0color) {
396 _FaxFillBits(dest_buf, columns, a0, a1);
397 }
398 if (a1 >= columns) {
399 return TRUE;
400 }
401 a0 = a1;
402 a0color = !a0color;
403 }
404 }
405 FX_BOOL _FaxSkipEOL(const uint8_t* src_buf, int bitsize, int& bitpos) {
406 int startbit = bitpos;
407 while (bitpos < bitsize) {
408 int bit = NEXTBIT;
409 if (bit) {
410 if (bitpos - startbit <= 11) {
411 bitpos = startbit;
412 }
413 return TRUE;
414 }
415 }
416 return FALSE;
417 }
418 FX_BOOL _FaxGet1DLine(const uint8_t* src_buf,
419 int bitsize,
420 int& bitpos,
421 uint8_t* dest_buf,
422 int columns) {
423 int color = TRUE;
424 int startpos = 0;
425 while (1) {
426 if (bitpos >= bitsize) {
427 return FALSE;
428 }
429 int run_len = 0;
430 while (1) {
431 int run = _FaxGetRun(color ? FaxWhiteRunIns : FaxBlackRunIns, src_buf,
432 bitpos, bitsize);
433 if (run < 0) {
434 while (bitpos < bitsize) {
435 int bit = NEXTBIT;
436 if (bit) {
437 return TRUE;
438 }
61 } 439 }
62 start_pos += 7; 440 return FALSE;
63 } 441 }
64 uint8_t skip = bit ? 0x00 : 0xff; 442 run_len += run;
65 int byte_pos = start_pos / 8; 443 if (run < 64) {
66 int max_byte = (max_pos + 7) / 8; 444 break;
67 while (byte_pos < max_byte) { 445 }
68 if (data_buf[byte_pos] != skip) { 446 }
69 break; 447 if (!color) {
70 } 448 _FaxFillBits(dest_buf, columns, startpos, startpos + run_len);
71 byte_pos ++; 449 }
72 } 450 startpos += run_len;
73 if (byte_pos == max_byte) { 451 if (startpos >= columns) {
74 return max_pos; 452 break;
75 } 453 }
76 int pos = leading_pos[data_buf[byte_pos]] + byte_pos * 8; 454 color = !color;
77 if (pos > max_pos) { 455 }
78 pos = max_pos; 456 return TRUE;
79 } 457 }
80 return pos; 458 class CCodec_FaxDecoder : public CCodec_ScanlineDecoder {
81 } 459 public:
82 void _FaxG4FindB1B2(const uint8_t* ref_buf, int columns, int a0, FX_BOOL a0color , int& b1, int& b2) 460 CCodec_FaxDecoder();
83 { 461 virtual ~CCodec_FaxDecoder();
84 if (a0color) { 462 FX_BOOL Create(const uint8_t* src_buf,
85 a0color = 1; 463 FX_DWORD src_size,
86 } 464 int width,
87 uint8_t first_bit = (a0 < 0) ? 1 : ((ref_buf[a0 / 8] & (1 << (7 - a0 % 8))) != 0); 465 int height,
88 b1 = _FindBit(ref_buf, columns, a0 + 1, !first_bit); 466 int K,
89 if (b1 >= columns) { 467 FX_BOOL EndOfLine,
90 b1 = b2 = columns; 468 FX_BOOL EncodedByteAlign,
91 return; 469 FX_BOOL BlackIs1,
92 } 470 int Columns,
93 if (first_bit == !a0color) { 471 int Rows);
94 b1 = _FindBit(ref_buf, columns, b1 + 1, first_bit); 472 virtual void v_DownScale(int dest_width, int dest_height) {}
95 first_bit = !first_bit; 473 virtual FX_BOOL v_Rewind();
96 } 474 virtual uint8_t* v_GetNextLine();
97 if (b1 >= columns) { 475 virtual FX_DWORD GetSrcOffset();
98 b1 = b2 = columns; 476 int m_Encoding, m_bEndOfLine, m_bByteAlign, m_bBlack;
99 return; 477 int bitpos;
100 } 478 const uint8_t* m_pSrcBuf;
101 b2 = _FindBit(ref_buf, columns, b1 + 1, first_bit); 479 FX_DWORD m_SrcSize;
102 } 480 uint8_t* m_pScanlineBuf;
103 void _FaxFillBits(uint8_t* dest_buf, int columns, int startpos, int endpos) 481 uint8_t* m_pRefBuf;
104 { 482 };
105 if (startpos < 0) { 483 CCodec_FaxDecoder::CCodec_FaxDecoder() {
106 startpos = 0; 484 m_pScanlineBuf = NULL;
107 } 485 m_pRefBuf = NULL;
108 if (endpos < 0) { 486 }
109 endpos = 0; 487 CCodec_FaxDecoder::~CCodec_FaxDecoder() {
110 } 488 if (m_pScanlineBuf) {
111 if (endpos >= columns) { 489 FX_Free(m_pScanlineBuf);
112 endpos = columns; 490 }
113 } 491 if (m_pRefBuf) {
114 if (startpos >= endpos) { 492 FX_Free(m_pRefBuf);
115 return; 493 }
116 } 494 }
117 int first_byte = startpos / 8; 495 FX_BOOL CCodec_FaxDecoder::Create(const uint8_t* src_buf,
118 int last_byte = (endpos - 1) / 8; 496 FX_DWORD src_size,
119 if (first_byte == last_byte) { 497 int width,
120 for (int i = startpos % 8; i <= (endpos - 1) % 8; i ++) { 498 int height,
121 dest_buf[first_byte] -= 1 << (7 - i); 499 int K,
122 } 500 FX_BOOL EndOfLine,
123 return; 501 FX_BOOL EncodedByteAlign,
124 } 502 FX_BOOL BlackIs1,
125 int i; 503 int Columns,
126 for (i = startpos % 8; i < 8; i ++) { 504 int Rows) {
127 dest_buf[first_byte] -= 1 << (7 - i); 505 m_Encoding = K;
128 } 506 m_bEndOfLine = EndOfLine;
129 for (i = 0; i <= (endpos - 1) % 8; i ++) { 507 m_bByteAlign = EncodedByteAlign;
130 dest_buf[last_byte] -= 1 << (7 - i); 508 m_bBlack = BlackIs1;
131 } 509 m_OrigWidth = Columns;
132 if (last_byte > first_byte + 1) { 510 m_OrigHeight = Rows;
133 FXSYS_memset(dest_buf + first_byte + 1, 0, last_byte - first_byte - 1); 511 if (m_OrigWidth == 0) {
134 } 512 m_OrigWidth = width;
135 } 513 }
136 #define NEXTBIT src_buf[bitpos/8] & (1 << (7-bitpos%8)); bitpos ++; 514 if (m_OrigHeight == 0) {
137 #define ADDBIT(code, bit) code = code << 1; if (bit) code ++; 515 m_OrigHeight = height;
138 #define GETBIT(bitpos) src_buf[bitpos/8] & (1 << (7-bitpos%8)) 516 }
139 static const uint8_t FaxBlackRunIns[] = { 517 m_Pitch = (m_OrigWidth + 31) / 32 * 4;
140 0, 518 m_OutputWidth = m_OrigWidth;
141 2, 519 m_OutputHeight = m_OrigHeight;
142 0x02, 3, 0, 520 m_pScanlineBuf = FX_Alloc(uint8_t, m_Pitch);
143 0x03, 2, 0, 521 m_pRefBuf = FX_Alloc(uint8_t, m_Pitch);
144 2, 522 m_pSrcBuf = src_buf;
145 0x02, 1, 0, 523 m_SrcSize = src_size;
146 0x03, 4, 0, 524 m_nComps = 1;
147 2, 525 m_bpc = 1;
148 0x02, 6, 0, 526 m_bColorTransformed = FALSE;
149 0x03, 5, 0, 527 return TRUE;
150 1, 528 }
151 0x03, 7, 0, 529 FX_BOOL CCodec_FaxDecoder::v_Rewind() {
152 2, 530 FXSYS_memset(m_pRefBuf, 0xff, m_Pitch);
153 0x04, 9, 0, 531 bitpos = 0;
154 0x05, 8, 0, 532 return TRUE;
155 3, 533 }
156 0x04, 10, 0, 534 uint8_t* CCodec_FaxDecoder::v_GetNextLine() {
157 0x05, 11, 0, 535 int bitsize = m_SrcSize * 8;
158 0x07, 12, 0, 536 _FaxSkipEOL(m_pSrcBuf, bitsize, bitpos);
159 2, 537 if (bitpos >= bitsize) {
160 0x04, 13, 0, 538 return NULL;
161 0x07, 14, 0, 539 }
162 1, 540 FXSYS_memset(m_pScanlineBuf, 0xff, m_Pitch);
163 0x18, 15, 0, 541 if (m_Encoding < 0) {
164 5, 542 _FaxG4GetRow(m_pSrcBuf, bitsize, bitpos, m_pScanlineBuf, m_pRefBuf,
165 0x08, 18, 0, 543 m_OrigWidth);
166 0x0f, 64, 0, 544 FXSYS_memcpy(m_pRefBuf, m_pScanlineBuf, m_Pitch);
167 0x17, 16, 0, 545 } else if (m_Encoding == 0) {
168 0x18, 17, 0, 546 _FaxGet1DLine(m_pSrcBuf, bitsize, bitpos, m_pScanlineBuf, m_OrigWidth);
169 0x37, 0, 0, 547 } else {
170 10, 548 FX_BOOL bNext1D = m_pSrcBuf[bitpos / 8] & (1 << (7 - bitpos % 8));
171 0x08, 0x00, 0x07, 549 bitpos++;
172 0x0c, 0x40, 0x07, 550 if (bNext1D) {
173 0x0d, 0x80, 0x07, 551 _FaxGet1DLine(m_pSrcBuf, bitsize, bitpos, m_pScanlineBuf, m_OrigWidth);
174 0x17, 24, 0, 552 } else {
175 0x18, 25, 0, 553 _FaxG4GetRow(m_pSrcBuf, bitsize, bitpos, m_pScanlineBuf, m_pRefBuf,
176 0x28, 23, 0, 554 m_OrigWidth);
177 0x37, 22, 0, 555 }
178 0x67, 19, 0, 556 FXSYS_memcpy(m_pRefBuf, m_pScanlineBuf, m_Pitch);
179 0x68, 20, 0, 557 }
180 0x6c, 21, 0, 558 if (m_bEndOfLine) {
181 54,
182 0x12, 1984 % 256, 1984 / 256,
183 0x13, 2048 % 256, 2048 / 256,
184 0x14, 2112 % 256, 2112 / 256,
185 0x15, 2176 % 256, 2176 / 256,
186 0x16, 2240 % 256, 2240 / 256,
187 0x17, 2304 % 256, 2304 / 256,
188 0x1c, 2368 % 256, 2368 / 256,
189 0x1d, 2432 % 256, 2432 / 256,
190 0x1e, 2496 % 256, 2496 / 256,
191 0x1f, 2560 % 256, 2560 / 256,
192 0x24, 52, 0,
193 0x27, 55, 0,
194 0x28, 56, 0,
195 0x2b, 59, 0,
196 0x2c, 60, 0,
197 0x33, 320 % 256, 320 / 256,
198 0x34, 384 % 256, 384 / 256,
199 0x35, 448 % 256, 448 / 256,
200 0x37, 53, 0,
201 0x38, 54, 0,
202 0x52, 50, 0,
203 0x53, 51, 0,
204 0x54, 44, 0,
205 0x55, 45, 0,
206 0x56, 46, 0,
207 0x57, 47, 0,
208 0x58, 57, 0,
209 0x59, 58, 0,
210 0x5a, 61, 0,
211 0x5b, 256 % 256, 256 / 256,
212 0x64, 48, 0,
213 0x65, 49, 0,
214 0x66, 62, 0,
215 0x67, 63, 0,
216 0x68, 30, 0,
217 0x69, 31, 0,
218 0x6a, 32, 0,
219 0x6b, 33, 0,
220 0x6c, 40, 0,
221 0x6d, 41, 0,
222 0xc8, 128, 0,
223 0xc9, 192, 0,
224 0xca, 26, 0,
225 0xcb, 27, 0,
226 0xcc, 28, 0,
227 0xcd, 29, 0,
228 0xd2, 34, 0,
229 0xd3, 35, 0,
230 0xd4, 36, 0,
231 0xd5, 37, 0,
232 0xd6, 38, 0,
233 0xd7, 39, 0,
234 0xda, 42, 0,
235 0xdb, 43, 0,
236 20,
237 0x4a, 640 % 256, 640 / 256,
238 0x4b, 704 % 256, 704 / 256,
239 0x4c, 768 % 256, 768 / 256,
240 0x4d, 832 % 256, 832 / 256,
241 0x52, 1280 % 256, 1280 / 256,
242 0x53, 1344 % 256, 1344 / 256,
243 0x54, 1408 % 256, 1408 / 256,
244 0x55, 1472 % 256, 1472 / 256,
245 0x5a, 1536 % 256, 1536 / 256,
246 0x5b, 1600 % 256, 1600 / 256,
247 0x64, 1664 % 256, 1664 / 256,
248 0x65, 1728 % 256, 1728 / 256,
249 0x6c, 512 % 256, 512 / 256,
250 0x6d, 576 % 256, 576 / 256,
251 0x72, 896 % 256, 896 / 256,
252 0x73, 960 % 256, 960 / 256,
253 0x74, 1024 % 256, 1024 / 256,
254 0x75, 1088 % 256, 1088 / 256,
255 0x76, 1152 % 256, 1152 / 256,
256 0x77, 1216 % 256, 1216 / 256,
257 0xff
258 };
259 static const uint8_t FaxWhiteRunIns[] = {
260 0,
261 0,
262 0,
263 6,
264 0x07, 2, 0,
265 0x08, 3, 0,
266 0x0B, 4, 0,
267 0x0C, 5, 0,
268 0x0E, 6, 0,
269 0x0F, 7, 0,
270 6,
271 0x07, 10, 0,
272 0x08, 11, 0,
273 0x12, 128, 0,
274 0x13, 8, 0,
275 0x14, 9, 0,
276 0x1b, 64, 0,
277 9,
278 0x03, 13, 0,
279 0x07, 1, 0,
280 0x08, 12, 0,
281 0x17, 192, 0,
282 0x18, 1664 % 256, 1664 / 256,
283 0x2a, 16, 0,
284 0x2B, 17, 0,
285 0x34, 14, 0,
286 0x35, 15, 0,
287 12,
288 0x03, 22, 0,
289 0x04, 23, 0,
290 0x08, 20, 0,
291 0x0c, 19, 0,
292 0x13, 26, 0,
293 0x17, 21, 0,
294 0x18, 28, 0,
295 0x24, 27, 0,
296 0x27, 18, 0,
297 0x28, 24, 0,
298 0x2B, 25, 0,
299 0x37, 256 % 256, 256 / 256,
300 42,
301 0x02, 29, 0,
302 0x03, 30, 0,
303 0x04, 45, 0,
304 0x05, 46, 0,
305 0x0a, 47, 0,
306 0x0b, 48, 0,
307 0x12, 33, 0,
308 0x13, 34, 0,
309 0x14, 35, 0,
310 0x15, 36, 0,
311 0x16, 37, 0,
312 0x17, 38, 0,
313 0x1a, 31, 0,
314 0x1b, 32, 0,
315 0x24, 53, 0,
316 0x25, 54, 0,
317 0x28, 39, 0,
318 0x29, 40, 0,
319 0x2a, 41, 0,
320 0x2b, 42, 0,
321 0x2c, 43, 0,
322 0x2d, 44, 0,
323 0x32, 61, 0,
324 0x33, 62, 0,
325 0x34, 63, 0,
326 0x35, 0, 0,
327 0x36, 320 % 256, 320 / 256,
328 0x37, 384 % 256, 384 / 256,
329 0x4a, 59, 0,
330 0x4b, 60, 0,
331 0x52, 49, 0,
332 0x53, 50, 0,
333 0x54, 51, 0,
334 0x55, 52, 0,
335 0x58, 55, 0,
336 0x59, 56, 0,
337 0x5a, 57, 0,
338 0x5b, 58, 0,
339 0x64, 448 % 256, 448 / 256,
340 0x65, 512 % 256, 512 / 256,
341 0x67, 640 % 256, 640 / 256,
342 0x68, 576 % 256, 576 / 256,
343 16,
344 0x98, 1472 % 256, 1472 / 256,
345 0x99, 1536 % 256, 1536 / 256,
346 0x9a, 1600 % 256, 1600 / 256,
347 0x9b, 1728 % 256, 1728 / 256,
348 0xcc, 704 % 256, 704 / 256,
349 0xcd, 768 % 256, 768 / 256,
350 0xd2, 832 % 256, 832 / 256,
351 0xd3, 896 % 256, 896 / 256,
352 0xd4, 960 % 256, 960 / 256,
353 0xd5, 1024 % 256, 1024 / 256,
354 0xd6, 1088 % 256, 1088 / 256,
355 0xd7, 1152 % 256, 1152 / 256,
356 0xd8, 1216 % 256, 1216 / 256,
357 0xd9, 1280 % 256, 1280 / 256,
358 0xda, 1344 % 256, 1344 / 256,
359 0xdb, 1408 % 256, 1408 / 256,
360 0,
361 3,
362 0x08, 1792 % 256, 1792 / 256,
363 0x0c, 1856 % 256, 1856 / 256,
364 0x0d, 1920 % 256, 1920 / 256,
365 10,
366 0x12, 1984 % 256, 1984 / 256,
367 0x13, 2048 % 256, 2048 / 256,
368 0x14, 2112 % 256, 2112 / 256,
369 0x15, 2176 % 256, 2176 / 256,
370 0x16, 2240 % 256, 2240 / 256,
371 0x17, 2304 % 256, 2304 / 256,
372 0x1c, 2368 % 256, 2368 / 256,
373 0x1d, 2432 % 256, 2432 / 256,
374 0x1e, 2496 % 256, 2496 / 256,
375 0x1f, 2560 % 256, 2560 / 256,
376 0xff,
377 };
378 int _FaxGetRun(const uint8_t* ins_array, const uint8_t* src_buf, int& bitpos, in t bitsize)
379 {
380 FX_DWORD code = 0;
381 int ins_off = 0;
382 while (1) {
383 uint8_t ins = ins_array[ins_off++];
384 if (ins == 0xff) {
385 return -1;
386 }
387 if (bitpos >= bitsize) {
388 return -1;
389 }
390 code <<= 1;
391 if (src_buf[bitpos / 8] & (1 << (7 - bitpos % 8))) {
392 code ++;
393 }
394 bitpos ++;
395 int next_off = ins_off + ins * 3;
396 for (; ins_off < next_off; ins_off += 3) {
397 if (ins_array[ins_off] == code) {
398 return ins_array[ins_off + 1] + ins_array[ins_off + 2] * 256;
399 }
400 }
401 }
402 }
403 FX_BOOL _FaxG4GetRow(const uint8_t* src_buf, int bitsize, int& bitpos, uint8_t* dest_buf, const uint8_t* ref_buf, int columns)
404 {
405 int a0 = -1, a0color = 1;
406 while (1) {
407 if (bitpos >= bitsize) {
408 return FALSE;
409 }
410 int a1, a2, b1, b2;
411 _FaxG4FindB1B2(ref_buf, columns, a0, a0color, b1, b2);
412 FX_BOOL bit = NEXTBIT;
413 int v_delta = 0;
414 if (bit) {
415 } else {
416 if (bitpos >= bitsize) {
417 return FALSE;
418 }
419 FX_BOOL bit1 = NEXTBIT;
420 if (bitpos >= bitsize) {
421 return FALSE;
422 }
423 FX_BOOL bit2 = NEXTBIT;
424 if (bit1 && bit2) {
425 v_delta = 1;
426 } else if (bit1) {
427 v_delta = -1;
428 } else if (bit2) {
429 int run_len1 = 0;
430 while (1) {
431 int run = _FaxGetRun(a0color ? FaxWhiteRunIns : FaxBlackRunI ns, src_buf, bitpos, bitsize);
432 run_len1 += run;
433 if (run < 64) {
434 break;
435 }
436 }
437 if (a0 < 0) {
438 run_len1 ++;
439 }
440 a1 = a0 + run_len1;
441 if (!a0color) {
442 _FaxFillBits(dest_buf, columns, a0, a1);
443 }
444 int run_len2 = 0;
445 while (1) {
446 int run = _FaxGetRun(a0color ? FaxBlackRunIns : FaxWhiteRunI ns, src_buf, bitpos, bitsize);
447 run_len2 += run;
448 if (run < 64) {
449 break;
450 }
451 }
452 a2 = a1 + run_len2;
453 if (a0color) {
454 _FaxFillBits(dest_buf, columns, a1, a2);
455 }
456 a0 = a2;
457 if (a0 < columns) {
458 continue;
459 }
460 return TRUE;
461 } else {
462 if (bitpos >= bitsize) {
463 return FALSE;
464 }
465 bit = NEXTBIT;
466 if (bit) {
467 if (!a0color) {
468 _FaxFillBits(dest_buf, columns, a0, b2);
469 }
470 if (b2 >= columns) {
471 return TRUE;
472 }
473 a0 = b2;
474 continue;
475 } else {
476 if (bitpos >= bitsize) {
477 return FALSE;
478 }
479 FX_BOOL bit1 = NEXTBIT;
480 if (bitpos >= bitsize) {
481 return FALSE;
482 }
483 FX_BOOL bit2 = NEXTBIT;
484 if (bit1 && bit2) {
485 v_delta = 2;
486 } else if (bit1) {
487 v_delta = -2;
488 } else if (bit2) {
489 if (bitpos >= bitsize) {
490 return FALSE;
491 }
492 bit = NEXTBIT;
493 if (bit) {
494 v_delta = 3;
495 } else {
496 v_delta = -3;
497 }
498 } else {
499 if (bitpos >= bitsize) {
500 return FALSE;
501 }
502 bit = NEXTBIT;
503 if (bit) {
504 bitpos += 3;
505 continue;
506 } else {
507 bitpos += 5;
508 return TRUE;
509 }
510 }
511 }
512 }
513 }
514 a1 = b1 + v_delta;
515 if (!a0color) {
516 _FaxFillBits(dest_buf, columns, a0, a1);
517 }
518 if (a1 >= columns) {
519 return TRUE;
520 }
521 a0 = a1;
522 a0color = !a0color;
523 }
524 }
525 FX_BOOL _FaxSkipEOL(const uint8_t* src_buf, int bitsize, int& bitpos)
526 {
527 int startbit = bitpos;
528 while (bitpos < bitsize) {
529 int bit = NEXTBIT;
530 if (bit) {
531 if (bitpos - startbit <= 11) {
532 bitpos = startbit;
533 }
534 return TRUE;
535 }
536 }
537 return FALSE;
538 }
539 FX_BOOL _FaxGet1DLine(const uint8_t* src_buf, int bitsize, int& bitpos, uint8_t* dest_buf, int columns)
540 {
541 int color = TRUE;
542 int startpos = 0;
543 while (1) {
544 if (bitpos >= bitsize) {
545 return FALSE;
546 }
547 int run_len = 0;
548 while (1) {
549 int run = _FaxGetRun(color ? FaxWhiteRunIns : FaxBlackRunIns, src_bu f, bitpos, bitsize);
550 if (run < 0) {
551 while (bitpos < bitsize) {
552 int bit = NEXTBIT;
553 if (bit) {
554 return TRUE;
555 }
556 }
557 return FALSE;
558 }
559 run_len += run;
560 if (run < 64) {
561 break;
562 }
563 }
564 if (!color) {
565 _FaxFillBits(dest_buf, columns, startpos, startpos + run_len);
566 }
567 startpos += run_len;
568 if (startpos >= columns) {
569 break;
570 }
571 color = !color;
572 }
573 return TRUE;
574 }
575 class CCodec_FaxDecoder : public CCodec_ScanlineDecoder
576 {
577 public:
578 CCodec_FaxDecoder();
579 virtual ~CCodec_FaxDecoder();
580 FX_BOOL Create(const uint8_t* src_buf, FX_DWORD src_size, int width, int height,
581 int K, FX_BOOL EndOfLine, FX_BOOL EncodedByteAlig n, FX_BOOL BlackIs1, int Columns, int Rows);
582 virtual void v_DownScale(int dest_width, int dest_height) {}
583 virtual FX_BOOL v_Rewind();
584 virtual uint8_t* v_GetNextLine();
585 virtual FX_DWORD GetSrcOffset();
586 int m_Encoding, m_bEndOfLine, m_bByteAlign, m_bBlack;
587 int bitpos;
588 const uint8_t* m_pSrcBuf;
589 FX_DWORD m_SrcSize;
590 uint8_t* m_pScanlineBuf;
591 uint8_t* m_pRefBuf;
592 };
593 CCodec_FaxDecoder::CCodec_FaxDecoder()
594 {
595 m_pScanlineBuf = NULL;
596 m_pRefBuf = NULL;
597 }
598 CCodec_FaxDecoder::~CCodec_FaxDecoder()
599 {
600 if (m_pScanlineBuf) {
601 FX_Free(m_pScanlineBuf);
602 }
603 if (m_pRefBuf) {
604 FX_Free(m_pRefBuf);
605 }
606 }
607 FX_BOOL CCodec_FaxDecoder::Create(const uint8_t* src_buf, FX_DWORD src_size, int width, int height,
608 int K, FX_BOOL EndOfLine, FX_BOOL EncodedByteA lign, FX_BOOL BlackIs1, int Columns, int Rows)
609 {
610 m_Encoding = K;
611 m_bEndOfLine = EndOfLine;
612 m_bByteAlign = EncodedByteAlign;
613 m_bBlack = BlackIs1;
614 m_OrigWidth = Columns;
615 m_OrigHeight = Rows;
616 if (m_OrigWidth == 0) {
617 m_OrigWidth = width;
618 }
619 if (m_OrigHeight == 0) {
620 m_OrigHeight = height;
621 }
622 m_Pitch = (m_OrigWidth + 31) / 32 * 4;
623 m_OutputWidth = m_OrigWidth;
624 m_OutputHeight = m_OrigHeight;
625 m_pScanlineBuf = FX_Alloc(uint8_t, m_Pitch);
626 m_pRefBuf = FX_Alloc(uint8_t, m_Pitch);
627 m_pSrcBuf = src_buf;
628 m_SrcSize = src_size;
629 m_nComps = 1;
630 m_bpc = 1;
631 m_bColorTransformed = FALSE;
632 return TRUE;
633 }
634 FX_BOOL CCodec_FaxDecoder::v_Rewind()
635 {
636 FXSYS_memset(m_pRefBuf, 0xff, m_Pitch);
637 bitpos = 0;
638 return TRUE;
639 }
640 uint8_t* CCodec_FaxDecoder::v_GetNextLine()
641 {
642 int bitsize = m_SrcSize * 8;
643 _FaxSkipEOL(m_pSrcBuf, bitsize, bitpos); 559 _FaxSkipEOL(m_pSrcBuf, bitsize, bitpos);
644 if (bitpos >= bitsize) { 560 }
645 return NULL; 561 if (m_bByteAlign && bitpos < bitsize) {
646 } 562 int bitpos0 = bitpos;
647 FXSYS_memset(m_pScanlineBuf, 0xff, m_Pitch); 563 int bitpos1 = (bitpos + 7) / 8 * 8;
648 if (m_Encoding < 0) { 564 while (m_bByteAlign && bitpos0 < bitpos1) {
649 _FaxG4GetRow(m_pSrcBuf, bitsize, bitpos, m_pScanlineBuf, m_pRefBuf, m_Or igWidth); 565 int bit = m_pSrcBuf[bitpos0 / 8] & (1 << (7 - bitpos0 % 8));
650 FXSYS_memcpy(m_pRefBuf, m_pScanlineBuf, m_Pitch); 566 if (bit != 0) {
651 } else if (m_Encoding == 0) { 567 m_bByteAlign = FALSE;
652 _FaxGet1DLine(m_pSrcBuf, bitsize, bitpos, m_pScanlineBuf, m_OrigWidth); 568 } else {
569 bitpos0++;
570 }
571 }
572 if (m_bByteAlign) {
573 bitpos = bitpos1;
574 }
575 }
576 if (m_bBlack) {
577 for (int i = 0; i < m_Pitch; i++) {
578 m_pScanlineBuf[i] = ~m_pScanlineBuf[i];
579 }
580 }
581 return m_pScanlineBuf;
582 }
583 FX_DWORD CCodec_FaxDecoder::GetSrcOffset() {
584 FX_DWORD ret = (bitpos + 7) / 8;
585 if (ret > m_SrcSize) {
586 ret = m_SrcSize;
587 }
588 return ret;
589 }
590 extern "C" {
591 void _FaxG4Decode(void*,
592 const uint8_t* src_buf,
593 FX_DWORD src_size,
594 int* pbitpos,
595 uint8_t* dest_buf,
596 int width,
597 int height,
598 int pitch) {
599 if (pitch == 0) {
600 pitch = (width + 7) / 8;
601 }
602 uint8_t* ref_buf = FX_Alloc(uint8_t, pitch);
603 FXSYS_memset(ref_buf, 0xff, pitch);
604 int bitpos = *pbitpos;
605 for (int iRow = 0; iRow < height; iRow++) {
606 uint8_t* line_buf = dest_buf + iRow * pitch;
607 FXSYS_memset(line_buf, 0xff, pitch);
608 _FaxG4GetRow(src_buf, src_size << 3, bitpos, line_buf, ref_buf, width);
609 FXSYS_memcpy(ref_buf, line_buf, pitch);
610 }
611 FX_Free(ref_buf);
612 *pbitpos = bitpos;
613 }
614 };
615 static const uint8_t BlackRunTerminator[128] = {
616 0x37, 10, 0x02, 3, 0x03, 2, 0x02, 2, 0x03, 3, 0x03, 4, 0x02, 4,
617 0x03, 5, 0x05, 6, 0x04, 6, 0x04, 7, 0x05, 7, 0x07, 7, 0x04, 8,
618 0x07, 8, 0x18, 9, 0x17, 10, 0x18, 10, 0x08, 10, 0x67, 11, 0x68, 11,
619 0x6c, 11, 0x37, 11, 0x28, 11, 0x17, 11, 0x18, 11, 0xca, 12, 0xcb, 12,
620 0xcc, 12, 0xcd, 12, 0x68, 12, 0x69, 12, 0x6a, 12, 0x6b, 12, 0xd2, 12,
621 0xd3, 12, 0xd4, 12, 0xd5, 12, 0xd6, 12, 0xd7, 12, 0x6c, 12, 0x6d, 12,
622 0xda, 12, 0xdb, 12, 0x54, 12, 0x55, 12, 0x56, 12, 0x57, 12, 0x64, 12,
623 0x65, 12, 0x52, 12, 0x53, 12, 0x24, 12, 0x37, 12, 0x38, 12, 0x27, 12,
624 0x28, 12, 0x58, 12, 0x59, 12, 0x2b, 12, 0x2c, 12, 0x5a, 12, 0x66, 12,
625 0x67, 12,
626 };
627 static const uint8_t BlackRunMarkup[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 static 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 static const uint8_t WhiteRunMarkup[80] = {
646 0x1b, 5, 0x12, 5, 0x17, 6, 0x37, 7, 0x36, 8, 0x37, 8, 0x64, 8,
647 0x65, 8, 0x68, 8, 0x67, 8, 0xcc, 9, 0xcd, 9, 0xd2, 9, 0xd3, 9,
648 0xd4, 9, 0xd5, 9, 0xd6, 9, 0xd7, 9, 0xd8, 9, 0xd9, 9, 0xda, 9,
649 0xdb, 9, 0x98, 9, 0x99, 9, 0x9a, 9, 0x18, 6, 0x9b, 9, 0x08, 11,
650 0x0c, 11, 0x0d, 11, 0x12, 12, 0x13, 12, 0x14, 12, 0x15, 12, 0x16, 12,
651 0x17, 12, 0x1c, 12, 0x1d, 12, 0x1e, 12, 0x1f, 12,
652 };
653 static void _AddBitStream(uint8_t* dest_buf,
654 int& dest_bitpos,
655 int data,
656 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 static void _FaxEncodeRun(uint8_t* dest_buf,
665 int& dest_bitpos,
666 int run,
667 FX_BOOL bWhite) {
668 while (run >= 2560) {
669 _AddBitStream(dest_buf, dest_bitpos, 0x1f, 12);
670 run -= 2560;
671 }
672 if (run >= 64) {
673 int markup = run - run % 64;
674 const uint8_t* p = bWhite ? WhiteRunMarkup : BlackRunMarkup;
675 p += (markup / 64 - 1) * 2;
676 _AddBitStream(dest_buf, dest_bitpos, *p, p[1]);
677 }
678 run %= 64;
679 const uint8_t* p = bWhite ? WhiteRunTerminator : BlackRunTerminator;
680 p += run * 2;
681 _AddBitStream(dest_buf, dest_bitpos, *p, p[1]);
682 }
683 static void _FaxEncode2DLine(uint8_t* dest_buf,
684 int& dest_bitpos,
685 const uint8_t* src_buf,
686 const uint8_t* ref_buf,
687 int cols) {
688 int a0 = -1, a0color = 1;
689 while (1) {
690 int a1 = _FindBit(src_buf, cols, a0 + 1, 1 - a0color);
691 int b1, 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 = 1 - a0color;
653 } else { 723 } else {
654 FX_BOOL bNext1D = m_pSrcBuf[bitpos / 8] & (1 << (7 - bitpos % 8)); 724 int a2 = _FindBit(src_buf, cols, a1 + 1, a0color);
655 bitpos ++; 725 dest_bitpos++;
656 if (bNext1D) { 726 dest_bitpos++;
657 _FaxGet1DLine(m_pSrcBuf, bitsize, bitpos, m_pScanlineBuf, m_OrigWidt h); 727 dest_buf[dest_bitpos / 8] |= 1 << (7 - dest_bitpos % 8);
658 } else { 728 dest_bitpos++;
659 _FaxG4GetRow(m_pSrcBuf, bitsize, bitpos, m_pScanlineBuf, m_pRefBuf, m_OrigWidth); 729 if (a0 < 0) {
660 } 730 a0 = 0;
661 FXSYS_memcpy(m_pRefBuf, m_pScanlineBuf, m_Pitch); 731 }
662 } 732 _FaxEncodeRun(dest_buf, dest_bitpos, a1 - a0, a0color);
663 if (m_bEndOfLine) { 733 _FaxEncodeRun(dest_buf, dest_bitpos, a2 - a1, 1 - a0color);
664 _FaxSkipEOL(m_pSrcBuf, bitsize, bitpos); 734 a0 = a2;
665 } 735 }
666 if (m_bByteAlign && bitpos < bitsize) { 736 if (a0 >= cols) {
667 int bitpos0 = bitpos; 737 return;
668 int bitpos1 = (bitpos + 7) / 8 * 8; 738 }
669 while (m_bByteAlign && bitpos0 < bitpos1) { 739 }
670 int bit = m_pSrcBuf[bitpos0 / 8] & (1 << (7 - bitpos0 % 8)); 740 }
671 if (bit != 0) { 741 class CCodec_FaxEncoder {
672 m_bByteAlign = FALSE; 742 public:
673 } else { 743 CCodec_FaxEncoder(const uint8_t* src_buf, int width, int height, int pitch);
674 bitpos0 ++; 744 ~CCodec_FaxEncoder();
675 } 745 void Encode(uint8_t*& dest_buf, FX_DWORD& dest_size);
676 } 746 void Encode2DLine(const uint8_t* scan_line);
677 if (m_bByteAlign) { 747 CFX_BinaryBuf m_DestBuf;
678 bitpos = bitpos1; 748 uint8_t* m_pRefLine;
679 } 749 uint8_t* m_pLineBuf;
680 } 750 int m_Cols, m_Rows, m_Pitch;
681 if (m_bBlack) { 751 const uint8_t* m_pSrcBuf;
682 for (int i = 0; i < m_Pitch; i ++) { 752 };
683 m_pScanlineBuf[i] = ~m_pScanlineBuf[i]; 753 CCodec_FaxEncoder::CCodec_FaxEncoder(const uint8_t* src_buf,
684 } 754 int width,
685 } 755 int height,
686 return m_pScanlineBuf; 756 int pitch) {
687 } 757 m_pSrcBuf = src_buf;
688 FX_DWORD CCodec_FaxDecoder::GetSrcOffset() 758 m_Cols = width;
689 { 759 m_Rows = height;
690 FX_DWORD ret = (bitpos + 7) / 8; 760 m_Pitch = pitch;
691 if (ret > m_SrcSize) { 761 m_pRefLine = FX_Alloc(uint8_t, m_Pitch);
692 ret = m_SrcSize; 762 FXSYS_memset(m_pRefLine, 0xff, m_Pitch);
693 } 763 m_pLineBuf = FX_Alloc2D(uint8_t, m_Pitch, 8);
694 return ret; 764 m_DestBuf.EstimateSize(0, 10240);
695 } 765 }
696 extern "C" { 766 CCodec_FaxEncoder::~CCodec_FaxEncoder() {
697 void _FaxG4Decode(void*, const uint8_t* src_buf, FX_DWORD src_size, int* pbi tpos, uint8_t* dest_buf, int width, int height, int pitch) 767 if (m_pRefLine) {
698 { 768 FX_Free(m_pRefLine);
699 if (pitch == 0) { 769 }
700 pitch = (width + 7) / 8; 770 if (m_pLineBuf) {
701 } 771 FX_Free(m_pLineBuf);
702 uint8_t* ref_buf = FX_Alloc(uint8_t, pitch); 772 }
703 FXSYS_memset(ref_buf, 0xff, pitch); 773 }
704 int bitpos = *pbitpos; 774 void CCodec_FaxEncoder::Encode(uint8_t*& dest_buf, FX_DWORD& dest_size) {
705 for (int iRow = 0; iRow < height; iRow ++) { 775 int dest_bitpos = 0;
706 uint8_t* line_buf = dest_buf + iRow * pitch; 776 uint8_t last_byte = 0;
707 FXSYS_memset(line_buf, 0xff, pitch); 777 for (int i = 0; i < m_Rows; i++) {
708 _FaxG4GetRow(src_buf, src_size << 3, bitpos, line_buf, ref_buf, widt h); 778 const uint8_t* scan_line = m_pSrcBuf + i * m_Pitch;
709 FXSYS_memcpy(ref_buf, line_buf, pitch); 779 FXSYS_memset(m_pLineBuf, 0, m_Pitch * 8);
710 } 780 m_pLineBuf[0] = last_byte;
711 FX_Free(ref_buf); 781 _FaxEncode2DLine(m_pLineBuf, dest_bitpos, scan_line, m_pRefLine, m_Cols);
712 *pbitpos = bitpos; 782 m_DestBuf.AppendBlock(m_pLineBuf, dest_bitpos / 8);
713 } 783 last_byte = m_pLineBuf[dest_bitpos / 8];
714 }; 784 dest_bitpos %= 8;
715 static const uint8_t BlackRunTerminator[128] = { 785 FXSYS_memcpy(m_pRefLine, scan_line, m_Pitch);
716 0x37, 10, 0x02, 3, 0x03, 2, 0x02, 2, 0x03, 3, 0x03, 4, 0x02, 4, 0x03, 5, 786 }
717 0x05, 6, 0x04, 6, 0x04, 7, 0x05, 7, 0x07, 7, 0x04, 8, 0x07, 8, 0x18, 9, 787 if (dest_bitpos) {
718 0x17, 10, 0x18, 10, 0x08, 10, 0x67, 11, 0x68, 11, 0x6c, 11, 0x37, 11, 0x28, 11, 788 m_DestBuf.AppendByte(last_byte);
719 0x17, 11, 0x18, 11, 0xca, 12, 0xcb, 12, 0xcc, 12, 0xcd, 12, 0x68, 12, 0x69, 12, 789 }
720 0x6a, 12, 0x6b, 12, 0xd2, 12, 0xd3, 12, 0xd4, 12, 0xd5, 12, 0xd6, 12, 0xd7, 12, 790 dest_buf = m_DestBuf.GetBuffer();
721 0x6c, 12, 0x6d, 12, 0xda, 12, 0xdb, 12, 0x54, 12, 0x55, 12, 0x56, 12, 0x57, 12, 791 dest_size = m_DestBuf.GetSize();
722 0x64, 12, 0x65, 12, 0x52, 12, 0x53, 12, 0x24, 12, 0x37, 12, 0x38, 12, 0x27, 12, 792 m_DestBuf.DetachBuffer();
723 0x28, 12, 0x58, 12, 0x59, 12, 0x2b, 12, 0x2c, 12, 0x5a, 12, 0x66, 12, 0x67, 12, 793 }
724 }; 794 FX_BOOL CCodec_FaxModule::Encode(const uint8_t* src_buf,
725 static const uint8_t BlackRunMarkup[80] = { 795 int width,
726 0x0f, 10, 0xc8, 12, 0xc9, 12, 0x5b, 12, 0x33, 12, 0x34, 12, 0x35, 12, 0x6c, 13, 796 int height,
727 0x6d, 13, 0x4a, 13, 0x4b, 13, 0x4c, 13, 0x4d, 13, 0x72, 13, 0x73, 13, 0x74, 13, 797 int pitch,
728 0x75, 13, 0x76, 13, 0x77, 13, 0x52, 13, 0x53, 13, 0x54, 13, 0x55, 13, 0x5a, 13, 798 uint8_t*& dest_buf,
729 0x5b, 13, 0x64, 13, 0x65, 13, 0x08, 11, 0x0c, 11, 0x0d, 11, 0x12, 12, 0x13, 12, 799 FX_DWORD& dest_size) {
730 0x14, 12, 0x15, 12, 0x16, 12, 0x17, 12, 0x1c, 12, 0x1d, 12, 0x1e, 12, 0x1f, 12, 800 CCodec_FaxEncoder encoder(src_buf, width, height, pitch);
731 }; 801 encoder.Encode(dest_buf, dest_size);
732 static const uint8_t WhiteRunTerminator[128] = { 802 return TRUE;
733 0x35, 8, 803 }
734 0x07, 6, 804 ICodec_ScanlineDecoder* CCodec_FaxModule::CreateDecoder(
735 0x07, 4, 805 const uint8_t* src_buf,
736 0x08, 4, 806 FX_DWORD src_size,
737 0x0B, 4, 807 int width,
738 0x0C, 4, 808 int height,
739 0x0E, 4, 809 int K,
740 0x0F, 4, 810 FX_BOOL EndOfLine,
741 0x13, 5, 811 FX_BOOL EncodedByteAlign,
742 0x14, 5, 812 FX_BOOL BlackIs1,
743 0x07, 5, 813 int Columns,
744 0x08, 5, 814 int Rows) {
745 0x08, 6, 815 CCodec_FaxDecoder* pDecoder = new CCodec_FaxDecoder;
746 0x03, 6, 816 pDecoder->Create(src_buf, src_size, width, height, K, EndOfLine,
747 0x34, 6, 817 EncodedByteAlign, BlackIs1, Columns, Rows);
748 0x35, 6, 818 return pDecoder;
749 0x2a, 6, 819 }
750 0x2B, 6,
751 0x27, 7,
752 0x0c, 7,
753 0x08, 7,
754 0x17, 7,
755 0x03, 7,
756 0x04, 7,
757 0x28, 7,
758 0x2B, 7,
759 0x13, 7,
760 0x24, 7,
761 0x18, 7,
762 0x02, 8,
763 0x03, 8,
764 0x1a, 8,
765 0x1b, 8,
766 0x12, 8,
767 0x13, 8,
768 0x14, 8,
769 0x15, 8,
770 0x16, 8,
771 0x17, 8,
772 0x28, 8,
773 0x29, 8,
774 0x2a, 8,
775 0x2b, 8,
776 0x2c, 8,
777 0x2d, 8,
778 0x04, 8,
779 0x05, 8,
780 0x0a, 8,
781 0x0b, 8,
782 0x52, 8,
783 0x53, 8,
784 0x54, 8,
785 0x55, 8,
786 0x24, 8,
787 0x25, 8,
788 0x58, 8,
789 0x59, 8,
790 0x5a, 8,
791 0x5b, 8,
792 0x4a, 8,
793 0x4b, 8,
794 0x32, 8,
795 0x33, 8,
796 0x34, 8,
797 };
798 static const uint8_t WhiteRunMarkup[80] = {
799 0x1b, 5,
800 0x12, 5,
801 0x17, 6,
802 0x37, 7,
803 0x36, 8,
804 0x37, 8,
805 0x64, 8,
806 0x65, 8,
807 0x68, 8,
808 0x67, 8,
809 0xcc, 9,
810 0xcd, 9,
811 0xd2, 9,
812 0xd3, 9,
813 0xd4, 9,
814 0xd5, 9,
815 0xd6, 9,
816 0xd7, 9,
817 0xd8, 9,
818 0xd9, 9,
819 0xda, 9,
820 0xdb, 9,
821 0x98, 9,
822 0x99, 9,
823 0x9a, 9,
824 0x18, 6,
825 0x9b, 9,
826 0x08, 11,
827 0x0c, 11,
828 0x0d, 11,
829 0x12, 12,
830 0x13, 12,
831 0x14, 12,
832 0x15, 12,
833 0x16, 12,
834 0x17, 12,
835 0x1c, 12,
836 0x1d, 12,
837 0x1e, 12,
838 0x1f, 12,
839 };
840 static void _AddBitStream(uint8_t* dest_buf, int& dest_bitpos, int data, int bit len)
841 {
842 for (int i = bitlen - 1; i >= 0; i --) {
843 if (data & (1 << i)) {
844 dest_buf[dest_bitpos / 8] |= 1 << (7 - dest_bitpos % 8);
845 }
846 dest_bitpos ++;
847 }
848 }
849 static void _FaxEncodeRun(uint8_t* dest_buf, int& dest_bitpos, int run, FX_BOOL bWhite)
850 {
851 while (run >= 2560) {
852 _AddBitStream(dest_buf, dest_bitpos, 0x1f, 12);
853 run -= 2560;
854 }
855 if (run >= 64) {
856 int markup = run - run % 64;
857 const uint8_t* p = bWhite ? WhiteRunMarkup : BlackRunMarkup;
858 p += (markup / 64 - 1) * 2;
859 _AddBitStream(dest_buf, dest_bitpos, *p, p[1]);
860 }
861 run %= 64;
862 const uint8_t* p = bWhite ? WhiteRunTerminator : BlackRunTerminator;
863 p += run * 2;
864 _AddBitStream(dest_buf, dest_bitpos, *p, p[1]);
865 }
866 static void _FaxEncode2DLine(uint8_t* dest_buf, int& dest_bitpos, const uint8_t* src_buf, const uint8_t* ref_buf, int cols)
867 {
868 int a0 = -1, a0color = 1;
869 while (1) {
870 int a1 = _FindBit(src_buf, cols, a0 + 1, 1 - a0color);
871 int b1, b2;
872 _FaxG4FindB1B2(ref_buf, cols, a0, a0color, b1, b2);
873 if (b2 < a1) {
874 dest_bitpos += 3;
875 dest_buf[dest_bitpos / 8] |= 1 << (7 - dest_bitpos % 8);
876 dest_bitpos ++;
877 a0 = b2;
878 } else if (a1 - b1 <= 3 && b1 - a1 <= 3) {
879 int delta = a1 - b1;
880 switch (delta) {
881 case 0:
882 dest_buf[dest_bitpos / 8] |= 1 << (7 - dest_bitpos % 8);
883 break;
884 case 1:
885 case 2:
886 case 3:
887 dest_bitpos += delta == 1 ? 1 : delta + 2;
888 dest_buf[dest_bitpos / 8] |= 1 << (7 - dest_bitpos % 8);
889 dest_bitpos ++;
890 dest_buf[dest_bitpos / 8] |= 1 << (7 - dest_bitpos % 8);
891 break;
892 case -1:
893 case -2:
894 case -3:
895 dest_bitpos += delta == -1 ? 1 : -delta + 2;
896 dest_buf[dest_bitpos / 8] |= 1 << (7 - dest_bitpos % 8);
897 dest_bitpos ++;
898 break;
899 }
900 dest_bitpos ++;
901 a0 = a1;
902 a0color = 1 - a0color;
903 } else {
904 int a2 = _FindBit(src_buf, cols, a1 + 1, a0color);
905 dest_bitpos ++;
906 dest_bitpos ++;
907 dest_buf[dest_bitpos / 8] |= 1 << (7 - dest_bitpos % 8);
908 dest_bitpos ++;
909 if (a0 < 0) {
910 a0 = 0;
911 }
912 _FaxEncodeRun(dest_buf, dest_bitpos, a1 - a0, a0color);
913 _FaxEncodeRun(dest_buf, dest_bitpos, a2 - a1, 1 - a0color);
914 a0 = a2;
915 }
916 if (a0 >= cols) {
917 return;
918 }
919 }
920 }
921 class CCodec_FaxEncoder
922 {
923 public:
924 CCodec_FaxEncoder(const uint8_t* src_buf, int width, int height, int pitch);
925 ~CCodec_FaxEncoder();
926 void Encode(uint8_t*& dest_buf, FX_DWORD& dest_size);
927 void Encode2DLine(const uint8_t* scan_line);
928 CFX_BinaryBuf m_DestBuf;
929 uint8_t* m_pRefLine;
930 uint8_t* m_pLineBuf;
931 int m_Cols, m_Rows, m_Pitch;
932 const uint8_t* m_pSrcBuf;
933 };
934 CCodec_FaxEncoder::CCodec_FaxEncoder(const uint8_t* src_buf, int width, int heig ht, int pitch)
935 {
936 m_pSrcBuf = src_buf;
937 m_Cols = width;
938 m_Rows = height;
939 m_Pitch = pitch;
940 m_pRefLine = FX_Alloc(uint8_t, m_Pitch);
941 FXSYS_memset(m_pRefLine, 0xff, m_Pitch);
942 m_pLineBuf = FX_Alloc2D(uint8_t, m_Pitch, 8);
943 m_DestBuf.EstimateSize(0, 10240);
944 }
945 CCodec_FaxEncoder::~CCodec_FaxEncoder()
946 {
947 if (m_pRefLine) {
948 FX_Free(m_pRefLine);
949 }
950 if (m_pLineBuf) {
951 FX_Free(m_pLineBuf);
952 }
953 }
954 void CCodec_FaxEncoder::Encode(uint8_t*& dest_buf, FX_DWORD& dest_size)
955 {
956 int dest_bitpos = 0;
957 uint8_t last_byte = 0;
958 for (int i = 0; i < m_Rows; i ++) {
959 const uint8_t* scan_line = m_pSrcBuf + i * m_Pitch;
960 FXSYS_memset(m_pLineBuf, 0, m_Pitch * 8);
961 m_pLineBuf[0] = last_byte;
962 _FaxEncode2DLine(m_pLineBuf, dest_bitpos, scan_line, m_pRefLine, m_Cols) ;
963 m_DestBuf.AppendBlock(m_pLineBuf, dest_bitpos / 8);
964 last_byte = m_pLineBuf[dest_bitpos / 8];
965 dest_bitpos %= 8;
966 FXSYS_memcpy(m_pRefLine, scan_line, m_Pitch);
967 }
968 if (dest_bitpos) {
969 m_DestBuf.AppendByte(last_byte);
970 }
971 dest_buf = m_DestBuf.GetBuffer();
972 dest_size = m_DestBuf.GetSize();
973 m_DestBuf.DetachBuffer();
974 }
975 FX_BOOL CCodec_FaxModule::Encode(const uint8_t* src_buf, int width, int height, int pitch, uint8_t*& dest_buf, FX_DWORD& dest_size)
976 {
977 CCodec_FaxEncoder encoder(src_buf, width, height, pitch);
978 encoder.Encode(dest_buf, dest_size);
979 return TRUE;
980 }
981 ICodec_ScanlineDecoder* CCodec_FaxModule::CreateDecoder(const uint8_t* src_buf, FX_DWORD src_size, int width, int height,
982 int K, FX_BOOL EndOfLine, FX_BOOL EncodedByteAlign, FX_BOOL BlackIs1, in t Columns, int Rows)
983 {
984 CCodec_FaxDecoder* pDecoder = new CCodec_FaxDecoder;
985 pDecoder->Create(src_buf, src_size, width, height, K, EndOfLine, EncodedByte Align, BlackIs1, Columns, Rows);
986 return pDecoder;
987 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698