Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 :
21 : #include "ccidecom.hxx"
22 :
23 : //=============================== Huffman tables ========================
24 :
25 : //---------------------------- White-Run ------------------------------
26 :
27 : #define CCIWhiteTableSize 105
28 :
29 : const CCIHuffmanTableEntry CCIWhiteTable[CCIWhiteTableSize]={
30 : { 0, 0x0035, 8 },
31 : { 1, 0x0007, 6 },
32 : { 2, 0x0007, 4 },
33 : { 3, 0x0008, 4 },
34 : { 4, 0x000b, 4 },
35 : { 5, 0x000c, 4 },
36 : { 6, 0x000e, 4 },
37 : { 7, 0x000f, 4 },
38 : { 8, 0x0013, 5 },
39 : { 9, 0x0014, 5 },
40 : { 10, 0x0007, 5 },
41 : { 11, 0x0008, 5 },
42 : { 12, 0x0008, 6 },
43 : { 13, 0x0003, 6 },
44 : { 14, 0x0034, 6 },
45 : { 15, 0x0035, 6 },
46 : { 16, 0x002a, 6 },
47 : { 17, 0x002b, 6 },
48 : { 18, 0x0027, 7 },
49 : { 19, 0x000c, 7 },
50 : { 20, 0x0008, 7 },
51 : { 21, 0x0017, 7 },
52 : { 22, 0x0003, 7 },
53 : { 23, 0x0004, 7 },
54 : { 24, 0x0028, 7 },
55 : { 25, 0x002b, 7 },
56 : { 26, 0x0013, 7 },
57 : { 27, 0x0024, 7 },
58 : { 28, 0x0018, 7 },
59 : { 29, 0x0002, 8 },
60 : { 30, 0x0003, 8 },
61 : { 31, 0x001a, 8 },
62 : { 32, 0x001b, 8 },
63 : { 33, 0x0012, 8 },
64 : { 34, 0x0013, 8 },
65 : { 35, 0x0014, 8 },
66 : { 36, 0x0015, 8 },
67 : { 37, 0x0016, 8 },
68 : { 38, 0x0017, 8 },
69 : { 39, 0x0028, 8 },
70 : { 40, 0x0029, 8 },
71 : { 41, 0x002a, 8 },
72 : { 42, 0x002b, 8 },
73 : { 43, 0x002c, 8 },
74 : { 44, 0x002d, 8 },
75 : { 45, 0x0004, 8 },
76 : { 46, 0x0005, 8 },
77 : { 47, 0x000a, 8 },
78 : { 48, 0x000b, 8 },
79 : { 49, 0x0052, 8 },
80 : { 50, 0x0053, 8 },
81 : { 51, 0x0054, 8 },
82 : { 52, 0x0055, 8 },
83 : { 53, 0x0024, 8 },
84 : { 54, 0x0025, 8 },
85 : { 55, 0x0058, 8 },
86 : { 56, 0x0059, 8 },
87 : { 57, 0x005a, 8 },
88 : { 58, 0x005b, 8 },
89 : { 59, 0x004a, 8 },
90 : { 60, 0x004b, 8 },
91 : { 61, 0x0032, 8 },
92 : { 62, 0x0033, 8 },
93 : { 63, 0x0034, 8 },
94 : { 64, 0x001b, 5 },
95 : { 128, 0x0012, 5 },
96 : { 192, 0x0017, 6 },
97 : { 256, 0x0037, 7 },
98 : { 320, 0x0036, 8 },
99 : { 384, 0x0037, 8 },
100 : { 448, 0x0064, 8 },
101 : { 512, 0x0065, 8 },
102 : { 576, 0x0068, 8 },
103 : { 640, 0x0067, 8 },
104 : { 704, 0x00cc, 9 },
105 : { 768, 0x00cd, 9 },
106 : { 832, 0x00d2, 9 },
107 : { 896, 0x00d3, 9 },
108 : { 960, 0x00d4, 9 },
109 : { 1024, 0x00d5, 9 },
110 : { 1088, 0x00d6, 9 },
111 : { 1152, 0x00d7, 9 },
112 : { 1216, 0x00d8, 9 },
113 : { 1280, 0x00d9, 9 },
114 : { 1344, 0x00da, 9 },
115 : { 1408, 0x00db, 9 },
116 : { 1472, 0x0098, 9 },
117 : { 1536, 0x0099, 9 },
118 : { 1600, 0x009a, 9 },
119 : { 1664, 0x0018, 6 },
120 : { 1728, 0x009b, 9 },
121 : { 1792, 0x0008, 11 },
122 : { 1856, 0x000c, 11 },
123 : { 1920, 0x000d, 11 },
124 : { 1984, 0x0012, 12 },
125 : { 2048, 0x0013, 12 },
126 : { 2112, 0x0014, 12 },
127 : { 2176, 0x0015, 12 },
128 : { 2240, 0x0016, 12 },
129 : { 2304, 0x0017, 12 },
130 : { 2368, 0x001c, 12 },
131 : { 2432, 0x001d, 12 },
132 : { 2496, 0x001e, 12 },
133 : { 2560, 0x001f, 12 },
134 : { 9999, 0x0001, 12 } // EOL
135 : };
136 :
137 : //---------------------------- Black-Run ------------------------------
138 :
139 : #define CCIBlackTableSize 105
140 :
141 : const CCIHuffmanTableEntry CCIBlackTable[CCIBlackTableSize]={
142 : { 0, 0x0037, 10 },
143 : { 1, 0x0002, 3 },
144 : { 2, 0x0003, 2 },
145 : { 3, 0x0002, 2 },
146 : { 4, 0x0003, 3 },
147 : { 5, 0x0003, 4 },
148 : { 6, 0x0002, 4 },
149 : { 7, 0x0003, 5 },
150 : { 8, 0x0005, 6 },
151 : { 9, 0x0004, 6 },
152 : { 10, 0x0004, 7 },
153 : { 11, 0x0005, 7 },
154 : { 12, 0x0007, 7 },
155 : { 13, 0x0004, 8 },
156 : { 14, 0x0007, 8 },
157 : { 15, 0x0018, 9 },
158 : { 16, 0x0017, 10 },
159 : { 17, 0x0018, 10 },
160 : { 18, 0x0008, 10 },
161 : { 19, 0x0067, 11 },
162 : { 20, 0x0068, 11 },
163 : { 21, 0x006c, 11 },
164 : { 22, 0x0037, 11 },
165 : { 23, 0x0028, 11 },
166 : { 24, 0x0017, 11 },
167 : { 25, 0x0018, 11 },
168 : { 26, 0x00ca, 12 },
169 : { 27, 0x00cb, 12 },
170 : { 28, 0x00cc, 12 },
171 : { 29, 0x00cd, 12 },
172 : { 30, 0x0068, 12 },
173 : { 31, 0x0069, 12 },
174 : { 32, 0x006a, 12 },
175 : { 33, 0x006b, 12 },
176 : { 34, 0x00d2, 12 },
177 : { 35, 0x00d3, 12 },
178 : { 36, 0x00d4, 12 },
179 : { 37, 0x00d5, 12 },
180 : { 38, 0x00d6, 12 },
181 : { 39, 0x00d7, 12 },
182 : { 40, 0x006c, 12 },
183 : { 41, 0x006d, 12 },
184 : { 42, 0x00da, 12 },
185 : { 43, 0x00db, 12 },
186 : { 44, 0x0054, 12 },
187 : { 45, 0x0055, 12 },
188 : { 46, 0x0056, 12 },
189 : { 47, 0x0057, 12 },
190 : { 48, 0x0064, 12 },
191 : { 49, 0x0065, 12 },
192 : { 50, 0x0052, 12 },
193 : { 51, 0x0053, 12 },
194 : { 52, 0x0024, 12 },
195 : { 53, 0x0037, 12 },
196 : { 54, 0x0038, 12 },
197 : { 55, 0x0027, 12 },
198 : { 56, 0x0028, 12 },
199 : { 57, 0x0058, 12 },
200 : { 58, 0x0059, 12 },
201 : { 59, 0x002b, 12 },
202 : { 60, 0x002c, 12 },
203 : { 61, 0x005a, 12 },
204 : { 62, 0x0066, 12 },
205 : { 63, 0x0067, 12 },
206 : { 64, 0x000f, 10 },
207 : { 128, 0x00c8, 12 },
208 : { 192, 0x00c9, 12 },
209 : { 256, 0x005b, 12 },
210 : { 320, 0x0033, 12 },
211 : { 384, 0x0034, 12 },
212 : { 448, 0x0035, 12 },
213 : { 512, 0x006c, 13 },
214 : { 576, 0x006d, 13 },
215 : { 640, 0x004a, 13 },
216 : { 704, 0x004b, 13 },
217 : { 768, 0x004c, 13 },
218 : { 832, 0x004d, 13 },
219 : { 896, 0x0072, 13 },
220 : { 960, 0x0073, 13 },
221 : { 1024, 0x0074, 13 },
222 : { 1088, 0x0075, 13 },
223 : { 1152, 0x0076, 13 },
224 : { 1216, 0x0077, 13 },
225 : { 1280, 0x0052, 13 },
226 : { 1344, 0x0053, 13 },
227 : { 1408, 0x0054, 13 },
228 : { 1472, 0x0055, 13 },
229 : { 1536, 0x005a, 13 },
230 : { 1600, 0x005b, 13 },
231 : { 1664, 0x0064, 13 },
232 : { 1728, 0x0065, 13 },
233 : { 1792, 0x0008, 11 },
234 : { 1856, 0x000c, 11 },
235 : { 1920, 0x000d, 11 },
236 : { 1984, 0x0012, 12 },
237 : { 2048, 0x0013, 12 },
238 : { 2112, 0x0014, 12 },
239 : { 2176, 0x0015, 12 },
240 : { 2240, 0x0016, 12 },
241 : { 2304, 0x0017, 12 },
242 : { 2368, 0x001c, 12 },
243 : { 2432, 0x001d, 12 },
244 : { 2496, 0x001e, 12 },
245 : { 2560, 0x001f, 12 },
246 : { 9999, 0x0001, 12 } // EOL
247 : };
248 :
249 :
250 : //---------------------------- 2D-Mode --------------------------------
251 :
252 : #define CCI2DMODE_UNCOMP 0
253 : #define CCI2DMODE_PASS 1
254 : #define CCI2DMODE_HORZ 2
255 : #define CCI2DMODE_VERT_L3 3
256 : #define CCI2DMODE_VERT_L2 4
257 : #define CCI2DMODE_VERT_L1 5
258 : #define CCI2DMODE_VERT_0 6
259 : #define CCI2DMODE_VERT_R1 7
260 : #define CCI2DMODE_VERT_R2 8
261 : #define CCI2DMODE_VERT_R3 9
262 :
263 : #define CCI2DModeTableSize 10
264 :
265 : const CCIHuffmanTableEntry CCI2DModeTable[CCI2DModeTableSize]={
266 : { CCI2DMODE_UNCOMP , 0x000f, 10 },
267 : { CCI2DMODE_PASS , 0x0001, 4 },
268 : { CCI2DMODE_HORZ , 0x0001, 3 },
269 : { CCI2DMODE_VERT_L3, 0x0002, 7 },
270 : { CCI2DMODE_VERT_L2, 0x0002, 6 },
271 : { CCI2DMODE_VERT_L1, 0x0002, 3 },
272 : { CCI2DMODE_VERT_0 , 0x0001, 1 },
273 : { CCI2DMODE_VERT_R1, 0x0003, 3 },
274 : { CCI2DMODE_VERT_R2, 0x0003, 6 },
275 : { CCI2DMODE_VERT_R3, 0x0003, 7 }
276 : };
277 :
278 :
279 : //-------------------------- 2D-Uncompressed-Mode ----------------------
280 :
281 : #define CCIUNCOMP_0White_1Black 0
282 : #define CCIUNCOMP_1White_1Black 1
283 : #define CCIUNCOMP_2White_1Black 2
284 : #define CCIUNCOMP_3White_1Black 3
285 : #define CCIUNCOMP_4White_1Black 4
286 : #define CCIUNCOMP_5White 5
287 : #define CCIUNCOMP_0White_End 6
288 : #define CCIUNCOMP_1White_End 7
289 : #define CCIUNCOMP_2White_End 8
290 : #define CCIUNCOMP_3White_End 9
291 : #define CCIUNCOMP_4White_End 10
292 :
293 : #define CCIUncompTableSize 11
294 :
295 : const CCIHuffmanTableEntry CCIUncompTable[CCIUncompTableSize]={
296 : { CCIUNCOMP_0White_1Black, 0x0001, 1 },
297 : { CCIUNCOMP_1White_1Black, 0x0001, 2 },
298 : { CCIUNCOMP_2White_1Black, 0x0001, 3 },
299 : { CCIUNCOMP_3White_1Black, 0x0001, 4 },
300 : { CCIUNCOMP_4White_1Black, 0x0001, 5 },
301 : { CCIUNCOMP_5White , 0x0001, 6 },
302 : { CCIUNCOMP_0White_End , 0x0001, 7 },
303 : { CCIUNCOMP_1White_End , 0x0001, 8 },
304 : { CCIUNCOMP_2White_End , 0x0001, 9 },
305 : { CCIUNCOMP_3White_End , 0x0001, 10 },
306 : { CCIUNCOMP_4White_End , 0x0001, 11 }
307 : };
308 :
309 :
310 : //================== backup of the Huffman tables ============================
311 : // To make sure that the Huffman tables do not contain errors they were entered
312 : // from two different sources (Phew) and compared.
313 : // Since an error could creep in to the source code while maintaining it
314 : // (e.g. an accidentaly key press in the editor) the tables are listed twice
315 : // and are compared during runtime. (If the comparison fails CCIDcompressor
316 : // throws an error) The whole thing may appear insane, but an error within the
317 : // tables would otherwise be really hard to discover and it's very unlikely that
318 : // one or more sample files run through all codes.
319 :
320 : const CCIHuffmanTableEntry CCIWhiteTableSave[CCIWhiteTableSize]={
321 : { 0, 0x0035, 8 },
322 : { 1, 0x0007, 6 },
323 : { 2, 0x0007, 4 },
324 : { 3, 0x0008, 4 },
325 : { 4, 0x000b, 4 },
326 : { 5, 0x000c, 4 },
327 : { 6, 0x000e, 4 },
328 : { 7, 0x000f, 4 },
329 : { 8, 0x0013, 5 },
330 : { 9, 0x0014, 5 },
331 : { 10, 0x0007, 5 },
332 : { 11, 0x0008, 5 },
333 : { 12, 0x0008, 6 },
334 : { 13, 0x0003, 6 },
335 : { 14, 0x0034, 6 },
336 : { 15, 0x0035, 6 },
337 : { 16, 0x002a, 6 },
338 : { 17, 0x002b, 6 },
339 : { 18, 0x0027, 7 },
340 : { 19, 0x000c, 7 },
341 : { 20, 0x0008, 7 },
342 : { 21, 0x0017, 7 },
343 : { 22, 0x0003, 7 },
344 : { 23, 0x0004, 7 },
345 : { 24, 0x0028, 7 },
346 : { 25, 0x002b, 7 },
347 : { 26, 0x0013, 7 },
348 : { 27, 0x0024, 7 },
349 : { 28, 0x0018, 7 },
350 : { 29, 0x0002, 8 },
351 : { 30, 0x0003, 8 },
352 : { 31, 0x001a, 8 },
353 : { 32, 0x001b, 8 },
354 : { 33, 0x0012, 8 },
355 : { 34, 0x0013, 8 },
356 : { 35, 0x0014, 8 },
357 : { 36, 0x0015, 8 },
358 : { 37, 0x0016, 8 },
359 : { 38, 0x0017, 8 },
360 : { 39, 0x0028, 8 },
361 : { 40, 0x0029, 8 },
362 : { 41, 0x002a, 8 },
363 : { 42, 0x002b, 8 },
364 : { 43, 0x002c, 8 },
365 : { 44, 0x002d, 8 },
366 : { 45, 0x0004, 8 },
367 : { 46, 0x0005, 8 },
368 : { 47, 0x000a, 8 },
369 : { 48, 0x000b, 8 },
370 : { 49, 0x0052, 8 },
371 : { 50, 0x0053, 8 },
372 : { 51, 0x0054, 8 },
373 : { 52, 0x0055, 8 },
374 : { 53, 0x0024, 8 },
375 : { 54, 0x0025, 8 },
376 : { 55, 0x0058, 8 },
377 : { 56, 0x0059, 8 },
378 : { 57, 0x005a, 8 },
379 : { 58, 0x005b, 8 },
380 : { 59, 0x004a, 8 },
381 : { 60, 0x004b, 8 },
382 : { 61, 0x0032, 8 },
383 : { 62, 0x0033, 8 },
384 : { 63, 0x0034, 8 },
385 : { 64, 0x001b, 5 },
386 : { 128, 0x0012, 5 },
387 : { 192, 0x0017, 6 },
388 : { 256, 0x0037, 7 },
389 : { 320, 0x0036, 8 },
390 : { 384, 0x0037, 8 },
391 : { 448, 0x0064, 8 },
392 : { 512, 0x0065, 8 },
393 : { 576, 0x0068, 8 },
394 : { 640, 0x0067, 8 },
395 : { 704, 0x00cc, 9 },
396 : { 768, 0x00cd, 9 },
397 : { 832, 0x00d2, 9 },
398 : { 896, 0x00d3, 9 },
399 : { 960, 0x00d4, 9 },
400 : { 1024, 0x00d5, 9 },
401 : { 1088, 0x00d6, 9 },
402 : { 1152, 0x00d7, 9 },
403 : { 1216, 0x00d8, 9 },
404 : { 1280, 0x00d9, 9 },
405 : { 1344, 0x00da, 9 },
406 : { 1408, 0x00db, 9 },
407 : { 1472, 0x0098, 9 },
408 : { 1536, 0x0099, 9 },
409 : { 1600, 0x009a, 9 },
410 : { 1664, 0x0018, 6 },
411 : { 1728, 0x009b, 9 },
412 : { 1792, 0x0008, 11 },
413 : { 1856, 0x000c, 11 },
414 : { 1920, 0x000d, 11 },
415 : { 1984, 0x0012, 12 },
416 : { 2048, 0x0013, 12 },
417 : { 2112, 0x0014, 12 },
418 : { 2176, 0x0015, 12 },
419 : { 2240, 0x0016, 12 },
420 : { 2304, 0x0017, 12 },
421 : { 2368, 0x001c, 12 },
422 : { 2432, 0x001d, 12 },
423 : { 2496, 0x001e, 12 },
424 : { 2560, 0x001f, 12 },
425 : { 9999, 0x0001, 12 } // EOL
426 : };
427 :
428 : const CCIHuffmanTableEntry CCIBlackTableSave[CCIBlackTableSize]={
429 : { 0, 0x0037, 10 },
430 : { 1, 0x0002, 3 },
431 : { 2, 0x0003, 2 },
432 : { 3, 0x0002, 2 },
433 : { 4, 0x0003, 3 },
434 : { 5, 0x0003, 4 },
435 : { 6, 0x0002, 4 },
436 : { 7, 0x0003, 5 },
437 : { 8, 0x0005, 6 },
438 : { 9, 0x0004, 6 },
439 : { 10, 0x0004, 7 },
440 : { 11, 0x0005, 7 },
441 : { 12, 0x0007, 7 },
442 : { 13, 0x0004, 8 },
443 : { 14, 0x0007, 8 },
444 : { 15, 0x0018, 9 },
445 : { 16, 0x0017, 10 },
446 : { 17, 0x0018, 10 },
447 : { 18, 0x0008, 10 },
448 : { 19, 0x0067, 11 },
449 : { 20, 0x0068, 11 },
450 : { 21, 0x006c, 11 },
451 : { 22, 0x0037, 11 },
452 : { 23, 0x0028, 11 },
453 : { 24, 0x0017, 11 },
454 : { 25, 0x0018, 11 },
455 : { 26, 0x00ca, 12 },
456 : { 27, 0x00cb, 12 },
457 : { 28, 0x00cc, 12 },
458 : { 29, 0x00cd, 12 },
459 : { 30, 0x0068, 12 },
460 : { 31, 0x0069, 12 },
461 : { 32, 0x006a, 12 },
462 : { 33, 0x006b, 12 },
463 : { 34, 0x00d2, 12 },
464 : { 35, 0x00d3, 12 },
465 : { 36, 0x00d4, 12 },
466 : { 37, 0x00d5, 12 },
467 : { 38, 0x00d6, 12 },
468 : { 39, 0x00d7, 12 },
469 : { 40, 0x006c, 12 },
470 : { 41, 0x006d, 12 },
471 : { 42, 0x00da, 12 },
472 : { 43, 0x00db, 12 },
473 : { 44, 0x0054, 12 },
474 : { 45, 0x0055, 12 },
475 : { 46, 0x0056, 12 },
476 : { 47, 0x0057, 12 },
477 : { 48, 0x0064, 12 },
478 : { 49, 0x0065, 12 },
479 : { 50, 0x0052, 12 },
480 : { 51, 0x0053, 12 },
481 : { 52, 0x0024, 12 },
482 : { 53, 0x0037, 12 },
483 : { 54, 0x0038, 12 },
484 : { 55, 0x0027, 12 },
485 : { 56, 0x0028, 12 },
486 : { 57, 0x0058, 12 },
487 : { 58, 0x0059, 12 },
488 : { 59, 0x002b, 12 },
489 : { 60, 0x002c, 12 },
490 : { 61, 0x005a, 12 },
491 : { 62, 0x0066, 12 },
492 : { 63, 0x0067, 12 },
493 : { 64, 0x000f, 10 },
494 : { 128, 0x00c8, 12 },
495 : { 192, 0x00c9, 12 },
496 : { 256, 0x005b, 12 },
497 : { 320, 0x0033, 12 },
498 : { 384, 0x0034, 12 },
499 : { 448, 0x0035, 12 },
500 : { 512, 0x006c, 13 },
501 : { 576, 0x006d, 13 },
502 : { 640, 0x004a, 13 },
503 : { 704, 0x004b, 13 },
504 : { 768, 0x004c, 13 },
505 : { 832, 0x004d, 13 },
506 : { 896, 0x0072, 13 },
507 : { 960, 0x0073, 13 },
508 : { 1024, 0x0074, 13 },
509 : { 1088, 0x0075, 13 },
510 : { 1152, 0x0076, 13 },
511 : { 1216, 0x0077, 13 },
512 : { 1280, 0x0052, 13 },
513 : { 1344, 0x0053, 13 },
514 : { 1408, 0x0054, 13 },
515 : { 1472, 0x0055, 13 },
516 : { 1536, 0x005a, 13 },
517 : { 1600, 0x005b, 13 },
518 : { 1664, 0x0064, 13 },
519 : { 1728, 0x0065, 13 },
520 : { 1792, 0x0008, 11 },
521 : { 1856, 0x000c, 11 },
522 : { 1920, 0x000d, 11 },
523 : { 1984, 0x0012, 12 },
524 : { 2048, 0x0013, 12 },
525 : { 2112, 0x0014, 12 },
526 : { 2176, 0x0015, 12 },
527 : { 2240, 0x0016, 12 },
528 : { 2304, 0x0017, 12 },
529 : { 2368, 0x001c, 12 },
530 : { 2432, 0x001d, 12 },
531 : { 2496, 0x001e, 12 },
532 : { 2560, 0x001f, 12 },
533 : { 9999, 0x0001, 12 } // EOL
534 : };
535 :
536 :
537 : const CCIHuffmanTableEntry CCI2DModeTableSave[CCI2DModeTableSize]={
538 : { CCI2DMODE_UNCOMP , 0x000f, 10 },
539 : { CCI2DMODE_PASS , 0x0001, 4 },
540 : { CCI2DMODE_HORZ , 0x0001, 3 },
541 : { CCI2DMODE_VERT_L3, 0x0002, 7 },
542 : { CCI2DMODE_VERT_L2, 0x0002, 6 },
543 : { CCI2DMODE_VERT_L1, 0x0002, 3 },
544 : { CCI2DMODE_VERT_0 , 0x0001, 1 },
545 : { CCI2DMODE_VERT_R1, 0x0003, 3 },
546 : { CCI2DMODE_VERT_R2, 0x0003, 6 },
547 : { CCI2DMODE_VERT_R3, 0x0003, 7 }
548 : };
549 :
550 :
551 : const CCIHuffmanTableEntry CCIUncompTableSave[CCIUncompTableSize]={
552 : { CCIUNCOMP_0White_1Black, 0x0001, 1 },
553 : { CCIUNCOMP_1White_1Black, 0x0001, 2 },
554 : { CCIUNCOMP_2White_1Black, 0x0001, 3 },
555 : { CCIUNCOMP_3White_1Black, 0x0001, 4 },
556 : { CCIUNCOMP_4White_1Black, 0x0001, 5 },
557 : { CCIUNCOMP_5White , 0x0001, 6 },
558 : { CCIUNCOMP_0White_End , 0x0001, 7 },
559 : { CCIUNCOMP_1White_End , 0x0001, 8 },
560 : { CCIUNCOMP_2White_End , 0x0001, 9 },
561 : { CCIUNCOMP_3White_End , 0x0001, 10 },
562 : { CCIUNCOMP_4White_End , 0x0001, 11 }
563 : };
564 :
565 : //=========================================================================
566 :
567 :
568 0 : CCIDecompressor::CCIDecompressor( sal_uLong nOpts, sal_uInt32 nImageWidth ) :
569 : bTableBad ( sal_False ),
570 : bStatus ( sal_False ),
571 : pByteSwap ( NULL ),
572 : nWidth ( nImageWidth ),
573 : nOptions ( nOpts ),
574 0 : pLastLine ( NULL )
575 : {
576 0 : if ( nOpts & CCI_OPTION_INVERSEBITORDER )
577 : {
578 0 : pByteSwap = new sal_uInt8[ 256 ];
579 0 : for ( int i = 0; i < 256; i++ )
580 : {
581 0 : pByteSwap[ i ] = sal::static_int_cast< sal_uInt8 >(
582 : ( i << 7 ) | ( ( i & 2 ) << 5 ) | ( ( i & 4 ) << 3 ) | ( ( i & 8 ) << 1 ) |
583 0 : ( ( i & 16 ) >> 1 ) | ( ( i & 32 ) >> 3 ) | ( ( i & 64 ) >> 5 ) | ( ( i & 128 ) >> 7 ));
584 : }
585 : }
586 :
587 0 : pWhiteLookUp =new CCILookUpTableEntry[1<<13];
588 0 : pBlackLookUp =new CCILookUpTableEntry[1<<13];
589 0 : p2DModeLookUp=new CCILookUpTableEntry[1<<10];
590 0 : pUncompLookUp=new CCILookUpTableEntry[1<<11];
591 :
592 0 : MakeLookUp(CCIWhiteTable,CCIWhiteTableSave,pWhiteLookUp,CCIWhiteTableSize,13);
593 0 : MakeLookUp(CCIBlackTable,CCIBlackTableSave,pBlackLookUp,CCIBlackTableSize,13);
594 0 : MakeLookUp(CCI2DModeTable,CCI2DModeTableSave,p2DModeLookUp,CCI2DModeTableSize,10);
595 0 : MakeLookUp(CCIUncompTable,CCIUncompTableSave,pUncompLookUp,CCIUncompTableSize,11);
596 0 : }
597 :
598 :
599 0 : CCIDecompressor::~CCIDecompressor()
600 : {
601 0 : delete[] pByteSwap;
602 0 : delete[] pLastLine;
603 0 : delete[] pWhiteLookUp;
604 0 : delete[] pBlackLookUp;
605 0 : delete[] p2DModeLookUp;
606 0 : delete[] pUncompLookUp;
607 0 : }
608 :
609 :
610 0 : void CCIDecompressor::StartDecompression( SvStream & rIStream )
611 : {
612 0 : pIStream = &rIStream;
613 0 : nInputBitsBufSize = 0;
614 0 : bFirstEOL = sal_True;
615 0 : bStatus = sal_True;
616 0 : nEOLCount = 0;
617 :
618 0 : if ( bTableBad == sal_True )
619 0 : return;
620 : }
621 :
622 :
623 0 : sal_Bool CCIDecompressor::DecompressScanline( sal_uInt8 * pTarget, sal_uLong nTargetBits )
624 : {
625 : sal_uInt16 i;
626 : sal_uInt8 * pSrc,* pDst;
627 : sal_Bool b2D;
628 :
629 0 : if ( nEOLCount >= 5 ) // RTC (Return To Controller)
630 0 : return sal_True;
631 :
632 0 : if ( bStatus == sal_False )
633 0 : return sal_False;
634 :
635 : // Wenn EOL-Codes vorhanden sind, steht der EOL-Code auch vor der ersten Zeile.
636 : // (und ich dachte EOL heisst 'End Of Line'...)
637 : // Daher lesen wir den EOL-Code immer vor jeder Zeile als erstes ein:
638 0 : if ( nOptions & CCI_OPTION_EOL )
639 : {
640 0 : if ( bFirstEOL )
641 : {
642 0 : sal_uInt32 nCurPos = pIStream->Tell();
643 0 : sal_uInt16 nOldInputBitsBufSize = nInputBitsBufSize;
644 0 : sal_uInt32 nOldInputBitsBuf = nInputBitsBuf;
645 0 : if ( ReadEOL( 32 ) == sal_False )
646 : {
647 0 : nInputBitsBufSize = nOldInputBitsBufSize;
648 0 : nInputBitsBuf = nOldInputBitsBuf;
649 0 : pIStream->Seek( nCurPos );
650 0 : nOptions &=~ CCI_OPTION_EOL; // CCITT Group 3 - Compression Type 2
651 : }
652 0 : bFirstEOL = sal_False;
653 : }
654 : else
655 : {
656 0 : if ( ReadEOL( nTargetBits ) == sal_False )
657 : {
658 0 : return bStatus;
659 : }
660 : }
661 : }
662 :
663 0 : if ( nEOLCount >= 5 ) // RTC (Return To Controller)
664 0 : return sal_True;
665 :
666 : // should the situation arise, generate a white previous line for 2D:
667 0 : if ( nOptions & CCI_OPTION_2D )
668 : {
669 0 : if ( pLastLine == NULL || nLastLineSize != ( ( nTargetBits + 7 ) >> 3 ) )
670 : {
671 0 : if ( pLastLine == NULL )
672 0 : delete[] pLastLine;
673 0 : nLastLineSize = ( nTargetBits + 7 ) >> 3;
674 0 : pLastLine = new sal_uInt8[ nLastLineSize ];
675 0 : pDst = pLastLine;
676 0 : for ( i = 0; i < nLastLineSize; i++ ) *( pDst++ ) = 0x00;
677 : }
678 : }
679 : // ggf. Zeilen-Anfang auf naechste Byte-Grenze runden:
680 0 : if ( nOptions & CCI_OPTION_BYTEALIGNROW )
681 0 : nInputBitsBufSize &= 0xfff8;
682 :
683 : // is it a 2D row?
684 0 : if ( nOptions & CCI_OPTION_2D )
685 : {
686 0 : if ( nOptions & CCI_OPTION_EOL )
687 0 : b2D = Read2DTag();
688 : else
689 0 : b2D = sal_True;
690 : }
691 : else
692 0 : b2D = sal_False;
693 :
694 : // read scanline:
695 0 : if ( b2D )
696 0 : Read2DScanlineData( pTarget, (sal_uInt16)nTargetBits );
697 : else
698 0 : Read1DScanlineData( pTarget, (sal_uInt16)nTargetBits );
699 :
700 : // if we're in 2D mode we have to remember the line:
701 0 : if ( nOptions & CCI_OPTION_2D && bStatus == sal_True )
702 : {
703 0 : pSrc = pTarget;
704 0 : pDst = pLastLine;
705 0 : for ( i = 0; i < nLastLineSize; i++ ) *(pDst++)=*(pSrc++);
706 : }
707 :
708 0 : if ( pIStream->GetError() )
709 0 : bStatus = sal_False;
710 :
711 0 : return bStatus;
712 : }
713 :
714 :
715 0 : void CCIDecompressor::MakeLookUp(const CCIHuffmanTableEntry * pHufTab,
716 : const CCIHuffmanTableEntry * pHufTabSave,
717 : CCILookUpTableEntry * pLookUp,
718 : sal_uInt16 nHuffmanTableSize,
719 : sal_uInt16 nMaxCodeBits)
720 : {
721 0 : sal_uInt16 nLookUpSize = 1 << nMaxCodeBits;
722 0 : memset(pLookUp, 0, nLookUpSize * sizeof(CCILookUpTableEntry));
723 :
724 0 : if (bTableBad==sal_True)
725 0 : return;
726 :
727 0 : sal_uInt16 nMask = 0xffff >> (16-nMaxCodeBits);
728 :
729 0 : for (sal_uInt16 i = 0; i < nHuffmanTableSize; ++i)
730 : {
731 0 : if ( pHufTab[i].nValue!=pHufTabSave[i].nValue ||
732 0 : pHufTab[i].nCode!=pHufTabSave[i].nCode ||
733 0 : pHufTab[i].nCodeBits!=pHufTabSave[i].nCodeBits ||
734 0 : pHufTab[i].nCodeBits==0 ||
735 0 : pHufTab[i].nCodeBits>nMaxCodeBits )
736 : {
737 0 : bTableBad=sal_True;
738 0 : return;
739 : }
740 0 : sal_uInt16 nMinCode = nMask & (pHufTab[i].nCode << (nMaxCodeBits-pHufTab[i].nCodeBits));
741 0 : sal_uInt16 nMaxCode = nMinCode | (nMask >> pHufTab[i].nCodeBits);
742 0 : for (sal_uInt16 j=nMinCode; j<=nMaxCode; ++j)
743 : {
744 0 : if (pLookUp[j].nCodeBits!=0)
745 : {
746 0 : bTableBad=sal_True;
747 0 : return;
748 : }
749 0 : pLookUp[j].nValue=pHufTab[i].nValue;
750 0 : pLookUp[j].nCodeBits=pHufTab[i].nCodeBits;
751 : }
752 : }
753 : }
754 :
755 :
756 0 : sal_Bool CCIDecompressor::ReadEOL( sal_uInt32 /*nMaxFillBits*/ )
757 : {
758 : sal_uInt16 nCode;
759 : sal_uInt8 nByte;
760 :
761 : // if (nOptions&CCI_OPTION_BYTEALIGNEOL) nMaxFillBits=7; else nMaxFillBits=0;
762 : // Buuuh: Entweder wird die Option in itiff.cxx nicht richtig gesetzt (-> Fehler in Doku)
763 : // oder es gibt tatsaechlich gemeine Export-Filter, die immer ein Align machen.
764 : // Ausserdem wurden Dateien gefunden, in denen mehr als die maximal 7 noetigen
765 : // Fuellbits vor dem EOL-Code stehen. Daher akzeptieren wir nun grundsaetzlich
766 : // bis zu 32-nonsense-Bits vor dem EOL-Code:
767 : // und ich habe eine Datei gefunden in der bis zu ??? Bloedsinn Bits stehen, zudem ist dort die Bit Reihenfolge verdreht (SJ);
768 :
769 0 : sal_uInt32 nMaxPos = pIStream->Tell();
770 0 : nMaxPos += nWidth >> 3;
771 :
772 0 : for ( ;; )
773 : {
774 0 : while ( nInputBitsBufSize < 12 )
775 : {
776 0 : *pIStream >> nByte;
777 0 : if ( pIStream->IsEof() )
778 0 : return sal_False;
779 0 : if ( pIStream->Tell() > nMaxPos )
780 0 : return sal_False;
781 :
782 0 : if ( nOptions & CCI_OPTION_INVERSEBITORDER )
783 0 : nByte = pByteSwap[ nByte ];
784 0 : nInputBitsBuf=(nInputBitsBuf<<8) | (sal_uLong)nByte;
785 0 : nInputBitsBufSize += 8;
786 : }
787 0 : nCode = (sal_uInt16)( ( nInputBitsBuf >> ( nInputBitsBufSize - 12 ) ) & 0x0fff );
788 0 : if ( nCode == 0x0001 )
789 : {
790 0 : nEOLCount++;
791 0 : nInputBitsBufSize -= 12;
792 0 : break;
793 : }
794 : else
795 0 : nInputBitsBufSize--;
796 : }
797 0 : return sal_True;
798 : }
799 :
800 :
801 0 : sal_Bool CCIDecompressor::Read2DTag()
802 : {
803 : sal_uInt8 nByte;
804 :
805 : // read abit and return sal_True if it's 0, otherwise return sal_False
806 0 : if (nInputBitsBufSize==0) {
807 0 : *pIStream >> nByte;
808 0 : if ( nOptions & CCI_OPTION_INVERSEBITORDER )
809 0 : nByte = pByteSwap[ nByte ];
810 0 : nInputBitsBuf=(sal_uLong)nByte;
811 0 : nInputBitsBufSize=8;
812 : }
813 0 : nInputBitsBufSize--;
814 0 : if ( ((nInputBitsBuf>>nInputBitsBufSize)&0x0001) ) return sal_False;
815 0 : else return sal_True;
816 : }
817 :
818 :
819 0 : sal_uInt8 CCIDecompressor::ReadBlackOrWhite()
820 : {
821 : sal_uInt8 nByte;
822 :
823 : // read a bit and deliver 0x00 if it's 0, otherwise 0xff
824 0 : if (nInputBitsBufSize==0) {
825 0 : *pIStream >> nByte;
826 0 : if ( nOptions & CCI_OPTION_INVERSEBITORDER )
827 0 : nByte = pByteSwap[ nByte ];
828 0 : nInputBitsBuf=(sal_uLong)nByte;
829 0 : nInputBitsBufSize=8;
830 : }
831 0 : nInputBitsBufSize--;
832 0 : if ( ((nInputBitsBuf>>nInputBitsBufSize)&0x0001) ) return 0xff;
833 0 : else return 0x00;
834 : }
835 :
836 :
837 0 : sal_uInt16 CCIDecompressor::ReadCodeAndDecode(const CCILookUpTableEntry * pLookUp,
838 : sal_uInt16 nMaxCodeBits)
839 : {
840 : // read a Huffman code and decode it:
841 0 : while (nInputBitsBufSize<nMaxCodeBits)
842 : {
843 0 : sal_uInt8 nByte(0);
844 0 : *pIStream >> nByte;
845 0 : if ( nOptions & CCI_OPTION_INVERSEBITORDER )
846 0 : nByte = pByteSwap[ nByte ];
847 0 : nInputBitsBuf=(nInputBitsBuf<<8) | (sal_uLong)nByte;
848 0 : nInputBitsBufSize+=8;
849 : }
850 : sal_uInt16 nCode = (sal_uInt16)((nInputBitsBuf>>(nInputBitsBufSize-nMaxCodeBits))
851 0 : &(0xffff>>(16-nMaxCodeBits)));
852 0 : sal_uInt16 nCodeBits = pLookUp[nCode].nCodeBits;
853 0 : if (nCodeBits==0) bStatus=sal_False;
854 0 : nInputBitsBufSize = nInputBitsBufSize - nCodeBits;
855 0 : return pLookUp[nCode].nValue;
856 : }
857 :
858 :
859 0 : void CCIDecompressor::FillBits(sal_uInt8 * pTarget, sal_uInt16 nTargetBits,
860 : sal_uInt16 nBitPos, sal_uInt16 nNumBits,
861 : sal_uInt8 nBlackOrWhite)
862 : {
863 0 : if ( nBitPos >= nTargetBits )
864 0 : return;
865 0 : if ( nBitPos + nNumBits > nTargetBits )
866 0 : nNumBits = nTargetBits - nBitPos;
867 :
868 0 : pTarget+=nBitPos>>3;
869 0 : nBitPos&=7;
870 :
871 0 : if (nBlackOrWhite==0x00) *pTarget &= 0xff << (8-nBitPos);
872 0 : else *pTarget |= 0xff >> nBitPos;
873 0 : if (nNumBits>8-nBitPos) {
874 0 : nNumBits-=8-nBitPos;
875 0 : while (nNumBits>=8) {
876 0 : *(++pTarget)=nBlackOrWhite;
877 0 : nNumBits-=8;
878 : }
879 0 : if (nNumBits>0) *(++pTarget)=nBlackOrWhite;
880 : }
881 : }
882 :
883 :
884 0 : sal_uInt16 CCIDecompressor::CountBits(const sal_uInt8 * pData, sal_uInt16 nDataSizeBits,
885 : sal_uInt16 nBitPos, sal_uInt8 nBlackOrWhite)
886 : {
887 : sal_uInt16 nPos,nLo;
888 : sal_uInt8 nData;
889 :
890 : // here the number of bits belonging together is being counted
891 : // which all have the color nBlackOrWhite (0xff oder 0x00)
892 : // from the position nBitPos on
893 :
894 0 : nPos=nBitPos;
895 0 : for (;;) {
896 0 : if (nPos>=nDataSizeBits) {
897 0 : nPos=nDataSizeBits;
898 0 : break;
899 : }
900 0 : nData=pData[nPos>>3];
901 0 : nLo=nPos & 7;
902 0 : if ( nLo==0 && nData==nBlackOrWhite) nPos+=8;
903 : else {
904 0 : if ( ((nData^nBlackOrWhite) & (0x80 >> nLo))!=0) break;
905 0 : nPos++;
906 : }
907 : }
908 0 : if (nPos<=nBitPos) return 0;
909 0 : else return nPos-nBitPos;
910 : }
911 :
912 :
913 0 : void CCIDecompressor::Read1DScanlineData(sal_uInt8 * pTarget, sal_uInt16 nTargetBits)
914 : {
915 : sal_uInt16 nCode,nCodeBits,nDataBits,nTgtFreeByteBits;
916 : sal_uInt8 nByte;
917 : sal_uInt8 nBlackOrWhite; // is 0xff for black or 0x00 for white
918 : sal_Bool bTerminatingCode;
919 :
920 : // the first code is always a "white-code":
921 0 : nBlackOrWhite=0x00;
922 :
923 : // number of bits that aren't written in the byte *pTarget yet:
924 0 : nTgtFreeByteBits=8;
925 :
926 : // loop through codes from the input stream:
927 0 : do {
928 :
929 : // die naechsten 13 Bits nach nCode holen, aber noch nicht
930 : // aus dem Eingabe-Buffer loeschen:
931 0 : while (nInputBitsBufSize<13) {
932 0 : *pIStream >> nByte;
933 0 : if ( nOptions & CCI_OPTION_INVERSEBITORDER )
934 0 : nByte = pByteSwap[ nByte ];
935 0 : nInputBitsBuf=(nInputBitsBuf<<8) | (sal_uLong)nByte;
936 0 : nInputBitsBufSize+=8;
937 : }
938 0 : nCode=(sal_uInt16)((nInputBitsBuf>>(nInputBitsBufSize-13))&0x1fff);
939 :
940 : // determine the number of DataBits CodeBits:
941 0 : if (nBlackOrWhite) {
942 0 : nCodeBits=pBlackLookUp[nCode].nCodeBits;
943 0 : nDataBits=pBlackLookUp[nCode].nValue;
944 : }
945 : else {
946 0 : nCodeBits=pWhiteLookUp[nCode].nCodeBits;
947 0 : nDataBits=pWhiteLookUp[nCode].nValue;
948 : }
949 : // is that an invalid code?
950 0 : if ( nDataBits == 9999 )
951 : {
952 : return;
953 : }
954 0 : if ( nCodeBits == 0 )
955 : {
956 : return; // das koennen sich jetzt um FuellBits handeln
957 : }
958 0 : nEOLCount = 0;
959 : // too much data?
960 0 : if (nDataBits>nTargetBits) {
961 : // Ja, koennte ein Folge-Fehler durch ungueltigen Code sein,
962 : // daher irdenwie weitermachen:
963 0 : nDataBits=nTargetBits;
964 : }
965 :
966 : // is that a 'Terminating-Code'?
967 0 : if (nDataBits<64) bTerminatingCode=sal_True; else bTerminatingCode=sal_False;
968 :
969 : // remove the read bits from the input buffer:
970 0 : nInputBitsBufSize = nInputBitsBufSize - nCodeBits;
971 :
972 : // write the number of data bits into the scanline:
973 0 : if (nDataBits>0) {
974 0 : nTargetBits = nTargetBits - nDataBits;
975 0 : if (nBlackOrWhite==0x00) *pTarget &= 0xff << nTgtFreeByteBits;
976 0 : else *pTarget |= 0xff >> (8-nTgtFreeByteBits);
977 0 : if (nDataBits<=nTgtFreeByteBits) {
978 0 : if (nDataBits==nTgtFreeByteBits) {
979 0 : pTarget++;
980 0 : nTgtFreeByteBits=8;
981 : }
982 0 : else nTgtFreeByteBits = nTgtFreeByteBits - nDataBits;
983 : }
984 : else {
985 0 : nDataBits = nDataBits - nTgtFreeByteBits;
986 0 : pTarget++;
987 0 : nTgtFreeByteBits=8;
988 0 : while (nDataBits>=8) {
989 0 : *(pTarget++)=nBlackOrWhite;
990 0 : nDataBits-=8;
991 : }
992 0 : if (nDataBits>0) {
993 0 : *pTarget=nBlackOrWhite;
994 0 : nTgtFreeByteBits = nTgtFreeByteBits - nDataBits;
995 : }
996 : }
997 : }
998 :
999 : // should the situation arise, switch Black <-> White:
1000 0 : if (bTerminatingCode==sal_True) nBlackOrWhite=~nBlackOrWhite;
1001 :
1002 : } while (nTargetBits>0 || bTerminatingCode==sal_False);
1003 : }
1004 :
1005 :
1006 :
1007 0 : void CCIDecompressor::Read2DScanlineData(sal_uInt8 * pTarget, sal_uInt16 nTargetBits)
1008 : {
1009 : sal_uInt16 n2DMode,nBitPos,nUncomp,nRun,nRun2,nt;
1010 : sal_uInt8 nBlackOrWhite;
1011 :
1012 0 : nBlackOrWhite=0x00;
1013 0 : nBitPos=0;
1014 :
1015 0 : while (nBitPos<nTargetBits && bStatus==sal_True) {
1016 :
1017 0 : n2DMode=ReadCodeAndDecode(p2DModeLookUp,10);
1018 0 : if (bStatus==sal_False) return;
1019 :
1020 0 : if (n2DMode==CCI2DMODE_UNCOMP) {
1021 0 : for (;;) {
1022 0 : nUncomp=ReadCodeAndDecode(pUncompLookUp,11);
1023 0 : if ( nUncomp <= CCIUNCOMP_4White_1Black ) {
1024 0 : nRun=nUncomp-CCIUNCOMP_0White_1Black;
1025 0 : FillBits(pTarget,nTargetBits,nBitPos,nRun,0x00);
1026 0 : nBitPos = nBitPos + nRun;
1027 0 : FillBits(pTarget,nTargetBits,nBitPos,1,0xff);
1028 0 : nBitPos++;
1029 : }
1030 0 : else if ( nUncomp == CCIUNCOMP_5White ) {
1031 0 : FillBits(pTarget,nTargetBits,nBitPos,5,0x00);
1032 0 : nBitPos = nBitPos + 5;
1033 : }
1034 : else {
1035 0 : nRun=nUncomp-CCIUNCOMP_0White_End;
1036 0 : FillBits(pTarget,nTargetBits,nBitPos,nRun,0x00);
1037 0 : nBitPos = nBitPos + nRun;
1038 0 : nBlackOrWhite=ReadBlackOrWhite();
1039 0 : break;
1040 : }
1041 : }
1042 : }
1043 :
1044 0 : else if (n2DMode==CCI2DMODE_PASS) {
1045 0 : if (nBitPos==0 && nBlackOrWhite==0x00 && CountBits(pLastLine,nTargetBits,0,0xff)!=0) nRun=0;
1046 : else {
1047 0 : nRun=CountBits(pLastLine,nTargetBits,nBitPos,~nBlackOrWhite);
1048 0 : nRun = nRun + CountBits(pLastLine,nTargetBits,nBitPos+nRun,nBlackOrWhite);
1049 : }
1050 0 : nRun = nRun + CountBits(pLastLine,nTargetBits,nBitPos+nRun,~nBlackOrWhite);
1051 0 : FillBits(pTarget,nTargetBits,nBitPos,nRun,nBlackOrWhite);
1052 0 : nBitPos = nBitPos + nRun;
1053 : }
1054 :
1055 0 : else if (n2DMode==CCI2DMODE_HORZ) {
1056 0 : if (nBlackOrWhite==0x00) {
1057 0 : nRun=0;
1058 0 : do {
1059 0 : nt=ReadCodeAndDecode(pWhiteLookUp,13);
1060 0 : nRun = nRun + nt;
1061 : } while (nt>=64);
1062 0 : nRun2=0;
1063 0 : do {
1064 0 : nt=ReadCodeAndDecode(pBlackLookUp,13);
1065 0 : nRun2 = nRun2 + nt;
1066 : } while (nt>=64);
1067 : }
1068 : else {
1069 0 : nRun=0;
1070 0 : do {
1071 0 : nt=ReadCodeAndDecode(pBlackLookUp,13);
1072 0 : nRun = nRun + nt;
1073 : } while (nt>=64);
1074 0 : nRun2=0;
1075 0 : do {
1076 0 : nt=ReadCodeAndDecode(pWhiteLookUp,13);
1077 0 : nRun2 = nRun2 + nt;
1078 : } while (nt>=64);
1079 : }
1080 0 : FillBits(pTarget,nTargetBits,nBitPos,nRun,nBlackOrWhite);
1081 0 : nBitPos = nBitPos + nRun;
1082 0 : FillBits(pTarget,nTargetBits,nBitPos,nRun2,~nBlackOrWhite);
1083 0 : nBitPos = nBitPos + nRun2;
1084 : }
1085 :
1086 : else { // it's one of the modes CCI2DMODE_VERT_...
1087 0 : if (nBitPos==0 && nBlackOrWhite==0x00 && CountBits(pLastLine,nTargetBits,0,0xff)!=0) nRun=0;
1088 : else {
1089 0 : nRun=CountBits(pLastLine,nTargetBits,nBitPos,~nBlackOrWhite);
1090 0 : nRun = nRun + CountBits(pLastLine,nTargetBits,nBitPos+nRun,nBlackOrWhite);
1091 : }
1092 0 : nRun+=n2DMode-CCI2DMODE_VERT_0;
1093 0 : FillBits(pTarget,nTargetBits,nBitPos,nRun,nBlackOrWhite);
1094 0 : nBitPos = nBitPos + nRun;
1095 0 : nBlackOrWhite=~nBlackOrWhite;
1096 : }
1097 : }
1098 : }
1099 :
1100 :
1101 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|