Back to index

radiance  4R0+20100331
meta2tga.c
Go to the documentation of this file.
00001 #ifndef lint
00002 static const char    RCSid[] = "$Id: meta2tga.c,v 1.6 2004/02/04 18:49:24 greg Exp $";
00003 #endif
00004 /*
00005  *  Program to convert meta-files to Targa 8-bit color-mapped format
00006  */
00007 
00008 #include  "copyright.h"
00009 
00010 #include  "rtprocess.h"
00011 #include  "meta.h"
00012 #include  "plot.h"
00013 #include  "rast.h"
00014 #include  "targa.h"
00015 
00016 #define  MAXALLOC  30000
00017 #define  DXSIZE  400        /* default x resolution */
00018 #define  DYSIZE  400        /* default y resolution */
00019 #define  XCOM  "pexpand +vOCImsp -DP %s | psort +y"
00020 
00021 
00022 char  *progname;
00023 
00024 SCANBLOCK     outblock;
00025 
00026 int  dxsize = DXSIZE, dysize = DYSIZE;
00027 
00028 int  maxalloc = MAXALLOC;
00029 
00030 int  ydown = 0;
00031 
00032 static char  outname[64];
00033 static char  *outtack = NULL;
00034 
00035 static FILE  *fout;
00036 
00037 static int  lineno = 0; 
00038 
00039 static short  condonly = FALSE,
00040              conditioned = FALSE;
00041 
00042 static int putthead(struct hdStruct  *hp, char  *ip, FILE  *fp);
00043 
00044 
00045 
00046 char *
00047 findtack(s)                 /* find place to tack on suffix */
00048 register char *s;
00049 {
00050        while (*s && *s != '.')
00051               s++;
00052        return(s);
00053 }
00054 
00055 
00056 int
00057 main(
00058        int  argc,
00059        char  **argv
00060 )
00061 
00062 {
00063  FILE  *fp;
00064  char  comargs[200], command[300];
00065 
00066   fout = stdout;
00067  progname = *argv++;
00068  argc--;
00069 
00070  condonly = FALSE;
00071  conditioned = FALSE;
00072  
00073  while (argc && **argv == '-')  {
00074     switch (*(*argv+1))  {
00075        case 'c':
00076          condonly = TRUE;
00077          break;
00078        case 'r':
00079          conditioned = TRUE;
00080          break;
00081        case 'm':
00082          minwidth = atoi(*++argv);
00083          argc--;
00084          break;
00085        case 'x':
00086          dxsize = atoi(*++argv);
00087          argc--;
00088          break;
00089        case 'y':
00090          dysize = atoi(*++argv);
00091          argc--;
00092          break;
00093        case 'o':
00094          strcpy(outname, *++argv);
00095          outtack = findtack(outname);
00096          argc--;
00097          break;
00098        default:
00099          error(WARNING, "unknown option");
00100          break;
00101        }
00102     argv++;
00103     argc--;
00104     }
00105 
00106  if (conditioned) {
00107     if (argc)
00108        while (argc)  {
00109          fp = efopen(*argv, "r");
00110          plot(fp);
00111          fclose(fp);
00112          argv++;
00113          argc--;
00114          }
00115     else
00116        plot(stdin);
00117     if (lineno)
00118        nextpage();
00119  } else  {
00120     comargs[0] = '\0';
00121     while (argc)  {
00122        strcat(comargs, " ");
00123        strcat(comargs, *argv);
00124        argv++;
00125        argc--;
00126        }
00127     sprintf(command, XCOM, comargs);
00128     if (condonly)
00129        return(system(command));
00130     else  {
00131        if ((fp = popen(command, "r")) == NULL)
00132           error(SYSTEM, "cannot execute input filter");
00133        plot(fp);
00134        pclose(fp);
00135        if (lineno)
00136          nextpage();
00137        }
00138     }
00139 
00140  return(0);
00141  }
00142 
00143 
00144 
00145 void
00146 thispage(void)              /* rewind current file */
00147 {
00148     if (lineno)
00149        error(USER, "cannot restart page in thispage");
00150 }
00151 
00152 
00153 void
00154 initfile(void)              /* initialize this file */
00155 {
00156     static int  filenum = 0;
00157     /*
00158     static unsigned char  cmap[24] = {255,255,255, 255,152,0, 0,188,0, 0,0,255,
00159                      179,179,0, 255,0,255, 0,200,200, 0,0,0};
00160      */
00161     static unsigned char  cmap[24] = {0,0,0, 0,0,255, 0,188,0, 255,152,0,
00162                      0,200,200, 255,0,255, 179,179,0, 255,255,255};
00163     struct hdStruct  thead;
00164     register int  i;
00165 
00166     if (outtack != NULL) {
00167        sprintf(outtack, "%d.tga", ++filenum);
00168        fout = efopen(outname, "w");
00169     }
00170     if (fout == NULL)
00171        error(USER, "no output file");
00172     thead.mapType = CM_HASMAP;
00173     thead.dataType = IM_CCMAP;
00174     thead.mapOrig = 0;
00175     thead.mapLength = 256;
00176     thead.CMapBits = 24;
00177     thead.XOffset = 0;
00178     thead.YOffset = 0;
00179     thead.x = dxsize;
00180     thead.y = dysize;
00181     thead.dataBits = 8;
00182     thead.imType = 0;
00183     putthead(&thead, NULL, fout);
00184     for (i = 0; i < 8*3; i++)
00185        putc(cmap[i], fout);
00186     while (i++ < 256*3)
00187        putc(0, fout);
00188 }
00189 
00190 
00191 
00192 void
00193 nextpage(void)              /* advance to next page */
00194 
00195 {
00196 
00197     if (lineno == 0)
00198        return;
00199     if (fout != NULL) {
00200        while (lineno < dysize) {
00201            nextblock();
00202            outputblock();
00203        }
00204        fclose(fout);
00205        fout = NULL;
00206     }
00207     lineno = 0;
00208 
00209 }
00210 
00211 
00212 
00213 #define MINRUN       4
00214 
00215 extern void
00216 printblock(void)            /* output scanline block to file */
00217 
00218 {
00219     int  i, c2;
00220     register unsigned char  *scanline;
00221     register int  j, beg, cnt = 0;
00222 
00223     if (lineno == 0)
00224        initfile();
00225     for (i = outblock.ybot; i <= outblock.ytop && i < dysize; i++) {
00226        scanline = outblock.cols[i-outblock.ybot];
00227        for (j = outblock.xleft; j <= outblock.xright; j += cnt) {
00228            for (beg = j; beg <= outblock.xright; beg += cnt) {
00229               for (cnt = 1; cnt < 128 && beg+cnt <= outblock.xright &&
00230                      scanline[beg+cnt] == scanline[beg]; cnt++)
00231                   ;
00232               if (cnt >= MINRUN)
00233                   break;                  /* long enough */
00234            }
00235            while (j < beg) {              /* write out non-run */
00236               if ((c2 = beg-j) > 128) c2 = 128;
00237               putc(c2-1, fout);
00238               while (c2--)
00239                   putc(scanline[j++], fout);
00240            }
00241            if (cnt >= MINRUN) {           /* write out run */
00242               putc(127+cnt, fout);
00243               putc(scanline[beg], fout);
00244            } else
00245               cnt = 0;
00246        }
00247        lineno++;
00248     }
00249     
00250 }
00251 
00252 
00253 void
00254 putint2(                    /* put a 2-byte positive integer */
00255        register int  i,
00256        register FILE *fp
00257 )
00258 {
00259        putc(i&0xff, fp);
00260        putc(i>>8&0xff, fp);
00261 }
00262 
00263 
00264 int
00265 putthead(            /* write header to output */
00266        struct hdStruct  *hp,
00267        char  *ip,
00268        register FILE  *fp
00269 )
00270 {
00271        if (ip != NULL)
00272               putc(strlen(ip), fp);
00273        else
00274               putc(0, fp);
00275        putc(hp->mapType, fp);
00276        putc(hp->dataType, fp);
00277        putint2(hp->mapOrig, fp);
00278        putint2(hp->mapLength, fp);
00279        putc(hp->CMapBits, fp);
00280        putint2(hp->XOffset, fp);
00281        putint2(hp->YOffset, fp);
00282        putint2(hp->x, fp);
00283        putint2(hp->y, fp);
00284        putc(hp->dataBits, fp);
00285        putc(hp->imType, fp);
00286 
00287        if (ip != NULL)
00288               fputs(ip, fp);
00289 
00290        return(ferror(fp) ? -1 : 0);
00291 }