about summary refs log tree commit diff
path: root/converter/ppm/ppmtoarbtxt.c
diff options
context:
space:
mode:
Diffstat (limited to 'converter/ppm/ppmtoarbtxt.c')
-rw-r--r--converter/ppm/ppmtoarbtxt.c505
1 files changed, 505 insertions, 0 deletions
diff --git a/converter/ppm/ppmtoarbtxt.c b/converter/ppm/ppmtoarbtxt.c
new file mode 100644
index 00000000..774a47c4
--- /dev/null
+++ b/converter/ppm/ppmtoarbtxt.c
@@ -0,0 +1,505 @@
+/* ppmtoarbtxt.c - convert portable pixmap to cleartext
+**
+** Renamed from ppmtotxt.c by Bryan Henderson in January 2003.
+**
+** Copyright (C) 1995 by Peter Kirchgessner
+**
+** Permission to use, copy, modify, and distribute this software and its
+** documentation for any purpose and without fee is hereby granted, provided
+** that the above copyright notice appear in all copies and that both that
+** copyright notice and this permission notice appear in supporting
+** documentation.  This software is provided "as is" without express or
+** implied warranty.
+*/
+
+#include <string.h>
+
+#include "ppm.h"
+#include "mallocvar.h"
+#include "nstring.h"
+
+typedef enum {
+/* The types of object we handle */
+    BDATA, IRED, IGREEN, IBLUE, ILUM, FRED, FGREEN, FBLUE, FLUM,
+    WIDTH, HEIGHT, POSX, POSY
+} SKL_OBJ_TYP;
+
+/* Maximum size for a format string ("%d" etc.) */
+#define MAXFORMAT 16
+
+/* The data we keep for each object */
+typedef union
+ {
+  struct BNDAT { char *bdat;   /* Binary data (text with newlines etc.) */
+                 int ndat;
+               } bin_data;
+
+  struct ICDAT { char icformat[MAXFORMAT];  /* Integer colors */
+                 int icolmin, icolmax;
+               } icol_data;
+
+  struct FCDAT { char fcformat[MAXFORMAT];  /* Float colors */
+                 double fcolmin, fcolmax;
+               } fcol_data;
+
+  struct IDAT  { char iformat[MAXFORMAT];   /* Integer data */
+               } i_data;
+ } SKL_OBJ_DATA;
+
+
+/* Each object has a type and some data */
+typedef struct
+ { 
+   SKL_OBJ_TYP otyp;
+   SKL_OBJ_DATA odata;
+ } SKL_OBJ;
+
+
+#define MAX_SKL_HEAD_OBJ 64
+#define MAX_SKL_BODY_OBJ 256
+#define MAX_SKL_TAIL_OBJ 64
+#define MAX_LINE_BUF 1024
+#define MAX_OBJ_BUF 80
+
+
+static void write_txt (fout, nobj, obj, width, height, x, y, red, green, blue)
+FILE *fout;
+int nobj;
+SKL_OBJ *obj[];
+int width, height, x, y;
+double red, green, blue;
+
+{register int count;
+
+#define WRITE_BNDAT(fd,theobj) \
+ {struct BNDAT *bdata = &((theobj)->odata.bin_data); \
+       fwrite (bdata->bdat,bdata->ndat,1,fd); }
+
+#define WRITE_ICOL(fd,theobj,thecol) \
+ {struct ICDAT *icdata = &((theobj)->odata.icol_data); \
+  fprintf (fd,icdata->icformat,(int)(icdata->icolmin \
+                + (icdata->icolmax - icdata->icolmin)*(thecol))); }
+
+#define WRITE_FCOL(fd,theobj,thecol) \
+ {struct FCDAT *fcdata = &((theobj)->odata.fcol_data); \
+  fprintf (fd,fcdata->fcformat,(double)(fcdata->fcolmin \
+                + (fcdata->fcolmax - fcdata->fcolmin)*(thecol))); }
+
+#define WRITE_IDAT(fd,theobj,thedat) \
+ {struct IDAT *idata = &((theobj)->odata.i_data); \
+  fprintf (fd,idata->iformat,thedat); }
+
+ for (count = 0; count < nobj; count++)
+ {
+   switch (obj[count]->otyp)
+   {
+     case BDATA:
+       WRITE_BNDAT (fout,obj[count]);
+       break;
+     case IRED:
+       WRITE_ICOL (fout,obj[count],red);
+       break;
+     case IGREEN:
+       WRITE_ICOL (fout,obj[count],green);
+       break;
+     case IBLUE:
+       WRITE_ICOL (fout,obj[count],blue);
+       break;
+     case ILUM:
+       WRITE_ICOL (fout,obj[count],0.299*red+0.587*green+0.114*blue);
+       break;
+     case FRED:
+       WRITE_FCOL (fout,obj[count],red);
+       break;
+     case FGREEN:
+       WRITE_FCOL (fout,obj[count],green);
+       break;
+     case FBLUE:
+       WRITE_FCOL (fout,obj[count],blue);
+       break;
+     case FLUM:
+       WRITE_FCOL (fout,obj[count],0.299*red+0.587*green+0.114*blue);
+       break;
+     case WIDTH:
+       WRITE_IDAT (fout,obj[count],width);
+       break;
+     case HEIGHT:
+       WRITE_IDAT (fout,obj[count],height);
+       break;
+     case POSX:
+       WRITE_IDAT (fout,obj[count],x);
+       break;
+     case POSY:
+       WRITE_IDAT (fout,obj[count],y);
+       break;
+   }
+ }
+}
+
+
+static SKL_OBJ *
+save_bin_data(int    const ndat, 
+              char * const bdat) {
+
+    /* Save binary data in Object */
+
+    SKL_OBJ *obj;
+
+    obj = (SKL_OBJ *)malloc (sizeof (SKL_OBJ) + ndat);
+    if (obj != NULL)
+    {
+        obj->otyp = BDATA;
+        obj->odata.bin_data.ndat = ndat;
+        obj->odata.bin_data.bdat = ((char *)(obj))+sizeof (SKL_OBJ);
+        memcpy (obj->odata.bin_data.bdat,bdat,ndat);
+    }
+    return (obj);
+}
+
+
+
+/* Save integer color data in Object */
+static SKL_OBJ *save_icol_data (ctyp,format,icolmin,icolmax)
+SKL_OBJ_TYP ctyp;
+char *format;
+int icolmin, icolmax;
+
+{SKL_OBJ *obj;
+
+ obj = (SKL_OBJ *)malloc (sizeof (SKL_OBJ));
+ if (obj != NULL)
+ {
+   obj->otyp = ctyp;
+   strcpy (obj->odata.icol_data.icformat,format);
+   obj->odata.icol_data.icolmin = icolmin;
+   obj->odata.icol_data.icolmax = icolmax;
+ }
+ return (obj);
+}
+
+
+/* Save float color data in Object */
+static SKL_OBJ *save_fcol_data (ctyp,format,fcolmin,fcolmax)
+SKL_OBJ_TYP ctyp;
+char *format;
+double fcolmin, fcolmax;
+
+{SKL_OBJ *obj;
+
+ obj = (SKL_OBJ *)malloc (sizeof (SKL_OBJ));
+ if (obj != NULL)
+ {
+   obj->otyp = ctyp;
+   strcpy (obj->odata.fcol_data.fcformat,format);
+   obj->odata.fcol_data.fcolmin = fcolmin;
+   obj->odata.fcol_data.fcolmax = fcolmax;
+ }
+ return (obj);
+}
+
+
+/* Save universal data in Object */
+static SKL_OBJ *save_i_data (ctyp,format)
+SKL_OBJ_TYP ctyp;
+char *format;
+
+{SKL_OBJ *obj;
+
+ obj = (SKL_OBJ *)malloc (sizeof (SKL_OBJ));
+ if (obj != NULL)
+ {
+   obj->otyp = ctyp;
+   strcpy (obj->odata.i_data.iformat,format);
+ }
+ return (obj);
+}
+
+
+/* Read skeleton file */
+static int read_skeleton (filename,maxskl,nskl,skl)
+char *filename;
+int maxskl,*nskl;
+SKL_OBJ **skl;
+
+{FILE *sklfile;
+ int slen, objlen, chr, n_odata;
+ int icolmin,icolmax;
+ double fcolmin,fcolmax;
+ SKL_OBJ_TYP otyp;
+ char line[MAX_LINE_BUF+MAX_OBJ_BUF+16];
+ char objstr[MAX_OBJ_BUF],typstr[MAX_OBJ_BUF];
+ char formstr[MAX_OBJ_BUF];
+ char meta1 = '#', meta2 = '(', meta3 = ')';
+
+#define SAVE_BIN(slen,line) \
+ { if ((skl[*nskl] = save_bin_data (slen,line)) != NULL) (*nskl)++; \
+   slen = 0; }
+
+#define ADD_STR(slen,line,addlen,addstr) \
+ {int count=0; line[slen++] = meta1; line[slen++] = meta2; \
+  while (count++ < addlen) line[slen++] = addstr[count]; }
+
+ if ((sklfile = fopen (filename,"r")) == NULL)
+   return (-1);
+
+ /* Parse skeleton file */
+ *nskl = 0;
+
+ slen = 0;
+ while ((chr = getc (sklfile)) != EOF)   /* Up to end of skeleton file */
+ {
+   if (*nskl >= maxskl) return (-1);
+
+   if (slen+1 >= MAX_LINE_BUF)   /* Buffer finished ? Save as binary object */
+   {
+     SAVE_BIN (slen,line);
+   }
+
+   if (chr != meta1)      /* Look for start of replacement string */
+   {
+     line[slen++] = chr;
+     continue;
+   }
+
+   if ((chr = getc (sklfile)) == EOF)
+   {
+     line[slen++] = meta1;
+     break;
+   }
+   if (chr != meta2) /* '(' ? Otherwise no replacement */
+   {
+     line[slen++] = meta1;
+     line[slen++] = chr;
+     continue;
+   }
+
+   objlen = 0;
+   for (;;)   /* Read replacement string up to ')' */
+   {
+     if (objlen == sizeof (objstr)) break; /* ')' not found */
+     if ((chr = getc (sklfile)) == EOF) break;
+     if (chr == meta3) break;
+     objstr[objlen++] = chr;
+   }
+   objstr[objlen] = '\0'; /* Now objstr keeps data without metas */
+
+   if (chr != meta3)    /* Object not found ? */
+   {
+     ADD_STR (slen,line,objlen,objstr);   /* Save what we already read */
+     if (chr == EOF) break;
+     continue;
+   }
+
+   typstr[0] = '\0';           /* Get typ of data */
+   sscanf (objstr,"%s",typstr);
+
+                   /* Check for integer colors */
+   if      (STREQ(typstr,"ired")  ) otyp = IRED;
+   else if (STREQ(typstr,"igreen")) otyp = IGREEN;
+   else if (STREQ(typstr,"iblue") ) otyp = IBLUE;
+   else if (STREQ(typstr,"ilum")  ) otyp = ILUM;
+                   /* Check for real colors */
+   else if (STREQ(typstr,"fred")  ) otyp = FRED;
+   else if (STREQ(typstr,"fgreen")) otyp = FGREEN;
+   else if (STREQ(typstr,"fblue") ) otyp = FBLUE;
+   else if (STREQ(typstr,"flum")  ) otyp = FLUM;
+                   /* Check for integer data */
+   else if (STREQ(typstr,"width") ) otyp = WIDTH;
+   else if (STREQ(typstr,"height")) otyp = HEIGHT;
+   else if (STREQ(typstr,"posx")  ) otyp = POSX;
+   else if (STREQ(typstr,"posy")  ) otyp = POSY;
+   else                                    otyp = BDATA;
+
+   if ((otyp == IRED) || (otyp == IGREEN) || (otyp == IBLUE) || (otyp == ILUM))
+   {
+     n_odata = sscanf (objstr,"%*s%s%d%d",formstr,&icolmin,&icolmax);
+
+     if (n_odata == EOF)  /* No arguments specified ? Use defaults */
+     {
+       strcpy (formstr,"%d"); icolmin = 0; icolmax = 255;
+     }
+     else if (n_odata != 3)  /* Wrong specification */
+     {
+       otyp = BDATA;
+     }
+   }
+
+   if ((otyp == FRED) || (otyp == FGREEN) || (otyp == FBLUE) || (otyp == FLUM))
+   {
+     n_odata = sscanf (objstr,"%*s%s%lf%lf",formstr,&fcolmin,&fcolmax);
+
+     if (n_odata == EOF)  /* No arguments specified ? Use defaults */
+     {
+       strcpy (formstr,"%f"); fcolmin = 0.0; fcolmax = 1.0;
+     }
+     else if (n_odata != 3)  /* Wrong specification */
+     {
+       otyp = BDATA;
+     }
+   }
+
+   if (   (otyp == WIDTH) || (otyp == HEIGHT)
+       || (otyp == POSX) || (otyp == POSY))
+   {
+     n_odata = sscanf (objstr,"%*s%s",formstr);
+
+     if (n_odata == EOF)  /* No arguments specified ? Use defaults */
+     {
+       strcpy (formstr,"%d");
+     }
+     else if (n_odata != 1)  /* Wrong specification */
+     {
+       otyp = BDATA;
+     }
+   }
+
+   if (otyp != BDATA)   /* Got an object definition ? */
+   {
+     if (slen > 0)      /* Save what we already found */
+     {
+       SAVE_BIN (slen,line);
+     }
+   }
+
+   /* Now process the object in objstr */
+   switch (otyp)
+   {
+     case BDATA:   /* Bad object definition ? Save as text */
+       ADD_STR (slen,line,objlen,objstr);
+       break;
+
+     case IRED:
+     case IGREEN:
+     case IBLUE:
+     case ILUM:
+       skl[*nskl] = save_icol_data (otyp,formstr,icolmin,icolmax);
+       if (skl[*nskl] != NULL) (*nskl)++;
+       break;
+
+     case FRED:
+     case FGREEN:
+     case FBLUE:
+     case FLUM:
+       skl[*nskl] = save_fcol_data (otyp,formstr,fcolmin,fcolmax);
+       if (skl[*nskl] != NULL) (*nskl)++;
+       break;
+
+     case WIDTH:
+     case HEIGHT:
+     case POSX:
+     case POSY:
+       skl[*nskl] = save_i_data (otyp,formstr);
+       if (skl[*nskl] != NULL) (*nskl)++;
+       break;
+   }
+ } /* EOF of skeleton file */
+
+ if (slen > 0)      /* Drop finishing newline character */
+ {
+   if (line[slen-1] == '\n') slen--;
+ }
+
+ if (slen > 0)      /* Something left ? */
+ {
+   SAVE_BIN (slen,line);   /* Save it */
+ }
+
+ fclose (sklfile);
+ return (0);
+}
+
+
+int main( argc, argv )
+int argc;
+char* argv[];
+
+{register int col;
+ register pixel* xP;
+ pixel* pixelrow;
+ pixval maxval,red,green,blue;
+ double dmaxval;
+ int argn, rows, cols, format, row;
+ int head_nskl,body_nskl,tail_nskl;
+ SKL_OBJ *head_skl[MAX_SKL_HEAD_OBJ];
+ SKL_OBJ *body_skl[MAX_SKL_BODY_OBJ];
+ SKL_OBJ *tail_skl[MAX_SKL_TAIL_OBJ];
+ FILE *ifp;
+ const char *usage = "bodyskl [ -hd headskl ] [ -tl tailskl ] [pnmfile]";
+
+ ppm_init( &argc, argv );
+
+ argn = 1;
+ if (argn == argc)
+   pm_usage( usage );
+                          /* Read body skeleton file */
+ if (read_skeleton (argv[argn],sizeof (body_skl)/sizeof (SKL_OBJ *),
+                    &body_nskl,body_skl) < 0)
+   pm_usage ( usage );
+ ++argn;
+
+ head_nskl = tail_nskl = 0;
+
+ while ( argn < argc && argv[argn][0] == '-' && argv[argn][1] != '\0')
+ {
+   if ( pm_keymatch ( argv[argn], "-hd", 1) && argn+1 < argc )
+   {
+     argn++;           /* Read header skeleton */
+     if (read_skeleton (argv[argn],sizeof (head_skl)/sizeof (SKL_OBJ *),
+                        &head_nskl,head_skl) < 0)
+       pm_usage ( usage );
+   }
+   else if ( pm_keymatch ( argv[argn], "-tl", 1) && argn+1 < argc )
+   {
+     argn++;           /* Read tail skeleton */
+     if (read_skeleton (argv[argn],sizeof (tail_skl)/sizeof (SKL_OBJ *),
+                        &tail_nskl,tail_skl) < 0)
+       pm_usage ( usage );
+   }
+   else
+   {
+     pm_usage ( usage );
+   }
+   argn++;
+ }
+
+ if ( argn != argc )
+ {
+   ifp = pm_openr( argv[argn] );
+   ++argn;
+ }
+ else 
+ {
+   ifp = stdin;
+ }
+
+ if ( argn != argc )
+   pm_usage( usage );
+
+ ppm_readppminit( ifp, &cols, &rows, &maxval, &format );
+ pixelrow = ppm_allocrow( cols );
+ dmaxval = (double)maxval;
+
+ if (head_nskl > 0)    /* Write header */
+   write_txt (stdout,head_nskl,head_skl,cols,rows,0,0,0.0,0.0,0.0);
+
+ for ( row = 0; row < rows; ++row )
+ {
+   ppm_readppmrow( ifp, pixelrow, cols, maxval, format );
+
+   for ( col = 0, xP = pixelrow; col < cols; ++col, ++xP )
+   {
+     red = PPM_GETR( *xP );
+     green = PPM_GETG( *xP );
+     blue = PPM_GETB( *xP );
+     write_txt (stdout,body_nskl,body_skl,cols,rows,col,row,
+                red/dmaxval,green/dmaxval,blue/dmaxval);
+   }
+ }
+
+ if (tail_nskl > 0)    /* Write trailer */
+   write_txt (stdout,tail_nskl,tail_skl,cols,rows,0,0,0.0,0.0,0.0);
+
+ pm_close( ifp );
+
+ exit( 0 );
+}