Statistics
| Revision:

gvsig-raster / libjni-potrace / trunk / libjni-potrace / resources / potrace-1.8 / src / flate.c @ 1780

History | View | Annotate | Download (8.75 KB)

1
/* Copyright (C) 2001-2007 Peter Selinger.
2
   This file is part of Potrace. It is free software and it is covered
3
   by the GNU General Public License. See the file COPYING for details. */
4

    
5
/* $Id: flate.c 147 2007-04-09 00:44:09Z selinger $ */
6

    
7
/* the PostScript compression module of Potrace. The basic interface
8
   is through the *_xship function, which processes a byte array and
9
   outputs it in compressed or verbatim form, depending on whether
10
   filter is 1 or 0. To flush the output, simply call with the empty
11
   string and filter=0. filter=2 is used to output encoded text but
12
   without the PostScript header to turn on the encoding. Each
13
   function has variants for shipping a single character, a
14
   null-terminated string, or a byte array. */
15

    
16
/* different compression algorithms are available. There is
17
   dummy_xship, which is just the identity, and flate_xship, which
18
   uses zlib compression. Also, lzw_xship provides LZW compression
19
   from the file lzw.c/h. a85_xship provides a85-encoding without
20
   compression. Each function returns the actual number of characters
21
   written. */
22

    
23
/* note: the functions provided here have global state and are not
24
   reentrant */
