"Fossies" - the Fresh Open Source Software Archive 
Member "fly-2.0.1/fly.c" (17 Jun 2009, 42143 Bytes) of package /linux/www/old/fly-2.0.1.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
1 /*******************************************************************************
2 ** fly: On-the-fly image creation utility
3 ** Martin Gleeson, martin@gleeson.com
4 ** Copyright (c), Martin Gleeson and The University of Melbourne, 1994-2001
5 ** Created: 9 December 1994
6 ** Last Update: 28th February 2001
7 **
8 ** Uses the gd library by Thomas Boutell, boutell@boutell.com
9 ** gd: Copyright 1994-1999, Quest Protein Database Centre,
10 ** Cold Spring Harbour Labs
11 **
12 ** Contributions from:
13 ** Philip Warner
14 ** patches to gd to retain support for GIF images
15 ** Claus Hofmann <claush@ipfr.bau-verm.uni-karlsruhe.de>
16 ** addition of 'transparent' directive.
17 ** addtion of code to check if colour already allocated
18 ** addition of feature to copy whole image if all coords are -1
19 ** John Bowe <bowe@osf.org>
20 ** addition of better argument parsing
21 ** Ian Reid <ian@robots.ox.ac.uk>
22 ** addition of reading existing image file from external program output
23 ** fix for line number calculations
24 ** Shoji Mori <mori@moriken.com>
25 ** fix for win32 binmode weirdness
26 ** Anatoly A. Orehovsky <tolik@mpeks.tomsk.su>
27 ** fix for garbage input files
28 **
29 *******************************************************************************/
30
31 /******************************************************************************
32 ** Defines
33 ******************************************************************************/
34
35 /* Uncomment the following line if your operating system doesn't support fork */
36 /* #define NO_FORK 1 */
37
38 #define NAMESIZE 1256
39
40 /******************************************************************************
41 ** Included Header Files
42 ******************************************************************************/
43
44 #include "gd.h"
45 #include "gdfonts.h"
46 #include "gdfontl.h"
47 #include "gdfontmb.h"
48 #include "gdfontt.h"
49 #include "gdfontg.h"
50 #include "fly.h"
51 #include <stdio.h>
52 #include <stdlib.h>
53 #include <errno.h>
54 #include <string.h>
55 #include <unistd.h>
56
57 #ifdef WIN32
58 #include <fcntl.h>
59 #include <io.h>
60 #endif
61
62 /******************************************************************************
63 ** Strings for usage and quick reference
64 ******************************************************************************/
65
66 char *version = "2.0.1";
67 char *usage = "Usage : fly [-h] [-q] [-i inputfile] [-o outputfile]";
68
69 char *help = "See <http://martin.gleeson.net/fly/> for documentation.\n\
70 \n\
71 Quick Reference to Directives: \n\
72 \n\
73 new\n\
74 size x,y\n\
75 name filename\n\
76 \n\
77 line x1,y1,x2,y2,R,G,B dline x1,y1,x2,y2,R,G,B \n\
78 rect x1,y1,x2,y2,R,G,B frect x1,y1,x2,y2,R,G,B \n\
79 square x,y,s,R,G,B fsquare x,y,s,R,G,B \n\
80 poly R,G,B,x1,y1...,xn,yn fpoly R,G,B,x1,y1...,xn,yn \n\
81 fill x,y,R,G,B filltoborder x,y,R1,G1,B1,R2,B2,G2 \n\
82 arc x1,y1,w,h,start,finish,R,G,B \n\
83 ellipse x1,y1,w,h,R,G,B \n\
84 circle x,y,d,R,G,B fcircle x,y,d,R,G,B \n\
85 \n\
86 string R,G,B,x,y,<size>,<string> \n\
87 stringup R,G,B,x,y,<size>,<string> \n\
88 (size = tiny, small, medium, large or giant) \n\
89 \n\
90 copy x,y,x1,y1,x2,y2,filename \n\
91 copyresized x1,y1,x2,y2,dx1,dy1,dx2,dy2,filename \n\
92 \n\
93 setpixel x,y,R,G,B \n\
94 getpixel x,y \n\
95 colourchange R1,G1,B1,R2,G2,B2 \n\
96 transparent R,G,B \n\
97 interlace \n\
98 \n\
99 setbrush filename killbrush \n\
100 settile filename killtile \n\
101 setstyle R1,G1,B1,R2,G2,B2,...,Rn,Bn,Gn killstyle \n\n\
102 sizex \n\
103 sizey \n\
104 rotate deg \n\
105 \n\
106 type gif|png|jpeg\n\
107 quality n (image quality when type = jpeg. Must be in the range 0-95)\n\
108 \n\
109 end\n";
110
111 /******************************************************************************
112 ** Internal Functions
113 ******************************************************************************/
114
115 int process_args(int argc, char *argv[]);
116 int get_token(FILE *infile);
117 int get_number(FILE *infile);
118 char *get_string(FILE *infile);
119 void sync_input(FILE *infile);
120 int get_colour(FILE *infile, gdImagePtr img);
121 void copy_to_img(FILE *infile, gdImagePtr img, int resize);
122 gdImagePtr get_image(int type, int argc, char *argv[]);
123 void *my_newmem(size_t size);
124 FILE *get_file(int *line_number, char **filename);
125 void swap(int *a, int *b);
126
127 /******************************************************************************
128 ** Global Variables
129 ******************************************************************************/
130
131 int finished = FALSE,
132 done = FALSE,
133 quiet = FALSE,
134 end_of_line = FALSE,
135 written_out = FALSE,
136 type = 0,
137 imgtype = PNG,
138 line_number = 1;
139
140 char *input_file = NULL,
141 *output_file = NULL;
142
143 FILE *outfile;
144 FILE *infile;
145 FILE *brushfile;
146 FILE *tilefile;
147 FILE *verbose_out;
148
149 /******************************************************************************
150 ** Main Program
151 ******************************************************************************/
152
153 int main(int argc, char *argv[]){
154 int colour = 0, colour1 = 0, colour2 = 0, type;
155 int status, size, side, jp_quality = 75;
156 int brush_on = 0, tile_on = 0, style_on = 0;
157 int num_entries, up = 0;
158 int i, n, c, x, y;
159 int size_x, size_y;
160 int arg[4096], style[1024];
161 char *s;
162 gdPoint points[2048];
163 gdImagePtr img = NULL, brush = NULL, tile = NULL, new_img = NULL;
164 gdFontPtr gdFont = gdFontSmall; /* just a default font */
165
166 status = process_args(argc, argv);
167 if (status == FALSE) exit(1);
168
169 START: type = get_token(infile);
170 while(((type == COMMENT) || (type == EMPTY) || (type == (int)NULL))) {
171 sync_input(infile);
172 type = get_token(infile);
173 if(finished == TRUE) goto FINISH;
174 }
175 if(finished == TRUE) goto FINISH;
176 if( type != NEW && type != EXISTING) {
177 fprintf(stderr,"Error: Must use 'new' or 'existing' directive first in input.\n");
178 exit(1);
179 }
180 img=get_image(type, argc, argv);
181
182 /* while more lines to process */
183 do{
184 type = get_token(infile);
185 switch(type){
186
187 case LINE: /* gdImageLine() */
188 for(i=1;i<=4;i++) {
189 arg[i]=get_number(infile);
190 }
191 if (!quiet) fprintf(verbose_out,"## Line ## drawn from %d,%d to %d,%d. (",
192 arg[1],arg[2],arg[3],arg[4]);
193 if( brush_on ) {
194 sync_input(infile);
195 gdImageLine(img,arg[1],arg[2],arg[3],arg[4],gdBrushed);
196 if (!quiet) fprintf(verbose_out,"colour = current brush");
197 } else if ( style_on ) {
198 sync_input(infile);
199 gdImageLine(img,arg[1],arg[2],arg[3],arg[4],gdStyled);
200 if (!quiet) fprintf(verbose_out,"colour = current style");
201 } else {
202 colour=get_colour(infile,img);
203 gdImageLine(img,arg[1],arg[2],arg[3],arg[4],colour);
204 }
205 if (!quiet) fprintf(verbose_out,")\n");
206 break;
207
208
209 case DLINE: /* gdImageDashedLine() */
210 for(i=1;i<=4;i++){
211 arg[i]=get_number(infile);
212 }
213 if (!quiet)
214 fprintf(verbose_out,"## Dashed Line ## drawn from %d,%d to %d,%d. (",
215 arg[1],arg[2],arg[3],arg[4]);
216 if( brush_on ){
217 sync_input(infile);
218 gdImageDashedLine(img,arg[1],arg[2],arg[3],arg[4],gdBrushed);
219 if (!quiet) fprintf(verbose_out,"colour = current brush");
220 } else if ( style_on ) {
221 sync_input(infile);
222 gdImageDashedLine(img,arg[1],arg[2],arg[3],arg[4],gdStyled);
223 if (!quiet) fprintf(verbose_out,"colour = current style");
224 } else{
225 colour=get_colour(infile,img);
226 gdImageDashedLine(img,arg[1],arg[2],arg[3],arg[4],colour);
227 }
228 if (!quiet) fprintf(verbose_out,")\n");
229 break;
230
231 case SQUARE: /* gdImageRectangle() */
232 for(i=1;i<=3;i++){
233 arg[i]=get_number(infile);
234 }
235 side = arg[3];
236 arg[3] = arg[1] + side; arg[4] = arg[2] + side;
237 if (!quiet) fprintf(verbose_out,"## Square ## drawn at %d,%d, side %d (",
238 arg[1],arg[2],side);
239 if( brush_on ){
240 sync_input(infile);
241 gdImageRectangle(img,arg[1],arg[2],arg[3],arg[4],gdBrushed);
242 if (!quiet) fprintf(verbose_out,"colour = current brush");
243 } else if ( style_on ) {
244 sync_input(infile);
245 gdImageRectangle(img,arg[1],arg[2],arg[3],arg[4],gdStyled);
246 if (!quiet) fprintf(verbose_out,"colour = current style");
247 } else{
248 colour=get_colour(infile,img);
249 gdImageRectangle(img,arg[1],arg[2],arg[3],arg[4],colour);
250 }
251 if (!quiet) fprintf(verbose_out,")\n");
252 break;
253
254 case FSQUARE: /* gdImageFilledRectangle() */
255 for(i=1;i<=3;i++){
256 arg[i]=get_number(infile);
257 }
258 side = arg[3];
259 arg[3] = arg[1] + side; arg[4] = arg[2] + side;
260 if (!quiet)
261 fprintf(verbose_out,"## Filled Square ## drawn from %d,%d, side %d. (",
262 arg[1],arg[2],side);
263 if( tile_on ){
264 sync_input(infile);
265 gdImageFilledRectangle(img,arg[1],arg[2],arg[3],arg[4],gdTiled);
266 if (!quiet) fprintf(verbose_out,"colour = current tile");
267 } else{
268 colour=get_colour(infile,img);
269 gdImageFilledRectangle(img,arg[1],arg[2],arg[3],arg[4],colour);
270 }
271 if (!quiet) fprintf(verbose_out,")\n");
272 break;
273
274 case RECT: /* gdImageRectangle() */
275 for(i=1;i<=4;i++){
276 arg[i]=get_number(infile);
277 }
278 if (!quiet) fprintf(verbose_out,"## Rectangle ## drawn from %d,%d to %d,%d. (",
279 arg[1],arg[2],arg[3],arg[4]);
280
281 /* Check location of vertices given and swap if necessary */
282 if((arg[1] > arg[3]) && (arg[4] > arg[2])) {
283 swap(&arg[1],&arg[3]);
284 } else if((arg[1] > arg[3]) && (arg[2] > arg[4])) {
285 swap(&arg[1],&arg[3]);
286 swap(&arg[2],&arg[4]);
287 } else if((arg[3] > arg[1]) && (arg[2] > arg[4])) {
288 swap(&arg[2],&arg[4]);
289 }
290
291 if( brush_on ){
292 sync_input(infile);
293 gdImageRectangle(img,arg[1],arg[2],arg[3],arg[4],gdBrushed);
294 if (!quiet) fprintf(verbose_out,"colour = current brush");
295 } else if ( style_on ) {
296 sync_input(infile);
297 gdImageRectangle(img,arg[1],arg[2],arg[3],arg[4],gdStyled);
298 if (!quiet) fprintf(verbose_out,"colour = current style");
299 } else{
300 colour=get_colour(infile,img);
301 gdImageRectangle(img,arg[1],arg[2],arg[3],arg[4],colour);
302 }
303 if (!quiet) fprintf(verbose_out,")\n");
304 break;
305
306 case FRECT: /* gdImageFilledRectangle() */
307 for(i=1;i<=4;i++){
308 arg[i]=get_number(infile);
309 }
310 if (!quiet) fprintf(verbose_out,"## Filled Rectangle ## drawn from %d,%d to %d,%d. (",
311 arg[1],arg[2],arg[3],arg[4]);
312
313 /* Check location of vertices given and swap if necessary */
314 if((arg[1] > arg[3]) && (arg[4] > arg[2])) {
315 swap(&arg[1],&arg[3]);
316 } else if((arg[1] > arg[3]) && (arg[2] > arg[4])) {
317 swap(&arg[1],&arg[3]);
318 swap(&arg[2],&arg[4]);
319 } else if((arg[3] > arg[1]) && (arg[2] > arg[4])) {
320 swap(&arg[2],&arg[4]);
321 }
322
323 if( tile_on ){
324 sync_input(infile);
325 gdImageFilledRectangle(img,arg[1],arg[2],arg[3],arg[4],gdTiled);
326 if (!quiet) fprintf(verbose_out,"colour = current tile");
327 } else{
328 colour=get_colour(infile,img);
329 gdImageFilledRectangle(img,arg[1],arg[2],arg[3],arg[4],colour);
330 }
331 if (!quiet) fprintf(verbose_out,")\n");
332 break;
333
334 case POLY: /* gdImagePolygon() */
335 done = FALSE; i=0;
336
337 if (!quiet) fprintf(verbose_out,"## Polygon ## (");
338 colour=get_colour(infile,img);
339 if (!quiet) fprintf(verbose_out,") ");
340
341 arg[i++] = get_number(infile); /* get first point */
342 arg[i++] = get_number(infile);
343
344 while( ! done ){ /* get next point until EOL*/
345 for(c=0; c<=1 ;c++){
346 arg[i++]=get_number(infile);
347 }
348 if (!quiet) fprintf(verbose_out,"%d,%d to %d,%d; ",
349 arg[i-4],arg[i-3],arg[i-2],arg[i -1]);
350 }
351
352 num_entries = i / 2; i=0;
353 for(n=0; n<num_entries; n++)
354 {
355 points[n].x = arg[i++];
356 points[n].y = arg[i++];
357 }
358 if( brush_on ) {
359 gdImagePolygon(img, points, num_entries, gdBrushed);
360 } else if ( style_on ) {
361 gdImagePolygon(img, points, num_entries, gdStyled);
362 } else {
363 gdImagePolygon(img, points, num_entries, colour);
364 }
365
366 done = FALSE;
367 if (!quiet) fprintf(verbose_out,"\n");
368 break;
369
370 case FPOLY: /* gdImageFilledPolygon() */
371 done = FALSE; i=0;
372
373 if (!quiet) fprintf(verbose_out,"## Filled Polygon ## (");
374 colour=get_colour(infile,img);
375 if (!quiet) fprintf(verbose_out,") ");
376
377 arg[i++] = get_number(infile); /* get first point */
378 arg[i++] = get_number(infile);
379
380 while( ! done ){ /* get next point until EOL*/
381 for(c=0; c<=1 ;c++){
382 arg[i++]=get_number(infile);
383 }
384 if (!quiet) fprintf(verbose_out,"%d,%d to %d,%d; ",
385 arg[i-4],arg[i-3],arg[i-2],arg[i -1]);
386 }
387
388 num_entries = i / 2; i=0;
389 for(n=0; n<num_entries; n++)
390 {
391 points[n].x = arg[i++];
392 points[n].y = arg[i++];
393 }
394
395 if( tile_on )
396 {
397 gdImageFilledPolygon(img, points, num_entries, gdTiled);
398 }
399 else
400 {
401 gdImageFilledPolygon(img, points, num_entries, colour);
402 }
403 done = FALSE;
404 if (!quiet) fprintf(verbose_out,"\n");
405 break;
406
407 case ARC: /* gdImageArc() */
408 for(i=1;i<7;i++){
409 arg[i]=get_number(infile);
410 }
411 if (!quiet) {
412 fprintf(verbose_out,"## Arc ## Centred at %d,%d, width %d, height %d,\n",
413 arg[1],arg[2],arg[3],arg[4]);
414 fprintf(verbose_out," starting at %d deg, ending at %d deg. (",
415 arg[5],arg[6]);
416 }
417 if( brush_on ){
418 sync_input(infile);
419 gdImageArc(img,arg[1],arg[2],arg[3],arg[4],arg[5],arg[6],gdBrushed);
420 if(!quiet) fprintf(verbose_out,"colour = current brush");
421 } else if ( style_on ) {
422 sync_input(infile);
423 gdImageArc(img,arg[1],arg[2],arg[3],arg[4],arg[5],arg[6],gdStyled);
424 if(!quiet) fprintf(verbose_out,"colour = current style");
425 } else{
426 colour=get_colour(infile,img);
427 gdImageArc(img,arg[1],arg[2],arg[3],arg[4],arg[5],arg[6],colour);
428 }
429 if (!quiet) fprintf(verbose_out,")\n");
430 break;
431
432 case ELLIPSE: /* gdImageArc() */
433 for(i=1;i<5;i++){
434 arg[i]=get_number(infile);
435 }
436 if (!quiet) {
437 fprintf(verbose_out,"## Ellipse ## Centred at %d,%d, width %d, height %d. (",
438 arg[1],arg[2],arg[3],arg[4]);
439 }
440 if( brush_on ){
441 sync_input(infile);
442 gdImageArc(img,arg[1],arg[2],arg[3],arg[4],0,360,gdBrushed);
443 if(!quiet) fprintf(verbose_out,"colour = current brush");
444 } else if ( style_on ) {
445 sync_input(infile);
446 gdImageArc(img,arg[1],arg[2],arg[3],arg[4],0,360,gdStyled);
447 if(!quiet) fprintf(verbose_out,"colour = current style");
448 } else{
449 colour=get_colour(infile,img);
450 gdImageArc(img,arg[1],arg[2],arg[3],arg[4],0,360,colour);
451 }
452 if (!quiet) fprintf(verbose_out,")\n");
453 break;
454
455 case CIRCLE:
456 case FCIRCLE:
457 for(i=1;i<4;i++){
458 arg[i]=get_number(infile);
459 }
460 if (!quiet) {
461 if (type == CIRCLE) {
462 fprintf(verbose_out,"## Circle ## Centred at %d,%d, diameter %d (",
463 arg[1],arg[2],arg[3]);
464 }
465 else {
466 fprintf(verbose_out,"## Filled Circle ## Centred at %d,%d, diameter %d (",
467 arg[1],arg[2],arg[3]);
468 }
469 }
470 if( brush_on ){
471 sync_input(infile);
472 gdImageArc(img,arg[1],arg[2],arg[3],arg[3],0,360,gdBrushed);
473 if(!quiet) fprintf(verbose_out,"colour = current brush");
474 } else if ( style_on ) {
475 sync_input(infile);
476 gdImageArc(img,arg[1],arg[2],arg[3],arg[3],0,360,gdStyled);
477 if(!quiet) fprintf(verbose_out,"colour = current style");
478 } else{
479 colour=get_colour(infile,img);
480 gdImageArc(img,arg[1],arg[2],arg[3],arg[3],0,360,colour);
481 }
482 if (type == FCIRCLE) gdImageFillToBorder(img,arg[1],arg[2],colour,colour);
483 if (!quiet) fprintf(verbose_out,")\n");
484 break;
485
486
487 case SETPIXEL: /* gdImageSetPixel */
488 for(i=1;i<=2;i++){
489 arg[i]=get_number(infile);
490 }
491 if (!quiet) fprintf(verbose_out,"## Set Pixel ## at %d,%d to ",arg[1],arg[2]);
492 colour=get_colour(infile,img);
493 gdImageSetPixel(img,arg[1],arg[2],colour);
494 if (!quiet) fprintf(verbose_out,".\n");
495 break;
496
497 case GETPIXEL: /* gdImageGetPixel */
498 for(i=1;i<=2;i++){
499 arg[i]=get_number(infile);
500 }
501 if (!quiet) fprintf(verbose_out,"## Get Pixel ## at %d,%d:",arg[1],arg[2]);
502 colour = gdImageGetPixel(img,arg[1],arg[2]);
503 arg[3] = gdImageRed(img,colour);
504 arg[4] = gdImageGreen(img,colour);
505 arg[5] = gdImageBlue(img,colour);
506 if (!quiet) fprintf(verbose_out," %d, %d, %d = %d.\n",
507 arg[3],arg[4],arg[5],colour);
508 break;
509
510 case COLOURCHANGE:
511 for(i=1;i<=6;i++){
512 arg[i]=get_number(infile);
513 }
514 /* colour is new colour */
515 colour = gdImageColorExact(img,arg[4],arg[5],arg[6]);
516 if (colour == -1) {
517 colour = gdImageColorAllocate(img,arg[4],arg[5],arg[6]);
518 }
519 /* colour1 is old colour */
520 colour1 = gdImageColorExact(img,arg[1],arg[2],arg[3]);
521 if (colour1 == -1) {
522 colour1 = gdImageColorAllocate(img,arg[1],arg[2],arg[3]);
523 }
524 size_x = gdImageSX(img);
525 size_y = gdImageSY(img);
526 for(x=0; x < size_x; x++) {
527 for(y=0; y < size_y; y++) {
528 colour2 = gdImageGetPixel(img,x,y);
529 if(colour2 == colour1) {
530 gdImageSetPixel(img,x,y,colour);
531 }
532 }
533 }
534 if (!quiet) fprintf(verbose_out,"## Colour Change ## %d,%d,%d (%d) changed to %d,%d,%d (%d).\n",
535 arg[1],arg[2],arg[3],colour1,arg[4],arg[5],arg[6],colour);
536
537 break;
538 case ROTATE:
539 i=get_number(infile);
540 if(! ((i == 90) || (i == 180) || (i == 270))) {
541 fprintf(verbose_out,"Error: line %d. Rotation must be 90, 180 or 270.\n", line_number);
542 break;
543 }
544 if (!quiet) fprintf(verbose_out,"## Rotate ## by %d degrees.\n",i);
545 size_x = gdImageSX(img);
546 size_y = gdImageSY(img);
547 switch(i) {
548 case 180:
549 new_img = gdImageCreate(size_x,size_y);
550 break;
551 case 90:
552 case 270:
553 new_img = gdImageCreate(size_y,size_x);
554 break;
555 }
556 for(x=0; x < size_x; x++) {
557 for(y=0; y < size_y; y++) {
558 int r, g, b;
559 colour = gdImageGetPixel(img,x,y);
560 r = gdImageRed(img,colour);
561 g = gdImageGreen(img,colour);
562 b = gdImageBlue(img,colour);
563 colour1 = gdImageColorExact(new_img,r,g,b);
564 if (colour1 == -1) { colour1 = gdImageColorAllocate(new_img,r,g,b); }
565 switch(i) {
566 case 90:
567 gdImageSetPixel(new_img,(size_y - y - 1),x,colour1);
568 break;
569 case 180:
570 gdImageSetPixel(new_img,(size_x - x - 1),(size_y - y - 1),colour1);
571 break;
572 case 270:
573 gdImageSetPixel(new_img,y,(size_x - x - 1),colour1);
574 break;
575 }
576 }
577 }
578 gdImageDestroy(img);
579 img = new_img;
580 break;
581
582 case FILL: /* gdImageFill() */
583 for(i=1;i<=2;i++){
584 arg[i]=get_number(infile);
585 }
586 if (!quiet) fprintf(verbose_out,"## Fill ## from %d,%d. (", arg[1],arg[2]);
587 if( tile_on ){
588 sync_input(infile);
589 gdImageFill(img,arg[1],arg[2],gdTiled);
590 } else {
591 colour=get_colour(infile,img);
592 gdImageFill(img,arg[1],arg[2],colour);
593 }
594 if (!quiet) fprintf(verbose_out,")\n");
595 break;
596
597 case FILLTOBORDER: /* gdImageFillToBorder() */
598 for(i=1;i<=2;i++){
599 arg[i]=get_number(infile);
600 }
601 if (!quiet) fprintf(verbose_out,"## Fill ## from %d,%d. (", arg[1],arg[2]);
602 colour=get_colour(infile,img);
603 if (!quiet) fprintf(verbose_out,") to Border of ");
604 if( tile_on ){
605 if (!quiet)
606 fprintf(verbose_out,"Line %d skipped: Cannot use tile with filltoborder.\n",line_number);
607 sync_input(infile);
608 } else {
609 colour2=get_colour(infile,img);
610 gdImageFillToBorder(img,arg[1],arg[2],colour,colour2);
611 }
612 if (!quiet) fprintf(verbose_out,".\n");
613 break;
614
615 case STRINGUP:
616 up = TRUE;
617 case STRING:
618 if (!quiet && up) fprintf(verbose_out,"## String (Up) ## (");
619 if (!quiet && !up) fprintf(verbose_out,"## String ## (");
620 colour=get_colour(infile,img);
621 if (!quiet) fprintf(verbose_out,") at location ");
622 for(i=1;i<=2;i++){
623 arg[i]=get_number(infile);
624 }
625 if (!quiet) fprintf(verbose_out," %d,%d, ",arg[1],arg[2]);
626 i = get_token(infile);
627 s = get_string(infile);
628 switch(i) {
629 case TINY:
630 gdFont = gdFontTiny;
631 if (!quiet) fprintf(verbose_out,"[size: tiny] contents: %s\n",s);
632 break;
633 case SMALL:
634 gdFont = gdFontSmall;
635 if (!quiet) fprintf(verbose_out,"[size: small] contents: %s\n",s);
636 break;
637 case MEDIUM:
638 gdFont = gdFontMediumBold;
639 if (!quiet) fprintf(verbose_out,"[size: medium-bold] contents: %s\n",s);
640 break;
641 case LARGE:
642 gdFont = gdFontLarge;
643 if (!quiet) fprintf(verbose_out,"[size: large] contents: %s\n",s);
644 break;
645 case GIANT:
646 gdFont = gdFontGiant;
647 if (!quiet) fprintf(verbose_out,"[size: giant] contents: %s\n",s);
648 break;
649 default:
650 if (!quiet) fprintf(verbose_out,"Error: line %d. Incorrect font size specifier.\n",
651 line_number);
652 break;
653 }
654 if( !up ) {
655 gdImageString(img, gdFont, arg[1],arg[2], (unsigned char *) s, colour);
656 } else {
657 gdImageStringUp(img, gdFont, arg[1],arg[2], (unsigned char *) s, colour);
658 }
659 up = FALSE;
660 break;
661
662 case SETBRUSH:
663 s = get_string(infile);
664 if ( (brushfile = fopen(s,"rb")) == NULL )
665 {
666 fprintf(stderr, "Failed to open brush file, %s\n",
667 output_file);
668 exit(1);
669 }
670 else
671 {
672 brush = gdImageCreateFromPng(brushfile);
673 gdImageSetBrush(img,brush);
674 brush_on = 1;
675 if (!quiet) fprintf(verbose_out,"## Brush Set ## to: %s\n",s);
676 }
677 break;
678
679 case KILLBRUSH:
680 brush_on = 0;
681 if (!quiet) fprintf(verbose_out,"## Brush Killed ##\n");
682 break;
683
684 case SETSTYLE:
685 i=0;
686 end_of_line = FALSE;
687 if (!quiet) fprintf(verbose_out,"## Style Set ## Colours: (");
688 while( ! end_of_line ){
689 colour=get_colour(infile,img);
690 if (!quiet && !end_of_line) fprintf(verbose_out,"), (");
691 style[i++] = colour;
692 }
693 if (!quiet) fprintf(verbose_out,")\n");
694 gdImageSetStyle(img, style, i-1);
695 style_on = TRUE;
696 end_of_line = FALSE;
697 break;
698
699 case KILLSTYLE:
700 style_on = 0;
701 if (!quiet) fprintf(verbose_out,"## Style Killed ##\n");
702 break;
703
704 case SETTILE:
705 s = get_string(infile);
706 if ( (tilefile = fopen(s,"rb")) == NULL )
707 {
708 fprintf(stderr, "Failed to open tile file, %s\n",
709 output_file);
710 exit(1);
711 }
712 else
713 {
714 tile = gdImageCreateFromPng(tilefile);
715 gdImageSetTile(img,tile);
716 tile_on = TRUE;
717 if (!quiet) fprintf(verbose_out,"## Tile Set ## to: %s\n",s);
718 }
719 break;
720
721 case KILLTILE:
722 tile_on = 0;
723 if (!quiet) fprintf(verbose_out,"## Tile Killed ##\n");
724 break;
725
726 case COPY:
727 copy_to_img(infile, img, 0);
728 break;
729
730 case COPYRESIZED:
731 copy_to_img(infile, img, 1);
732 break;
733
734 case TRANSPARENT:
735 if (!quiet) fprintf(verbose_out,"## Make transparent ## [");
736 colour=get_colour(infile,img);
737 gdImageColorTransparent(img,colour);
738 if (!quiet) fprintf(verbose_out,"]\n");
739 break;
740
741 case INTERLACE:
742 gdImageInterlace(img,1);
743 if (!quiet) fprintf(verbose_out,"## Image is interlaced ##\n");
744 break;
745
746 case SIZEX:
747 size = gdImageSX(img);
748 if (!quiet) fprintf(verbose_out,"## Size - X ## is %d\n",size);
749 break;
750
751 case SIZEY:
752 size = gdImageSY(img);
753 if (!quiet) fprintf(verbose_out,"## Size - Y ## is %d\n",size);
754 break;
755
756 case NAME:
757 s = get_string(infile);
758 if ( (outfile = fopen(s,"wb")) == NULL )
759 {
760 fprintf(stderr, "Failed to open output file, %s\n",
761 output_file);
762 exit(1);
763 }
764 else
765 {
766 if (!quiet) fprintf(verbose_out,"## Output to file %s ##\n",s);
767 }
768 break;
769
770 case TYPE:
771 imgtype = get_token(infile);
772 if(imgtype != JPEG && imgtype != PNG && imgtype != GIF){
773 fprintf(verbose_out,"Error: line %d: Image type must be jpeg, gif or png.\n",line_number);
774 exit(1);
775 }
776 break;
777
778 case QUALITY:
779 i=get_number(infile);
780 jp_quality = i;
781 if(imgtype != JPEG){
782 fprintf(verbose_out,"Error: line %d: Cannot use quality directive unless type is set to jpeg first.\n",line_number);
783 exit(1);
784 }
785 if(i < 0 || i > 95){
786 fprintf(verbose_out,"Line %d skipped: Image quality must be within the range 0-95. %d is not an acceptable value.\n",line_number, i);
787 exit(1);
788 }
789
790 break;
791
792 case COMMENT:
793 sync_input(infile);
794 break;
795
796 case EMPTY:
797 break;
798
799 case END:
800 gdImagePng(img,outfile);
801 fclose(outfile);
802 gdImageDestroy(img);
803 written_out = TRUE;
804 if (!quiet) fprintf(verbose_out,"End of image directives.\n");
805 if(!finished) { goto START; } else { goto FINISH; }
806
807 default:
808 if( ! finished ) {
809 if (!quiet) fprintf(verbose_out,
810 "Line %d skipped: bad directive or syntax error.\n",line_number);
811 } else {
812 if (!quiet) fprintf(verbose_out,"EOF: fly finished.\n");
813 }
814 sync_input(infile);
815 break;
816 }
817 } while( ! finished );
818
819 /* Write the gd to the image output file and exit */
820 FINISH: if(!written_out && img) {
821 if(imgtype == JPEG) {
822 gdImageJpeg(img,outfile,jp_quality);
823 } else if(imgtype == GIF) {
824 gdImageGif(img,outfile);
825 } else {
826 gdImagePng(img,outfile);
827 }
828 fclose(outfile);
829 gdImageDestroy(img);
830 }
831 exit(0);
832 }
833
834 /******************************************************************************
835 **
836 ** get_string
837 **
838 ** returns a string from the current input line: from the current point
839 ** to the end of line.
840 **
841 ** Used by:
842 ** string,stringup,chr,chrup,setbrush,settile
843 **
844 ******************************************************************************/
845 char *get_string(FILE *infile){
846 int c,i=0;
847 char temp[1024], *string, *p;
848
849 while(( (c=getc(infile)) != EOF ) && ( c != '\n') ){
850 temp[i++]=c;
851 }
852
853 if( c == '\n' ) { line_number++; }
854 if( c == EOF ) {
855 finished = TRUE;
856 }
857 temp[i]='\0';
858 p=temp;
859 string=(char *)my_newmem(strlen(p));
860 sprintf(string,"%s",temp);
861
862 return string;
863 }
864
865 /******************************************************************************
866 **
867 ** get_token
868 **
869 ** Gets the next "token" from the input line.
870 **
871 ** Used by:
872 ** all
873 **
874 ******************************************************************************/
875 int get_token(FILE *infile){
876 int c,i=0;
877 char temp[80], *input_type, *p;
878 char *line="line",
879 *poly="poly",
880 *fpoly="fpoly",
881 *rect="rect",
882 *frect="frect",
883 *square="square",
884 *fsquare="fsquare",
885 *dline="dline",
886 *arc="arc",
887 *size="size",
888 *new="new",
889 *existing="existing",
890 *setpixel="setpixel",
891 *getpixel="getpixel",
892 *filltoborder="filltoborder",
893 *fill="fill",
894 *string="string",
895 *stringup="stringup",
896 *copy="copy",
897 *copyresized="copyresized",
898 *transparent="transparent",
899 *interlace="interlace",
900 *sizex="sizex",
901 *sizey="sizey",
902 *setbrush="setbrush",
903 *killbrush="killbrush",
904 *settile="settile",
905 *killtile="killtile",
906 *setstyle="setstyle",
907 *killstyle="killstyle",
908 *tiny="tiny",
909 *small="small",
910 *medium="medium",
911 *large="large",
912 *giant="giant",
913 *zero="0",
914 *one="1",
915 *circle="circle",
916 *fcircle="fcircle",
917 *comment="#",
918 *name="name",
919 *end="end",
920 *ellipse="ellipse",
921 *colourchange="colourchange",
922 *rotate="rotate",
923 *type="type",
924 *quality="quality",
925 *gif="gif",
926 *png="png",
927 *jpeg="jpeg";
928
929 while(((c=getc(infile))!=EOF)&&(c!=' ')&&(c!='\n')&&(c!=',')&&(c!='=')&&(c!='\r'))
930 {
931 temp[i++]=c;
932 if(temp[0] == '#') break;
933 }
934 if (c == EOF) finished = TRUE;
935
936 if (c == '\n' || c == '\r') {
937 line_number++;
938 if (i == 0) { return EMPTY; }
939 } else if (c == EOF) {
940 return (int)NULL;
941 }
942
943 temp[i]='\0';
944 p=temp;
945 input_type=(char*)my_newmem(strlen(p));
946 sprintf(input_type,"%s",temp);
947
948 if( strcmp(input_type, line) == 0 ){
949 free(input_type);
950 return LINE;
951 }
952 if( strcmp(input_type, rect) == 0 ){
953 free(input_type);
954 return RECT;
955 }
956 if( strcmp(input_type, square) == 0 ){
957 free(input_type);
958 return SQUARE;
959 }
960 if( strcmp(input_type, fsquare) == 0 ){
961 free(input_type);
962 return FSQUARE;
963 }
964 if( strcmp(input_type, dline) == 0 ){
965 free(input_type);
966 return DLINE;
967 }
968 if( strcmp(input_type, frect) == 0 ){
969 free(input_type);
970 return FRECT;
971 }
972 if( strcmp(input_type, fcircle) == 0 ){
973 free(input_type);
974 return FCIRCLE;
975 }
976 if( strcmp(input_type, circle) == 0 ){
977 free(input_type);
978 return CIRCLE;
979 }
980 if( strcmp(input_type, arc) == 0 ){
981 free(input_type);
982 return ARC;
983 }
984 if( strcmp(input_type, poly) == 0 ){
985 free(input_type);
986 return POLY;
987 }
988 if( strcmp(input_type, fpoly) == 0 ){
989 free(input_type);
990 return FPOLY;
991 }
992 if( strcmp(input_type, size) == 0 ){
993 free(input_type);
994 return SIZE;
995 }
996 if( strcmp(input_type, new) == 0 ){
997 free(input_type);
998 return NEW;
999 }
1000 if( strcmp(input_type, existing) == 0 ){
1001 free(input_type);
1002 return EXISTING;
1003 }
1004 if( strcmp(input_type, copyresized) == 0 ){
1005 free(input_type);
1006 return COPYRESIZED;
1007 }
1008 if( strcmp(input_type, copy) == 0 ){
1009 free(input_type);
1010 return COPY;
1011 }
1012 if( strcmp(input_type, fill) == 0 ){
1013 free(input_type);
1014 return FILL;
1015 }
1016 if( strcmp(input_type, filltoborder) == 0 ){
1017 free(input_type);
1018 return FILLTOBORDER;
1019 }
1020 if( strcmp(input_type, setpixel) == 0 ){
1021 free(input_type);
1022 return SETPIXEL;
1023 }
1024 if( strcmp(input_type, getpixel) == 0 ){
1025 free(input_type);
1026 return GETPIXEL;
1027 }
1028 if( strcmp(input_type, string) == 0 ){
1029 free(input_type);
1030 return STRING;
1031 }
1032 if( strcmp(input_type, stringup) == 0 ){
1033 free(input_type);
1034 return STRINGUP;
1035 }
1036 if( strcmp(input_type, sizex) == 0 ){
1037 free(input_type);
1038 return SIZEX;
1039 }
1040 if( strcmp(input_type, sizey) == 0 ){
1041 free(input_type);
1042 return SIZEY;
1043 }
1044 if( strcmp(input_type, setbrush) == 0 ){
1045 free(input_type);
1046 return SETBRUSH;
1047 }
1048 if( strcmp(input_type, killbrush) == 0 ){
1049 free(input_type);
1050 return KILLBRUSH;
1051 }
1052 if( strcmp(input_type, settile) == 0 ){
1053 free(input_type);
1054 return SETTILE;
1055 }
1056 if( strcmp(input_type, killtile) == 0 ){
1057 free(input_type);
1058 return KILLTILE;
1059 }
1060 if( strcmp(input_type, setstyle) == 0 ){
1061 free(input_type);
1062 return SETSTYLE;
1063 }
1064 if( strcmp(input_type, killstyle) == 0 ){
1065 free(input_type);
1066 return KILLSTYLE;
1067 }
1068 if( strcmp(input_type, interlace) == 0 ){
1069 free(input_type);
1070 return INTERLACE;
1071 }
1072 if( strcmp(input_type, transparent) == 0 ){
1073 free(input_type);
1074 return TRANSPARENT;
1075 }
1076 if( strcmp(input_type, tiny) == 0 ){
1077 free(input_type);
1078 return TINY;
1079 }
1080 if( strcmp(input_type, zero) == 0 ){
1081 free(input_type);
1082 return SMALL;
1083 }
1084 if( strcmp(input_type, small) == 0 ){
1085 free(input_type);
1086 return SMALL;
1087 }
1088 if( strcmp(input_type, medium) == 0 ){
1089 free(input_type);
1090 return MEDIUM;
1091 }
1092 if( strcmp(input_type, one) == 0 ){
1093 free(input_type);
1094 return LARGE;
1095 }
1096 if( strcmp(input_type, large) == 0 ){
1097 free(input_type);
1098 return LARGE;
1099 }
1100 if( strcmp(input_type, giant) == 0 ){
1101 free(input_type);
1102 return GIANT;
1103 }
1104 if( strcmp(input_type, name) == 0){
1105 free(input_type);
1106 return NAME;
1107 }
1108 if( strcmp(input_type, comment) == 0){
1109 free(input_type);
1110 return COMMENT;
1111 }
1112 if( strcmp(input_type, end) == 0){
1113 free(input_type);
1114 return END;
1115 }
1116 if( strcmp(input_type, ellipse) == 0){
1117 free(input_type);
1118 return ELLIPSE;
1119 }
1120 if( strcmp(input_type, colourchange) == 0){
1121 free(input_type);
1122 return COLOURCHANGE;
1123 }
1124 if( strcmp(input_type, rotate) == 0){
1125 free(input_type);
1126 return ROTATE;
1127 }
1128 if( strcmp(input_type, type) == 0){
1129 free(input_type);
1130 return TYPE;
1131 }
1132 if( strcmp(input_type, quality) == 0){
1133 free(input_type);
1134 return QUALITY;
1135 }
1136 if( strcmp(input_type, gif) == 0){
1137 free(input_type);
1138 return GIF;
1139 }
1140 if( strcmp(input_type, png) == 0){
1141 free(input_type);
1142 return PNG;
1143 }
1144 if( strcmp(input_type, jpeg) == 0){
1145 free(input_type);
1146 return JPEG;
1147 }
1148 free(input_type);
1149 ungetc(c,infile);
1150 return (int)NULL;
1151 }
1152
1153 /******************************************************************************
1154 **
1155 ** get_number
1156 **
1157 ** grabs a number from the current input line. Reads up to a comma or newline.
1158 **
1159 ** Used by:
1160 ** line, dline, rect, frect, poly, fpoly, arc, setpixel, fill, filltoborder,
1161 ** string, stringup, chr, chrup.
1162 **
1163 ******************************************************************************/
1164 int get_number(FILE *infile){
1165 int c,i=0;
1166 char tmp[80];
1167
1168 while(( (c=getc(infile)) != EOF ) && ( c != ',') && (c != '\n')){
1169 tmp[i++]=c;
1170 }
1171 if( c == '\n' ) { line_number++; }
1172 if( c != EOF ) {
1173 tmp[i]='\0';
1174 if( c == '\n') {
1175 done = TRUE;
1176 }
1177 return atoi(tmp);
1178 } else {
1179 tmp[i]='\0';
1180 finished = TRUE;
1181 return atoi(tmp);
1182 }
1183 }
1184
1185 /******************************************************************************
1186 **
1187 ** get_colour
1188 **
1189 ** Gets a R,G,B colour value from the current input line.
1190 ** Returns the integer colour index.
1191 **
1192 ** Used by:
1193 ** line, dline, rect, frect, poly, fpoly, arc, setpixel, fill, filltoborder,
1194 ** string, stringup, chr, chrup, setstyle, transparent.
1195 **
1196 ******************************************************************************/
1197 int get_colour(FILE *infile, gdImagePtr img){
1198 int c,i,count,colourIndex, colour[3];
1199 char temp[5];
1200
1201 for(count=0;count<3;count++){
1202 i=0;
1203 while(( (c=getc(infile)) != EOF )&&( c !=',')&&(c !='\n')){
1204 temp[i++]=c;
1205 }
1206 if( c == '\n' ) { line_number++; }
1207 temp[i]='\0';
1208 if( c == '\n') end_of_line = TRUE;
1209 if( c == EOF ) finished = TRUE;
1210 colour[count]=atoi(temp);
1211 }
1212 if( (c=getc(infile)) != EOF ) {
1213 ungetc(c,infile);
1214 } else {
1215 finished = TRUE;
1216 }
1217 /* Original comments from Claus Hofmann. I don't have any idea what they
1218 * mean, but I'll put 'em here anyhow.
1219 */
1220 /* zuerst nachschauen, ob es die gewuenschte Farbe schon in der
1221 * colortable gibt. Erst wenn es die Farbe nicht gibt einen neuen
1222 * Index in der Tabelle allocieren.
1223 */
1224 colourIndex=gdImageColorExact(img,colour[0],colour[1],colour[2]);
1225 if (colourIndex == -1) {
1226 colourIndex=gdImageColorAllocate(img,colour[0],colour[1],colour[2]);
1227 }
1228 if (!quiet)
1229 fprintf(verbose_out,"colour: %d, %d, %d = %d",
1230 colour[0],colour[1],colour[2], colourIndex);
1231 return colourIndex;
1232
1233 }
1234
1235 /******************************************************************************
1236 **
1237 ** copy_to_img
1238 **
1239 ** Copies a img to the current image. Location of img and coordinates are
1240 ** specified on the input line.
1241 **
1242 ** Used by:
1243 ** copy, copyresized.
1244 **
1245 ******************************************************************************/
1246 void copy_to_img(FILE *infile, gdImagePtr img, int resize){
1247 int i=0,arg[8];
1248 char *filename;
1249 FILE *img_to_copy;
1250 gdImagePtr img_file;
1251
1252 /* Get the coordinates */
1253 for(i=0;i<=5;i++){
1254 arg[i]=get_number(infile);
1255 }
1256 if( resize == 1 ){
1257 arg[i]=get_number(infile);
1258 i++;
1259 arg[i]=get_number(infile);
1260 }
1261 if((img_to_copy = get_file(&line_number, &filename)) == NULL) {
1262 fprintf(stderr,"Error: Cannot read existing image file \"%s\"\n",
1263 filename);
1264 exit(1);
1265 }
1266 if(imgtype == JPEG) {
1267 img_file = gdImageCreateFromJpeg(img_to_copy);
1268 } else if(imgtype == GIF) {
1269 img_file = gdImageCreateFromGif(img_to_copy);
1270 } else {
1271 img_file = gdImageCreateFromPng(img_to_copy);
1272 }
1273 fclose(img_to_copy);
1274
1275 if( resize == 1 )
1276 {
1277 if((arg[0] == -1)&&(arg[1] == -1) &(arg[2] == -1)&&(arg[3] == -1)){
1278 if(!quiet) fprintf(verbose_out,"Copying %s (entire area) to area %d,%d - %d,%d.\n",
1279 filename,arg[4],arg[5],arg[6], arg[7]);
1280 gdImageCopyResized(img, img_file, arg[4], arg[5], 0, 0,
1281 (arg[6] - arg[4]), (arg[7] - arg[5]), img_file->sx, img_file->sy);
1282 }
1283 else {
1284 if(!quiet) fprintf(verbose_out,"Copying %s (area %d,%d - %d,%d) to area %d,%d - %d,%d.\n",
1285 filename,arg[4],arg[5],arg[6], arg[7],arg[0],arg[1],arg[2],arg[3]);
1286 gdImageCopyResized(img, img_file, arg[4], arg[5], arg[0], arg[1],
1287 (arg[6] - arg[4] + 1), (arg[7] - arg[5] + 1), (arg[2] - arg[0] + 1),
1288 (arg[3] - arg[1] + 1));
1289 }
1290 }
1291 else
1292 {
1293 if ((arg[2] == -1)&&(arg[3] == -1) &(arg[4] == -1)&&(arg[5] == -1)) {
1294 /* another comment from Claus Hofmann. I'm getting curious now. */
1295 /* gesamtes Bild
1296 */
1297 arg[2] = arg[3] = 0;
1298 arg[4] = img_file->sx;
1299 arg[5] = img_file->sy;
1300 }
1301 if(!quiet) fprintf(verbose_out,"Copying %s to coordinates %d,%d\n",filename,arg[0],arg[1]);
1302 gdImageCopy(img, img_file, arg[0], arg[1], arg[2], arg[3],
1303 arg[4] - arg[2], arg[5] - arg[3]);
1304 }
1305 gdImageDestroy(img_file);
1306
1307 return;
1308 }
1309
1310 /******************************************************************************
1311 **
1312 ** sync_input
1313 **
1314 ** synchronises input line - reads to end of line, leaving file pointer
1315 ** at first character of next line.
1316 **
1317 ** Used by:
1318 ** main program - error handling.
1319 **
1320 ******************************************************************************/
1321 void
1322 sync_input(FILE *infile)
1323 {
1324 int c = 0;
1325
1326 if( c == '\n' ) return;
1327 while( ( (c=getc(infile)) != EOF ) && (c != '\n') && (c != '\r')) ;
1328 if( c == EOF ) finished = TRUE;
1329 if( c == '\n' || c == '\r') line_number++;
1330 return;
1331 }
1332
1333 /******************************************************************************
1334 **
1335 ** process_args
1336 **
1337 ** processes the command line arguments
1338 **
1339 ** Used by:
1340 ** main program.
1341 **
1342 ******************************************************************************/
1343 int
1344 process_args(int argc, char *argv[])
1345 {
1346 int c = 0, errflag=0;
1347 extern char *optarg;
1348 extern int optind;
1349
1350 while ((c=getopt(argc, argv, "qhvi:o:")) != EOF) {
1351 switch (c) {
1352 case 'q': quiet = TRUE;
1353 break;
1354 case 'v':
1355 case 'h': fprintf(stdout,"fly, version %s\n\n%s\n", version, help);
1356 exit(0);
1357 break;
1358 case 'o': output_file=(char *)my_newmem(strlen(optarg)*sizeof(char));
1359 sprintf(output_file,"%s",optarg);
1360 break;
1361 case 'i': input_file=(char *)my_newmem(strlen(optarg)*sizeof(char));
1362 sprintf(input_file,"%s",optarg);
1363 break;
1364 case '?': errflag = 1;
1365 break;
1366 }
1367 if (errflag) {
1368 fprintf(stderr,"%s\n", usage);
1369 exit(1);
1370 }
1371 }
1372 if( input_file ) {
1373 if ( (infile = fopen(input_file,"r")) == NULL ) {
1374 fprintf(stderr, "Failed to open input file, %s.\n",
1375 input_file);
1376 return FALSE;
1377 }
1378 } else {
1379 infile = stdin;
1380 }
1381 if( output_file ) {
1382 if ( (outfile = fopen(output_file,"wb")) == NULL ) {
1383 fprintf(stderr, "Failed to open output file, %s.\n",
1384 output_file);
1385 return FALSE;
1386 }
1387 verbose_out = stdout;
1388 } else {
1389 #ifdef WIN32
1390 _setmode( _fileno( stdout ), _O_BINARY ) ;
1391 #endif
1392 outfile = stdout;
1393 verbose_out = stderr;
1394 }
1395 return TRUE;
1396 }
1397
1398 /******************************************************************************
1399 **
1400 ** get_image
1401 **
1402 ** creates a new image or uses an existing one as a template.
1403 **
1404 ** Used by:
1405 ** main program
1406 **
1407 ******************************************************************************/
1408 gdImagePtr get_image(int type, int argc, char *argv[]){
1409
1410
1411 FILE *in;
1412 int n=0, num[10];
1413 char *filename;
1414 gdImagePtr image = NULL;
1415 int newtype;
1416
1417 if( type == EXISTING ) {
1418 /* fprintf(stderr,"Creating image from existing file:"); */
1419 if ((in = get_file(&line_number, &filename)) == NULL ) {
1420 fprintf(stderr,"Error: Cannot read existing image file \"%s\"\n",
1421 filename);
1422 exit(1);
1423 }
1424 else {
1425 if(!quiet) fprintf(verbose_out,"Creating image from existing image <%s>\n",
1426 filename);
1427 image = gdImageCreateFromPng(in);
1428 fclose(in);
1429 }
1430 }
1431 else if( type == NEW ){
1432 newtype = get_token(infile);
1433 while( (newtype == COMMENT) || (newtype == EMPTY) || (newtype != SIZE) ) {
1434 if(newtype != EMPTY) sync_input(infile);
1435 newtype = get_token(infile);
1436 }
1437 if( newtype != SIZE ) {
1438 if( argc == 2){
1439 fprintf(stderr,"Error: <stdin> second line ");
1440 fprintf(stderr,"must have a 'size' command\n");
1441 }
1442 else{
1443 fprintf(stderr,"Error: %s second line must ", argv[1]);
1444 fprintf(stderr,"have a 'size' command\n");
1445 }
1446 exit(1);
1447 }
1448 for( n=1; n<=2; n++ ){
1449 num[n]=get_number(infile);
1450 }
1451 if (!quiet)
1452 {
1453 if( output_file )
1454 {
1455 fprintf(verbose_out,"Creating new %d by %d image, <%s>\n",
1456 num[1],num[2],output_file);
1457 }
1458 else
1459 {
1460 fprintf(verbose_out,"Creating new %d by %d image\n",
1461 num[1],num[2]);
1462 }
1463 }
1464 image = gdImageCreate(num[1],num[2]);
1465 }
1466 written_out = FALSE;
1467 return image;
1468 }
1469
1470 /******************************************************************************
1471 **
1472 ** my_newmem: grab some memory.
1473 **
1474 ** - Concentrates memory error handling in one place.
1475 **
1476 **
1477 ** Used by:
1478 ** string,stringup,chr,chrup,setbrush,settile
1479 **
1480 ******************************************************************************/
1481 void *
1482 my_newmem(size_t size)
1483 {
1484 void *p;
1485
1486 if ((p = malloc(size +1)) == NULL)
1487 {
1488 fprintf(stderr, "fly: ran out of memory\n");
1489 exit(1);
1490 }
1491
1492 return p;
1493 }
1494
1495 /******************************************************************************
1496 **
1497 ** get_file
1498 **
1499 ** reads a file name and opens a file corresponding to the
1500 ** name read. if the name is back-quoted `...` then it is
1501 ** interpreted as a shell command.
1502 **
1503 ** Contributed by Ian Reid <ian@robots.ox.ac.uk>
1504 **
1505 ** Bug fix to type of ch by John Mitchell <johnm@magnet.com>
1506 **
1507 ** Used by:
1508 ** get_image
1509 ** copy_to_img
1510 **
1511 ******************************************************************************/
1512
1513 FILE *get_file(int *line_number, char **filename)
1514 {
1515 FILE *in;
1516 int ch;
1517 char fname[NAMESIZE];
1518 int n=0;
1519
1520 if ((fname[n++]=getc(infile)) == '`') {
1521 while (( (ch=getc(infile)) != EOF ) && ( ch != '`' ) && n<NAMESIZE) {
1522 fname[n++]=ch;
1523 }
1524 } else {
1525 while(( (ch=getc(infile)) != EOF ) && ( ch != ' ') && ( ch != '\n') && n<NAMESIZE){
1526 fname[n++]=ch;
1527 }
1528 }
1529 if (ch == '\n') { (*line_number)++; }
1530 if (ch==EOF || n==NAMESIZE) {
1531 fprintf(stderr, "Error: EOF or out space while reading filename (perhaps missing \"`\"?)\n");
1532 return NULL;
1533 }
1534 fname[n]='\0';
1535 if (fname[0]=='`') {
1536 #ifndef NO_FORK
1537 /* open a pipe to get data from a shell command */
1538 int pid, p[2];
1539
1540 *filename = (char *) my_newmem( n );
1541 strncpy(*filename, fname+1, n);
1542
1543 if (pipe(p) < 0) {
1544 fprintf(stderr, "Error: pipe creation failed\n");
1545 return NULL;
1546 }
1547 if ((pid=fork()) < 0) {
1548 fprintf(stderr, "Error: fork failed\n");
1549 return NULL;
1550 } else if (pid>0) {
1551 /* child */
1552 close(p[0]); close(1); dup(p[1]); close(p[1]);
1553 exit( system (*filename) );
1554 }
1555 /* parent */
1556 close(p[1]);
1557 in = fdopen(p[0], "rb");
1558 #else
1559 fprintf(stderr,"Error: Reading image from external command not supported on this Operating System\n");
1560 exit(1);
1561 #endif
1562 } else {
1563 /* open an ordinary file */
1564 *filename = (char *) my_newmem( n+1 );
1565 sprintf(*filename,"%s",fname);
1566 in = fopen(*filename, "rb");
1567 }
1568
1569 return in;
1570 }
1571 /******************************************************************************/
1572 void swap(int *a, int *b) {
1573 int temp;
1574
1575 temp = *b;
1576 *b = *a;
1577 *a = temp;
1578 }
1579 /******************************************************************************/