summaryrefslogtreecommitdiff
path: root/graphics/sam2p/pts_fax.h
blob: dd4ee052b1e594b62a27bc8e640433ad0765aa3e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
/*
 * pts_fax.h -- a compact CCITTFax compressor and uncompressor) interface
 * compiled by pts@fazekas.hu at Sun Jul  7 19:51:42 CEST 2002
 *
 * For usage example, see fax_test.c.
 *
 * algorithm ripped from GNU Ghostscript, implementation and (C):
 *
Copyright (C) 1993, 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises.  All
rights reserved.

GNU Ghostscript is free software; you can redistribute it and/or
modify it under the terms of version 2 of the GNU General Public
License as published by the Free Software Foundation.

GNU Ghostscript is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty
of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program so you can know your rights and responsibilities.
It should be in a file named doc/COPYING. If not, write to the
Free Software Foundation, Inc., 59 Temple Place Suite 330, Boston, MA
02111-1307, USA.
 */

/*$Id: pts_fax.h,v 1.4 2005/07/20 21:15:08 pts Exp $ */
/* CCITTFax filter state definition */
/* Requires strimpl.h */

#ifndef PTS_FAX_H
#  define PTS_FAX_H 1

#ifdef __GNUC__
#ifndef __clang__
#pragma interface
#endif
#endif

/* #include "scommon.h" */
/*$Id: pts_fax.h,v 1.4 2005/07/20 21:15:08 pts Exp $ */
/* Definitions common to stream clients and implementors */

/* #ifndef scommon_DEFINED */
/* #  define scommon_DEFINED */

/**** pts ****/
#if 0
#include "gsmemory.h"
#include "gsstype.h"		/* for extern_st */
#endif

/**** pts ****/
#include "config2.h"
/* ^^^ should #define SIZEOF_INT
 * ^^^ should #define _, and ___
 * ^^^ should #define? USE_BULITIN_FAXD
 * ^^^ should #define? USE_BULITIN_FAXE
 * ^^^ should define const
 */
#if 0 /* example for Linux i386 gcc 2.95: */
  #define SIZEOF_INT 4
  #if ((defined(__STDC__) || defined(__PROTOTYPES__)) && !defined(NO_PROTO)) || defined(__cplusplus)
  # define _(args) args
  # define OF(args) args
  # define ___(arg2s,arg1s,argafter) arg2s /* Dat: no direct comma allowed in args :-( */
  #else
  # define _(args) ()
  # define OF(args) ()
  # define ___(arg2s,arg1s,argafter) arg1s argafter /* Dat: no direct comma allowed in args :-( */
  #endif
  #define USE_BUILTIN_FAXE 1
  #define USE_BUILITN_FAXD 1
#endif

typedef void (*gssss_memset_t)(void *s, int c, unsigned n); /* Imp: not `unsigned' len */
/** The function must not return out of memory. */
typedef void* (*gssss_xalloc_t)(unsigned len); /* Imp: not `unsigned' len */
typedef void (*gssss_free_t)(void *ptr);
typedef void (*gssss_memcpy_t)(void *dest, const void *src, unsigned len); /* Imp: not `unsigned' len */

/*
 * There are three major structures involved in the stream package.
 *
 * A stream is an "object" that owns a buffer, which it uses to implement
 * unsigned char-oriented sequential access in a standard way, and a set of
 * procedures that handle things like buffer refilling.  See stream.h
 * for more information about streams.
 */
#ifndef stream_DEFINED
#  define stream_DEFINED
typedef struct stream_s stream;

#endif
/*
 * A stream_state records the state specific to a given variety of stream.
 * The buffer processing function of a stream maintains this state.
 */
typedef struct stream_state_s stream_state;

/*
 * A stream_template provides the information needed to create a stream.
 * The client must fill in any needed setup parameters in the appropriate
 * variety of stream_state, and then call the initialization function
 * provided by the template.  See strimpl.h for more information about
 * stream_templates.
 */
typedef struct stream_template_s stream_template;

