Back to index

plt-scheme  4.2.1
wx_xbm.cc
Go to the documentation of this file.
00001 /*
00002  * xvxbm.c - load routine for X11 Bitmap format pictures
00003  *
00004  * LoadXBM(fname)  -  loads an X11 Bitmap file\
00005  * WriteXBM(fp, pic, w, h)
00006  */
00007 
00008 /*
00009  * Copyright 1989, 1990 by the University of Pennsylvania
00010  *
00011  * Permission to use, copy, and distribute for non-commercial purposes,
00012  * is hereby granted without fee, providing that the above copyright
00013  * notice appear in all copies and that both the copyright notice and this
00014  * permission notice appear in supporting documentation.
00015  *
00016  * The software may be modified for your own purposes, but modified versions
00017  * may not be distributed.
00018  *
00019  * This software is provided "as is" without any express or implied warranty.
00020  */
00021 
00022 
00023 #include <stdlib.h>
00024 #include "wx_image.h"
00025 
00026 #ifdef MZ_PRECISE_GC
00027 END_XFORM_ARITH;
00028 #endif
00029 
00030 /*
00031  * File Format:
00032  *   (format identifier:  "#define" as first couple chars in file)
00033  *
00034  * looks for first line beginning with '#define'
00035  *   reads "#define identifier width"  (identifier is ignored)
00036  * looks for next line beginning with '#define'
00037  *   reads "#define identifier height" (identifier is ignored)
00038  * looks for next occurence of characters '0x'
00039  *   read next two chars as two hex digits
00040  *   move forward to next occurence of '0x'
00041  *   repeat
00042  */
00043  
00044 
00045 /*******************************************/
00046 int wxImage::LoadXBM(char *fname, int /* nc */)
00047 /*******************************************/
00048 {
00049   FILE  *fp;
00050   int    c, c1;
00051   int    i, j, k, bit, w, h;
00052   byte  *pix;
00053   long   filesize;
00054   char   line[256];
00055   byte   hex[256];
00056 
00057   k = 0;
00058 
00059   fp=fopen(fname,"r");
00060   if (!fp) return 1;
00061 
00062   /* figure out the file size (for Informational Purposes Only) */
00063   fseek(fp, 0L, 2);
00064   filesize = ftell(fp);
00065   fseek(fp, 0L, 0);
00066 
00067 
00068   /* read width:  skip lines until we hit a #define */
00069   while (1) {
00070     if (!fgets(line,256,fp)) {
00071       fclose(fp);
00072       return 1;
00073       // return(XBMError("EOF reached in header info."));
00074     }
00075 
00076     if (strncmp(line,"#define",7)==0) {
00077       if (sscanf(line,"#define %*s %d", &w) != 1) {
00078        fclose(fp);
00079         return 1;
00080        // return(XBMError("Unable to read 'width'"));
00081       }
00082       else break;
00083     }
00084   }
00085 
00086 
00087   /* read height:  skip lines until we hit another #define */
00088   while (1) {
00089     if (!fgets(line,256,fp)) {
00090       fclose(fp);
00091       return 1;
00092       // return(XBMError("EOF reached in header info."));
00093     }
00094 
00095     if (strncmp(line,"#define",7)==0) {
00096       if (sscanf(line,"#define %*s %d", &h) != 1) {
00097        fclose(fp);
00098         return 1;
00099        // return(XBMError("Unable to read 'height'"));
00100       }
00101       else break;
00102     }
00103   }
00104 
00105 
00106 
00107   /* scan forward until we see the first '0x' */
00108   c = getc(fp);  c1 = getc(fp);
00109   while (c1!=EOF && !(c=='0' && c1=='x') ) { c = c1;  c1 = getc(fp); }
00110 
00111   if (c1==EOF) {
00112     fclose(fp);
00113     return 1;
00114     // return(XBMError("No bitmap data found"));
00115   }
00116 
00117 
00118   /* load up the stuff XV expects us to load up */
00119 
00120 //  SetISTR(ISTR_FORMAT,"X11 Bitmap  (%ld bytes)", filesize);
00121 
00122   {
00123     byte *ba;
00124     ba = (byte *) calloc(w*h,1);
00125     pic = ba;
00126   }
00127   if (!pic) FatalError("couldn't malloc 'pic'");
00128 
00129   pWIDE = w;  pHIGH = h;
00130 
00131   /* B/W bitmaps have a two entry colormap */
00132   r[0] = g[0] = b[0] = 255;     /* 0 = white */
00133   r[1] = g[1] = b[1] = 0;       /* 1 = black */
00134 
00135 
00136   /* initialize the 'hex' array for zippy ASCII-hex -> int conversion */
00137 
00138   for (i=0; i<256; i++) { hex[i]=0; }
00139   for (i='0'; i<='9'; i++) { hex[i] = i - '0'; }
00140   for (i='a'; i<='f'; i++) { hex[i] = i + 10 - 'a'; }
00141   for (i='A'; i<='F'; i++) { hex[i] = i + 10 - 'A'; }
00142 
00143   /* read/convert the image data */
00144 
00145   for (i=0, pix=pic; i<h; i++) {
00146     for (j=0,bit=0; j<w; j++, pix++, bit = ((bit + 1) & 0x7)) {
00147 
00148       if (!bit) {
00149        /* get next byte from file.  we're already positioned at it */
00150        c = getc(fp);  c1 = getc(fp);
00151        if (c<0 || c1<0) { 
00152          /* EOF: break out of loop */       
00153          c=c1='0'; i=h; j=w;
00154 //       XBMError("The file would appear to be truncated.");
00155        }
00156 
00157        k = (hex[c] << 4) + hex[c1];
00158 
00159        /* advance to next '0x' */
00160        c = getc(fp);  c1 = getc(fp);
00161        while (c1!=EOF && !(c=='0' && c1=='x') ) { c = c1;  c1 = getc(fp); }
00162       }
00163 
00164       *pix = (k&1) ? 1 : 0;
00165       k = k >> 1;
00166     }
00167   }
00168 
00169   fclose(fp);
00170 
00171   return 0;
00172 }  
00173 
00174 
00175 
00176 /*******************************************/
00177 int wxImage::WriteXBM(FILE *fp, byte *pic, int w, int h, char *fname)
00178 {
00179   /* pic is expected to be an array of w*h bytes.  '0' is considered 'black'
00180      non-zero is considered white.  Some sort of stippling algorithm should've
00181      been called already to produce pic, otherwise the output won't be at all
00182      useful */
00183 
00184   int   i,j,k,bit,len,nbytes;
00185   byte *pix;
00186   char name[256], *foo;
00187 
00188   /* figure out a reasonable basename */
00189   strcpy(name,fname);
00190   foo = strchr(name,'.');
00191   if (foo) *foo='\0';                 /* truncated name at first '.' */
00192 
00193   fprintf(fp,"#define %s_width %d\n",name,w);  
00194   fprintf(fp,"#define %s_height %d\n",name,h);
00195   fprintf(fp,"static char %s_bits[] = {\n",name);
00196 
00197   fprintf(fp," ");
00198 
00199   nbytes = h * ((w+7)/8);   /* # of bytes to write */
00200 
00201   for (i=0, len=1, pix=pic; i<h; i++) {
00202     for (j=bit=k=0; j<w; j++,pix++) {
00203       k = (k>>1);
00204       if (*pix) k |= 0x80;
00205       bit++;
00206       if (bit==8) {
00207        fprintf(fp,"0x%02x",(byte) ~k);
00208        nbytes--;  len += 4;
00209        if (nbytes) { fprintf(fp,",");  len++; }
00210        if (len>72) { fprintf(fp,"\n ");  len=1; }
00211        bit = k = 0;
00212       }
00213     }
00214 
00215     if (bit) {
00216       k = k >> (8-bit);
00217       fprintf(fp,"0x%02x",(byte) ~k);
00218       nbytes--;  len += 4;
00219       if (nbytes) { fprintf(fp,",");  len++; }
00220       if (len>72) { fprintf(fp,"\n ");  len=1; }
00221     }
00222   }
00223 
00224   fprintf(fp,"};\n");
00225 
00226   if (ferror(fp)) return -1;
00227   return 0;
00228 }