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

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

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

Powered by Google App Engine
This is Rietveld 408576698