/*
 * The stream package works with bytes, not chars.
 * This is to ensure unsigned representation on all systems.
 * A stream currently can only be read or written, not both.
 * Note also that the read procedure returns an int, not a char or a unsigned char;
 * we use negative values to indicate exceptional conditions.
 * (We cast these values to int explicitly, because some compilers
 * don't do this if the other arm of a conditional is a unsigned char.)
 */
/* End of data */
#define PTSFAX_EOFC ((int)(-1))
/* Error */
#define PTSFAX_ERRC ((int)(-2))
/* Interrupt */
/* #define INTC ((int)(-3)) */
/****** INTC IS NOT USED YET ******/
/* Callout */
/* #define CALLC ((int)(-4)) */
#define max_stream_exception 4
/* The following hack is needed for initializing scan_char_array in iscan.c. */
#define stream_exception_repeat(x) x, x, x, x

/*
 * Define cursors for reading from or writing into a buffer.
 * We lay them out this way so that we can alias
 * the write pointer and the read limit.
 */
typedef struct stream_cursor_read_s {
    const unsigned char *ptr;
    const unsigned char *limit;
    unsigned char *_skip;
} stream_cursor_read;
typedef struct stream_cursor_write_s {
    const unsigned char *_skip;
    unsigned char *ptr;
    unsigned char *limit;
} stream_cursor_write;
typedef union stream_cursor_s {
    stream_cursor_read r;
    stream_cursor_write w;
} stream_cursor;

/*
 * Define the prototype for the procedures known to both the generic
 * stream code and the stream implementations.
 */

/* Initialize the stream state (after the client parameters are set). */
#define stream_proc_init(proc)\
  int proc _((stream_state *))

/* Process a buffer.  See strimpl.h for details. */
#define stream_proc_process(proc)\
  int proc _((stream_state *, stream_cursor_read *,\
    stream_cursor_write *, bool))

/* Release the stream state when closing. */
#define stream_proc_release(proc)\
  void proc _((stream_state *))

/* Initialize the client parameters to default values. */
#define stream_proc_set_defaults(proc)\
  void proc _((stream_state *))

/* Reinitialize any internal stream state.  Note that this does not */
/* affect buffered data.  We declare this as returning an int so that */
/* it can be the same as the init procedure; however, reinit cannot fail. */
#define stream_proc_reinit(proc)\
  int proc _((stream_state *))

/* Report an error.  Note that this procedure is stored in the state, */
/* not in the main stream structure. */
#define stream_proc_report_error(proc)\
  int proc _((stream_state *, const char *))
stream_proc_report_error(s_no_report_error);

/*
 * Some types of streams have the ability to read their parameters from
 * a parameter list, and to write all (or only the non-default)
 * parameters to a parameter list.  Since these are not virtual
 * procedures for the stream (they operate on stream_state structures
 * even if no actual stream has been created), we name them differently.
 */
#define stream_state_proc_get_params(proc, state_type)\
  int proc _((gs_param_list *plist, const state_type *ss, bool all))
#define stream_state_proc_put_params(proc, state_type)\
  int proc _((gs_param_list *plist, state_type *ss))

/*
 * Define a generic stream state.  If a processing procedure has no
 * state of its own, it can use stream_state; otherwise, it must
 * create a "subclass".  There is a hack in stream.h to allow the stream
 * itself to serve as the "state" of a couple of heavily used stream types.
 *
 * In order to simplify the structure descriptors for concrete streams,
 * we require that the generic stream state not contain any pointers
 * to garbage-collectable storage.
 */
#define STREAM_MAX_ERROR_STRING 79
#define stream_state_common\
	const stream_template *template_; /**** pts C++ */\
	gssss_memset_t memset_;\
	gssss_xalloc_t xalloc_;\
	gssss_free_t   free_;\
	gssss_memcpy_t memcpy_;\
	/* gs_memory_t *memory; */ /**** pts ****/ \
	stream_proc_report_error((*report_error));\
        int min_left; /* required bytes for lookahead */ \
	char error_string[STREAM_MAX_ERROR_STRING + 1]
