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