mkbitmap.c
Go to the documentation of this file.
00001 /* Copyright (C) 2001-2007 Peter Selinger.
00002    This file is part of Potrace. It is free software and it is covered
00003    by the GNU General Public License. See the file COPYING for details. */
00004 
00005 /* mkbitmap.c: a standalone program for converting greymaps to bitmaps
00006    while optionally applying the following enhancements: highpass
00007    filter, interpolated scaling, inversion. */
00008 
00009 #include <stdio.h>
00010 #include <errno.h>
00011 #include <string.h>
00012 #include <stdlib.h>
00013 #include <math.h>
00014 #include <getopt.h>
00015 
00016 #include "greymap.h"
00017 #include "bitmap_io.h"
00018 #include "platform.h"
00019 
00020 #ifdef HAVE_CONFIG_H
00021 #include "config.h"
00022 #endif
00023 
00024 #define SAFE_MALLOC(var, n, typ) \
00025   if ((var = (typ *)malloc((n)*sizeof(typ))) == NULL) goto malloc_error 
00026 
00027 /* structure to hold command line options */
00028 struct info_s {
00029   char *outfile;     /* output file */
00030   char **infiles;    /* input files */
00031   int infilecount;   /* how many input files? */
00032   int invert;        /* invert input? */
00033   int highpass;      /* use highpass filter? */
00034   double lambda;     /* highpass filter radius */
00035   int scale;         /* scaling factor */
00036   int linear;        /* linear scaling? */
00037   int bilevel;       /* convert to bilevel? */
00038   double level;      /* cutoff grey level */
00039   char *outext;      /* default output file extension */
00040 };
00041 typedef struct info_s info_t;
00042 
00043 static info_t info;
00044 
00045 /* apply highpass filter to greymap. Return 0 on success, 1 on error
00046    with errno set. */
00047 static int highpass(greymap_t *gm, double lambda) {
00048   greymap_t *gm1;
00049   double f, g;
00050   double c, d;
00051   double B;
00052   int x, y;
00053 
00054   /* we obtain a highpass filter by subtracting a lowpass filter from
00055      the identity */
00056   /* create scrap greymap */
00057   gm1 = gm_new(gm->w, gm->h);
00058   if (!gm1) {
00059     return 1;
00060   }
00061 
00062   /* calculate filter coefficients from given lambda */
00063   B =  1+2/(lambda*lambda);
00064   c = B-sqrt(B*B-1);
00065   d = 1-c;
00066 
00067   for (y=0; y<gm->h; y++) {
00068     /* apply low-pass filter to row y */
00069     /* left-to-right */
00070     f = g = 0;
00071     for (x=0; x<gm->w; x++) {
00072       f = f*c + GM_GET(gm, x, y)*d;
00073       g = g*c + f*d;
00074       GM_UPUT(gm1, x, y, g);
00075     }
00076 
00077     /* right-to-left */
00078     for (x=gm->w-1; x>=0; x--) {
00079       f = f*c + GM_GET(gm1, x, y)*d;
00080       g = g*c + f*d;
00081       GM_UPUT(gm1, x, y, g);
00082     }
00083 
00084     /* left-to-right mop-up */
00085     for (x=0; x<gm->w; x++) {
00086       f = f*c;
00087       g = g*c + f*d;
00088       if (f+g < 1/255.0) {
00089         break;
00090       }
00091       GM_UPUT(gm1, x, y, GM_GET(gm1, x, y)+g);
00092     }
00093   }
00094 
00095   for (x=0; x<gm->w; x++) {
00096     /* apply low-pass filter to column x */
00097     /* bottom-to-top */
00098     f = g = 0;
00099     for (y=0; y<gm->h; y++) {
00100       f = f*c + GM_GET(gm1, x, y)*d;
00101       g = g*c + f*d;
00102       GM_UPUT(gm1, x, y, g);
00103     }
00104 
00105     /* top-to-bottom */
00106     for (y=gm->h-1; y>=0; y--) {
00107       f = f*c + GM_GET(gm1, x, y)*d;
00108       g = g*c + f*d;
00109       GM_UPUT(gm1, x, y, g);
00110     }
00111 
00112     /* bottom-to-top mop-up */
00113     for (y=0; y<gm->h; y++) {
00114       f = f*c;
00115       g = g*c + f*d;
00116       if (f+g < 1/255.0) {
00117         break;
00118       }
00119       GM_UPUT(gm1, x, y, GM_GET(gm1, x, y)+g);
00120     }
00121   }
00122 
00123   /* original - lo-pass = hi-pass */
00124   for (y=0; y<gm->h; y++) {
00125     for (x=0; x<gm->w; x++) {
00126       f = GM_GET(gm, x, y);
00127       f -= GM_GET(gm1, x, y);
00128       f += 128;    /* normalize! */
00129       GM_PUT(gm, x, y, f);
00130     }
00131   }
00132   gm_free(gm1);
00133   return 0;
00134 }
00135 
00136 /* scale greymap by factor s, using linear interpolation. If
00137    bilevel=0, return a pointer to a greymap_t. If bilevel=1, return a
00138    pointer to a potrace_bitmap_t and use cutoff threshold c (0=black,
00139    1=white).  On error, return NULL with errno set. */
00140 
00141 static void *interpolate_linear(greymap_t *gm, int s, int bilevel, double c) {
00142   int p00, p01, p10, p11;
00143   int i, j, x, y;
00144   double xx, yy, av;
00145   int c1 = 0;
00146   int w, h;
00147   double p0, p1;
00148   greymap_t *gm_out = NULL;
00149   potrace_bitmap_t *bm_out = NULL;
00150 
00151   w = gm->w;
00152   h = gm->h;
00153 
00154   /* allocate output bitmap/greymap */
00155   if (bilevel) {
00156     bm_out = bm_new(w*s, h*s);
00157     if (!bm_out) {
00158       return NULL;
00159     }
00160     bm_clear(bm_out, 0);
00161     c1 = (int)(c*255);
00162   } else {
00163     gm_out = gm_new(w*s, h*s);
00164     if (!gm_out) {
00165       return NULL;
00166     }
00167   }
00168 
00169   /* interpolate */
00170   for (i=0; i<w; i++) {
00171     for (j=0; j<h; j++) {
00172       p00 = GM_GET(gm, i, j);
00173       p01 = GM_GET(gm, i, j+1);
00174       p10 = GM_GET(gm, i+1, j);
00175       p11 = GM_GET(gm, i+1, j+1);
00176       
00177       if (bilevel) {
00178         /* treat two special cases which are very common */
00179         if (p00 < c1 && p01 < c1 && p10 < c1 && p11 < c1) {
00180           for (x=0; x<s; x++) {
00181             for (y=0; y<s; y++) {
00182               BM_PUT(bm_out, i*s+x, j*s+y, 1);
00183             }
00184           }
00185           continue;
00186         }
00187         if (p00 >= c1 && p01 >= c1 && p10 >= c1 && p11 >= c1) {
00188           continue;
00189         }
00190       }
00191       
00192       /* the general case */
00193       for (x=0; x<s; x++) {
00194         xx = x/(double)s;
00195         p0 = p00*(1-xx) + p10*xx;
00196         p1 = p01*(1-xx) + p11*xx;
00197         for (y=0; y<s; y++) {
00198           yy = y/(double)s;
00199           av = p0*(1-yy) + p1*yy;
00200           if (bilevel) {
00201             BM_PUT(bm_out, i*s+x, j*s+y, av < c1);
00202           } else {
00203             GM_PUT(gm_out, i*s+x, j*s+y, av);
00204           }
00205         }
00206       }
00207     }
00208   }
00209   if (bilevel) {
00210     return (void *)bm_out;
00211   } else {
00212     return (void *)gm_out;
00213   }
00214 }
00215 
00216 /* same as interpolate_linear, except use cubic interpolation (slower
00217    and better). */
00218 
00219 /* we need this typedef so that the SAFE_MALLOC macro will work */
00220 typedef double double4[4];
00221 
00222 static void *interpolate_cubic(greymap_t *gm, int s, int bilevel, double c) {
00223   int w, h;
00224   double4 *poly = NULL; /* poly[s][4]: fixed interpolation polynomials */
00225   double p[4];              /* four current points */
00226   double4 *window = NULL; /* window[s][4]: current state */
00227   double t, v;
00228   int k, l, i, j, x, y;
00229   double c1 = 0;
00230   greymap_t *gm_out = NULL;
00231   potrace_bitmap_t *bm_out = NULL;
00232 
00233   SAFE_MALLOC(poly, s, double4);
00234   SAFE_MALLOC(window, s, double4);
00235 
00236   w = gm->w;
00237   h = gm->h;
00238 
00239   /* allocate output bitmap/greymap */
00240   if (bilevel) {
00241     bm_out = bm_new(w*s, h*s);
00242     if (!bm_out) {
00243       goto malloc_error;
00244     }
00245     bm_clear(bm_out, 0);
00246     c1 = c * 255;
00247   } else {
00248     gm_out = gm_new(w*s, h*s);
00249     if (!gm_out) {
00250       goto malloc_error;
00251     }
00252   }
00253 
00254   /* pre-calculate interpolation polynomials */
00255   for (k=0; k<s; k++) {
00256     t = k/(double)s;
00257     poly[k][0] = 0.5 * t * (t-1) * (1-t);
00258     poly[k][1] = -(t+1) * (t-1) * (1-t) + 0.5 * (t-1) * (t-2) * t;
00259     poly[k][2] = 0.5 * (t+1) * t * (1-t) - t * (t-2) * t;
00260     poly[k][3] = 0.5 * t * (t-1) * t;
00261   }
00262 
00263   /* interpolate */
00264   for (y=0; y<h; y++) {
00265     x=0;
00266     for (i=0; i<4; i++) {
00267       for (j=0; j<4; j++) {
00268         p[j] = GM_BGET(gm, x+i-1, y+j-1);
00269       }
00270       for (k=0; k<s; k++) {
00271         window[k][i] = 0.0;
00272         for (j=0; j<4; j++) {
00273           window[k][i] += poly[k][j] * p[j];
00274         }
00275       }
00276     }
00277     while (1) {
00278       for (l=0; l<s; l++) {
00279         for (k=0; k<s; k++) {
00280           v = 0.0;
00281           for (i=0; i<4; i++) {
00282             v += window[k][i] * poly[l][i];
00283           }
00284           if (bilevel) {
00285             BM_PUT(bm_out, x*s+l, y*s+k, v < c1);
00286           } else {
00287             GM_PUT(gm_out, x*s+l, y*s+k, v);
00288           }         
00289         }
00290       }
00291       x++;
00292       if (x>=w) {
00293         break;
00294       }
00295       for (i=0; i<3; i++) {
00296         for (k=0; k<s; k++) {
00297           window[k][i] = window[k][i+1];
00298         }
00299       }
00300       i=3;
00301       for (j=0; j<4; j++) {
00302         p[j] = GM_BGET(gm, x+i-1, y+j-1);
00303       }
00304       for (k=0; k<s; k++) {
00305         window[k][i] = 0.0;
00306         for (j=0; j<4; j++) {
00307           window[k][i] += poly[k][j] * p[j];
00308         }
00309       }
00310     }
00311   }
00312 
00313   free(poly);
00314   free(window);
00315 
00316   if (bilevel) {
00317     return (void *)bm_out;
00318   } else {
00319     return (void *)gm_out;
00320   }
00321 
00322  malloc_error:
00323   free(poly);
00324   free(window);
00325   return NULL;
00326 }
00327 
00328 /* ---------------------------------------------------------------------- */
00329 
00330 /* process a single file, containing one or more images. On error,
00331    print error message to stderr and exit with code 2. On warning,
00332    print warning message to stderr. */
00333 
00334 static void process_file(FILE *fin, FILE *fout, char *infile, char *outfile) {
00335   int r;
00336   greymap_t *gm;
00337   potrace_bitmap_t *bm;
00338   void *sm;
00339   int x, y;
00340   int count;
00341 
00342   for (count=0; ; count++) {
00343     r = gm_read(fin, &gm);
00344     switch (r) {
00345     case -1:  /* system error */
00346       fprintf(stderr, ""MKBITMAP": %s: %s\n", infile, strerror(errno));
00347       exit(2);
00348     case -2:  /* corrupt file format */
00349       fprintf(stderr, ""MKBITMAP": %s: file format error: %s\n", infile, gm_read_error);
00350       exit(2);
00351     case -3:  /* empty file */
00352       if (count>0) {  /* end of file */
00353         return;
00354       }
00355       fprintf(stderr, ""MKBITMAP": %s: empty file\n", infile);
00356       exit(2);
00357     case -4:  /* wrong magic */
00358       if (count>0) {
00359         fprintf(stderr, ""MKBITMAP": %s: warning: junk at end of file\n", infile);
00360         return;
00361       }
00362       fprintf(stderr, ""MKBITMAP": %s: file format not recognized\n", infile);
00363       fprintf(stderr, "Possible input file formats are: pnm (pbm, pgm, ppm), bmp.\n");
00364       exit(2);
00365     case 1:  /* unexpected end of file */
00366       fprintf(stderr, ""MKBITMAP": %s: warning: premature end of file\n", infile);
00367       break;
00368     }
00369     
00370     if (info.invert) {
00371       for (y=0; y<gm->h; y++) {
00372         for (x=0; x<gm->w; x++) {
00373           GM_UPUT(gm, x, y, 255-GM_UGET(gm, x, y));
00374         }
00375       }
00376     }
00377     
00378     if (info.highpass) {
00379       r = highpass(gm, info.lambda);
00380       if (r) {
00381         fprintf(stderr, ""MKBITMAP": %s: %s\n", infile, strerror(errno));
00382         exit(2);
00383       }
00384     }
00385     
00386     if (info.linear) {
00387       sm = interpolate_linear(gm, info.scale, info.bilevel, info.level);
00388     } else {
00389       sm = interpolate_cubic(gm, info.scale, info.bilevel, info.level);
00390     }      
00391     if (!sm) {
00392       fprintf(stderr, ""MKBITMAP": %s: %s\n", infile, strerror(errno));
00393       exit(2);
00394     }
00395     gm_free(gm);
00396     
00397     if (info.bilevel) {
00398       bm = (potrace_bitmap_t *)sm;
00399       bm_writepbm(fout, bm);
00400       bm_free(bm);
00401     } else {
00402       gm = (greymap_t *)sm;
00403       gm_writepgm(fout, gm, NULL, 1, GM_MODE_POSITIVE, 1.0);
00404       gm_free(gm);
00405     }    
00406   }
00407 }
00408 
00409 /* ---------------------------------------------------------------------- */
00410 /* some info functions and option processing */
00411 
00412 static int license(FILE *f) {
00413   fprintf(f, 
00414   "This program is free software; you can redistribute it and/or modify\n"
00415   "it under the terms of the GNU General Public License as published by\n"
00416   "the Free Software Foundation; either version 2 of the License, or\n"
00417   "(at your option) any later version.\n"
00418   "\n"
00419   "This program is distributed in the hope that it will be useful,\n"
00420   "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
00421   "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
00422   "GNU General Public License for more details.\n"
00423   "\n"
00424   "You should have received a copy of the GNU General Public License\n"
00425   "along with this program; if not, write to the Free Software\n"
00426   "Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.\n"
00427           );
00428   return 0;
00429 }
00430 
00431 static int usage(FILE *f) {
00432   fprintf(f, "Usage: "MKBITMAP" [options] [file...]\n");
00433   fprintf(f, "Options:\n");
00434   fprintf(f, " -h, --help           - print this help message and exit\n");
00435   fprintf(f, " -v, --version        - print version info and exit\n");
00436   fprintf(f, " -l, --license        - print license info and exit\n");
00437   fprintf(f, " -o, --output <file>  - output to file\n");
00438   fprintf(f, " -x, --nodefaults     - turn off default options\n");
00439   fprintf(f, "Inversion:\n");
00440   fprintf(f, " -i, --invert         - invert the input (undo 'blackboard' effect)\n");
00441   fprintf(f, "Highpass filtering:\n");
00442   fprintf(f, " -f, --filter <n>     - apply highpass filter with radius n (default 4)\n");
00443   fprintf(f, " -n, --nofilter       - no highpass filtering\n");
00444   fprintf(f, "Scaling:\n");
00445   fprintf(f, " -s, --scale <n>      - scale by integer factor n (default 2)\n");
00446   fprintf(f, " -1, --linear         - use linear interpolation\n");
00447   fprintf(f, " -3, --cubic          - use cubic interpolation (default)\n");
00448   fprintf(f, "Thresholding:\n");
00449   fprintf(f, " -t, --threshold <n>  - set threshold for bilevel conversion (default 0.45)\n");
00450   fprintf(f, " -g, --grey           - no bilevel conversion, output a greymap\n");
00451 
00452   fprintf(f, "\n");
00453   fprintf(f, "Possible input file formats are: pnm (pbm, pgm, ppm), bmp.\n");
00454   fprintf(f, "The default options are: -f 4 -s 2 -3 -t 0.45\n");
00455   
00456   return 0;
00457 }
00458 
00459 static struct option longopts[] = {
00460   {"help",          0, 0, 'h'},
00461   {"version",       0, 0, 'v'},
00462   {"license",       0, 0, 'l'},
00463   {"output",        1, 0, 'o'},
00464   {"reset",         0, 0, 'x'},
00465   {"invert",        0, 0, 'i'},
00466   {"filter",        1, 0, 'f'},
00467   {"nofilter",      0, 0, 'n'},
00468   {"scale",         1, 0, 's'},
00469   {"linear",        0, 0, '1'},
00470   {"cubic",         0, 0, '3'},
00471   {"grey",          0, 0, 'g'},
00472   {"threshold",     1, 0, 't'},
00473   {0, 0, 0, 0}
00474 };
00475 
00476 static char *shortopts = "hvlo:xif:ns:13gt:";
00477 
00478 /* process options. On error, print error message to stderr and exit
00479    with code 1 */
00480 static void dopts(int ac, char *av[]) {
00481   int c;
00482   char *p;
00483   
00484   /* set defaults for command line parameters */
00485   info.outfile = NULL;    /* output file */
00486   info.infiles = NULL;    /* input files */
00487   info.infilecount = 0;   /* how many input files? */
00488   info.invert = 0;        /* invert input? */
00489   info.highpass = 1;      /* use highpass filter? */
00490   info.lambda = 4;        /* highpass filter radius */
00491   info.scale = 2;         /* scaling factor */
00492   info.linear = 0;        /* linear scaling? */
00493   info.bilevel = 1;       /* convert to bilevel? */
00494   info.level = 0.45;      /* cutoff grey level */
00495   info.outext = ".pbm";   /* output file extension */
00496 
00497   while ((c = getopt_long(ac, av, shortopts, longopts, NULL)) != -1) {
00498     switch (c) {
00499     case 'h':
00500       fprintf(stdout, ""MKBITMAP" "VERSION". Transforms images into bitmaps with scaling and filtering.\n\n");
00501       usage(stdout);
00502       exit(0);
00503       break;
00504     case 'v':
00505       fprintf(stdout, ""MKBITMAP" "VERSION". Copyright (C) 2001-2007 Peter Selinger.\n");
00506       exit(0);
00507       break;
00508     case 'l':
00509       fprintf(stdout, ""MKBITMAP" "VERSION". Copyright (C) 2001-2007 Peter Selinger.\n\n");
00510       license(stdout);
00511       exit(0);
00512       break;
00513     case 'o':
00514       free(info.outfile);
00515       info.outfile = strdup(optarg);
00516       break;
00517     case 'x':
00518       info.invert = 0;
00519       info.highpass = 0;
00520       info.scale = 1;
00521       info.bilevel = 0;
00522       info.outext = ".pgm";
00523       break;
00524     case 'i':
00525       info.invert = 1;
00526       break;
00527     case 'f':
00528       info.highpass = 1;
00529       info.lambda = strtod(optarg, &p);
00530       if (*p || info.lambda<0) {
00531         fprintf(stderr, ""MKBITMAP": invalid filter radius -- %s\n", optarg);
00532         exit(1);
00533       }
00534       break;
00535     case 'n':
00536       info.highpass = 0;
00537       break;
00538     case 's':
00539       info.scale = strtol(optarg, &p, 0);
00540       if (*p || info.scale<=0) {
00541         fprintf(stderr, ""MKBITMAP": invalid scaling factor -- %s\n", optarg);
00542         exit(1);
00543       }
00544       break;
00545     case '1':
00546       info.linear = 1;
00547       break;
00548     case '3':
00549       info.linear = 0;
00550       break;
00551     case 'g':
00552       info.bilevel = 0;
00553       info.outext = ".pgm";
00554       break;
00555     case 't':
00556       info.bilevel = 1;
00557       info.outext = ".pbm";
00558       info.level = strtod(optarg, &p);
00559       if (*p || info.level<0) {
00560         fprintf(stderr, ""MKBITMAP": invalid threshold -- %s\n", optarg);
00561         exit(1);
00562       }
00563       break;
00564     case '?':
00565       fprintf(stderr, "Try --help for more info\n");
00566       exit(1);
00567       break;
00568     default:
00569       fprintf(stderr, ""MKBITMAP": Unimplemented option -- %c\n", c);
00570       exit(1);
00571     }
00572   }
00573   info.infiles = &av[optind];
00574   info.infilecount = ac-optind;
00575   return;
00576 }
00577 
00578 /* ---------------------------------------------------------------------- */
00579 /* auxiliary functions for file handling */
00580 
00581 /* open a file for reading. Return stdin if filename is NULL or "-" */ 
00582 static FILE *my_fopen_read(char *filename) {
00583   if (filename == NULL || strcmp(filename, "-") == 0) {
00584     return stdin;
00585   }
00586   return fopen(filename, "rb");
00587 }
00588 
00589 /* open a file for writing. Return stdout if filename is NULL or "-" */ 
00590 static FILE *my_fopen_write(char *filename) {
00591   if (filename == NULL || strcmp(filename, "-") == 0) {
00592     return stdout;
00593   }
00594   return fopen(filename, "wb");
00595 }
00596 
00597 /* close a file, but do nothing is filename is NULL or "-" */
00598 static void my_fclose(FILE *f, char *filename) {
00599   if (filename == NULL || strcmp(filename, "-") == 0) {
00600     return;
00601   }
00602   fclose(f);
00603 }
00604 
00605 /* make output filename from input filename. Return an allocated value. */
00606 static char *make_outfilename(char *infile, char *ext) {
00607   char *outfile;
00608   char *p;
00609 
00610   if (strcmp(infile, "-") == 0) {
00611     return strdup("-");
00612   }
00613 
00614   outfile = (char *) malloc(strlen(infile)+strlen(ext)+5);
00615   if (!outfile) {
00616     return NULL;
00617   }
00618   strcpy(outfile, infile);
00619   p = strrchr(outfile, '.');
00620   if (p) {
00621     *p = 0;
00622   }
00623   strcat(outfile, ext);
00624 
00625   /* check that input and output filenames are different */
00626   if (strcmp(infile, outfile) == 0) {
00627     strcpy(outfile, infile);
00628     strcat(outfile, "-out");
00629   }
00630 
00631   return outfile;
00632 }
00633 
00634 /* ---------------------------------------------------------------------- */
00635 /* Main function */
00636 
00637 int main(int ac, char *av[]) {
00638   FILE *fin, *fout;
00639   int i;
00640   char *outfile;
00641 
00642   /* platform-specific initializations, e.g., set file i/o to binary */
00643   platform_init();
00644 
00645   /* process options */
00646   dopts(ac, av);
00647 
00648   /* there are several ways to call us:
00649      mkbitmap                    -- stdin to stdout
00650      mkbitmap -o outfile         -- stdin to outfile
00651      mkbitmap file...            -- encode each file and generate outfile names
00652      mkbitmap file... -o outfile -- concatenate files and write to outfile
00653   */
00654 
00655   if (info.infilecount == 0 && info.outfile == NULL) {  /* stdin to stdout */
00656 
00657     process_file(stdin, stdout, "stdin", "stdout");
00658     return 0;
00659 
00660   } else if (info.infilecount == 0) {                  /* stdin to outfile */
00661 
00662     fout = my_fopen_write(info.outfile);
00663     if (!fout) {
00664       fprintf(stderr, ""MKBITMAP": %s: %s\n", info.outfile, strerror(errno));
00665       exit(2);
00666     }
00667     process_file(stdin, fout, "stdin", info.outfile);
00668     my_fclose(fout, info.outfile);
00669     return 0;
00670 
00671   } else if (info.outfile == NULL) {       /* infiles -> multiple outfiles */
00672 
00673     for (i=0; i<info.infilecount; i++) {
00674       outfile = make_outfilename(info.infiles[i], info.outext);
00675       if (!outfile) {
00676         fprintf(stderr, ""MKBITMAP": %s\n", strerror(errno));
00677         exit(2);
00678       }
00679       fin = my_fopen_read(info.infiles[i]);
00680       if (!fin) {
00681         fprintf(stderr, ""MKBITMAP": %s: %s\n", info.infiles[i], strerror(errno));
00682         exit(2);
00683       }
00684       fout = my_fopen_write(outfile);
00685       if (!fout) {
00686         fprintf(stderr, ""MKBITMAP": %s: %s\n", outfile, strerror(errno));
00687         exit(2);
00688       }
00689       process_file(fin, fout, info.infiles[i], outfile);
00690       my_fclose(fin, info.infiles[i]);
00691       my_fclose(fout, outfile);
00692       free(outfile);
00693     }
00694     return 0;
00695 
00696   } else {                                    /* infiles to single outfile */
00697 
00698     fout = my_fopen_write(info.outfile);
00699     if (!fout) {
00700       fprintf(stderr, ""MKBITMAP": %s: %s\n", info.outfile, strerror(errno));
00701       exit(2);
00702     }
00703     for (i=0; i<info.infilecount; i++) {
00704       fin = my_fopen_read(info.infiles[i]);
00705       if (!fin) {
00706         fprintf(stderr, ""MKBITMAP": %s: %s\n", info.infiles[i], strerror(errno));
00707         exit(2);
00708       }
00709       process_file(fin, fout, info.infiles[i], info.outfile);
00710       my_fclose(fin, info.infiles[i]);
00711     }
00712     my_fclose(fout, info.outfile);
00713     return 0;
00714 
00715   }      
00716 
00717   /* not reached */
00718 }
00719 
00720 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines


portrait_painter
Author(s): Niklas Meinzer, Ina Baumgarten
autogenerated on Wed Dec 26 2012 16:00:43