struct stream_state_s {
    stream_state_common;
};

/* extern_st(st_stream_state); */ /**** pts ****/
#define public_st_stream_state() /* in stream.c */\
  gs_public_st_simple(st_stream_state, stream_state, "stream_state")

/**** pts ****/
/* original strimpl.h coming */
/*$Id: pts_fax.h,v 1.4 2005/07/20 21:15:08 pts Exp $ */
/* Definitions for stream implementors */
/* Requires stdio.h */

/*
 * The 'process' procedure does the real work of the stream.
 * It must process as much input information (from pr->ptr + 1 through
 * pr->limit) as it can, subject to space available for output
 * (pw->ptr + 1 through pw->limit), updating pr->ptr and pw->ptr.
 *
 * The procedure return value must be one of:
 *      PTSFAX_EOFC - an end-of-data pattern was detected in the input,
 *        or no more input can be processed for some other reason (e.g.,
 *        the stream was told only to read a certain amount of data).
 *      PTSFAX_ERRC - a syntactic error was detected in the input.
 *      0 - more input data is needed.
 *      1 - more output space is needed.
 * If the procedure returns PTSFAX_EOFC, it can assume it will never be called
 * again for that stream.
 *
 * If the procedure is called with last = 1, this is an indication that
 * no more input will ever be supplied (after the input in the current
 * buffer defined by *pr); the procedure should produce as much output
 * as possible, including an end-of-data marker if applicable.  In this
 * case:
 *      - If the procedure returns 1, it may be called again (also with
 *        last = 1).
 *      - If the procedure returns any other value other than 1, the
 *        procedure will never be called again for that stream.
 *      - If the procedure returns 0, this is taken as equivalent to
 *        returning PTSFAX_EOFC.
 *      - If the procedure returns PTSFAX_EOFC (or 0), the stream's end_status
 *        is set to PTSFAX_EOFC, meaning no more writing is allowed.
 *
 * Note that these specifications do not distinguish input from output
 * streams.  This is deliberate: The processing procedures should work
 * regardless of which way they are oriented in a stream pipeline.
 * (The PostScript language does take a position as whether any given
 * filter may be used for input or output, but this occurs at a higher level.)
 *
 * The value returned by the process procedure of a stream whose data source
 * or sink is external (i.e., not another stream) is interpreted slightly
 * differently.  For an external data source, a return value of 0 means
 * "no more input data are available now, but more might become available
 * later."  For an external data sink, a return value of 1 means "there is
 * no more room for output data now, but there might be room later."
 *
 * It appears that the Adobe specifications, read correctly, require that when
 * the process procedure of a decoding filter has filled up the output
 * buffer, it must still peek ahead in the input to determine whether or not
 * the next thing in the input stream is EOD.  If the next thing is an EOD (or
 * end-of-data, indicated by running out of input data with last = true), the
 * process procedure must return PTSFAX_EOFC; if the next thing is definitely not
 * an EOD, the process procedure must return 1 (output full) (without, of
 * course, consuming the non-EOD datum); if the procedure cannot determine
 * whether or not the next thing is an EOD, it must return 0 (need more input).
 * Decoding filters that don't have EOD (for example, NullDecode) can use
 * a simpler algorithm: if the output buffer is full, then if there is more
 * input, return 1, otherwise return 0 (which is taken as PTSFAX_EOFC if last
 * is true).  All this may seem a little awkward, but it is needed in order
 * to have consistent behavior regardless of where buffer boundaries fall --
 * in particular, if a buffer boundary falls just before an EOD.  It is
 * actually quite easy to implement if the main loop of the process
 * procedure tests for running out of input rather than for filling the
 * output: with this structure, exhausting the input always returns 0,
 * and discovering that the output buffer is full when attempting to store
 * more output always returns 1.
 *
 * Even this algorithm for handling end-of-buffer is not sufficient if an
 * EOD falls just after a buffer boundary, but the generic stream code
 * handles this case: the process procedures need only do what was just
 * described.
 */

