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 : pIStream ( NULL ),
573 : nWidth ( nImageWidth ),
574 : nOptions ( nOpts ),
575 0 : pLastLine ( NULL )
576 : {
577 0 : if ( nOpts & CCI_OPTION_INVERSEBITORDER )
578 : {
579 0 : pByteSwap = new sal_uInt8[ 256 ];
580 0 : for ( int i = 0; i < 256; i++ )
581 : {
582 0 : pByteSwap[ i ] = sal::static_int_cast< sal_uInt8 >(
583 0 : ( i << 7 ) | ( ( i & 2 ) << 5 ) | ( ( i & 4 ) << 3 ) | ( ( i & 8 ) << 1 ) |
584 0 : ( ( i & 16 ) >> 1 ) | ( ( i & 32 ) >> 3 ) | ( ( i & 64 ) >> 5 ) | ( ( i & 128 ) >> 7 ));
585 : }
586 : }
587 :
588 0 : pWhiteLookUp =new CCILookUpTableEntry[1<<13];
589 0 : pBlackLookUp =new CCILookUpTableEntry[1<<13];
590 0 : p2DModeLookUp=new CCILookUpTableEntry[1<<10];
591 0 : pUncompLookUp=new CCILookUpTableEntry[1<<11];
592 :
593 0 : MakeLookUp(CCIWhiteTable,CCIWhiteTableSave,pWhiteLookUp,CCIWhiteTableSize,13);
594 0 : MakeLookUp(CCIBlackTable,CCIBlackTableSave,pBlackLookUp,CCIBlackTableSize,13);
595 0 : MakeLookUp(CCI2DModeTable,CCI2DModeTableSave,p2DModeLookUp,CCI2DModeTableSize,10);
596 0 : MakeLookUp(CCIUncompTable,CCIUncompTableSave,pUncompLookUp,CCIUncompTableSize,11);
597 0 : }
598 :
599 :
600 0 : CCIDecompressor::~CCIDecompressor()
601 : {
602 0 : delete[] pByteSwap;
603 0 : delete[] pLastLine;
604 0 : delete[] pWhiteLookUp;
605 0 : delete[] pBlackLookUp;
606 0 : delete[] p2DModeLookUp;
607 0 : delete[] pUncompLookUp;
608 0 : }
609 :
610 :
611 0 : void CCIDecompressor::StartDecompression( SvStream & rIStream )
612 : {
613 0 : pIStream = &rIStream;
614 0 : nInputBitsBufSize = 0;
615 0 : bFirstEOL = sal_True;
616 0 : bStatus = sal_True;
617 0 : nEOLCount = 0;
618 :
619 0 : if ( bTableBad == sal_True )
620 0 : return;
621 : }
622 :
623 :
624 0 : sal_Bool CCIDecompressor::DecompressScanline( sal_uInt8 * pTarget, sal_uLong nTargetBits, bool bLastLine )
625 : {
626 : sal_uInt16 i;
627 : sal_uInt8 * pDst;
628 : sal_Bool b2D;
629 :
630 0 : if ( nEOLCount >= 5 ) // RTC (Return To Controller)
631 0 : return sal_True;
632 :
633 0 : if ( bStatus == sal_False )
634 0 : return sal_False;
635 :
636 : // If EOL-Codes exist, the EOL-Code also appeared in front of the first line.
637 : // (and I thought it means 'End of Line'...)
638 : // Therefore we read the EOL-Code always at the beginning of each line first:
639 0 : if ( nOptions & CCI_OPTION_EOL )
640 : {
641 0 : if ( bFirstEOL )
642 : {
643 0 : sal_uInt32 nCurPos = pIStream->Tell();
644 0 : sal_uInt16 nOldInputBitsBufSize = nInputBitsBufSize;
645 0 : sal_uInt32 nOldInputBitsBuf = nInputBitsBuf;
646 0 : if ( ReadEOL( 32 ) == sal_False )
647 : {
648 0 : nInputBitsBufSize = nOldInputBitsBufSize;
649 0 : nInputBitsBuf = nOldInputBitsBuf;
650 0 : pIStream->Seek( nCurPos );
651 0 : nOptions &=~ CCI_OPTION_EOL; // CCITT Group 3 - Compression Type 2
652 : }
653 0 : bFirstEOL = sal_False;
654 : }
655 : else
656 : {
657 0 : if ( ReadEOL( nTargetBits ) == sal_False )
658 : {
659 0 : return bStatus;
660 : }
661 : }
662 : }
663 :
664 0 : if ( nEOLCount >= 5 ) // RTC (Return To Controller)
665 0 : return sal_True;
666 :
667 : // should the situation arise, generate a white previous line for 2D:
668 0 : if ( nOptions & CCI_OPTION_2D )
669 : {
670 0 : if ( pLastLine == NULL || nLastLineSize != ( ( nTargetBits + 7 ) >> 3 ) )
671 : {
672 0 : if ( pLastLine == NULL )
673 0 : delete[] pLastLine;
674 0 : nLastLineSize = ( nTargetBits + 7 ) >> 3;
675 0 : pLastLine = new sal_uInt8[ nLastLineSize ];
676 0 : pDst = pLastLine;
677 0 : for ( i = 0; i < nLastLineSize; i++ ) *( pDst++ ) = 0x00;
678 : }
679 : }
680 : // conditionally align start of line to next byte:
681 0 : if ( nOptions & CCI_OPTION_BYTEALIGNROW )
682 0 : nInputBitsBufSize &= 0xfff8;
683 :
684 : // is it a 2D row?
685 0 : if ( nOptions & CCI_OPTION_2D )
686 : {
687 0 : if ( nOptions & CCI_OPTION_EOL )
688 0 : b2D = Read2DTag();
689 : else
690 0 : b2D = sal_True;
691 : }
692 : else
693 0 : b2D = sal_False;
694 :
695 : // read scanline:
696 0 : if ( b2D )
697 0 : Read2DScanlineData( pTarget, (sal_uInt16)nTargetBits );
698 : else
699 0 : Read1DScanlineData( pTarget, (sal_uInt16)nTargetBits );
700 :
701 : // if we're in 2D mode we have to remember the line:
702 0 : if ( nOptions & CCI_OPTION_2D && bStatus == sal_True )
703 : {
704 0 : sal_uInt8 *pSrc = pTarget;
705 0 : pDst = pLastLine;
706 0 : for ( i = 0; i < nLastLineSize; i++ ) *(pDst++)=*(pSrc++);
707 : }
708 :
709 : // #i122984#
710 0 : if( !bStatus && bLastLine )
711 : {
712 0 : bStatus = sal_True;
713 : }
714 :
715 0 : if ( pIStream->GetError() )
716 0 : bStatus = sal_False;
717 :
718 0 : return bStatus;
719 : }
720 :
721 :
722 0 : void CCIDecompressor::MakeLookUp(const CCIHuffmanTableEntry * pHufTab,
723 : const CCIHuffmanTableEntry * pHufTabSave,
724 : CCILookUpTableEntry * pLookUp,
725 : sal_uInt16 nHuffmanTableSize,
726 : sal_uInt16 nMaxCodeBits)
727 : {
728 0 : sal_uInt16 nLookUpSize = 1 << nMaxCodeBits;
729 0 : memset(pLookUp, 0, nLookUpSize * sizeof(CCILookUpTableEntry));
730 :
731 0 : if (bTableBad==sal_True)
732 0 : return;
733 :
734 0 : sal_uInt16 nMask = 0xffff >> (16-nMaxCodeBits);
735 :
736 0 : for (sal_uInt16 i = 0; i < nHuffmanTableSize; ++i)
737 : {
738 0 : if ( pHufTab[i].nValue!=pHufTabSave[i].nValue ||
739 0 : pHufTab[i].nCode!=pHufTabSave[i].nCode ||
740 0 : pHufTab[i].nCodeBits!=pHufTabSave[i].nCodeBits ||
741 0 : pHufTab[i].nCodeBits==0 ||
742 0 : pHufTab[i].nCodeBits>nMaxCodeBits )
743 : {
744 0 : bTableBad=sal_True;
745 0 : return;
746 : }
747 0 : sal_uInt16 nMinCode = nMask & (pHufTab[i].nCode << (nMaxCodeBits-pHufTab[i].nCodeBits));
748 0 : sal_uInt16 nMaxCode = nMinCode | (nMask >> pHufTab[i].nCodeBits);
749 0 : for (sal_uInt16 j=nMinCode; j<=nMaxCode; ++j)
750 : {
751 0 : if (pLookUp[j].nCodeBits!=0)
752 : {
753 0 : bTableBad=sal_True;
754 0 : return;
755 : }
756 0 : pLookUp[j].nValue=pHufTab[i].nValue;
757 0 : pLookUp[j].nCodeBits=pHufTab[i].nCodeBits;
758 : }
759 : }
760 : }
761 :
762 :
763 0 : sal_Bool CCIDecompressor::ReadEOL( sal_uInt32 /*nMaxFillBits*/ )
764 : {
765 : sal_uInt16 nCode;
766 : sal_uInt8 nByte;
767 :
768 : // if (nOptions&CCI_OPTION_BYTEALIGNEOL) nMaxFillBits=7; else nMaxFillBits=0;
769 : // D'oh: Either the option in itiff.cxx is not set correctly (-> error in documentation)
770 : // or there exist some nasty export filter who always do align.
771 : // In addition files were found in which more than the necessary maximum of 7 filling
772 : // bits were found. Therefore we now generally accept up to 32 nonsense bits in front of the EOL-Code:
773 : // And I found a file in which up to ??? nonsense bits are written. Furthemore the byte order is switched in it. (SJ)
774 :
775 0 : sal_uInt32 nMaxPos = pIStream->Tell();
776 0 : nMaxPos += nWidth >> 3;
777 :
778 : for ( ;; )
779 : {
780 0 : while ( nInputBitsBufSize < 12 )
781 : {
782 0 : pIStream->ReadUChar( nByte );
783 0 : if ( pIStream->IsEof() )
784 0 : return sal_False;
785 0 : if ( pIStream->Tell() > nMaxPos )
786 0 : return sal_False;
787 :
788 0 : if ( nOptions & CCI_OPTION_INVERSEBITORDER )
789 0 : nByte = pByteSwap[ nByte ];
790 0 : nInputBitsBuf=(nInputBitsBuf<<8) | (sal_uLong)nByte;
791 0 : nInputBitsBufSize += 8;
792 : }
793 0 : nCode = (sal_uInt16)( ( nInputBitsBuf >> ( nInputBitsBufSize - 12 ) ) & 0x0fff );
794 0 : if ( nCode == 0x0001 )
795 : {
796 0 : nEOLCount++;
797 0 : nInputBitsBufSize -= 12;
798 0 : break;
799 : }
800 : else
801 0 : nInputBitsBufSize--;
802 : }
803 0 : return sal_True;
804 : }
805 :
806 :
807 0 : sal_Bool CCIDecompressor::Read2DTag()
808 : {
809 : sal_uInt8 nByte;
810 :
811 : // read abit and return sal_True if it's 0, otherwise return sal_False
812 0 : if (nInputBitsBufSize==0) {
813 0 : pIStream->ReadUChar( nByte );
814 0 : if ( nOptions & CCI_OPTION_INVERSEBITORDER )
815 0 : nByte = pByteSwap[ nByte ];
816 0 : nInputBitsBuf=(sal_uLong)nByte;
817 0 : nInputBitsBufSize=8;
818 : }
819 0 : nInputBitsBufSize--;
820 0 : if ( ((nInputBitsBuf>>nInputBitsBufSize)&0x0001) ) return sal_False;
821 0 : else return sal_True;
822 : }
823 :
824 :
825 0 : sal_uInt8 CCIDecompressor::ReadBlackOrWhite()
826 : {
827 : sal_uInt8 nByte;
828 :
829 : // read a bit and deliver 0x00 if it's 0, otherwise 0xff
830 0 : if (nInputBitsBufSize==0) {
831 0 : pIStream->ReadUChar( nByte );
832 0 : if ( nOptions & CCI_OPTION_INVERSEBITORDER )
833 0 : nByte = pByteSwap[ nByte ];
834 0 : nInputBitsBuf=(sal_uLong)nByte;
835 0 : nInputBitsBufSize=8;
836 : }
837 0 : nInputBitsBufSize--;
838 0 : if ( ((nInputBitsBuf>>nInputBitsBufSize)&0x0001) ) return 0xff;
839 0 : else return 0x00;
840 : }
841 :
842 :
843 0 : sal_uInt16 CCIDecompressor::ReadCodeAndDecode(const CCILookUpTableEntry * pLookUp,
844 : sal_uInt16 nMaxCodeBits)
845 : {
846 : // read a Huffman code and decode it:
847 0 : while (nInputBitsBufSize<nMaxCodeBits)
848 : {
849 0 : sal_uInt8 nByte(0);
850 0 : pIStream->ReadUChar( nByte );
851 0 : if ( nOptions & CCI_OPTION_INVERSEBITORDER )
852 0 : nByte = pByteSwap[ nByte ];
853 0 : nInputBitsBuf=(nInputBitsBuf<<8) | (sal_uLong)nByte;
854 0 : nInputBitsBufSize+=8;
855 : }
856 0 : sal_uInt16 nCode = (sal_uInt16)((nInputBitsBuf>>(nInputBitsBufSize-nMaxCodeBits))
857 0 : &(0xffff>>(16-nMaxCodeBits)));
858 0 : sal_uInt16 nCodeBits = pLookUp[nCode].nCodeBits;
859 0 : if (nCodeBits==0) bStatus=sal_False;
860 0 : nInputBitsBufSize = nInputBitsBufSize - nCodeBits;
861 0 : return pLookUp[nCode].nValue;
862 : }
863 :
864 :
865 0 : void CCIDecompressor::FillBits(sal_uInt8 * pTarget, sal_uInt16 nTargetBits,
866 : sal_uInt16 nBitPos, sal_uInt16 nNumBits,
867 : sal_uInt8 nBlackOrWhite)
868 : {
869 0 : if ( nBitPos >= nTargetBits )
870 0 : return;
871 0 : if ( nBitPos + nNumBits > nTargetBits )
872 0 : nNumBits = nTargetBits - nBitPos;
873 :
874 0 : pTarget+=nBitPos>>3;
875 0 : nBitPos&=7;
876 :
877 0 : if (nBlackOrWhite==0x00) *pTarget &= 0xff << (8-nBitPos);
878 0 : else *pTarget |= 0xff >> nBitPos;
879 0 : if (nNumBits>8-nBitPos) {
880 0 : nNumBits-=8-nBitPos;
881 0 : while (nNumBits>=8) {
882 0 : *(++pTarget)=nBlackOrWhite;
883 0 : nNumBits-=8;
884 : }
885 0 : if (nNumBits>0) *(++pTarget)=nBlackOrWhite;
886 : }
887 : }
888 :
889 :
890 0 : sal_uInt16 CCIDecompressor::CountBits(const sal_uInt8 * pData, sal_uInt16 nDataSizeBits,
891 : sal_uInt16 nBitPos, sal_uInt8 nBlackOrWhite)
892 : {
893 : sal_uInt16 nPos,nLo;
894 : sal_uInt8 nData;
895 :
896 : // here the number of bits belonging together is being counted
897 : // which all have the color nBlackOrWhite (0xff oder 0x00)
898 : // from the position nBitPos on
899 :
900 0 : nPos=nBitPos;
901 : for (;;) {
902 0 : if (nPos>=nDataSizeBits) {
903 0 : nPos=nDataSizeBits;
904 0 : break;
905 : }
906 0 : nData=pData[nPos>>3];
907 0 : nLo=nPos & 7;
908 0 : if ( nLo==0 && nData==nBlackOrWhite) nPos+=8;
909 : else {
910 0 : if ( ((nData^nBlackOrWhite) & (0x80 >> nLo))!=0) break;
911 0 : nPos++;
912 : }
913 : }
914 0 : if (nPos<=nBitPos) return 0;
915 0 : else return nPos-nBitPos;
916 : }
917 :
918 :
919 0 : void CCIDecompressor::Read1DScanlineData(sal_uInt8 * pTarget, sal_uInt16 nTargetBits)
920 : {
921 : sal_uInt16 nCode,nCodeBits,nDataBits,nTgtFreeByteBits;
922 : sal_uInt8 nByte;
923 : sal_uInt8 nBlackOrWhite; // is 0xff for black or 0x00 for white
924 : sal_Bool bTerminatingCode;
925 :
926 : // the first code is always a "white-code":
927 0 : nBlackOrWhite=0x00;
928 :
929 : // number of bits that aren't written in the byte *pTarget yet:
930 0 : nTgtFreeByteBits=8;
931 :
932 : // loop through codes from the input stream:
933 0 : do {
934 :
935 : // fetch next 13 bits into nCodem but dont remove them from
936 : // the input buffer:
937 0 : while (nInputBitsBufSize<13) {
938 0 : pIStream->ReadUChar( nByte );
939 0 : if ( nOptions & CCI_OPTION_INVERSEBITORDER )
940 0 : nByte = pByteSwap[ nByte ];
941 0 : nInputBitsBuf=(nInputBitsBuf<<8) | (sal_uLong)nByte;
942 0 : nInputBitsBufSize+=8;
943 : }
944 0 : nCode=(sal_uInt16)((nInputBitsBuf>>(nInputBitsBufSize-13))&0x1fff);
945 :
946 : // determine the number of DataBits CodeBits:
947 0 : if (nBlackOrWhite) {
948 0 : nCodeBits=pBlackLookUp[nCode].nCodeBits;
949 0 : nDataBits=pBlackLookUp[nCode].nValue;
950 : }
951 : else {
952 0 : nCodeBits=pWhiteLookUp[nCode].nCodeBits;
953 0 : nDataBits=pWhiteLookUp[nCode].nValue;
954 : }
955 : // is that an invalid code?
956 0 : if ( nDataBits == 9999 )
957 : {
958 0 : return;
959 : }
960 0 : if ( nCodeBits == 0 )
961 : {
962 0 : return; // could be filling bits now
963 : }
964 0 : nEOLCount = 0;
965 : // too much data?
966 0 : if (nDataBits>nTargetBits) {
967 : // Yes, could be a subsequent error cause by an invalid code
968 : // Thefore continue anyhow:
969 0 : nDataBits=nTargetBits;
970 : }
971 :
972 : // is that a 'Terminating-Code'?
973 0 : if (nDataBits<64) bTerminatingCode=sal_True; else bTerminatingCode=sal_False;
974 :
975 : // remove the read bits from the input buffer:
976 0 : nInputBitsBufSize = nInputBitsBufSize - nCodeBits;
977 :
978 : // write the number of data bits into the scanline:
979 0 : if (nDataBits>0) {
980 0 : nTargetBits = nTargetBits - nDataBits;
981 0 : if (nBlackOrWhite==0x00) *pTarget &= 0xff << nTgtFreeByteBits;
982 0 : else *pTarget |= 0xff >> (8-nTgtFreeByteBits);
983 0 : if (nDataBits<=nTgtFreeByteBits) {
984 0 : if (nDataBits==nTgtFreeByteBits) {
985 0 : pTarget++;
986 0 : nTgtFreeByteBits=8;
987 : }
988 0 : else nTgtFreeByteBits = nTgtFreeByteBits - nDataBits;
989 : }
990 : else {
991 0 : nDataBits = nDataBits - nTgtFreeByteBits;
992 0 : pTarget++;
993 0 : nTgtFreeByteBits=8;
994 0 : while (nDataBits>=8) {
995 0 : *(pTarget++)=nBlackOrWhite;
996 0 : nDataBits-=8;
997 : }
998 0 : if (nDataBits>0) {
999 0 : *pTarget=nBlackOrWhite;
1000 0 : nTgtFreeByteBits = nTgtFreeByteBits - nDataBits;
1001 : }
1002 : }
1003 : }
1004 :
1005 : // should the situation arise, switch Black <-> White:
1006 0 : if (bTerminatingCode==sal_True) nBlackOrWhite=~nBlackOrWhite;
1007 :
1008 0 : } while (nTargetBits>0 || bTerminatingCode==sal_False);
1009 : }
1010 :
1011 :
1012 :
1013 0 : void CCIDecompressor::Read2DScanlineData(sal_uInt8 * pTarget, sal_uInt16 nTargetBits)
1014 : {
1015 : sal_uInt16 n2DMode,nBitPos,nUncomp,nRun,nRun2,nt;
1016 : sal_uInt8 nBlackOrWhite;
1017 :
1018 0 : nBlackOrWhite=0x00;
1019 0 : nBitPos=0;
1020 :
1021 0 : while (nBitPos<nTargetBits && bStatus==sal_True) {
1022 :
1023 0 : n2DMode=ReadCodeAndDecode(p2DModeLookUp,10);
1024 0 : if (bStatus==sal_False) return;
1025 :
1026 0 : if (n2DMode==CCI2DMODE_UNCOMP) {
1027 : for (;;) {
1028 0 : nUncomp=ReadCodeAndDecode(pUncompLookUp,11);
1029 0 : if ( nUncomp <= CCIUNCOMP_4White_1Black ) {
1030 0 : nRun=nUncomp-CCIUNCOMP_0White_1Black;
1031 0 : FillBits(pTarget,nTargetBits,nBitPos,nRun,0x00);
1032 0 : nBitPos = nBitPos + nRun;
1033 0 : FillBits(pTarget,nTargetBits,nBitPos,1,0xff);
1034 0 : nBitPos++;
1035 : }
1036 0 : else if ( nUncomp == CCIUNCOMP_5White ) {
1037 0 : FillBits(pTarget,nTargetBits,nBitPos,5,0x00);
1038 0 : nBitPos = nBitPos + 5;
1039 : }
1040 : else {
1041 0 : nRun=nUncomp-CCIUNCOMP_0White_End;
1042 0 : FillBits(pTarget,nTargetBits,nBitPos,nRun,0x00);
1043 0 : nBitPos = nBitPos + nRun;
1044 0 : nBlackOrWhite=ReadBlackOrWhite();
1045 0 : break;
1046 : }
1047 : }
1048 : }
1049 :
1050 0 : else if (n2DMode==CCI2DMODE_PASS) {
1051 0 : if (nBitPos==0 && nBlackOrWhite==0x00 && CountBits(pLastLine,nTargetBits,0,0xff)!=0) nRun=0;
1052 : else {
1053 0 : nRun=CountBits(pLastLine,nTargetBits,nBitPos,~nBlackOrWhite);
1054 0 : nRun = nRun + CountBits(pLastLine,nTargetBits,nBitPos+nRun,nBlackOrWhite);
1055 : }
1056 0 : nRun = nRun + CountBits(pLastLine,nTargetBits,nBitPos+nRun,~nBlackOrWhite);
1057 0 : FillBits(pTarget,nTargetBits,nBitPos,nRun,nBlackOrWhite);
1058 0 : nBitPos = nBitPos + nRun;
1059 : }
1060 :
1061 0 : else if (n2DMode==CCI2DMODE_HORZ) {
1062 0 : if (nBlackOrWhite==0x00) {
1063 0 : nRun=0;
1064 0 : do {
1065 0 : nt=ReadCodeAndDecode(pWhiteLookUp,13);
1066 0 : nRun = nRun + nt;
1067 : } while (nt>=64);
1068 0 : nRun2=0;
1069 0 : do {
1070 0 : nt=ReadCodeAndDecode(pBlackLookUp,13);
1071 0 : nRun2 = nRun2 + nt;
1072 : } while (nt>=64);
1073 : }
1074 : else {
1075 0 : nRun=0;
1076 0 : do {
1077 0 : nt=ReadCodeAndDecode(pBlackLookUp,13);
1078 0 : nRun = nRun + nt;
1079 : } while (nt>=64);
1080 0 : nRun2=0;
1081 0 : do {
1082 0 : nt=ReadCodeAndDecode(pWhiteLookUp,13);
1083 0 : nRun2 = nRun2 + nt;
1084 : } while (nt>=64);
1085 : }
1086 0 : FillBits(pTarget,nTargetBits,nBitPos,nRun,nBlackOrWhite);
1087 0 : nBitPos = nBitPos + nRun;
1088 0 : FillBits(pTarget,nTargetBits,nBitPos,nRun2,~nBlackOrWhite);
1089 0 : nBitPos = nBitPos + nRun2;
1090 : }
1091 :
1092 : else { // it's one of the modes CCI2DMODE_VERT_...
1093 0 : if (nBitPos==0 && nBlackOrWhite==0x00 && CountBits(pLastLine,nTargetBits,0,0xff)!=0) nRun=0;
1094 : else {
1095 0 : nRun=CountBits(pLastLine,nTargetBits,nBitPos,~nBlackOrWhite);
1096 0 : nRun = nRun + CountBits(pLastLine,nTargetBits,nBitPos+nRun,nBlackOrWhite);
1097 : }
1098 0 : nRun+=n2DMode-CCI2DMODE_VERT_0;
1099 0 : FillBits(pTarget,nTargetBits,nBitPos,nRun,nBlackOrWhite);
1100 0 : nBitPos = nBitPos + nRun;
1101 0 : nBlackOrWhite=~nBlackOrWhite;
1102 : }
1103 : }
1104 : }
1105 :
1106 :
1107 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|