25

    
26
#ifdef HAVE_CONFIG_H
27
#include "config.h"
28
#endif
29

    
30
#include <stdio.h>
31
#include <string.h>
32
#include <stdlib.h>
33
#include <errno.h>
34

    
35
#ifdef HAVE_ZLIB
36
#include <zlib.h>
37
#endif
38

    
39
#include "flate.h"
40
#include "lzw.h"
41

    
42
#define OUTSIZE 1000
43

    
44
static int a85init(FILE *f);
45
static int a85finish(FILE *f);
46
static int a85write(FILE *f, char *buf, int n);
47
static int a85out(FILE *f, int n);
48
static int a85spool(FILE *f, char c);
49

    
50
/* ---------------------------------------------------------------------- */
51
/* dummy interface: no encoding */
52

    
53
int dummy_xship(FILE *f, int filter, char *s, int len) {
54
  fwrite(s, 1, len, f);
55
  return len;
56
}
57

    
58
/* ---------------------------------------------------------------------- */
59
/* flate interface: zlib (=postscript level 3) compression and a85 */
60

    
61
#ifdef HAVE_ZLIB
62

    
63
int pdf_xship(FILE *f, int filter, char *s, int len) {
64
        static int fstate = 0;
65
        static z_stream c_stream;
66
        char outbuf[OUTSIZE];
67
        int err;
68
        int n=0;
69

    
70
  if (filter && !fstate) {
71
    /* switch on filtering */
72
    c_stream.zalloc = Z_NULL;
73
    c_stream.zfree = Z_NULL;
74
    c_stream.opaque = Z_NULL;
75
    err = deflateInit(&c_stream, 9);
76
    if (err != Z_OK) {
77
      fprintf(stderr, "deflateInit: %s (%d)\n", c_stream.msg, err);
78
      exit(1);
79
    }
80
    c_stream.avail_in = 0;
81
    fstate = 1;
82
  } else if (!filter && fstate) {
83
    /* switch off filtering */
84
    /* flush stream */
85
    do {
86
      c_stream.next_out = (Bytef*)outbuf;
87
      c_stream.avail_out = OUTSIZE;
88

    
89
      err = deflate(&c_stream, Z_FINISH);
90
      if (err != Z_OK && err != Z_STREAM_END) {
91
        fprintf(stderr, "deflate: %s (%d)\n", c_stream.msg, err);
92
        exit(1);
93
      }
94
      n += fwrite(outbuf, 1, OUTSIZE-c_stream.avail_out, f);
95
    } while (err != Z_STREAM_END);
96

    
97
    fstate = 0;
98
  }
99
  if (!fstate) {
100
    fwrite(s, 1, len, f);
101
    return n+len;
102
  }
103
  
104
  /* do the actual compression */
105
  c_stream.next_in = (Bytef*) s;
106
  c_stream.avail_in = len;
107

    
108
  do {
109
    c_stream.next_out = (Bytef*) outbuf;
110
    c_stream.avail_out = OUTSIZE;
111

    
112
    err = deflate(&c_stream, Z_NO_FLUSH);
113
    if (err != Z_OK) {
114
      fprintf(stderr, "deflate: %s (%d)\n", c_stream.msg, err);
115
      exit(1);
116
    }
117
    n += fwrite(outbuf, 1, OUTSIZE-c_stream.avail_out, f);
118
  } while (!c_stream.avail_out);
119
  
120
  return n;
121
}
122

    
123
/* ship len bytes from s using zlib compression. */
124
int flate_xship(FILE *f, int filter, char *s, int len) {
125
  static int fstate = 0;
126
  static z_stream c_stream;
127
  char outbuf[OUTSIZE];
128
  int err;
129
  int n=0;
130

    
131
  if (filter && !fstate) {
132
    /* switch on filtering */
133
    if (filter == 1) {
134
      n += fprintf(f, "currentfile /ASCII85Decode filter /FlateDecode filter cvx exec\n");
135
    }
136
    c_stream.zalloc = Z_NULL;
137
    c_stream.zfree = Z_NULL;
138
    c_stream.opaque = Z_NULL;
139
    err = deflateInit(&c_stream, 9);
140
    if (err != Z_OK) {
141
      fprintf(stderr, "deflateInit: %s (%d)\n", c_stream.msg, err);
142
      exit(1);
143
    }
144
    c_stream.avail_in = 0;
145
    n += a85init(f);
146
    fstate = 1;
147
  } else if (!filter && fstate) {
148
    /* switch off filtering */
149
    /* flush stream */
150
    do {
151
      c_stream.next_out = (Bytef*)outbuf;
152
      c_stream.avail_out = OUTSIZE;
153

    
154
      err = deflate(&c_stream, Z_FINISH);
155
      if (err != Z_OK && err != Z_STREAM_END) {
156
        fprintf(stderr, "deflate: %s (%d)\n", c_stream.msg, err);
157
        exit(1);
158
      }
159
      n += a85write(f, outbuf, OUTSIZE-c_stream.avail_out);
160
    } while (err != Z_STREAM_END);
161

    
162
    n += a85finish(f);
163

    
164
    fstate = 0;
165
  }
166
  if (!fstate) {
167
    fwrite(s, 1, len, f);
168
    return n+len;
169
  }
170
  
171
  /* do the actual compression */
172
  c_stream.next_in = (Bytef*) s;
173
  c_stream.avail_in = len;
174

    
175
  do {
176
    c_stream.next_out = (Bytef*) outbuf;
177
    c_stream.avail_out = OUTSIZE;
178

    
179
    err = deflate(&c_stream, Z_NO_FLUSH);
180
    if (err != Z_OK) {
181
      fprintf(stderr, "deflate: %s (%d)\n", c_stream.msg, err);
182
      exit(1);
183
    }
184
    n += a85write(f, outbuf, OUTSIZE-c_stream.avail_out);
185
  } while (!c_stream.avail_out);
186
  
187
  return n;
188
}
189

    
190
#else  /* HAVE_ZLIB */
191

    
192
int pdf_xship(FILE *f, int filter, char *s, int len) {
193
  return dummy_xship(f, filter, s, len);
194
}
195

    
196
int flate_xship(FILE *f, int filter, char *s, int len) {
197
  return dummy_xship(f, filter, s, len);
198
}
199

    
200
#endif /* HAVE_ZLIB */
201

    
202
/* ---------------------------------------------------------------------- */
203
/* lzw interface: LZW (=postscript level 2) compression with a85.
204
   This relies on lzw.c/h to do the actual compression. */
