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