/*
 * The set_defaults procedure in the template has a dual purpose: it sets
 * default values for all parameters that the client can set before calling
 * the init procedure, and it also must initialize all pointers in the
 * stream state to a value that will be valid for the garbage collector
 * (normally 0).  The latter implies that:
 *
 *	Any stream whose state includes additional pointers (beyond those
 *	in stream_state_common) must have a set_defaults procedure.
 */

/*
 * Note that all decoding filters that require an explicit EOD in the
 * source data must have an init procedure that sets min_left = 1.
 * This effectively provides a 1-unsigned char lookahead in the source data,
 * which is required so that the stream can close itself "after reading
 * the last unsigned char of data" (per Adobe specification), as noted above.
 */

/*
 * Define a template for creating a stream.
 *
 * The meaning of min_in_size and min_out_size is the following:
 * If the amount of input information is at least min_in_size,
 * and the available output space is at least min_out_size,
 * the process procedure guarantees that it will make some progress.
 * (It may make progress even if this condition is not met, but this is
 * not guaranteed.)
 */
struct stream_template_s {

    /* Define the structure type for the stream state. */
    /* gs_memory_type_ptr_t stype; */ /**** pts ****/

    /* Define an optional initialization procedure. */
    stream_proc_init((*init));

    /* Define the processing procedure. */
    /* (The init procedure can reset other procs if it wants.) */
    stream_proc_process((*process));

    /* Define the minimum buffer sizes. */
    unsigned int min_in_size;		/* minimum size for process input */
    unsigned int min_out_size;		/* minimum size for process output */

    /* Define an optional releasing procedure. */
    stream_proc_release((*release));

    /* Define an optional parameter defaulting and pointer initialization */
    /* procedure. */
    stream_proc_set_defaults((*set_defaults));

    /* Define an optional reinitialization procedure. */
    stream_proc_reinit((*reinit));

};


#if 0
/* Hex decoding utility procedure */
typedef enum {
    hex_ignore_garbage = 0,
    hex_ignore_whitespace = 1,
    hex_ignore_leading_whitespace = 2
} hex_syntax;
int s_hex_process _((stream_cursor_read *, stream_cursor_write *, int *, hex_syntax));	/* in sstring.c */
#endif
/* end of former strimpl.h */
/* #endif */ /* scommon_INCLUDED */
/* end of former scommon.h */



/* ------ Common state ------ */

/*
 * Define the common stream state for Huffman-coded filters.
 * Invariants when writing:
 *      0 <= bits_left <= hc_bits_size;
 *      Only the leftmost (hc_bits_size - bits_left) bits of bits
 *        contain valid data.
 */
#define stream_hc_state_common\
	stream_state_common;\
		/* The client sets the following before initialization. */\
	bool FirstBitLowOrder;\
		/* The following are updated dynamically. */\
	unsigned int bits;		/* most recent bits of input or */\
				/* current bits of output */\
	int bits_left		/* # of valid low bits (input) or */\
				/* unused low bits (output) in above, */\
				/* 0 <= bits_left <= 7 */
typedef struct stream_hc_state_s {
    stream_hc_state_common;
} stream_hc_state;

/* Common state */
#define stream_CF_state_common\
	stream_hc_state_common;\
		/* The client sets the following before initialization. */\
	bool Uncompressed;\
	int K;\
	bool EndOfLine;\
	bool EncodedByteAlign;\
	int Columns;\
	int Rows;\
	bool EndOfBlock;\
	bool BlackIs1;\
	int DamagedRowsBeforeError;	/* (Decode only) */\
	/*bool FirstBitLowOrder;*/	/* in stream_hc_state_common */\
	int DecodedByteAlign;\
		/* The init procedure sets the following. */\
	unsigned int raster;\
	unsigned char *lbuf;		/* current scan line buffer */\
				/* (only if decoding or 2-D encoding) */\
	unsigned char *lprev;		/* previous scan line buffer (only if 2-D) */\
		/* The following are updated dynamically. */\
	int k_left		/* number of next rows to encode in 2-D */\
				/* (only if K > 0) */
