home *** CD-ROM | disk | FTP | other *** search
/ vsiftp.vmssoftware.com / VSIPUBLIC@vsiftp.vmssoftware.com.tar / FREEWARE / FREEWARE40.ZIP / xv310a / xvxpm.c < prev    next >
C/C++ Source or Header  |  1995-06-12  |  18KB  |  699 lines

  1. /*
  2.  * xvxpm.c - load routine for X11 XPM v3 format pictures
  3.  *
  4.  * LoadXPM(fname,pinfo)
  5.  * WriteXPM(fp,pic,ptype,w,h,rp,gp,bp,nc,col,name)
  6.  */
  7.  
  8. /*
  9.  * Written by Chris P. Ross (cross@eng.umd.edu) to support XPM v3
  10.  * format images.
  11.  *
  12.  * Thanks go to Sam Yates (syates@spam.maths.adelaide.edu.au) for
  13.  * provideing inspiration.
  14.  */
  15.  
  16. #define VALUES_LEN    80    /* Max length of values line */
  17. #define TOKEN_LEN    8    /* Max length of color token */
  18.  
  19. #include "xv.h"
  20.  
  21.  
  22. /*
  23.  * File format:
  24.  *  (A file format def should go here)
  25.  *
  26.  */
  27.  
  28. typedef struct hent {
  29.   char        token[TOKEN_LEN];
  30.   union {
  31.     byte      index;
  32.     byte      rgb[3];
  33.   } color_val;
  34.   struct hent *next;
  35. } hentry;
  36.  
  37. #define cv_index    color_val.index
  38. #define cv_rgb        color_val.rgb
  39.  
  40.  
  41.  
  42. /* Local (Global) Variables */
  43. static byte    hex[256];
  44. static hentry **hashtab;        /* Hash table */
  45. static int      hash_len;       /* number of hash buckets */
  46. static int    bufchar;    /* Buffered character from XpmGetc */
  47. static short    in_quote;    /* Is the current point in the file in */
  48.                                 /*  a quoted string? */
  49.  
  50. /* Local Functions */
  51. static int     XpmLoadError  PARM((char*, char*));
  52. static int     XpmGetc         PARM((FILE*));
  53. static int     hash          PARM((char *));
  54. static int     hash_init     PARM((int));
  55. static int     hash_insert   PARM((hentry *));
  56. static hentry *hash_search   PARM((char *));
  57. static void    hash_destroy  PARM((void));
  58.  
  59.  
  60. /**************************************/
  61. int LoadXPM(fname, pinfo)
  62.      char *fname;
  63.      PICINFO *pinfo;
  64. {
  65.   /* returns '1' on success */
  66.   
  67.   FILE    *fp;
  68.   hentry   item;
  69.   int      c;
  70.   char    *bname;
  71.   char     values[VALUES_LEN];
  72.   byte    *pic;
  73.   byte    *i_sptr;        /* image search pointer */
  74.   long     filesize;
  75.   int      w, h, nc, cpp, line_pos;
  76.   short    i, j, k;        /* for() loop indexes */
  77.   hentry  *clmp;        /* colormap hash-table */
  78.   hentry  *c_sptr;        /* cmap hash-table search pointer*/
  79.   XColor   col;
  80.   
  81.   bname = BaseName(fname);
  82.   fp = fopen(fname, "r");
  83.   if (!fp)
  84.     return (XpmLoadError(bname, "couldn't open file"));
  85.   
  86.   if (DEBUG)
  87.     printf("LoadXPM(): Loading xpm from %s\n", fname);
  88.   
  89.   fseek(fp, 0L, 2);
  90.   filesize = ftell(fp);
  91.   fseek(fp, 0L, 0);
  92.   
  93.   bufchar = -2;
  94.   in_quote = FALSE;
  95.   
  96.   /* Read in the values line.  It is the first string in the
  97.    * xpm, and contains four numbers.  w, h, num_colors, and
  98.    * chars_per_pixel. */
  99.   
  100.   /* First, get to the first string */
  101.   while (((c = XpmGetc(fp))!=EOF) && (c != '"')) ;
  102.   line_pos = 0;
  103.   
  104.   /* Now, read in the string */
  105.   while (((c = XpmGetc(fp))!=EOF) && (line_pos < VALUES_LEN) && (c != '"')) {
  106.     values[line_pos++] = c;
  107.   }
  108.   if (c != '"')
  109.     return (XpmLoadError(bname, "error parsing values line"));
  110.   
  111.   values[line_pos] = '\0';
  112.   sscanf(values, "%d%d%d%d", &w, &h, &nc, &cpp);
  113.   if (nc <= 0 || cpp <= 0)
  114.     return (XpmLoadError(bname, "No colours in Xpm?"));
  115.   
  116.   if (nc > 256)
  117.     pinfo->type = PIC24;
  118.   else
  119.     pinfo->type = PIC8;
  120.   
  121.   if (DEBUG)
  122.     printf("LoadXPM(): reading a %dx%d image (%d colors)\n", w, h, nc);
  123.   
  124.   /* We got this far... */
  125.   WaitCursor();
  126.   
  127.   if (!hash_init(nc))
  128.     return (XpmLoadError(bname, "Not enough memory to hash colormap"));
  129.   
  130.   clmp = (hentry *) malloc(nc * sizeof(hentry)); /* Holds the colormap */
  131.   if (pinfo->type == PIC8) pic = (byte *) malloc((size_t) (w*h));
  132.                       else pic = (byte *) malloc((size_t) (w*h*3));
  133.   
  134.   if (!clmp || !pic)
  135.     return (XpmLoadError(bname, "Not enough memory to load pixmap"));
  136.   
  137.   c_sptr = clmp;
  138.   i_sptr = pic;
  139.   
  140.   /* initialize the 'hex' array for zippy ASCII-hex -> int conversion */
  141.   
  142.   for (i = 0 ; i < 256 ; i++)   hex[i] = 0;
  143.   for (i = '0'; i <= '9' ; i++) hex[i] = i - '0';
  144.   for (i = 'a'; i <= 'f' ; i++) hex[i] = i - 'a' + 10;
  145.   for (i = 'A'; i <= 'F' ; i++) hex[i] = i - 'A' + 10;
  146.   
  147.   /* Again, we've made progress. */
  148.   WaitCursor();
  149.   
  150.   /* Now, we need to read the colormap. */
  151.   pinfo->colType = F_BWDITHER;
  152.   for (i = 0 ; i < nc ; i++) {
  153.     while (((c = XpmGetc(fp))!=EOF) && (c != '"')) ;
  154.     if (c != '"')
  155.       return (XpmLoadError(bname, "Error reading colormap"));
  156.     
  157.     for (j = 0 ; j < cpp ; j++)
  158.       c_sptr->token[j] = XpmGetc(fp);
  159.     c_sptr->token[j] = '\0';
  160.     
  161.     while (((c = XpmGetc(fp))!=EOF) && ((c == ' ') || (c == '\t'))) ;
  162.     if (c == EOF)        /* The failure condition of getc() */
  163.       return (XpmLoadError(bname, "Error parsing colormap line"));
  164.     
  165.     do {
  166.       char  key[3];
  167.       char  color[40];    /* Need to figure a good size for this... */
  168.       short hd;        /* Hex digits per R, G, or B */
  169.       
  170.       for (j=0; j<2 && (c != ' ') && (c != '\t') && (c != EOF); j++) {
  171.     key[j] = c;
  172.     c = XpmGetc(fp);
  173.       }
  174.       key[j] = '\0';
  175.  
  176.       while (((c = XpmGetc(fp))!=EOF) && ((c == ' ') || (c == '\t'))) ;
  177.       if (c == EOF)    /* The failure condition of getc() */
  178.     return (XpmLoadError(bname, "Error parsing colormap line"));
  179.  
  180.       for (j=0; j<39 && (c!=' ') && (c!='\t') && (c!='"') && c!=EOF; j++) {
  181.     color[j] = c;
  182.     c = XpmGetc(fp);
  183.       }
  184.       color[j]='\0';
  185.  
  186.       while ((c == ' ') || (c == '\t'))
  187.     c = XpmGetc(fp);
  188.       
  189.       if (DEBUG > 1)
  190.     printf("LoadXPM(): Got color key '%s', color '%s'\n",
  191.            key, color);
  192.       
  193.       if (key[0] == 's')    /* Don't find a color for a symbolic name */
  194.     continue;
  195.       
  196.       if (XParseColor(theDisp,theCmap,color,&col)) {
  197.     if (pinfo->type == PIC8) {
  198.       pinfo->r[i] = col.red >> 8;
  199.       pinfo->g[i] = col.green >> 8;
  200.       pinfo->b[i] = col.blue >> 8;
  201.       c_sptr->cv_index = i;
  202.  
  203.       /* Is there a better way to do this? */
  204.       if (pinfo->colType != F_FULLCOLOR)
  205.         if (pinfo->colType == F_GREYSCALE)
  206.           if (pinfo->r[i] == pinfo->g[i] &&
  207.           pinfo->g[i] == pinfo->b[i])
  208.         /* Still greyscale... */
  209.         ;
  210.           else
  211.         /* It's color */
  212.         pinfo->colType = F_FULLCOLOR;
  213.         else
  214.           if (pinfo->r[i] == pinfo->g[i] &&
  215.           pinfo->g[i] == pinfo->b[i])
  216.         if ((pinfo->r[i] == 0 || pinfo->r[i] == 0xff) &&
  217.             (pinfo->g[i] == 0 || pinfo->g[i] == 0xff) &&
  218.             (pinfo->b[i] == 0 || pinfo->b[i] == 0xff))
  219.           /* It's B/W */
  220.           ;
  221.         else
  222.           /* It's greyscale */
  223.           pinfo->colType = F_GREYSCALE;
  224.           else
  225.         /* It's color */
  226.         pinfo->colType = F_FULLCOLOR;
  227.       
  228.     }
  229.     else {   /* PIC24 */
  230.       c_sptr->cv_rgb[0] = col.red >> 8;
  231.       c_sptr->cv_rgb[1] = col.green >> 8;
  232.       c_sptr->cv_rgb[2] = col.blue >> 8;
  233.     }
  234.       }
  235.  
  236.       else {      /* 'None' or unrecognized color spec */
  237.     int rgb;
  238.  
  239.     if (strcmp(color, "None") == 0) rgb = 0xb2c0dc;  /* infobg */
  240.     else {
  241.       SetISTR(ISTR_INFO, "%s:  unknown color spec '%s'", bname, color);
  242.       Timer(1000);
  243.       rgb = 0x808080;
  244.     }
  245.     
  246.     if (pinfo->type == PIC8) {
  247.       pinfo->r[i] = (rgb>>16) & 0xff;
  248.       pinfo->g[i] = (rgb>> 8) & 0xff;
  249.       pinfo->b[i] = (rgb>> 0) & 0xff;
  250.       c_sptr->cv_index = i;
  251.     }
  252.     else {
  253.       c_sptr->cv_rgb[0] = (rgb>>16) & 0xff;
  254.       c_sptr->cv_rgb[1] = (rgb>> 8) & 0xff;
  255.       c_sptr->cv_rgb[2] = (rgb>> 0) & 0xff;
  256.     }
  257.       }
  258.  
  259.       
  260.       xvbcopy((char *) c_sptr, (char *) &item, sizeof(item));
  261.       hash_insert(&item);
  262.       
  263.       if (DEBUG > 1) 
  264.     printf("LoadXPM():  Cmap entry %d, 0x%02x 0x%02x 0x%02x, token '%s'\n",
  265.            i, pinfo->r[i], pinfo->g[i], pinfo->b[i], c_sptr->token);
  266.       
  267.       if (*key == 'c') {    /* This is the color entry, keep it. */
  268.     while (c!='"' && c!=EOF) c = XpmGetc(fp);
  269.     break;
  270.       }
  271.       
  272.     } while (c != '"');
  273.     c_sptr++;
  274.  
  275.     if (!(i%13)) WaitCursor();
  276.   } /* for */
  277.   
  278.  
  279.   if (DEBUG)
  280.     printf("LoadXPM(): Read and stored colormap.\n");
  281.   
  282.   /* Now, read the pixmap. */
  283.   for (i = 0 ; i < h ; i++) {
  284.     while (((c = XpmGetc(fp))!=EOF) && (c != '"')) ;
  285.     if (c != '"')
  286.       return (XpmLoadError(bname, "Error reading colormap"));
  287.     
  288.     for (j = 0 ; j < w ; j++) {
  289.       char pixel[TOKEN_LEN];
  290.       hentry *mapentry;
  291.       
  292.       for (k = 0 ; k < cpp ; k++)
  293.     pixel[k] = XpmGetc(fp);
  294.       pixel[k] = '\0';
  295.  
  296.       if (!(mapentry = (hentry *) hash_search(pixel))) {
  297.     /* No colormap entry found.  What do we do?  Bail for now */
  298.     if (DEBUG)
  299.       printf("LoadXPM(): Found token '%s', can't find entry in colormap\n",
  300.          pixel);
  301.     return (XpmLoadError(bname, "Can't map resolve into colormap"));
  302.       }
  303.       
  304.       if (pinfo->type == PIC8)
  305.     *i_sptr++ = mapentry->cv_index;
  306.       else {
  307.     *i_sptr++ = mapentry->cv_rgb[0];
  308.     *i_sptr++ = mapentry->cv_rgb[1];
  309.     *i_sptr++ = mapentry->cv_rgb[2];
  310.       }
  311.     }  /* for ( j < w ) */
  312.     (void)XpmGetc(fp);        /* Throw away the close " */
  313.   
  314.     if (!(i%7)) WaitCursor();
  315.   }  /* for ( i < h ) */
  316.   
  317.   pinfo->pic = pic;
  318.   pinfo->normw = pinfo->w = w;
  319.   pinfo->normh = pinfo->h = h;
  320.   pinfo->frmType = F_XPM;
  321.  
  322.   if (DEBUG) printf("LoadXPM(): pinfo->colType is %d\n", pinfo->colType);
  323.   
  324.   sprintf(pinfo->fullInfo, "Xpm v3 Pixmap (%ld bytes)", filesize);
  325.   sprintf(pinfo->shrtInfo, "%dx%d Xpm.", w, h);
  326.   pinfo->comment = (char *)NULL;
  327.   
  328.   hash_destroy();
  329.   free(clmp);
  330.   
  331.   if (fp != stdin)
  332.     fclose(fp);
  333.   
  334.   return(1);
  335. }
  336.  
  337.  
  338. /***************************************/
  339. static int XpmLoadError(fname, st)
  340.      char *fname, *st;
  341. {
  342.   SetISTR(ISTR_WARNING, "%s:  %s", fname, st);
  343.   return 0;
  344. }
  345.  
  346.  
  347. /***************************************/
  348. static int XpmGetc(f)
  349.      FILE *f;
  350. {
  351.   int    c, d, lastc;
  352.   
  353.   if (bufchar != -2) {
  354.     /* The last invocation of this routine read the character... */
  355.     c = bufchar;
  356.     bufchar = -2;
  357.     return(c);
  358.   }
  359.   
  360.   if ((c = getc(f)) == EOF)
  361.     return(EOF);
  362.   
  363.   if (c == '"')
  364.     in_quote = !in_quote;
  365.   else if (!in_quote && c == '/') {    /* might be a C-style comment */
  366.     if ((d = getc(f)) == EOF)
  367.       return(EOF);
  368.     if (d == '*') {                /* yup, it *is* a comment */
  369.       if ((lastc = getc(f)) == EOF)
  370.     return(EOF);
  371.       do {                /* skip through to the end */
  372.     if ((c = getc(f)) == EOF)
  373.       return(EOF);
  374.     if (lastc != '*' || c != '/')    /* end of comment */
  375.       lastc = c;
  376.       } while (lastc != '*' || c != '/');
  377.       if ((c = getc(f)) == EOF)
  378.     return(EOF);
  379.     } else                    /* nope, not a comment */
  380.       bufchar = d;
  381.   }
  382.   return(c);
  383. }
  384.  
  385.  
  386. /***************************************/
  387. /*         hashing functions           */
  388. /***************************************/
  389.  
  390.  
  391. /***************************************/
  392. static int hash(token) 
  393.      char *token;
  394. {
  395.   int i, sum;
  396.  
  397.   for (i=sum=0; token[i] != '\0'; i++)
  398.     sum += token[i];
  399.   
  400.   sum = sum % hash_len;
  401.   return (sum);
  402. }
  403.  
  404.  
  405. /***************************************/
  406. static int hash_init(hsize)
  407.      int hsize;
  408. {
  409.   /*
  410.    * hash_init() - This function takes an arg, but doesn't do anything with
  411.    * it.  It could easily be expanded to figure out the "optimal" number of
  412.    * buckets.  But, for now, a hard-coded 257 will do.  (Until I finish the
  413.    * 24-bit image writing code.  :-)
  414.    */
  415.  
  416.   int i;
  417.   
  418.   hash_len = 257;
  419.  
  420.   hashtab = (hentry **) malloc(sizeof(hentry *) * hash_len);
  421.   if (!hashtab) {
  422.     SetISTR(ISTR_WARNING, "Couldn't malloc hashtable in LoadXPM()!\n");
  423.     return 0;
  424.   }
  425.  
  426.   for (i = 0 ; i < hash_len ; i++)
  427.     hashtab[i] = NULL;
  428.   
  429.   return 1;
  430. }
  431.  
  432.  
  433. /***************************************/
  434. static int hash_insert(entry)
  435.      hentry *entry;
  436. {
  437.   int     key;
  438.   hentry *tmp;
  439.   
  440.   key = hash(entry->token);
  441.   
  442.   tmp = (hentry *) malloc(sizeof(hentry));
  443.   if (!tmp) {
  444.     SetISTR(ISTR_WARNING, "Couldn't malloc hash entry in LoadXPM()!\n");
  445.     return 0;
  446.   }
  447.   
  448.   xvbcopy((char *)entry, (char *)tmp, sizeof(hentry));
  449.   
  450.   if (hashtab[key]) tmp->next = hashtab[key];
  451.                else tmp->next = NULL;
  452.   
  453.   hashtab[key] = tmp;
  454.   
  455.   return 1;
  456. }
  457.  
  458.  
  459. /***************************************/
  460. static hentry *hash_search(token)
  461.      char *token;
  462. {
  463.   int     key;
  464.   hentry *tmp;
  465.   
  466.   key = hash(token);
  467.   
  468.   tmp = hashtab[key];
  469.   while (tmp && strcmp(token, tmp->token)) {
  470.     tmp = tmp->next;
  471.   }
  472.  
  473.   return tmp;
  474. }
  475.  
  476.  
  477. /***************************************/
  478. static void hash_destroy()
  479. {
  480.   int     i;
  481.   hentry *tmp;
  482.   
  483.   for (i=0; i<hash_len; i++) {
  484.     while (hashtab[i]) {
  485.       tmp = hashtab[i]->next;
  486.       free(hashtab[i]);
  487.       hashtab[i] = tmp;
  488.     }
  489.   }
  490.   
  491.   free(hashtab);
  492.   return;
  493. }
  494.  
  495.  
  496.  
  497. /**************************************************************************/
  498. int WriteXPM(fp, pic, ptype, w, h, rp, gp, bp, nc, col, name, comments)
  499.      FILE *fp;            /* File to write to */
  500.      byte *pic;            /* Image data */
  501.      int ptype;            /* PIC8 or PIC24 */
  502.      int w, h;            /* width, & height */
  503.      byte *rp, *gp, *bp;    /* Colormap pointers */
  504.      int nc, col;        /* number of colors, & colorstyle */
  505.      char *name;        /* name of file (/image) */
  506.      char *comments;        /* image comments (not currently used */
  507. {
  508.   /* Note here, that tokenchars is assumed to contain 64 valid token */
  509.   /* characters.  It's hardcoded to assume this for benefit of generating */
  510.   /* tokens, when there are more than 64^2 colors. */
  511.   
  512.   short    i, imax, j;    /* for() loop indices */
  513.   short    cpp = 0;
  514.   char    *tokenchars = 
  515.             ".#abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
  516.   char    *tokens;
  517.   char    image_name[256], *foo;
  518.   byte    grey;
  519.  
  520. #ifndef USE_UNFINISHED_24BIT_WRITING_CODE
  521.   byte    *pic8, *sptr;
  522.   byte    rtemp[256], gtemp[256], btemp[256], hist[256], trans[256];
  523.   long    li;        /* for() loop index */
  524.   int    numcol;
  525. #endif
  526.   
  527.   if (DEBUG)
  528.     if (ptype == PIC8)
  529.       printf("WriteXPM(): Write a %d color, colortype %d, PIC8 image.\n",
  530.          nc, col);
  531.     else
  532.       printf("WriteXPM(): Write a colortype %d, PIC24 image.\n", col);
  533.   
  534.   foo = BaseName(name);
  535.   strcpy(image_name, foo);
  536.   foo = (char *)strchr(image_name, '.');
  537.   if (foo)
  538.     *foo = '\0';        /* Truncate name at first '.' */
  539.   
  540. #ifdef USE_UNFINISHED_24BIT_WRITING_CODE
  541.   if (ptype == PIC24)
  542.     return -1;
  543. #else
  544.   /* XXX - The colormap returned from Conv24to8 is not a specific  */
  545.   /* size (and Conv24to8 doesn't tell me how many entries there    */
  546.   /* are, or not in this rev of code at least) and not necessarily */
  547.   /* 'packed'.  Code in here to do that should be removed if       */
  548.   /* Conv24to8 is "fixed" to do this...                            */
  549.   /*    Chris P. Ross (cross@eng.umd.edu)  28-Sept-94              */
  550.   
  551.   numcol = 0;
  552.   
  553.   if (ptype == PIC24) {
  554.     /* Reduce to an 8-bit image.  Would be nice to actually write */
  555.     /* the 24-bit image.  I'll have to code that someday...       */
  556.     pic8 = Conv24to8(pic, w, h, 256, rtemp, gtemp, btemp);
  557.     if (!pic8) {
  558.       SetISTR(ISTR_WARNING, 
  559.           "%s:  Unable to convert to 8-bit image in WriteXPM()",
  560.           image_name);
  561.       return 1;
  562.     }
  563.     if (DEBUG) printf("WriteXPM(): Converted 24bit image.\n");
  564.  
  565.     /* This will count the number of colors in use, and build an */
  566.     /* index array into the colormap (which may not be 'packed') */
  567.     /* Thanks to John Bradley for this code..                    */
  568.  
  569.     xvbzero((char *) hist, sizeof(hist));
  570.     numcol = 0;
  571.  
  572.     if (DEBUG)
  573.       printf("WriteXPM(): Counting colors (width: %d, height: %d)...\n", w, h);
  574.  
  575.     for (li = 0, sptr = pic8 ; li < (w*h) ; li++, sptr++) {
  576.       hist[*sptr] = 1;
  577.     }
  578.  
  579.     if (DEBUG)
  580.       printf("WriteXPM(): building translation table...\n");
  581.     for (i = 0 ; i < 256 ; i++) {
  582.       trans[i] = numcol;
  583.       rtemp[numcol] = rtemp[i];
  584.       gtemp[numcol] = gtemp[i];
  585.       btemp[numcol] = btemp[i];
  586.       numcol += hist[i];
  587.     }
  588.     rp=rtemp; gp=gtemp; bp=btemp;
  589.     if (DEBUG)
  590.       printf("WriteXPM(): Converted 24bit image now has %d colors.\n", numcol);
  591.   } else {
  592.     pic8 = pic;
  593.     numcol = nc;
  594.   }
  595. #endif
  596.  
  597.   
  598. #ifdef USE_UNFINISHED_24BIT_WRITING_CODE
  599.   if (ptype == PIC24) cpp = 4;
  600.   else if (numcol > 64) cpp = 2;
  601.   else cpp = 1;
  602. #else
  603.   if (numcol > 64) cpp = 2;
  604.   else cpp = 1;
  605. #endif
  606.  
  607.   fprintf(fp, "/* XPM */\n");
  608.   fprintf(fp, "static char *%s[] = {\n", image_name);
  609.   fprintf(fp, "/* width height num_colors chars_per_pixel */\n");
  610.   fprintf(fp, "\"   %3d   %3d   %6d            %1d\",\n", w, h, numcol, cpp);
  611.   fprintf(fp, "/* colors */\n");
  612.   
  613.   switch (cpp) {
  614.  
  615.   case 1:            /* <= 64 colors; index into tokenchars */
  616.     if (col == F_GREYSCALE)
  617.       for (i = 0 ; i < numcol ; i ++) {
  618.     grey = MONO(rp[i], gp[i], bp[i]);
  619.     fprintf(fp, "\"%c c #%02x%02x%02x\",\n", tokenchars[i],
  620.         grey, grey, grey);
  621.       }
  622.     else
  623.       for (i = 0 ; i < numcol ; i ++)
  624.     fprintf(fp, "\"%c c #%02x%02x%02x\",\n", tokenchars[i],
  625.         rp[i], gp[i], bp[i]);
  626.     fprintf(fp, "/* pixels */\n");
  627.     for (i = 0 ; i < h ; i ++) {
  628.       fprintf(fp, "\"");
  629.       if (!(i%20))
  630.     WaitCursor();
  631.       for (j = 0 ; j < w ; j++) {
  632.     if (rp == rtemp)
  633.       fprintf(fp, "%c", tokenchars[trans[*pic8++]]);
  634.     else
  635.       fprintf(fp, "%c", tokenchars[*pic8++]);
  636.       }
  637.       if (i < h-1)
  638.     fprintf(fp, "\",\n");
  639.     }
  640.     break;
  641.  
  642.   case 2:            /* 64 < colors < 64^2; build new token list */
  643.     tokens = (char *) malloc((size_t) ((2*numcol) + 1) );
  644.     if (numcol & 0x3f)
  645.       imax = (numcol >> 6) + 1;
  646.     else
  647.       imax = (numcol >> 6);
  648.     for (i = 0 ; i < imax ; i++)
  649.       for (j =  0 ; j < 64 && ((i<<6)+j) < numcol ; j++) {
  650.     *(tokens+((i<<6)+j)*2) = tokenchars[i];
  651.     *(tokens+((i<<6)+j)*2+1) = tokenchars[j];
  652.       }
  653.     if (col == F_GREYSCALE)
  654.       for (i = 0 ; i < numcol ; i++) {
  655.     grey = MONO(rp[i], gp[i], bp[i]);
  656.     fprintf(fp, "\"%c%c c #%02x%02x%02x\",\n", tokens[i*2],
  657.         tokens[i*2+1], grey, grey, grey);
  658.       }
  659.     else
  660.       for (i = 0 ; i < numcol ; i++)
  661.     fprintf(fp, "\"%c%c c #%02x%02x%02x\",\n", tokens[i*2],
  662.         tokens[i*2+1], rp[i], gp[i], bp[i]);
  663.     fprintf(fp, "/* pixels */\n");
  664.     for (i = 0 ; i < h ; i++) {
  665.       fprintf(fp, "\"");
  666.       if (!(i%13))
  667.     WaitCursor();
  668.       for (j = 0 ; j < w ; j++) {
  669.     if (rp == rtemp)
  670.       fprintf(fp, "%c%c", tokens[trans[*pic8]*2],
  671.           tokens[(trans[*pic8]*2)+1]);
  672.     else
  673.       fprintf(fp, "%c%c", tokens[(*pic8*2)],
  674.           tokens[(*pic8*2)+1]);
  675.     pic8++;
  676.       }
  677.       if (i < h-1)
  678.     fprintf(fp, "\",\n");
  679.     }
  680.     break;
  681.  
  682.   case 4:
  683.     /* Generate a colormap */
  684.     
  685.     break;
  686.   default:
  687.     break;
  688.   }
  689.   
  690.   if (fprintf(fp, "\"\n};\n") == EOF) {
  691.     return 1;
  692.   } else
  693.     return 0;
  694. }
  695.  
  696.  
  697.  
  698.  
  699.