1 | /**************************************************************************
|
---|
2 | *
|
---|
3 | * mgtic.c -- Program to compress/decompress textual images
|
---|
4 | * Copyright (C) 1994 Stuart Inglis
|
---|
5 | *
|
---|
6 | * This program is free software; you can redistribute it and/or modify
|
---|
7 | * it under the terms of the GNU General Public License as published by
|
---|
8 | * the Free Software Foundation; either version 2 of the License, or
|
---|
9 | * (at your option) any later version.
|
---|
10 | *
|
---|
11 | * This program is distributed in the hope that it will be useful,
|
---|
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
---|
14 | * GNU General Public License for more details.
|
---|
15 | *
|
---|
16 | * You should have received a copy of the GNU General Public License
|
---|
17 | * along with this program; if not, write to the Free Software
|
---|
18 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
---|
19 | *
|
---|
20 | * $Id: mgtic.c 3745 2003-02-20 21:20:24Z mdewsnip $
|
---|
21 | *
|
---|
22 | **************************************************************************
|
---|
23 | *
|
---|
24 | * This file is the basis of mgtic, which compresses the components of an
|
---|
25 | * image.
|
---|
26 | * The compressed file contains the following sections:
|
---|
27 | * mgtic magic_no
|
---|
28 | * mgtic version
|
---|
29 | * lossy/lossless flag
|
---|
30 | * internal/external library flag
|
---|
31 | * cols, rows, number of marks, library size
|
---|
32 | * [library sequence]
|
---|
33 | * symbol sequence
|
---|
34 | * offset sequence
|
---|
35 | * [residue bitmap]
|
---|
36 | *
|
---|
37 | **************************************************************************/
|
---|
38 |
|
---|
39 | #include "sysfuncs.h"
|
---|
40 |
|
---|
41 | #include "marklist.h"
|
---|
42 | #include "pbmtools.h"
|
---|
43 | #include "extractor.h"
|
---|
44 | #include "utils.h"
|
---|
45 | #include "match.h"
|
---|
46 | #include "sortmarks.h"
|
---|
47 | #include "codesyms.h"
|
---|
48 | #include "arithcode.h"
|
---|
49 | #include "codeoffsets.h"
|
---|
50 | #include "bilevel.h"
|
---|
51 |
|
---|
52 | static char library_template[] =
|
---|
53 | {
|
---|
54 | ".ppppp.;"
|
---|
55 | "pp222pp;"
|
---|
56 | "p22222p;"
|
---|
57 | "p22*...;"
|
---|
58 | };
|
---|
59 |
|
---|
60 | void
|
---|
61 | usage ()
|
---|
62 | {
|
---|
63 | fprintf (stderr, "usage: \n"
|
---|
64 | "\tmgtic -e [-L] [-Q] [-X] libraryfile infile [>compressed]\n"
|
---|
65 | "or\n"
|
---|
66 | "\tmgtic -d [-L] [-X libraryfile] compressed [>outfile]\n");
|
---|
67 | exit (1);
|
---|
68 | }
|
---|
69 |
|
---|
70 |
|
---|
71 | /* encode the list of marks 'list', w.r.t. the library 'library' */
|
---|
72 | void
|
---|
73 | match_sequence (marklistptr list, marklistptr library, marklistptr * symbol_list, Pixel ** recon, int quick)
|
---|
74 | {
|
---|
75 | int carryx, carryy, gap;
|
---|
76 | int lastx = 0, lasty = 0;
|
---|
77 | int i, j;
|
---|
78 | marktype d, d2;
|
---|
79 | marklistptr liststep, librarystep;
|
---|
80 | int score, found;
|
---|
81 | int r, c;
|
---|
82 | int p;
|
---|
83 |
|
---|
84 | carryx = carryy = 0;
|
---|
85 | gap = max (1, marklist_length (list) / 10);
|
---|
86 |
|
---|
87 | for (liststep = list, i = 0; liststep; liststep = liststep->next, i++)
|
---|
88 | {
|
---|
89 | if (V)
|
---|
90 | if (!(i % gap))
|
---|
91 | fprintf (stderr, ".");
|
---|
92 | d = liststep->data;
|
---|
93 |
|
---|
94 | found = -1;
|
---|
95 | score = INT_MAX;
|
---|
96 | for (librarystep = library, j = 0; librarystep; librarystep = librarystep->next, j++)
|
---|
97 | {
|
---|
98 | d2 = librarystep->data;
|
---|
99 |
|
---|
100 | if (NOT_SCREENED (d2, d))
|
---|
101 | if ((p = MATCH (&d, &d2)) < MATCH_VAL)
|
---|
102 | {
|
---|
103 | if (p < score)
|
---|
104 | {
|
---|
105 | score = p;
|
---|
106 | found = j;
|
---|
107 | if (quick)
|
---|
108 | break;
|
---|
109 | }
|
---|
110 | }
|
---|
111 | }
|
---|
112 | /*
|
---|
113 | if(found<0){
|
---|
114 | for(librarystep=library,j=0; librarystep; librarystep=librarystep->next,j++){
|
---|
115 | d2=librarystep->data;
|
---|
116 |
|
---|
117 | if((p=MATCH(&d,&d2))<MATCH_VAL){
|
---|
118 | if(p<score){
|
---|
119 | score=p;found=j; if(quick) break;
|
---|
120 | }
|
---|
121 | }
|
---|
122 | }
|
---|
123 | }
|
---|
124 | */
|
---|
125 | if (found >= 0)
|
---|
126 | {
|
---|
127 | liststep->data.symnum = found;
|
---|
128 | marklist_getat (library, found, &d2);
|
---|
129 | d2.symnum = found;
|
---|
130 |
|
---|
131 | d2.xoffset = d.xpos - lastx + carryx; /* propagate changes to next mark */
|
---|
132 | d2.yoffset = d.ypos - lasty + carryy;
|
---|
133 | carryx = (d2.xcen - d.xcen); /* offet centroids because thats where we match them! */
|
---|
134 | carryy = (d2.ycen - d.ycen);
|
---|
135 | d2.xoffset -= carryx; /* make the changes to this mark */
|
---|
136 | d2.yoffset -= carryy;
|
---|
137 | lastx = d.xpos + d2.w;
|
---|
138 | lasty = d.ypos;
|
---|
139 |
|
---|
140 | marklist_add (symbol_list, d2);
|
---|
141 |
|
---|
142 | /* add to the reconstructed image--this is the lossy version */
|
---|
143 | for (r = 0; r < d2.h; r++)
|
---|
144 | for (c = 0; c < d2.w; c++)
|
---|
145 | if (pbm_getpixel (d2.bitmap, c, r))
|
---|
146 | pbm_putpixel_trunc (recon, d.xpos + c - carryx, d.ypos + r - carryy, 1, d2.w, d2.h);
|
---|
147 | }
|
---|
148 | else
|
---|
149 | {
|
---|
150 | /* didn't match at all..hopefully noise */
|
---|
151 | if ((liststep->data.w >= 10) || (liststep->data.w >= 10))
|
---|
152 | {
|
---|
153 | fprintf (stderr, "mgtic: warning, unable to match a char.\n");
|
---|
154 | write_library_mark (stderr, liststep->data);
|
---|
155 | }
|
---|
156 | if (V)
|
---|
157 | fprintf (stderr, "x");
|
---|
158 | liststep->data.symnum = -1;
|
---|
159 | }
|
---|
160 | }
|
---|
161 | if (V)
|
---|
162 | fprintf (stderr, "\n");
|
---|
163 | }
|
---|
164 |
|
---|
165 |
|
---|
166 |
|
---|
167 |
|
---|
168 | void
|
---|
169 | main (int argc, char *args[])
|
---|
170 | {
|
---|
171 | int i, n, r, c, ch;
|
---|
172 | FILE *inf;
|
---|
173 | marklistptr library = NULL, list = NULL, step = NULL;
|
---|
174 | marklistptr symbol_list = NULL;
|
---|
175 | marktype d, d2;
|
---|
176 | Pixel **bitmap, **recon, **bitmapcopy;
|
---|
177 | char *splitfilename = NULL;
|
---|
178 | int cols, rows, count, librarysize, lossy = 1;
|
---|
179 | int quick = 0;
|
---|
180 | int ticencode = 0, ticdecode = 0, external = 0;
|
---|
181 | char *libraryname = NULL, *infile = NULL;
|
---|
182 | char *s1 = NULL, *s2 = NULL;
|
---|
183 | char bufferin[BUFSIZ], bufferout[BUFSIZ];
|
---|
184 |
|
---|
185 | if (argc < 2)
|
---|
186 | usage ();
|
---|
187 |
|
---|
188 | while ((ch = getopt (argc, args, "edlLQhvXR:")) != -1)
|
---|
189 | switch (ch)
|
---|
190 | {
|
---|
191 | case 'e':
|
---|
192 | ticencode = 1;
|
---|
193 | break;
|
---|
194 | case 'd':
|
---|
195 | ticdecode = 1;
|
---|
196 | break;
|
---|
197 | case 'l':
|
---|
198 | lossy = 1;
|
---|
199 | break;
|
---|
200 | case 'L':
|
---|
201 | lossy = 0;
|
---|
202 | break;
|
---|
203 | case 'Q':
|
---|
204 | quick = 1;
|
---|
205 | break;
|
---|
206 | case 'v':
|
---|
207 | V = 1;
|
---|
208 | break;
|
---|
209 | case 'X':
|
---|
210 | external = 1;
|
---|
211 | break;
|
---|
212 | case 'R':
|
---|
213 | splitfilename = optarg;
|
---|
214 | break;
|
---|
215 | case 'h':
|
---|
216 | case '?':
|
---|
217 | usage ();
|
---|
218 | }
|
---|
219 |
|
---|
220 | for (i = 1; i < argc; i++)
|
---|
221 | if (args[i][0] != '-')
|
---|
222 | if (strcmp (args[i - 1], "-R"))
|
---|
223 | { /* ignore arg following -R, ie. -R <filename> */
|
---|
224 | if (!s1)
|
---|
225 | s1 = args[i];
|
---|
226 | else if (!s2)
|
---|
227 | s2 = args[i];
|
---|
228 | else
|
---|
229 | error_msg (args[0], "too many filenames", "");
|
---|
230 | }
|
---|
231 |
|
---|
232 | if (ticencode == ticdecode)
|
---|
233 | error_msg (args[0], "please specify either encode XOR decode", "");
|
---|
234 |
|
---|
235 | if (ticencode)
|
---|
236 | {
|
---|
237 | /*****************
|
---|
238 | ENCODING STAGE
|
---|
239 | *****************/
|
---|
240 | long PrevBits = 0;
|
---|
241 | long BITS_header = 0, BITS_symbols = 0, BITS_offsets = 0, BITS_residue = 0,
|
---|
242 | BITS_footer = 0, BITS_library = 0;
|
---|
243 |
|
---|
244 | libraryname = s1;
|
---|
245 | if (!libraryname)
|
---|
246 | error_msg (args[0], "please specify a library file", "");
|
---|
247 | infile = s2;
|
---|
248 | if (!infile)
|
---|
249 | error_msg (args[0], "please specify a file name", "");
|
---|
250 |
|
---|
251 | inf = fopen (infile, "rb");
|
---|
252 | if (inf == NULL)
|
---|
253 | error_msg (args[0], "Trouble opening file:", infile);
|
---|
254 | setbuf (inf, bufferin);
|
---|
255 |
|
---|
256 | count = librarysize = read_library (libraryname, &library);
|
---|
257 |
|
---|
258 | if (V)
|
---|
259 | fprintf (stderr, "%s: processing...\n", args[0]);
|
---|
260 |
|
---|
261 | if (pbm_isapbmfile (inf))
|
---|
262 | {
|
---|
263 | if (V)
|
---|
264 | fprintf (stderr, "reading file %s...\n", infile);
|
---|
265 | bitmap = pbm_readfile (inf, &cols, &rows);
|
---|
266 | fclose (inf);
|
---|
267 |
|
---|
268 | bitmapcopy = pbm_copy (bitmap, cols, rows);
|
---|
269 |
|
---|
270 | if (V)
|
---|
271 | fprintf (stderr, "extracting...");
|
---|
272 | ExtractAllMarks (bitmap, &list, cols, rows);
|
---|
273 | if (V)
|
---|
274 | fprintf (stderr, "(%d marks)\n", marklist_length (list));
|
---|
275 |
|
---|
276 | /* sort into reading order */
|
---|
277 | if (V)
|
---|
278 | fprintf (stderr, "sorting...\n");
|
---|
279 | list = sortmarks (list);
|
---|
280 |
|
---|
281 | pbm_freearray (&bitmap, rows); /* clear old version */
|
---|
282 | bitmap = bitmapcopy; /* point to the copy */
|
---|
283 | recon = pbm_allocarray (cols, rows);
|
---|
284 |
|
---|
285 | if (V)
|
---|
286 | fprintf (stderr, "matching...");
|
---|
287 |
|
---|
288 | match_sequence (list, library, &symbol_list, recon, quick);
|
---|
289 |
|
---|
290 |
|
---|
291 | PrevBits = 0;
|
---|
292 | setbuf (stdout, bufferout);
|
---|
293 | /* start output */
|
---|
294 | magic_write (stdout, MAGIC_TIC);
|
---|
295 | InitArithEncoding ();
|
---|
296 |
|
---|
297 | EncodeGammaDist (1); /* version 1 of the program */
|
---|
298 | EncodeGammaDist (lossy); /* lossy=1 = no residue */
|
---|
299 | EncodeGammaDist (external); /* 1== external file */
|
---|
300 |
|
---|
301 | count = marklist_length (symbol_list);
|
---|
302 | if (V)
|
---|
303 | fprintf (stderr, "encoding cols, rows, and number of symbols=%d\n", count);
|
---|
304 |
|
---|
305 | EncodeGammaDist (cols);
|
---|
306 | EncodeGammaDist (rows);
|
---|
307 | EncodeGammaDist (count);
|
---|
308 | EncodeGammaDist (librarysize);
|
---|
309 |
|
---|
310 | BITS_header = CountOfBitsOut - PrevBits;
|
---|
311 | PrevBits = CountOfBitsOut;
|
---|
312 |
|
---|
313 |
|
---|
314 | /* output the library sequence */
|
---|
315 | if (external == 0)
|
---|
316 | {
|
---|
317 | if (V)
|
---|
318 | fprintf (stderr, "encoding library\n");
|
---|
319 |
|
---|
320 | bl_clearmodel ();
|
---|
321 | bl_writetemplate (library_template);
|
---|
322 | for (step = library; step; step = step->next)
|
---|
323 | bl_compress_mark (step->data);
|
---|
324 | bl_freemodel ();
|
---|
325 | BITS_library = CountOfBitsOut - PrevBits;
|
---|
326 | PrevBits = CountOfBitsOut;
|
---|
327 | }
|
---|
328 |
|
---|
329 | /* output the symbol sequence */
|
---|
330 | if (V)
|
---|
331 | fprintf (stderr, "encoding symbol sequence\n");
|
---|
332 | InitPPM ();
|
---|
333 | EncodeSymbols (symbol_list, count);
|
---|
334 | BITS_symbols = CountOfBitsOut - PrevBits;
|
---|
335 | PrevBits = CountOfBitsOut;
|
---|
336 |
|
---|
337 |
|
---|
338 | /* output the offset sequence */
|
---|
339 | if (V)
|
---|
340 | fprintf (stderr, "encoding offset sequence\n");
|
---|
341 | EncodeOffsets (symbol_list, count);
|
---|
342 | BITS_offsets = CountOfBitsOut - PrevBits;
|
---|
343 | PrevBits = CountOfBitsOut;
|
---|
344 |
|
---|
345 | EncodeChecksum (); /* code lossy checksum */
|
---|
346 |
|
---|
347 | /* calculate the residue...and compress it---if need be! */
|
---|
348 | if (!lossy)
|
---|
349 | {
|
---|
350 | if (V)
|
---|
351 | fprintf (stderr, "encoding residue...\n");
|
---|
352 |
|
---|
353 | d.bitmap = bitmap;
|
---|
354 | d.h = rows;
|
---|
355 | d.w = cols;
|
---|
356 | d2.bitmap = recon;
|
---|
357 | d2.h = rows;
|
---|
358 | d2.w = cols;
|
---|
359 |
|
---|
360 | if (splitfilename)
|
---|
361 | {
|
---|
362 | FILE *temp;
|
---|
363 |
|
---|
364 | CloseDownArithEncoding ();
|
---|
365 | fclose (stdout);
|
---|
366 | /* no residue result */
|
---|
367 | BITS_footer = CountOfBitsOut - PrevBits;
|
---|
368 |
|
---|
369 | temp = fopen (splitfilename, "wb");
|
---|
370 | if (temp == NULL)
|
---|
371 | error_msg (args[0], "Trouble creating file:", splitfilename);
|
---|
372 |
|
---|
373 | arith_out = temp;
|
---|
374 | InitArithEncoding ();
|
---|
375 | bl_clair_compress (d, d2);
|
---|
376 | CloseDownArithEncoding ();
|
---|
377 | BITS_residue = CountOfBitsOut;
|
---|
378 | fclose (temp);
|
---|
379 | }
|
---|
380 | else
|
---|
381 | {
|
---|
382 | bl_clair_compress (d, d2);
|
---|
383 | BITS_residue = CountOfBitsOut - PrevBits;
|
---|
384 | PrevBits = CountOfBitsOut;
|
---|
385 | EncodeChecksum (); /* code lossless checksum */
|
---|
386 | CloseDownArithEncoding ();
|
---|
387 | BITS_footer = CountOfBitsOut - PrevBits;
|
---|
388 | }
|
---|
389 | }
|
---|
390 | else
|
---|
391 | {
|
---|
392 | if (V)
|
---|
393 | fprintf (stderr, "not encoding residue..lossy mode\n");
|
---|
394 | CloseDownArithEncoding ();
|
---|
395 | BITS_footer = CountOfBitsOut - PrevBits;
|
---|
396 | }
|
---|
397 |
|
---|
398 | /* because we edit the values above */
|
---|
399 | CountOfBitsOut = BITS_header + BITS_library + BITS_symbols + BITS_offsets + BITS_residue + BITS_footer;
|
---|
400 |
|
---|
401 | fprintf (stderr, "bits: header=%ld, library=%ld, "
|
---|
402 | "symbols=%ld, offsets=%ld, residue=%ld, footer=%ld\n",
|
---|
403 | BITS_header, BITS_library, BITS_symbols,
|
---|
404 | BITS_offsets, BITS_residue, BITS_footer);
|
---|
405 | fprintf (stderr, "total bits: %ld, ", CountOfBitsOut);
|
---|
406 | fprintf (stderr, "Lossy CR: %4.2f", (cols * rows) / (float) (CountOfBitsOut - BITS_residue));
|
---|
407 | if (external)
|
---|
408 | fprintf (stderr, " (excluding external lib)");
|
---|
409 | fprintf (stderr, ", Lossless CR: %4.2f\n", (!lossy) * (cols * rows) / (float) (CountOfBitsOut));
|
---|
410 | }
|
---|
411 | else
|
---|
412 | error_msg (args[0], "unknown format of bitmap--expecting PBM.", "");
|
---|
413 | }
|
---|
414 | else
|
---|
415 | {
|
---|
416 | /*****************
|
---|
417 | DECODING STAGE
|
---|
418 | *****************/
|
---|
419 | int lastx, lasty;
|
---|
420 | librarysize = 0;
|
---|
421 |
|
---|
422 | if (external)
|
---|
423 | {
|
---|
424 | libraryname = s1;
|
---|
425 | infile = s2;
|
---|
426 | count = librarysize = read_library (libraryname, &library);
|
---|
427 | }
|
---|
428 | else
|
---|
429 | {
|
---|
430 | infile = s1;
|
---|
431 | if (infile && s2)
|
---|
432 | error_msg (args[0], "too many filenames", "");
|
---|
433 | }
|
---|
434 |
|
---|
435 | if (!freopen (infile, "rb", stdin))
|
---|
436 | error_msg (args[0], "Trouble opening file:", infile);
|
---|
437 |
|
---|
438 |
|
---|
439 | if (V)
|
---|
440 | fprintf (stderr, "decompressing...\n");
|
---|
441 |
|
---|
442 | setbuf (stdin, bufferin);
|
---|
443 | magic_check (stdin, MAGIC_TIC);
|
---|
444 |
|
---|
445 | InitArithDecoding ();
|
---|
446 |
|
---|
447 | {
|
---|
448 | int version = DecodeGammaDist ();
|
---|
449 | if (version != 1)
|
---|
450 | error_msg (args[0], "Need later version of decompressor.", "");
|
---|
451 | }
|
---|
452 |
|
---|
453 | {
|
---|
454 | int templossy = DecodeGammaDist ();
|
---|
455 | if (!lossy)
|
---|
456 | lossy = templossy; /* can only choose if encoded file is lossless */
|
---|
457 | if (V)
|
---|
458 | {
|
---|
459 | if (lossy)
|
---|
460 | fprintf (stderr, "lossy mode\n");
|
---|
461 | else
|
---|
462 | fprintf (stderr, "lossless mode\n");
|
---|
463 | }
|
---|
464 | }
|
---|
465 |
|
---|
466 | if (DecodeGammaDist ())
|
---|
467 | { /* if compressed file doesn't contain library */
|
---|
468 | if (!external)
|
---|
469 | error_msg (args[0], "compressed file doesn't contain library, specify externally", "");
|
---|
470 | external = 1;
|
---|
471 | }
|
---|
472 | else
|
---|
473 | { /* if compressed file contains library */
|
---|
474 | if (external)
|
---|
475 | fprintf (stderr, "ignoring external library file\n");
|
---|
476 | external = 0;
|
---|
477 | }
|
---|
478 |
|
---|
479 | cols = DecodeGammaDist ();
|
---|
480 | rows = DecodeGammaDist ();
|
---|
481 | count = DecodeGammaDist ();
|
---|
482 |
|
---|
483 | i = DecodeGammaDist (); /* librarysize */
|
---|
484 | if (external)
|
---|
485 | {
|
---|
486 | if (i > librarysize)
|
---|
487 | error_msg (args[0], "external library file is too small!", "");
|
---|
488 | else if (i < librarysize)
|
---|
489 | fprintf (stderr, "%s: warning, expecting a different (smaller) library.\n", args[0]);
|
---|
490 | }
|
---|
491 | librarysize = i;
|
---|
492 |
|
---|
493 | if (V)
|
---|
494 | fprintf (stderr, "cols %d, rows %d, num syms %d, library size %d\n", cols, rows, count, librarysize);
|
---|
495 |
|
---|
496 | /* decode library */
|
---|
497 | if (external == 0)
|
---|
498 | {
|
---|
499 | if (V)
|
---|
500 | fprintf (stderr, "reading library\n");
|
---|
501 | bl_clearmodel ();
|
---|
502 | bl_readtemplate ();
|
---|
503 | for (n = 0; n < librarysize; n++)
|
---|
504 | {
|
---|
505 | bl_decompress_mark (&d);
|
---|
506 | d.symnum = n;
|
---|
507 | if (library == NULL)
|
---|
508 | step = marklist_add (&library, d);
|
---|
509 | else
|
---|
510 | step = marklist_add (&step, d);
|
---|
511 | }
|
---|
512 | bl_freemodel ();
|
---|
513 | if (V)
|
---|
514 | fprintf (stderr, "read %d marks from library\n", marklist_length (library));
|
---|
515 | }
|
---|
516 |
|
---|
517 | recon = pbm_allocarray (cols, rows);
|
---|
518 |
|
---|
519 | /* decode symbols */
|
---|
520 | InitPPM ();
|
---|
521 | if (V)
|
---|
522 | fprintf (stderr, "decompressing %d symbols\n", count);
|
---|
523 | symbol_list = DecodeSymbols (count);
|
---|
524 |
|
---|
525 | /* decode offsets */
|
---|
526 | if (V)
|
---|
527 | fprintf (stderr, "reading offsets...\n");
|
---|
528 | DecodeOffsets (symbol_list, count);
|
---|
529 | lastx = lasty = 0;
|
---|
530 | for (step = symbol_list; step; step = step->next)
|
---|
531 | {
|
---|
532 | lastx = lastx + step->data.xoffset;
|
---|
533 | lasty = lasty + step->data.yoffset;
|
---|
534 |
|
---|
535 | marklist_getat (library, step->data.symnum, &d2);
|
---|
536 | for (r = 0; r < d2.h; r++)
|
---|
537 | for (c = 0; c < d2.w; c++)
|
---|
538 | if (pbm_getpixel (d2.bitmap, c, r))
|
---|
539 | pbm_putpixel_trunc (recon, lastx + c, lasty + r, 1, cols, rows); /* we don't care, already warned them! */
|
---|
540 | lastx += d2.w;
|
---|
541 | }
|
---|
542 |
|
---|
543 | DecodeChecksum (args[0]);
|
---|
544 |
|
---|
545 | /* decode the residue */
|
---|
546 | if (!lossy)
|
---|
547 | {
|
---|
548 | if (V)
|
---|
549 | fprintf (stderr, "decoding residue...\n");
|
---|
550 |
|
---|
551 | bitmap = pbm_allocarray (cols, rows);
|
---|
552 | d.bitmap = bitmap;
|
---|
553 | d.w = d2.w = cols;
|
---|
554 | d.h = d2.h = rows;
|
---|
555 |
|
---|
556 | d2.bitmap = recon;
|
---|
557 |
|
---|
558 | /* NOTE: the 2nd argument is clairvoyantly compressed */
|
---|
559 | if (splitfilename)
|
---|
560 | {
|
---|
561 | FILE *temp;
|
---|
562 |
|
---|
563 | CloseDownArithDecoding ();
|
---|
564 | fclose (stdin);
|
---|
565 |
|
---|
566 | temp = fopen (splitfilename, "rb");
|
---|
567 | if (temp == NULL)
|
---|
568 | error_msg (args[0], "Trouble opening file:", splitfilename);
|
---|
569 |
|
---|
570 | arith_in = temp;
|
---|
571 | InitArithDecoding ();
|
---|
572 | bl_clair_decompress (d, d2);
|
---|
573 | CloseDownArithDecoding ();
|
---|
574 | fclose (temp);
|
---|
575 | }
|
---|
576 | else
|
---|
577 | {
|
---|
578 | bl_clair_decompress (d, d2);
|
---|
579 | DecodeChecksum (args[0]);
|
---|
580 | CloseDownArithDecoding ();
|
---|
581 | }
|
---|
582 | pbm_freearray (&recon, rows);
|
---|
583 | recon = bitmap; /* point to the bitmap */
|
---|
584 | }
|
---|
585 | else
|
---|
586 | {
|
---|
587 | CloseDownArithDecoding ();
|
---|
588 | }
|
---|
589 |
|
---|
590 | if (V)
|
---|
591 | fprintf (stderr, "writing pbm file...\n");
|
---|
592 | setbuf (stdout, bufferout);
|
---|
593 | pbm_writefile (stdout, recon, cols, rows);
|
---|
594 | pbm_freearray (&recon, rows);
|
---|
595 | } /* end decoding */
|
---|
596 | }
|
---|