205

    
206
/* use Postscript level 2 compression. Ship len bytes from str. */
207
int lzw_xship(FILE *f, int filter, char *str, int len) {
208
  static int fstate = 0;
209
  static lzw_stream_t *s = NULL;
210
  char outbuf[OUTSIZE];
211
  int err;
212
  int n=0;
213

    
214
  if (filter && !fstate) {
215
    /* switch on filtering */
216
    if (filter == 1) {
217
      n += fprintf(f, "currentfile /ASCII85Decode filter /LZWDecode filter cvx exec\n");
218
    }
219
    s = lzw_init();
220
    if (s == NULL) {
221
      fprintf(stderr, "lzw_init: %s\n", strerror(errno));
222
      exit(1);
223
    }
224
    n += a85init(f);
225
    fstate = 1;
226
  } else if (!filter && fstate) {
227
    /* switch off filtering */
228
    /* flush stream */
229
    s->next_in = 0;
230
    s->avail_in = 0;
231
    do {
232
      s->next_out = outbuf;
233
      s->avail_out = OUTSIZE;
234

    
235
      err = lzw_compress(s, LZW_EOD);
236
      if (err) {
237
        fprintf(stderr, "lzw_compress: %s\n", strerror(errno));
238
        exit(1);
239
      }
240
      n += a85write(f, outbuf, OUTSIZE - s->avail_out);
241
    } while (s->avail_out == 0);
242

    
243
    n += a85finish(f);
244

    
245
    lzw_free(s);
246
    s = NULL;
247

    
248
    fstate = 0;
249
  }
250
  if (!fstate) {
251
    fwrite(str, 1, len, f);
252
    return n+len;
253
  }
254
  
255
  /* do the actual compression */
256
  s->next_in = str;
257
  s->avail_in = len;
258

    
259
  do {
260
    s->next_out = outbuf;
261
    s->avail_out = OUTSIZE;
262

    
263
    err = lzw_compress(s, LZW_NORMAL);
264
    if (err) {
265
      fprintf(stderr, "lzw_compress: %s\n", strerror(errno));
266
      exit(1);
267
    }
268
    n += a85write(f, outbuf, OUTSIZE - s->avail_out);
269
  } while (s->avail_out == 0);
270
  
271
  return n;
272
}
273

    
274
/* ---------------------------------------------------------------------- */
275
/* a85 interface: a85 encoding without compression */
276

    
277
/* ship len bytes from s using a85 encoding only. */
278
int a85_xship(FILE *f, int filter, char *s, int len) {
279
  static int fstate = 0;
280
  int n=0;
281

    
282
  if (filter && !fstate) {
283
    /* switch on filtering */
284
    if (filter == 1) {
285
      n += fprintf(f, "currentfile /ASCII85Decode filter cvx exec\n");
286
    }
287
    n += a85init(f);
288
    fstate = 1;
289
  } else if (!filter && fstate) {
290
    /* switch off filtering */
291
    /* flush stream */
292
    n += a85finish(f);
293
    fstate = 0;
294
  }
295
  if (!fstate) {
296
    fwrite(s, 1, len, f);
297
    return n+len;
298
  }
299
  
300
  n += a85write(f, s, len);
301
  
302
  return n;
303
}
304

    
305
/* ---------------------------------------------------------------------- */
306
/* low-level a85 backend */
307

    
308
static unsigned long a85buf[4];
309
static int a85n;
310
static int a85col;
311

    
312
static int a85init(FILE *f) {
313
  a85n = 0;
314
  a85col = 0;
315
  return 0;
316
}
317

    
318
static int a85finish(FILE *f) {
319
  int r=0;
320

    
321
  if (a85n) {
322
    r+=a85out(f, a85n);
323
  }
324
  fputs("~>\n", f);
325
  return r+2;
326
}
327

    
328
static int a85write(FILE *f, char *buf, int n) {
329
  int i;
330
  int r=0;
331

    
332
  for (i=0; i<n; i++) {
333
    a85buf[a85n] = (unsigned char)buf[i];
334
    a85n++;
335
    
336
    if (a85n == 4) {
337
      r+=a85out(f, 4);
338
      a85n = 0;
339
    }
340
  }
341
  return r;
342
}
343

    
344
static int a85out(FILE *f, int n) {
345
  char out[5];
346
  unsigned long s;
347
  int r=0;
348
  int i;
349

    
350
  for (i=n; i<4; i++) {
351
    a85buf[i] = 0;
352
  }
353

    
354
  s = (a85buf[0]<<24) + (a85buf[1]<<16) + (a85buf[2]<<8) + (a85buf[3]<<0);
355

    
356
  if (!s) {
357
    r+=a85spool(f, 'z');
358
  } else {
359
    for (i=4; i>=0; i--) {
360
      out[i] = s % 85;
361
      s /= 85;
362
    }
363
    for (i=0; i<n+1; i++) {
364
      r+=a85spool(f, out[i]+33);
365
    }
366
  } 
367
  return r;
368
}
369

    
370
static int a85spool(FILE *f, char c) {
371
  fputc(c, f);
372

    
373
  a85col++;
374
  if (a85col>70) {
375
    fputc('\n', f);
376
    a85col=0;
377
    return 2;
378
  }
379
  
380
  return 1;
381
}