1 /*
2  * testfax_main.c -- CCITTFax(En|De)code usage sample
3  * by pts@fazekas.hu at Sat Jul  6 20:03:35 CEST 2002
4  * Sun Jul  7 22:25:55 CEST 2002
5  *
6  * Note that this sample is incomplete since the parameters (such as /K)
7  * cannot be set from the command line.
8  */
9 
10 #include "pts_fax.h"
11 #include <stdlib.h>
12 #include <string.h>
13 #include <stdio.h>
14 #include <assert.h>
15 
16 #ifdef __GNUC__
17 #ifndef __clang__
18 #pragma implementation
19 #endif
20 #endif
21 
22 #if OBJDEP
23 #  warning PROVIDES: testfax_main
24 #endif
25 
gsfax_xalloc(unsigned n)26 static void* gsfax_xalloc(unsigned n) {
27   void *ret;
28   if ((ret=malloc(n))==0) abort();
29   return ret;
30 }
gsfax_free(void * ptr)31 static void gsfax_free(void *ptr) {
32   free(ptr);
33 }
gsfax_memset(void * s,int c,unsigned n)34 static void gsfax_memset(void *s, int c, unsigned n) {
35   /*return*/ memset(s,c,n);
36 }
gsfax_memcpy(void * dest,const void * src,unsigned n)37 static void gsfax_memcpy(void *dest, const void *src, unsigned n) {
38   /*return*/ memcpy(dest, src, n);
39 }
40 
41 
42 
43 #if 0
44 CCITTFaxEncode:
45 
46 bool Uncompressed=false;
47 int  K=0;
48 bool EndOfLine=false;
49 bool EncodedByteAlign=false;
50 int  Columns=1728;
51 int  Rows=0; // Decode only
52 bool EndOfBlock=true;
53 bool BlackIs1=false;
54 int  DamagedRowsBeforeError=0; // Decode only
55 bool FirstBitLowOrder=false; // GS only
56 int  DecodedByteAlign=1; // GS only
57 bool CloseSource;
58 bool CloseTarget;
59 #endif
60 
61 /* GS expected
62  * min_left=0
63  * bits_left=32
64  *
65  */
66 
work(FILE * f,stream_template const * template_,stream_state * state)67 static void work(FILE *f, stream_template const*template_, stream_state *state) {
68   unsigned got, pog;
69   stream_cursor_read r;
70   stream_cursor_write w;
71   unsigned char rbuf[4096], wbuf[1000], *hard, *rlimit;
72   bool last;
73 
74   #if __CHECKER__
75     memset(&r, 0, sizeof(r));
76     memset(&w, 0, sizeof(w));
77   #endif
78 
79   template_->init(state);
80 
81   r.ptr=rlimit=rbuf-1;
82   hard=rbuf+sizeof(rbuf)-1;
83   assert(hard-r.ptr>=(int)template_->min_in_size);
84   last=false;
85 
86 
87   while (1) {
88     assert(r.ptr==rbuf-1);
89     if (last==false) {
90       if (0==(got=fread(rlimit+1, 1, hard-rlimit, f))) last=true;
91       rlimit+=got;
92     }
93     /* if (r.ptr==rlimit) break; */
94     w.ptr=wbuf-1;
95     w.limit=wbuf+sizeof(wbuf)-1;
96     assert(w.limit-w.ptr>=(int)template_->min_out_size);
97     r.limit=rlimit;
98     pog=template_->process(state, &r, &w, last);
99     fprintf(stderr, "pog=%d write=%d last=%d\n", pog, w.ptr-(wbuf-1), last);
100     if ((int)pog==PTSFAX_ERRC) {
101       fprintf(stderr, "syntax error!\n");
102       abort();
103     }
104     /* assert(last || r.ptr>=rbuf); */
105     fwrite(wbuf, 1, w.ptr-(wbuf-1), stdout);
106     if (last && (pog==0 || (int)pog==PTSFAX_EOFC)) break;
107     if (r.ptr!=rbuf-1) {
108       fprintf(stderr, "limit=%d\n", rlimit-r.ptr);
109       memmove(rbuf, r.ptr+1, rlimit-r.ptr);
110       rlimit=rbuf-1+(rlimit-r.ptr);
111       r.ptr=rbuf-1;
112     }
113   }
114 
115   template_->release(state);
116 }
117 
main(int argc,char ** argv)118 int main(int argc, char **argv) {
119   FILE *f;
120 
121   (void)argc;
122   (void)argv;
123 /*
124 -* Define a limit on the Rows parameter, close to max_int. *-
125 #define cf_max_height 32000
126     if (code >= 0 &&
127 	(state.K < -cf_max_height || state.K > cf_max_height ||
128 	 state.Columns < 0 || state.Columns > cfe_max_width ||
129 	 state.Rows < 0 || state.Rows > cf_max_height ||
130 	 state.DamagedRowsBeforeError < 0 ||
131 	 state.DamagedRowsBeforeError > cf_max_height ||
132 	 state.DecodedByteAlign < 1 || state.DecodedByteAlign > 16 ||
133 	 (state.DecodedByteAlign & (state.DecodedByteAlign - 1)) != 0)
134 	)
135 */
136 
137   f=stdin;
138   /* f=fopen("stdpre.x","rb"); */
139   /* f=fopen("216","rb"); */
140   assert(f!=0);
141 
142   if (0) {
143   #if USE_BUILTIN_FAXE
144   #if OBJDEP
145   #  warning REQUIRES: pts_faxe
146   #endif
147   } else if (argc==2 && 0==strcmp(argv[1], "encode")) {
148     stream_CFE_state sCFEs;
149     sCFEs.memset_=gsfax_memset;
150     sCFEs.xalloc_=gsfax_xalloc;
151     sCFEs.free_=gsfax_free;
152     sCFEs.memcpy_=gsfax_memcpy;
153     s_CFE_template.set_defaults((stream_state*)&sCFEs);
154     /* sCFEs.K=-1; ... */
155     work(f, (stream_template const*)&s_CFE_template, (stream_state*)&sCFEs);
156   #endif
157   #if USE_BUILTIN_FAXD
158   #if OBJDEP
159   #  warning REQUIRES: pts_faxd
160   #endif
161   } else if (argc==2 && 0==strcmp(argv[1], "decode")) {
162     stream_CFD_state sCFDs;
163     sCFDs.memset_=gsfax_memset;
164     sCFDs.xalloc_=gsfax_xalloc;
165     sCFDs.free_=gsfax_free;
166     sCFDs.memcpy_=gsfax_memcpy;
167     s_CFD_template.set_defaults((stream_state*)&sCFDs);
168     /* sCFEs.K=-1; ... */
169     work(f, (stream_template const*)&s_CFD_template, (stream_state*)&sCFDs);
170   #endif
171   } else {
172     fprintf(stderr, "Usage: %s encode|decode <INFILE >OUTFILE\n", argv[0]);
173     return 2;
174   }
175   fclose(f);
176 
177   return 0;
178 }
179