1 /* using GS DLL as a ps colorpage separator.
2         Carsten Hammer Oc�-Deutschland GmbH
3         Hammer.Carsten@oce.de			*/
4 
5 #ifdef _Windows
6 /* Compile with:
7  * cl -D_Windows -Isrc -Febin\pscolor.exe test.c lex.yy.c bin\gsdll32.lib
8  */
9 #include <windows.h>
10 #define GSDLLEXPORT __declspec(dllimport)
11 #endif
12 
13 #include <stdio.h>
14 #include <malloc.h>
15 
16 #include "stdpre.h"
17 #include "iapi.h"    /* Ghostscript interpreter public interface */
18 #include "gdevdsp.h"
19 #include "string_.h"
20 #include "ierrors.h"
21 #include "gscdefs.h"
22 #include "gstypes.h"
23 #include "iref.h"
24 #include "iminst.h"
25 #include "imain.h"
26 
27 #include "gsdll.h"   /* old DLL public interface */
28 
29 unsigned char *myimage;
30 int breite,hoehe,seite=0,myraster;
31 FILE *color_fd,*black_fd,*temp_fd,*choose;
32 FILE *read_fd;
33 
34 //#define DISPLAY_DEBUG
35 
36 int yylex(char *buf,int *mylen);
37 
38 /* stdio functions */
39 static int GSDLLCALL
gsdll_stdin(void * instance,char * buf,int len)40 gsdll_stdin(void *instance, char *buf, int len)
41 {
42     int c;
43     int count = 0;
44     char *init=buf;
45     int eof;
46     int hlen=len;
47     eof=yylex(buf,&hlen);
48 //    fprintf(stderr, "eof %d\n",eof);
49     if(eof==1001){
50     fprintf(color_fd,"%s",buf);
51     fflush(color_fd);
52     fprintf(black_fd,"%s",buf);
53     fflush(black_fd);
54     return (strlen(buf));
55     } else if(eof==1000){
56     fprintf(temp_fd,"%s",buf);
57         fflush(temp_fd);
58         fclose(temp_fd);
59         read_fd=fopen("temp.ps","rb");
60 //    fprintf(stderr, "Seitenende %d %d %s\n",hlen,strlen(buf),buf);
61         while( (c=fgetc(read_fd)) != EOF)
62         {
63                 fputc(c,choose);
64         }
65  //   fprintf(stderr, "Seitenende ende %d %d %s\n",hlen,strlen(buf),buf);
66         fflush(choose);
67         fclose(read_fd);
68         temp_fd=fopen("temp.ps","wb");
69     return (strlen(buf));
70     } else if(eof!=0){
71 //    fprintf(stderr, "Mittendrin %s\n",buf);
72     fprintf(temp_fd,"%s",buf);
73     fflush(temp_fd);
74     return (strlen(buf));
75     } else {
76     fprintf(stderr, "Dateiende\n");
77         read_fd=fopen("temp.ps","rb");
78         while( (c=fgetc(read_fd)) != EOF)
79         {
80                 fputc(c,choose);
81         }
82         fflush(choose);
83         fclose(read_fd);
84         fclose(temp_fd);
85         temp_fd=fopen("temp.ps","wb");
86     return 0;
87         }
88 }
89 #if 0
90 static int GSDLLCALL
91 gsdll_stdin(void *instance, char *buf, int len)
92 {
93     int ch;
94     int count = 0;
95         size_t back;
96     char *init=buf;
97     while (count < len) {
98         ch = fgetc(stdin);
99         if (ch == EOF){
100 #ifdef DISPLAY_DEBUG
101     fprintf(stderr, "lese %s\n",buf);
102 #endif
103         fwrite(init,1,count,temp_fd);
104         fflush(temp_fd);
105             return 0;
106         }
107         *buf++ = ch;
108         count++;
109         if (ch == '\n')
110             break;
111     }
112 #ifdef DISPLAY_DEBUG
113     fprintf(stderr, "lese %s\n",buf);
114 #endif
115         fwrite(init,1,count,temp_fd);
116         fflush(temp_fd);
117     return count;
118 }
119 #endif
120 
121 static int GSDLLCALL
gsdll_stdout(void * instance,const char * str,int len)122 gsdll_stdout(void *instance, const char *str, int len)
123 {
124     fwrite(str, 1, len, stdout);
125     fflush(stdout);
126     return len;
127 }
128 
129 static int GSDLLCALL
gsdll_stderr(void * instance,const char * str,int len)130 gsdll_stderr(void *instance, const char *str, int len)
131 {
132     fwrite(str, 1, len, stderr);
133     fflush(stderr);
134     return len;
135 }
136 
137 /* New device has been opened */
138 /* This is the first event from this device. */
display_open(void * handle,void * device)139 static int display_open(void *handle, void *device)
140 {
141 #ifdef DISPLAY_DEBUG
142     char buf[256];
143     sprintf(buf, "display_open(0x%x, 0x%x)\n", handle, device);
144     fprintf(stderr, buf);
145 #endif
146     return 0;
147 }
148 
149 /* Device is about to be closed. */
150 /* Device will not be closed until this function returns. */
display_preclose(void * handle,void * device)151 static int display_preclose(void *handle, void *device)
152 {
153 #ifdef DISPLAY_DEBUG
154     char buf[256];
155     sprintf(buf, "display_preclose(0x%x, 0x%x)\n", handle, device);
156     fprintf(stderr, buf);
157 #endif
158     /* do nothing - no thread synchonisation needed */
159     return 0;
160 }
161 
162 /* Device has been closed. */
163 /* This is the last event from this device. */
display_close(void * handle,void * device)164 static int display_close(void *handle, void *device)
165 {
166 #ifdef DISPLAY_DEBUG
167     char buf[256];
168     sprintf(buf, "display_close(0x%x, 0x%x)\n", handle, device);
169     fprintf(stderr, buf);
170 #endif
171     return 0;
172 }
173 
174 /* Device is about to be resized. */
175 /* Resize will only occur if this function returns 0. */
display_presize(void * handle,void * device,int width,int height,int raster,unsigned int format)176 static int display_presize(void *handle, void *device, int width, int height,
177         int raster, unsigned int format)
178 {
179 #ifdef DISPLAY_DEBUG
180     char buf[256];
181     sprintf(buf, "display_presize(0x%x, 0x%x, width=%d height=%d raster=%d\n\
182   format=%d)\n",
183        handle, device, width, height, raster, format);
184     fprintf(stderr, buf);
185 #endif
186     return 0;
187 }
188 
189 /* Device has been resized. */
190 /* New pointer to raster returned in pimage */
display_size(void * handle,void * device,int width,int height,int raster,unsigned int format,unsigned char * pimage)191 static int display_size(void *handle, void *device, int width, int height,
192         int raster, unsigned int format, unsigned char *pimage)
193 {
194 
195 #ifdef DISPLAY_DEBUG
196     char buf[256];
197     sprintf(buf, "display_size(0x%x, 0x%x, width=%d height=%d raster=%d\n\
198   format=%d image=0x%x)\n",
199        handle, device, width, height, raster, format, pimage);
200     fprintf(stderr, buf);
201 #endif
202         myimage=pimage;
203         breite=width;
204         hoehe=height;
205         myraster=raster;
206            return 0;
207 }
208 
209 /* flushpage */
display_sync(void * handle,void * device)210 static int display_sync(void *handle, void *device)
211 {
212 
213 #ifdef DISPLAY_DEBUG
214     char buf[256];
215     sprintf(buf, "display_sync(0x%x, 0x%x)\n", handle, device);
216     fprintf(stderr, buf);
217 #endif
218 
219     return 0;
220 }
221 
222 /* showpage */
223 /* If you want to pause on showpage, then don't return immediately */
display_page(void * handle,void * device,int copies,int flush)224 static int display_page(void *handle, void *device, int copies, int flush)
225 {
226         int i,t,color=0;
227 #ifdef DISPLAY_DEBUG
228     char buf[256];
229     sprintf(buf, "display_page(0x%x, 0x%x, copies=%d flush=%d)\n",
230         handle, device, copies, flush);
231     fprintf(stderr, buf);
232 #endif
233         seite++;
234         for(i=hoehe-1;i>=0;i=i-1){
235                 for(t=breite-1;t>=0;t=t-1){
236                         if((myimage[i*myraster+t*3+0]!=myimage[i*myraster+t*3+1])||(myimage[i*myraster+t*3+1]!=myimage[i*myraster+t*3+2])){
237                                 color=1;
238                                 fprintf(stderr,"Ungleich %d,%d %x,%x,%x\n",i,t,myimage[i*myraster+t*3+0],myimage[i*myraster+t*3+1],myimage[i*myraster+t*3+2]);
239                                 goto out;
240                         }
241                 }
242         }
243 out:
244         if(color){
245         fprintf(stderr,"[%d]Color\n",seite);
246         choose=color_fd;
247         } else {
248         fprintf(stderr,"[%d]Grey\n",seite);
249         choose=black_fd;
250         }
251 /*
252         read_fd=fopen("temp.ps","rb");
253         while( (c=fgetc(read_fd)) != EOF)
254         {
255                 fputc(c,choose);
256         }
257         fflush(choose);
258         fclose(read_fd);
259         fclose(temp_fd);
260         temp_fd=fopen("temp.ps","wb");
261 */
262     return 0;
263 }
264 
265 /* Poll the caller for cooperative multitasking. */
266 /* If this function is NULL, polling is not needed */
display_update(void * handle,void * device,int x,int y,int w,int h)267 static int display_update(void *handle, void *device,
268     int x, int y, int w, int h)
269 {
270     return 0;
271 }
272 
273 display_callback display = {
274     sizeof(display_callback),
275     DISPLAY_VERSION_MAJOR,
276     DISPLAY_VERSION_MINOR,
277     display_open,
278     display_preclose,
279     display_close,
280     display_presize,
281     display_size,
282     display_sync,
283     display_page,
284     display_update,
285     NULL,	/* memalloc */
286     NULL	/* memfree */
287 };
288 
289 static gs_main_instance *minst;
290 const char start_string[] = "systemdict /start get exec\n";
291 
main(int argc,char * argv[])292 int main(int argc, char *argv[])
293 {
294     int code;
295     const char * gsargv[12];
296     char arg[64];
297     int gsargc;
298     gsargv[0] = "ps2colordetect";	/* actual value doesn't matter */
299     gsargv[1] = "-dNOPAUSE";
300     gsargv[2] = "-dBATCH";
301     gsargv[3] = "-dSAFER";
302 //    gsargv[4] = "-sDEVICE=pdfwrite";
303     gsargv[4] = "-sDEVICE=display";
304     gsargv[5] = "-dDisplayHandle=0";
305     sprintf(arg,"-dDisplayFormat=%d",DISPLAY_COLORS_RGB|DISPLAY_ALPHA_NONE|DISPLAY_DEPTH_8|DISPLAY_LITTLEENDIAN|DISPLAY_BOTTOMFIRST);
306     gsargv[6] = arg;
307     gsargv[7] = "-sOutputFile=out.pdf";
308     gsargv[8] = "-c";
309     gsargv[9] = ".setpdfwrite";
310     gsargv[10] = "-f";
311 //    gsargv[11] = "input.ps";
312     gsargv[11] = "-";
313     gsargc=12;
314 
315     code = gsapi_new_instance(&minst, NULL);
316     if (code < 0)
317         return 1;
318     gsapi_set_stdio(minst, gsdll_stdin, gsdll_stdout, gsdll_stderr);
319     gsapi_set_display_callback(minst, &display);
320 
321         color_fd=fopen("color.ps","wb");
322         black_fd=fopen("black.ps","wb");
323         temp_fd=fopen("temp.ps","wb");
324         choose=black_fd;
325 
326     code = gsapi_init_with_args(minst, gsargc, gsargv);
327     gsapi_exit(minst);
328 
329     gsapi_delete_instance(minst);
330 
331         fclose(color_fd);
332         fclose(black_fd);
333         fclose(temp_fd);
334 
335     if ((code == 0) || (code == e_Quit))
336         return 0;
337     return 1;
338 }
339