Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : :
30 : : #include "ccidecom.hxx"
31 : :
32 : : //=============================== Huffman tables ========================
33 : :
34 : : //---------------------------- White-Run ------------------------------
35 : :
36 : : #define CCIWhiteTableSize 105
37 : :
38 : : const CCIHuffmanTableEntry CCIWhiteTable[CCIWhiteTableSize]={
39 : : { 0, 0x0035, 8 },
40 : : { 1, 0x0007, 6 },
41 : : { 2, 0x0007, 4 },
42 : : { 3, 0x0008, 4 },
43 : : { 4, 0x000b, 4 },
44 : : { 5, 0x000c, 4 },
45 : : { 6, 0x000e, 4 },
46 : : { 7, 0x000f, 4 },
47 : : { 8, 0x0013, 5 },
48 : : { 9, 0x0014, 5 },
49 : : { 10, 0x0007, 5 },
50 : : { 11, 0x0008, 5 },
51 : : { 12, 0x0008, 6 },
52 : : { 13, 0x0003, 6 },
53 : : { 14, 0x0034, 6 },
54 : : { 15, 0x0035, 6 },
55 : : { 16, 0x002a, 6 },
56 : : { 17, 0x002b, 6 },
57 : : { 18, 0x0027, 7 },
58 : : { 19, 0x000c, 7 },
59 : : { 20, 0x0008, 7 },
60 : : { 21, 0x0017, 7 },
61 : : { 22, 0x0003, 7 },
62 : : { 23, 0x0004, 7 },
63 : : { 24, 0x0028, 7 },
64 : : { 25, 0x002b, 7 },
65 : : { 26, 0x0013, 7 },
66 : : { 27, 0x0024, 7 },
67 : : { 28, 0x0018, 7 },
68 : : { 29, 0x0002, 8 },
69 : : { 30, 0x0003, 8 },
70 : : { 31, 0x001a, 8 },
71 : : { 32, 0x001b, 8 },
72 : : { 33, 0x0012, 8 },
73 : : { 34, 0x0013, 8 },
74 : : { 35, 0x0014, 8 },
75 : : { 36, 0x0015, 8 },
76 : : { 37, 0x0016, 8 },
77 : : { 38, 0x0017, 8 },
78 : : { 39, 0x0028, 8 },
79 : : { 40, 0x0029, 8 },
80 : : { 41, 0x002a, 8 },
81 : : { 42, 0x002b, 8 },
82 : : { 43, 0x002c, 8 },
83 : : { 44, 0x002d, 8 },
84 : : { 45, 0x0004, 8 },
85 : : { 46, 0x0005, 8 },
86 : : { 47, 0x000a, 8 },
87 : : { 48, 0x000b, 8 },
88 : : { 49, 0x0052, 8 },
89 : : { 50, 0x0053, 8 },
90 : : { 51, 0x0054, 8 },
91 : : { 52, 0x0055, 8 },
92 : : { 53, 0x0024, 8 },
93 : : { 54, 0x0025, 8 },
94 : : { 55, 0x0058, 8 },
95 : : { 56, 0x0059, 8 },
96 : : { 57, 0x005a, 8 },
97 : : { 58, 0x005b, 8 },
98 : : { 59, 0x004a, 8 },
99 : : { 60, 0x004b, 8 },
100 : : { 61, 0x0032, 8 },
101 : : { 62, 0x0033, 8 },
102 : : { 63, 0x0034, 8 },
103 : : { 64, 0x001b, 5 },
104 : : { 128, 0x0012, 5 },
105 : : { 192, 0x0017, 6 },
106 : : { 256, 0x0037, 7 },
107 : : { 320, 0x0036, 8 },
108 : : { 384, 0x0037, 8 },
109 : : { 448, 0x0064, 8 },
110 : : { 512, 0x0065, 8 },
111 : : { 576, 0x0068, 8 },
112 : : { 640, 0x0067, 8 },
113 : : { 704, 0x00cc, 9 },
114 : : { 768, 0x00cd, 9 },
115 : : { 832, 0x00d2, 9 },
116 : : { 896, 0x00d3, 9 },
117 : : { 960, 0x00d4, 9 },
118 : : { 1024, 0x00d5, 9 },
119 : : { 1088, 0x00d6, 9 },
120 : : { 1152, 0x00d7, 9 },
121 : : { 1216, 0x00d8, 9 },
122 : : { 1280, 0x00d9, 9 },
123 : : { 1344, 0x00da, 9 },
124 : : { 1408, 0x00db, 9 },
125 : : { 1472, 0x0098, 9 },
126 : : { 1536, 0x0099, 9 },
127 : : { 1600, 0x009a, 9 },
128 : : { 1664, 0x0018, 6 },
129 : : { 1728, 0x009b, 9 },
130 : : { 1792, 0x0008, 11 },
131 : : { 1856, 0x000c, 11 },
132 : : { 1920, 0x000d, 11 },
133 : : { 1984, 0x0012, 12 },
134 : : { 2048, 0x0013, 12 },
135 : : { 2112, 0x0014, 12 },
136 : : { 2176, 0x0015, 12 },
137 : : { 2240, 0x0016, 12 },
138 : : { 2304, 0x0017, 12 },
139 : : { 2368, 0x001c, 12 },
140 : : { 2432, 0x001d, 12 },
141 : : { 2496, 0x001e, 12 },
142 : : { 2560, 0x001f, 12 },
143 : : { 9999, 0x0001, 12 } // EOL
144 : : };
145 : :
146 : : //---------------------------- Black-Run ------------------------------
147 : :
148 : : #define CCIBlackTableSize 105
149 : :
150 : : const CCIHuffmanTableEntry CCIBlackTable[CCIBlackTableSize]={
151 : : { 0, 0x0037, 10 },
152 : : { 1, 0x0002, 3 },
153 : : { 2, 0x0003, 2 },
154 : : { 3, 0x0002, 2 },
155 : : { 4, 0x0003, 3 },
156 : : { 5, 0x0003, 4 },
157 : : { 6, 0x0002, 4 },
158 : : { 7, 0x0003, 5 },
159 : : { 8, 0x0005, 6 },
160 : : { 9, 0x0004, 6 },
161 : : { 10, 0x0004, 7 },
162 : : { 11, 0x0005, 7 },
163 : : { 12, 0x0007, 7 },
164 : : { 13, 0x0004, 8 },
165 : : { 14, 0x0007, 8 },
166 : : { 15, 0x0018, 9 },
167 : : { 16, 0x0017, 10 },
168 : : { 17, 0x0018, 10 },
169 : : { 18, 0x0008, 10 },
170 : : { 19, 0x0067, 11 },
171 : : { 20, 0x0068, 11 },
172 : : { 21, 0x006c, 11 },
173 : : { 22, 0x0037, 11 },
174 : : { 23, 0x0028, 11 },
175 : : { 24, 0x0017, 11 },
176 : : { 25, 0x0018, 11 },
177 : : { 26, 0x00ca, 12 },
178 : : { 27, 0x00cb, 12 },
179 : : { 28, 0x00cc, 12 },
180 : : { 29, 0x00cd, 12 },
181 : : { 30, 0x0068, 12 },
182 : : { 31, 0x0069, 12 },
183 : : { 32, 0x006a, 12 },
184 : : { 33, 0x006b, 12 },
185 : : { 34, 0x00d2, 12 },
186 : : { 35, 0x00d3, 12 },
187 : : { 36, 0x00d4, 12 },
188 : : { 37, 0x00d5, 12 },
189 : : { 38, 0x00d6, 12 },
190 : : { 39, 0x00d7, 12 },
191 : : { 40, 0x006c, 12 },
192 : : { 41, 0x006d, 12 },
193 : : { 42, 0x00da, 12 },
194 : : { 43, 0x00db, 12 },
195 : : { 44, 0x0054, 12 },
196 : : { 45, 0x0055, 12 },
197 : : { 46, 0x0056, 12 },
198 : : { 47, 0x0057, 12 },
199 : : { 48, 0x0064, 12 },
200 : : { 49, 0x0065, 12 },
201 : : { 50, 0x0052, 12 },
202 : : { 51, 0x0053, 12 },
203 : : { 52, 0x0024, 12 },
204 : : { 53, 0x0037, 12 },
205 : : { 54, 0x0038, 12 },
206 : : { 55, 0x0027, 12 },
207 : : { 56, 0x0028, 12 },
208 : : { 57, 0x0058, 12 },
209 : : { 58, 0x0059, 12 },
210 : : { 59, 0x002b, 12 },
211 : : { 60, 0x002c, 12 },
212 : : { 61, 0x005a, 12 },
213 : : { 62, 0x0066, 12 },
214 : : { 63, 0x0067, 12 },
215 : : { 64, 0x000f, 10 },
216 : : { 128, 0x00c8, 12 },
217 : : { 192, 0x00c9, 12 },
218 : : { 256, 0x005b, 12 },
219 : : { 320, 0x0033, 12 },
220 : : { 384, 0x0034, 12 },
221 : : { 448, 0x0035, 12 },
222 : : { 512, 0x006c, 13 },
223 : : { 576, 0x006d, 13 },
224 : : { 640, 0x004a, 13 },
225 : : { 704, 0x004b, 13 },
226 : : { 768, 0x004c, 13 },
227 : : { 832, 0x004d, 13 },
228 : : { 896, 0x0072, 13 },
229 : : { 960, 0x0073, 13 },
230 : : { 1024, 0x0074, 13 },
231 : : { 1088, 0x0075, 13 },
232 : : { 1152, 0x0076, 13 },
233 : : { 1216, 0x0077, 13 },
234 : : { 1280, 0x0052, 13 },
235 : : { 1344, 0x0053, 13 },
236 : : { 1408, 0x0054, 13 },
237 : : { 1472, 0x0055, 13 },
238 : : { 1536, 0x005a, 13 },
239 : : { 1600, 0x005b, 13 },
240 : : { 1664, 0x0064, 13 },
241 : : { 1728, 0x0065, 13 },
242 : : { 1792, 0x0008, 11 },
243 : : { 1856, 0x000c, 11 },
244 : : { 1920, 0x000d, 11 },
245 : : { 1984, 0x0012, 12 },
246 : : { 2048, 0x0013, 12 },
247 : : { 2112, 0x0014, 12 },
248 : : { 2176, 0x0015, 12 },
249 : : { 2240, 0x0016, 12 },
250 : : { 2304, 0x0017, 12 },
251 : : { 2368, 0x001c, 12 },
252 : : { 2432, 0x001d, 12 },
253 : : { 2496, 0x001e, 12 },
254 : : { 2560, 0x001f, 12 },
255 : : { 9999, 0x0001, 12 } // EOL
256 : : };
257 : :
258 : :
259 : : //---------------------------- 2D-Mode --------------------------------
260 : :
261 : : #define CCI2DMODE_UNCOMP 0
262 : : #define CCI2DMODE_PASS 1
263 : : #define CCI2DMODE_HORZ 2
264 : : #define CCI2DMODE_VERT_L3 3
265 : : #define CCI2DMODE_VERT_L2 4
266 : : #define CCI2DMODE_VERT_L1 5
267 : : #define CCI2DMODE_VERT_0 6
268 : : #define CCI2DMODE_VERT_R1 7
269 : : #define CCI2DMODE_VERT_R2 8
270 : : #define CCI2DMODE_VERT_R3 9
271 : :
272 : : #define CCI2DModeTableSize 10
273 : :
274 : : const CCIHuffmanTableEntry CCI2DModeTable[CCI2DModeTableSize]={
275 : : { CCI2DMODE_UNCOMP , 0x000f, 10 },
276 : : { CCI2DMODE_PASS , 0x0001, 4 },
277 : : { CCI2DMODE_HORZ , 0x0001, 3 },
278 : : { CCI2DMODE_VERT_L3, 0x0002, 7 },
279 : : { CCI2DMODE_VERT_L2, 0x0002, 6 },
280 : : { CCI2DMODE_VERT_L1, 0x0002, 3 },
281 : : { CCI2DMODE_VERT_0 , 0x0001, 1 },
282 : : { CCI2DMODE_VERT_R1, 0x0003, 3 },
283 : : { CCI2DMODE_VERT_R2, 0x0003, 6 },
284 : : { CCI2DMODE_VERT_R3, 0x0003, 7 }
285 : : };
286 : :
287 : :
288 : : //-------------------------- 2D-Uncompressed-Mode ----------------------
289 : :
290 : : #define CCIUNCOMP_0White_1Black 0
291 : : #define CCIUNCOMP_1White_1Black 1
292 : : #define CCIUNCOMP_2White_1Black 2
293 : : #define CCIUNCOMP_3White_1Black 3
294 : : #define CCIUNCOMP_4White_1Black 4
295 : : #define CCIUNCOMP_5White 5
296 : : #define CCIUNCOMP_0White_End 6
297 : : #define CCIUNCOMP_1White_End 7
298 : : #define CCIUNCOMP_2White_End 8
299 : : #define CCIUNCOMP_3White_End 9
300 : : #define CCIUNCOMP_4White_End 10
301 : :
302 : : #define CCIUncompTableSize 11
303 : :
304 : : const CCIHuffmanTableEntry CCIUncompTable[CCIUncompTableSize]={
305 : : { CCIUNCOMP_0White_1Black, 0x0001, 1 },
306 : : { CCIUNCOMP_1White_1Black, 0x0001, 2 },
307 : : { CCIUNCOMP_2White_1Black, 0x0001, 3 },
308 : : { CCIUNCOMP_3White_1Black, 0x0001, 4 },
309 : : { CCIUNCOMP_4White_1Black, 0x0001, 5 },
310 : : { CCIUNCOMP_5White , 0x0001, 6 },
311 : : { CCIUNCOMP_0White_End , 0x0001, 7 },
312 : : { CCIUNCOMP_1White_End , 0x0001, 8 },
313 : : { CCIUNCOMP_2White_End , 0x0001, 9 },
314 : : { CCIUNCOMP_3White_End , 0x0001, 10 },
315 : : { CCIUNCOMP_4White_End , 0x0001, 11 }
316 : : };
317 : :
318 : :
319 : : //================== backup of the Huffman tables ============================
320 : : // To make sure that the Huffman tables do not contain errors they were entered
321 : : // from two different sources (Phew) and compared.
322 : : // Since an error could creep in to the source code while maintaining it
323 : : // (e.g. an accidentaly key press in the editor) the tables are listed twice
324 : : // and are compared during runtime. (If the comparison fails CCIDcompressor
325 : : // throws an error) The whole thing may appear insane, but an error within the
326 : : // tables would otherwise be really hard to discover and it's very unlikely that
327 : : // one or more sample files run through all codes.
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 : :
577 : 0 : 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 : 0 : pLastLine ( NULL )
584 : : {
585 [ # # ]: 0 : if ( nOpts & CCI_OPTION_INVERSEBITORDER )
586 : : {
587 : 0 : pByteSwap = new sal_uInt8[ 256 ];
588 [ # # ]: 0 : for ( int i = 0; i < 256; i++ )
589 : : {
590 : 0 : pByteSwap[ i ] = sal::static_int_cast< sal_uInt8 >(
591 : : ( i << 7 ) | ( ( i & 2 ) << 5 ) | ( ( i & 4 ) << 3 ) | ( ( i & 8 ) << 1 ) |
592 : 0 : ( ( i & 16 ) >> 1 ) | ( ( i & 32 ) >> 3 ) | ( ( i & 64 ) >> 5 ) | ( ( i & 128 ) >> 7 ));
593 : : }
594 : : }
595 : :
596 : 0 : pWhiteLookUp =new CCILookUpTableEntry[1<<13];
597 : 0 : pBlackLookUp =new CCILookUpTableEntry[1<<13];
598 : 0 : p2DModeLookUp=new CCILookUpTableEntry[1<<10];
599 : 0 : pUncompLookUp=new CCILookUpTableEntry[1<<11];
600 : :
601 : 0 : MakeLookUp(CCIWhiteTable,CCIWhiteTableSave,pWhiteLookUp,CCIWhiteTableSize,13);
602 : 0 : MakeLookUp(CCIBlackTable,CCIBlackTableSave,pBlackLookUp,CCIBlackTableSize,13);
603 : 0 : MakeLookUp(CCI2DModeTable,CCI2DModeTableSave,p2DModeLookUp,CCI2DModeTableSize,10);
604 : 0 : MakeLookUp(CCIUncompTable,CCIUncompTableSave,pUncompLookUp,CCIUncompTableSize,11);
605 : 0 : }
606 : :
607 : :
608 : 0 : CCIDecompressor::~CCIDecompressor()
609 : : {
610 [ # # ]: 0 : delete[] pByteSwap;
611 [ # # ]: 0 : delete[] pLastLine;
612 [ # # ]: 0 : delete[] pWhiteLookUp;
613 [ # # ]: 0 : delete[] pBlackLookUp;
614 [ # # ]: 0 : delete[] p2DModeLookUp;
615 [ # # ]: 0 : delete[] pUncompLookUp;
616 : 0 : }
617 : :
618 : :
619 : 0 : void CCIDecompressor::StartDecompression( SvStream & rIStream )
620 : : {
621 : 0 : pIStream = &rIStream;
622 : 0 : nInputBitsBufSize = 0;
623 : 0 : bFirstEOL = sal_True;
624 : 0 : bStatus = sal_True;
625 : 0 : nEOLCount = 0;
626 : :
627 [ # # ]: 0 : if ( bTableBad == sal_True )
628 : 0 : return;
629 : : }
630 : :
631 : :
632 : 0 : sal_Bool CCIDecompressor::DecompressScanline( sal_uInt8 * pTarget, sal_uLong nTargetBits )
633 : : {
634 : : sal_uInt16 i;
635 : : sal_uInt8 * pSrc,* pDst;
636 : : sal_Bool b2D;
637 : :
638 [ # # ]: 0 : if ( nEOLCount >= 5 ) // RTC (Return To Controller)
639 : 0 : return sal_True;
640 : :
641 [ # # ]: 0 : if ( bStatus == sal_False )
642 : 0 : 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 [ # # ]: 0 : if ( nOptions & CCI_OPTION_EOL )
648 : : {
649 [ # # ]: 0 : if ( bFirstEOL )
650 : : {
651 : 0 : sal_uInt32 nCurPos = pIStream->Tell();
652 : 0 : sal_uInt16 nOldInputBitsBufSize = nInputBitsBufSize;
653 : 0 : sal_uInt32 nOldInputBitsBuf = nInputBitsBuf;
654 [ # # ]: 0 : if ( ReadEOL( 32 ) == sal_False )
655 : : {
656 : 0 : nInputBitsBufSize = nOldInputBitsBufSize;
657 : 0 : nInputBitsBuf = nOldInputBitsBuf;
658 : 0 : pIStream->Seek( nCurPos );
659 : 0 : nOptions &=~ CCI_OPTION_EOL; // CCITT Group 3 - Compression Type 2
660 : : }
661 : 0 : bFirstEOL = sal_False;
662 : : }
663 : : else
664 : : {
665 [ # # ]: 0 : if ( ReadEOL( nTargetBits ) == sal_False )
666 : : {
667 : 0 : return bStatus;
668 : : }
669 : : }
670 : : }
671 : :
672 [ # # ]: 0 : if ( nEOLCount >= 5 ) // RTC (Return To Controller)
673 : 0 : return sal_True;
674 : :
675 : : // should the situation arise, generate a white previous line for 2D:
676 [ # # ]: 0 : if ( nOptions & CCI_OPTION_2D )
677 : : {
678 [ # # ][ # # ]: 0 : if ( pLastLine == NULL || nLastLineSize != ( ( nTargetBits + 7 ) >> 3 ) )
679 : : {
680 [ # # ]: 0 : if ( pLastLine == NULL )
681 [ # # ]: 0 : delete[] pLastLine;
682 : 0 : nLastLineSize = ( nTargetBits + 7 ) >> 3;
683 : 0 : pLastLine = new sal_uInt8[ nLastLineSize ];
684 : 0 : pDst = pLastLine;
685 [ # # ]: 0 : for ( i = 0; i < nLastLineSize; i++ ) *( pDst++ ) = 0x00;
686 : : }
687 : : }
688 : : // ggf. Zeilen-Anfang auf naechste Byte-Grenze runden:
689 [ # # ]: 0 : if ( nOptions & CCI_OPTION_BYTEALIGNROW )
690 : 0 : nInputBitsBufSize &= 0xfff8;
691 : :
692 : : // is it a 2D row?
693 [ # # ]: 0 : if ( nOptions & CCI_OPTION_2D )
694 : : {
695 [ # # ]: 0 : if ( nOptions & CCI_OPTION_EOL )
696 : 0 : b2D = Read2DTag();
697 : : else
698 : 0 : b2D = sal_True;
699 : : }
700 : : else
701 : 0 : b2D = sal_False;
702 : :
703 : : // read scanline:
704 [ # # ]: 0 : if ( b2D )
705 : 0 : Read2DScanlineData( pTarget, (sal_uInt16)nTargetBits );
706 : : else
707 : 0 : Read1DScanlineData( pTarget, (sal_uInt16)nTargetBits );
708 : :
709 : : // if we're in 2D mode we have to remember the line:
710 [ # # ][ # # ]: 0 : if ( nOptions & CCI_OPTION_2D && bStatus == sal_True )
711 : : {
712 : 0 : pSrc = pTarget;
713 : 0 : pDst = pLastLine;
714 [ # # ]: 0 : for ( i = 0; i < nLastLineSize; i++ ) *(pDst++)=*(pSrc++);
715 : : }
716 : :
717 [ # # ]: 0 : if ( pIStream->GetError() )
718 : 0 : bStatus = sal_False;
719 : :
720 : 0 : return bStatus;
721 : : }
722 : :
723 : :
724 : 0 : void CCIDecompressor::MakeLookUp(const CCIHuffmanTableEntry * pHufTab,
725 : : const CCIHuffmanTableEntry * pHufTabSave,
726 : : CCILookUpTableEntry * pLookUp,
727 : : sal_uInt16 nHuffmanTableSize,
728 : : sal_uInt16 nMaxCodeBits)
729 : : {
730 : 0 : sal_uInt16 nLookUpSize = 1 << nMaxCodeBits;
731 : 0 : memset(pLookUp, 0, nLookUpSize * sizeof(CCILookUpTableEntry));
732 : :
733 [ # # ]: 0 : if (bTableBad==sal_True)
734 : 0 : return;
735 : :
736 : 0 : sal_uInt16 nMask = 0xffff >> (16-nMaxCodeBits);
737 : :
738 [ # # ]: 0 : for (sal_uInt16 i = 0; i < nHuffmanTableSize; ++i)
739 : : {
740 [ # # ][ # # ]: 0 : if ( pHufTab[i].nValue!=pHufTabSave[i].nValue ||
[ # # ][ # # ]
[ # # ]
741 : 0 : pHufTab[i].nCode!=pHufTabSave[i].nCode ||
742 : 0 : pHufTab[i].nCodeBits!=pHufTabSave[i].nCodeBits ||
743 : 0 : pHufTab[i].nCodeBits==0 ||
744 : 0 : pHufTab[i].nCodeBits>nMaxCodeBits )
745 : : {
746 : 0 : bTableBad=sal_True;
747 : 0 : return;
748 : : }
749 : 0 : sal_uInt16 nMinCode = nMask & (pHufTab[i].nCode << (nMaxCodeBits-pHufTab[i].nCodeBits));
750 : 0 : sal_uInt16 nMaxCode = nMinCode | (nMask >> pHufTab[i].nCodeBits);
751 [ # # ]: 0 : for (sal_uInt16 j=nMinCode; j<=nMaxCode; ++j)
752 : : {
753 [ # # ]: 0 : if (pLookUp[j].nCodeBits!=0)
754 : : {
755 : 0 : bTableBad=sal_True;
756 : 0 : return;
757 : : }
758 : 0 : pLookUp[j].nValue=pHufTab[i].nValue;
759 : 0 : pLookUp[j].nCodeBits=pHufTab[i].nCodeBits;
760 : : }
761 : : }
762 : : }
763 : :
764 : :
765 : 0 : sal_Bool CCIDecompressor::ReadEOL( sal_uInt32 /*nMaxFillBits*/ )
766 : : {
767 : : sal_uInt16 nCode;
768 : : sal_uInt8 nByte;
769 : :
770 : : // if (nOptions&CCI_OPTION_BYTEALIGNEOL) nMaxFillBits=7; else nMaxFillBits=0;
771 : : // Buuuh: Entweder wird die Option in itiff.cxx nicht richtig gesetzt (-> Fehler in Doku)
772 : : // oder es gibt tatsaechlich gemeine Export-Filter, die immer ein Align machen.
773 : : // Ausserdem wurden Dateien gefunden, in denen mehr als die maximal 7 noetigen
774 : : // Fuellbits vor dem EOL-Code stehen. Daher akzeptieren wir nun grundsaetzlich
775 : : // bis zu 32-nonsense-Bits vor dem EOL-Code:
776 : : // und ich habe eine Datei gefunden in der bis zu ??? Bloedsinn Bits stehen, zudem ist dort die Bit Reihenfolge verdreht (SJ);
777 : :
778 : 0 : sal_uInt32 nMaxPos = pIStream->Tell();
779 : 0 : nMaxPos += nWidth >> 3;
780 : :
781 : 0 : for ( ;; )
782 : : {
783 [ # # ]: 0 : while ( nInputBitsBufSize < 12 )
784 : : {
785 [ # # ]: 0 : *pIStream >> nByte;
786 [ # # ]: 0 : if ( pIStream->IsEof() )
787 : 0 : return sal_False;
788 [ # # ]: 0 : if ( pIStream->Tell() > nMaxPos )
789 : 0 : return sal_False;
790 : :
791 [ # # ]: 0 : if ( nOptions & CCI_OPTION_INVERSEBITORDER )
792 : 0 : nByte = pByteSwap[ nByte ];
793 : 0 : nInputBitsBuf=(nInputBitsBuf<<8) | (sal_uLong)nByte;
794 : 0 : nInputBitsBufSize += 8;
795 : : }
796 : 0 : nCode = (sal_uInt16)( ( nInputBitsBuf >> ( nInputBitsBufSize - 12 ) ) & 0x0fff );
797 [ # # ]: 0 : if ( nCode == 0x0001 )
798 : : {
799 : 0 : nEOLCount++;
800 : 0 : nInputBitsBufSize -= 12;
801 : 0 : break;
802 : : }
803 : : else
804 : 0 : nInputBitsBufSize--;
805 : : }
806 : 0 : return sal_True;
807 : : }
808 : :
809 : :
810 : 0 : sal_Bool CCIDecompressor::Read2DTag()
811 : : {
812 : : sal_uInt8 nByte;
813 : :
814 : : // read abit and return sal_True if it's 0, otherwise return sal_False
815 [ # # ]: 0 : if (nInputBitsBufSize==0) {
816 [ # # ]: 0 : *pIStream >> nByte;
817 [ # # ]: 0 : if ( nOptions & CCI_OPTION_INVERSEBITORDER )
818 : 0 : nByte = pByteSwap[ nByte ];
819 : 0 : nInputBitsBuf=(sal_uLong)nByte;
820 : 0 : nInputBitsBufSize=8;
821 : : }
822 : 0 : nInputBitsBufSize--;
823 [ # # ]: 0 : if ( ((nInputBitsBuf>>nInputBitsBufSize)&0x0001) ) return sal_False;
824 : 0 : else return sal_True;
825 : : }
826 : :
827 : :
828 : 0 : sal_uInt8 CCIDecompressor::ReadBlackOrWhite()
829 : : {
830 : : sal_uInt8 nByte;
831 : :
832 : : // read a bit and deliver 0x00 if it's 0, otherwise 0xff
833 [ # # ]: 0 : if (nInputBitsBufSize==0) {
834 [ # # ]: 0 : *pIStream >> nByte;
835 [ # # ]: 0 : if ( nOptions & CCI_OPTION_INVERSEBITORDER )
836 : 0 : nByte = pByteSwap[ nByte ];
837 : 0 : nInputBitsBuf=(sal_uLong)nByte;
838 : 0 : nInputBitsBufSize=8;
839 : : }
840 : 0 : nInputBitsBufSize--;
841 [ # # ]: 0 : if ( ((nInputBitsBuf>>nInputBitsBufSize)&0x0001) ) return 0xff;
842 : 0 : else return 0x00;
843 : : }
844 : :
845 : :
846 : 0 : sal_uInt16 CCIDecompressor::ReadCodeAndDecode(const CCILookUpTableEntry * pLookUp,
847 : : sal_uInt16 nMaxCodeBits)
848 : : {
849 : : // read a Huffman code and decode it:
850 [ # # ]: 0 : while (nInputBitsBufSize<nMaxCodeBits)
851 : : {
852 : 0 : sal_uInt8 nByte(0);
853 [ # # ]: 0 : *pIStream >> nByte;
854 [ # # ]: 0 : if ( nOptions & CCI_OPTION_INVERSEBITORDER )
855 : 0 : nByte = pByteSwap[ nByte ];
856 : 0 : nInputBitsBuf=(nInputBitsBuf<<8) | (sal_uLong)nByte;
857 : 0 : nInputBitsBufSize+=8;
858 : : }
859 : : sal_uInt16 nCode = (sal_uInt16)((nInputBitsBuf>>(nInputBitsBufSize-nMaxCodeBits))
860 : 0 : &(0xffff>>(16-nMaxCodeBits)));
861 : 0 : sal_uInt16 nCodeBits = pLookUp[nCode].nCodeBits;
862 [ # # ]: 0 : if (nCodeBits==0) bStatus=sal_False;
863 : 0 : nInputBitsBufSize = nInputBitsBufSize - nCodeBits;
864 : 0 : return pLookUp[nCode].nValue;
865 : : }
866 : :
867 : :
868 : 0 : void CCIDecompressor::FillBits(sal_uInt8 * pTarget, sal_uInt16 nTargetBits,
869 : : sal_uInt16 nBitPos, sal_uInt16 nNumBits,
870 : : sal_uInt8 nBlackOrWhite)
871 : : {
872 [ # # ]: 0 : if ( nBitPos >= nTargetBits )
873 : 0 : return;
874 [ # # ]: 0 : if ( nBitPos + nNumBits > nTargetBits )
875 : 0 : nNumBits = nTargetBits - nBitPos;
876 : :
877 : 0 : pTarget+=nBitPos>>3;
878 : 0 : nBitPos&=7;
879 : :
880 [ # # ]: 0 : if (nBlackOrWhite==0x00) *pTarget &= 0xff << (8-nBitPos);
881 : 0 : else *pTarget |= 0xff >> nBitPos;
882 [ # # ]: 0 : if (nNumBits>8-nBitPos) {
883 : 0 : nNumBits-=8-nBitPos;
884 [ # # ]: 0 : while (nNumBits>=8) {
885 : 0 : *(++pTarget)=nBlackOrWhite;
886 : 0 : nNumBits-=8;
887 : : }
888 [ # # ]: 0 : if (nNumBits>0) *(++pTarget)=nBlackOrWhite;
889 : : }
890 : : }
891 : :
892 : :
893 : 0 : sal_uInt16 CCIDecompressor::CountBits(const sal_uInt8 * pData, sal_uInt16 nDataSizeBits,
894 : : sal_uInt16 nBitPos, sal_uInt8 nBlackOrWhite)
895 : : {
896 : : sal_uInt16 nPos,nLo;
897 : : sal_uInt8 nData;
898 : :
899 : : // here the number of bits belonging together is being counted
900 : : // which all have the color nBlackOrWhite (0xff oder 0x00)
901 : : // from the position nBitPos on
902 : :
903 : 0 : nPos=nBitPos;
904 : 0 : for (;;) {
905 [ # # ]: 0 : if (nPos>=nDataSizeBits) {
906 : 0 : nPos=nDataSizeBits;
907 : 0 : break;
908 : : }
909 : 0 : nData=pData[nPos>>3];
910 : 0 : nLo=nPos & 7;
911 [ # # ][ # # ]: 0 : if ( nLo==0 && nData==nBlackOrWhite) nPos+=8;
912 : : else {
913 [ # # ]: 0 : if ( ((nData^nBlackOrWhite) & (0x80 >> nLo))!=0) break;
914 : 0 : nPos++;
915 : : }
916 : : }
917 [ # # ]: 0 : if (nPos<=nBitPos) return 0;
918 : 0 : else return nPos-nBitPos;
919 : : }
920 : :
921 : :
922 : 0 : void CCIDecompressor::Read1DScanlineData(sal_uInt8 * pTarget, sal_uInt16 nTargetBits)
923 : : {
924 : : sal_uInt16 nCode,nCodeBits,nDataBits,nTgtFreeByteBits;
925 : : sal_uInt8 nByte;
926 : : sal_uInt8 nBlackOrWhite; // is 0xff for black or 0x00 for white
927 : : sal_Bool bTerminatingCode;
928 : :
929 : : // the first code is always a "white-code":
930 : 0 : nBlackOrWhite=0x00;
931 : :
932 : : // number of bits that aren't written in the byte *pTarget yet:
933 : 0 : nTgtFreeByteBits=8;
934 : :
935 : : // loop through codes from the input stream:
936 [ # # ][ # # ]: 0 : do {
[ # # ]
937 : :
938 : : // die naechsten 13 Bits nach nCode holen, aber noch nicht
939 : : // aus dem Eingabe-Buffer loeschen:
940 [ # # ]: 0 : while (nInputBitsBufSize<13) {
941 [ # # ]: 0 : *pIStream >> nByte;
942 [ # # ]: 0 : if ( nOptions & CCI_OPTION_INVERSEBITORDER )
943 : 0 : nByte = pByteSwap[ nByte ];
944 : 0 : nInputBitsBuf=(nInputBitsBuf<<8) | (sal_uLong)nByte;
945 : 0 : nInputBitsBufSize+=8;
946 : : }
947 : 0 : nCode=(sal_uInt16)((nInputBitsBuf>>(nInputBitsBufSize-13))&0x1fff);
948 : :
949 : : // determine the number of DataBits CodeBits:
950 [ # # ]: 0 : if (nBlackOrWhite) {
951 : 0 : nCodeBits=pBlackLookUp[nCode].nCodeBits;
952 : 0 : nDataBits=pBlackLookUp[nCode].nValue;
953 : : }
954 : : else {
955 : 0 : nCodeBits=pWhiteLookUp[nCode].nCodeBits;
956 : 0 : nDataBits=pWhiteLookUp[nCode].nValue;
957 : : }
958 : : // is that an invalid code?
959 [ # # ]: 0 : if ( nDataBits == 9999 )
960 : : {
961 : : return;
962 : : }
963 [ # # ]: 0 : if ( nCodeBits == 0 )
964 : : {
965 : : return; // das koennen sich jetzt um FuellBits handeln
966 : : }
967 : 0 : nEOLCount = 0;
968 : : // too much data?
969 [ # # ]: 0 : if (nDataBits>nTargetBits) {
970 : : // Ja, koennte ein Folge-Fehler durch ungueltigen Code sein,
971 : : // daher irdenwie weitermachen:
972 : 0 : nDataBits=nTargetBits;
973 : : }
974 : :
975 : : // is that a 'Terminating-Code'?
976 [ # # ]: 0 : if (nDataBits<64) bTerminatingCode=sal_True; else bTerminatingCode=sal_False;
977 : :
978 : : // remove the read bits from the input buffer:
979 : 0 : nInputBitsBufSize = nInputBitsBufSize - nCodeBits;
980 : :
981 : : // write the number of data bits into the scanline:
982 [ # # ]: 0 : if (nDataBits>0) {
983 : 0 : nTargetBits = nTargetBits - nDataBits;
984 [ # # ]: 0 : if (nBlackOrWhite==0x00) *pTarget &= 0xff << nTgtFreeByteBits;
985 : 0 : else *pTarget |= 0xff >> (8-nTgtFreeByteBits);
986 [ # # ]: 0 : if (nDataBits<=nTgtFreeByteBits) {
987 [ # # ]: 0 : if (nDataBits==nTgtFreeByteBits) {
988 : 0 : pTarget++;
989 : 0 : nTgtFreeByteBits=8;
990 : : }
991 : 0 : else nTgtFreeByteBits = nTgtFreeByteBits - nDataBits;
992 : : }
993 : : else {
994 : 0 : nDataBits = nDataBits - nTgtFreeByteBits;
995 : 0 : pTarget++;
996 : 0 : nTgtFreeByteBits=8;
997 [ # # ]: 0 : while (nDataBits>=8) {
998 : 0 : *(pTarget++)=nBlackOrWhite;
999 : 0 : nDataBits-=8;
1000 : : }
1001 [ # # ]: 0 : if (nDataBits>0) {
1002 : 0 : *pTarget=nBlackOrWhite;
1003 : 0 : nTgtFreeByteBits = nTgtFreeByteBits - nDataBits;
1004 : : }
1005 : : }
1006 : : }
1007 : :
1008 : : // should the situation arise, switch Black <-> White:
1009 [ # # ]: 0 : if (bTerminatingCode==sal_True) nBlackOrWhite=~nBlackOrWhite;
1010 : :
1011 : : } while (nTargetBits>0 || bTerminatingCode==sal_False);
1012 : : }
1013 : :
1014 : :
1015 : :
1016 : 0 : void CCIDecompressor::Read2DScanlineData(sal_uInt8 * pTarget, sal_uInt16 nTargetBits)
1017 : : {
1018 : : sal_uInt16 n2DMode,nBitPos,nUncomp,nRun,nRun2,nt;
1019 : : sal_uInt8 nBlackOrWhite;
1020 : :
1021 : 0 : nBlackOrWhite=0x00;
1022 : 0 : nBitPos=0;
1023 : :
1024 [ # # ][ # # ]: 0 : while (nBitPos<nTargetBits && bStatus==sal_True) {
[ # # ]
1025 : :
1026 : 0 : n2DMode=ReadCodeAndDecode(p2DModeLookUp,10);
1027 [ # # ]: 0 : if (bStatus==sal_False) return;
1028 : :
1029 [ # # ]: 0 : if (n2DMode==CCI2DMODE_UNCOMP) {
1030 : 0 : for (;;) {
1031 : 0 : nUncomp=ReadCodeAndDecode(pUncompLookUp,11);
1032 [ # # ]: 0 : if ( nUncomp <= CCIUNCOMP_4White_1Black ) {
1033 : 0 : nRun=nUncomp-CCIUNCOMP_0White_1Black;
1034 : 0 : FillBits(pTarget,nTargetBits,nBitPos,nRun,0x00);
1035 : 0 : nBitPos = nBitPos + nRun;
1036 : 0 : FillBits(pTarget,nTargetBits,nBitPos,1,0xff);
1037 : 0 : nBitPos++;
1038 : : }
1039 [ # # ]: 0 : else if ( nUncomp == CCIUNCOMP_5White ) {
1040 : 0 : FillBits(pTarget,nTargetBits,nBitPos,5,0x00);
1041 : 0 : nBitPos = nBitPos + 5;
1042 : : }
1043 : : else {
1044 : 0 : nRun=nUncomp-CCIUNCOMP_0White_End;
1045 : 0 : FillBits(pTarget,nTargetBits,nBitPos,nRun,0x00);
1046 : 0 : nBitPos = nBitPos + nRun;
1047 : 0 : nBlackOrWhite=ReadBlackOrWhite();
1048 : 0 : break;
1049 : : }
1050 : : }
1051 : : }
1052 : :
1053 [ # # ]: 0 : else if (n2DMode==CCI2DMODE_PASS) {
1054 [ # # ][ # # ]: 0 : if (nBitPos==0 && nBlackOrWhite==0x00 && CountBits(pLastLine,nTargetBits,0,0xff)!=0) nRun=0;
[ # # ][ # # ]
1055 : : else {
1056 : 0 : nRun=CountBits(pLastLine,nTargetBits,nBitPos,~nBlackOrWhite);
1057 : 0 : nRun = nRun + CountBits(pLastLine,nTargetBits,nBitPos+nRun,nBlackOrWhite);
1058 : : }
1059 : 0 : nRun = nRun + CountBits(pLastLine,nTargetBits,nBitPos+nRun,~nBlackOrWhite);
1060 : 0 : FillBits(pTarget,nTargetBits,nBitPos,nRun,nBlackOrWhite);
1061 : 0 : nBitPos = nBitPos + nRun;
1062 : : }
1063 : :
1064 [ # # ]: 0 : else if (n2DMode==CCI2DMODE_HORZ) {
1065 [ # # ]: 0 : if (nBlackOrWhite==0x00) {
1066 : 0 : nRun=0;
1067 [ # # ]: 0 : do {
1068 : 0 : nt=ReadCodeAndDecode(pWhiteLookUp,13);
1069 : 0 : nRun = nRun + nt;
1070 : : } while (nt>=64);
1071 : 0 : nRun2=0;
1072 [ # # ]: 0 : do {
1073 : 0 : nt=ReadCodeAndDecode(pBlackLookUp,13);
1074 : 0 : nRun2 = nRun2 + nt;
1075 : : } while (nt>=64);
1076 : : }
1077 : : else {
1078 : 0 : nRun=0;
1079 [ # # ]: 0 : do {
1080 : 0 : nt=ReadCodeAndDecode(pBlackLookUp,13);
1081 : 0 : nRun = nRun + nt;
1082 : : } while (nt>=64);
1083 : 0 : nRun2=0;
1084 [ # # ]: 0 : do {
1085 : 0 : nt=ReadCodeAndDecode(pWhiteLookUp,13);
1086 : 0 : nRun2 = nRun2 + nt;
1087 : : } while (nt>=64);
1088 : : }
1089 : 0 : FillBits(pTarget,nTargetBits,nBitPos,nRun,nBlackOrWhite);
1090 : 0 : nBitPos = nBitPos + nRun;
1091 : 0 : FillBits(pTarget,nTargetBits,nBitPos,nRun2,~nBlackOrWhite);
1092 : 0 : nBitPos = nBitPos + nRun2;
1093 : : }
1094 : :
1095 : : else { // it's one of the modes CCI2DMODE_VERT_...
1096 [ # # ][ # # ]: 0 : if (nBitPos==0 && nBlackOrWhite==0x00 && CountBits(pLastLine,nTargetBits,0,0xff)!=0) nRun=0;
[ # # ][ # # ]
1097 : : else {
1098 : 0 : nRun=CountBits(pLastLine,nTargetBits,nBitPos,~nBlackOrWhite);
1099 : 0 : nRun = nRun + CountBits(pLastLine,nTargetBits,nBitPos+nRun,nBlackOrWhite);
1100 : : }
1101 : 0 : nRun+=n2DMode-CCI2DMODE_VERT_0;
1102 : 0 : FillBits(pTarget,nTargetBits,nBitPos,nRun,nBlackOrWhite);
1103 : 0 : nBitPos = nBitPos + nRun;
1104 : 0 : nBlackOrWhite=~nBlackOrWhite;
1105 : : }
1106 : : }
1107 : : }
1108 : :
1109 : :
1110 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|