typedef struct stream_CF_state_s {
    stream_CF_state_common;
} stream_CF_state;

/* Define common default parameter setting. */
#define s_CF_set_defaults_inline(ss)\
  ((ss)->Uncompressed = false,\
   (ss)->K = 0,\
   (ss)->EndOfLine = false,\
   (ss)->EncodedByteAlign = false,\
   (ss)->Columns = 1728,\
   (ss)->Rows = 0,\
   (ss)->EndOfBlock = true,\
   (ss)->BlackIs1 = false,\
		/* Added by Adobe since the Red Book */\
   (ss)->DamagedRowsBeforeError = 0, /* always set, for s_CF_get_params */\
   (ss)->FirstBitLowOrder = false,\
		/* Added by us */\
   (ss)->DecodedByteAlign = 1,\
	/* Clear pointers */\
   (ss)->lbuf = 0, (ss)->lprev = 0)

/* CCITTFaxEncode */
typedef struct stream_CFE_state_s {
    stream_CF_state_common;
    /* The init procedure sets the following. */
    int max_code_bytes;		/* max # of bytes for an encoded line */
    unsigned char *lcode;		/* buffer for encoded output line */
    /* The following change dynamically. */
    int read_count;		/* # of bytes to copy into lbuf */
    int write_count;		/* # of bytes to copy out of lcode */
    int code_bytes;		/* # of occupied bytes in lcode */
} stream_CFE_state;

#define private_st_CFE_state()	/* in scfe.c */\
  gs_private_st_ptrs3(st_CFE_state, stream_CFE_state, "CCITTFaxEncode state",\
    cfe_enum_ptrs, cfe_reloc_ptrs, lbuf, lprev, lcode)
#define s_CFE_set_defaults_inline(ss)\
  (s_CF_set_defaults_inline(ss), (ss)->lcode = 0)
#if USE_BUILTIN_FAXE
/**** pts ****/
#if SIZEOF_INT > 2
#  define cfe_max_width (2560 * 32000 * 2 / 3)
#else
#  define cfe_max_width ((int)((unsigned)-1/2 - 40))	/* avoid overflows */
#endif
#ifdef __cplusplus
extern "C"
#else
extern
#endif
const stream_template s_CFE_template;
#endif

/* CCITTFaxDecode */
typedef struct stream_CFD_state_s {
    stream_CF_state_common;
    int cbit;			/* bits left to fill in current decoded */
    /* unsigned char at lbuf[wpos] (0..7) */
    int rows_left;		/* number of rows left */
    int rpos;			/* rptr for copying lbuf to client */
    int wpos;			/* rlimit/wptr for filling lbuf or */
    /* copying to client */
    int eol_count;		/* number of EOLs seen so far */
    unsigned char invert;		/* current value of 'white' */
    /* for 2-D decoding */
    int run_color;		/* -1 if processing white run, */
    /* 0 if between runs but white is next, */
    /* 1 if between runs and black is next, */
    /* 2 if processing black run */
    int damaged_rows;		/* # of consecutive damaged rows preceding */
    /* the current row */
    bool skipping_damage;	/* true if skipping a damaged row looking */
    /* for EOL */
    /* The following are not used yet. */
    int uncomp_run;		/* non-0 iff we are in an uncompressed */
    /* run straddling a scan line (-1 if white, */
    /* 1 if black) */
    int uncomp_left;		/* # of bits left in the run */
    int uncomp_exit;		/* non-0 iff this is an exit run */
    /* (-1 if next run white, 1 if black) */
} stream_CFD_state;

#define private_st_CFD_state()	/* in scfd.c */\
  gs_private_st_ptrs2(st_CFD_state, stream_CFD_state, "CCITTFaxDecode state",\
    cfd_enum_ptrs, cfd_reloc_ptrs, lbuf, lprev)
#define s_CFD_set_defaults_inline(ss)\
  s_CF_set_defaults_inline(ss)
#if USE_BUILTIN_FAXD
extern const stream_template s_CFD_template;
#endif

#endif /* pts_fax.h */