home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / x / volume5 / xldimage / part01 / pbm.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-11-13  |  4.7 KB  |  229 lines

  1. /* pbm.c:
  2.  *
  3.  * portable bit map (pbm) format images
  4.  *
  5.  * jim frost 09.27.89
  6.  */
  7.  
  8. #include "xloadimage.h"
  9.  
  10. static int          IntTable[256];
  11. static unsigned int Initialized= 0;
  12.  
  13. #define NOTINT  -1
  14. #define COMMENT -2
  15. #define SPACE   -3
  16. #define NEWLINE -4
  17.  
  18. #define BADREAD    0 /* read error */
  19. #define NOTPBM     1 /* not a pbm file */
  20. #define PBMNORMAL  2 /* pbm normal type file */
  21. #define PBMCOMPACT 3 /* pbm compacty type file */
  22.  
  23. static void initializeTable()
  24. { unsigned int a;
  25.  
  26.   for (a= 0; a < 256; a++)
  27.     IntTable[a]= NOTINT;
  28.   IntTable['#']= COMMENT;
  29.   IntTable['\n']= NEWLINE;
  30.   IntTable['\r']= IntTable['\t']= IntTable[' ']= SPACE;
  31.   IntTable['0']= 0;
  32.   IntTable['1']= 1;
  33.   IntTable['2']= 2;
  34.   IntTable['3']= 3;
  35.   IntTable['4']= 4;
  36.   IntTable['5']= 5;
  37.   IntTable['6']= 6;
  38.   IntTable['7']= 7;
  39.   IntTable['8']= 8;
  40.   IntTable['9']= 9;
  41.   Initialized= 1;
  42. }
  43.  
  44. static int pbmReadChar(zf)
  45.      ZFILE *zf;
  46. { int c;
  47.  
  48.   if ((c= zgetc(zf)) == EOF) {
  49.     zclose(zf);
  50.     return(-1);
  51.   }
  52.   if (IntTable[c] == COMMENT)
  53.     do {
  54.       if ((c= zgetc(zf)) == EOF)
  55.     return(-1);
  56.     } while (IntTable[c] != NEWLINE);
  57.   return(c);
  58. }
  59.  
  60. static int pbmReadInt(zf)
  61.      ZFILE *zf;
  62. { int c, value;
  63.  
  64.   for (;;) {
  65.     c= pbmReadChar(zf);
  66.     if (c < 0)
  67.       return(-1);
  68.     if (IntTable[c] >= 0)
  69.       break;
  70.   };
  71.  
  72.   value= IntTable[c];
  73.   for (;;) {
  74.     c= pbmReadChar(zf);
  75.     if (c < 0)
  76.       return(-1);
  77.     if (IntTable[c] < 0)
  78.       return(value);
  79.     value= (value * 10) + IntTable[c];
  80.   }
  81. }
  82.  
  83. static int isPBM(zf, name, width, height, verbose)
  84.      ZFILE        *zf;
  85.      char         *name;
  86.      int          *width, *height;
  87.      unsigned int  verbose;
  88. { unsigned char buf[4];
  89.  
  90.   if (! Initialized)
  91.     initializeTable();
  92.  
  93.   if (zread(zf, buf, 2) != 2)
  94.     return(NOTPBM);
  95.   if (memToVal(buf, 2) == memToVal("P1", 2)) {
  96.     if (((*width= pbmReadInt(zf)) < 0) || ((*height= pbmReadInt(zf)) < 0))
  97.       return(NOTPBM);
  98.     if (verbose)
  99.       printf("%s is a %dx%d PBM image\n", name, *width, *height);
  100.     return(PBMNORMAL);
  101.   }
  102.   if (memToVal(buf, 2) == 0x2a17) {
  103.     if (zread(zf, buf, 4) != 4)
  104.       return(NOTPBM);
  105.     *width= memToVal(buf, 2);
  106.     *height= memToVal(buf + 2, 2);
  107.     if (verbose)
  108.       printf("%s is a %dx%d Compact PBM image\n", name, *width, *height);
  109.     return(PBMCOMPACT);
  110.   }
  111.   return(NOTPBM);
  112. }
  113.  
  114. int pbmIdent(fullname, name)
  115.      char *fullname, *name;
  116. { ZFILE *zf;
  117.   int    width, height, ret;
  118.  
  119.   if (! (zf= zopen(fullname, name)))
  120.     return(0);
  121.  
  122.   ret= isPBM(zf, name, &width, &height, 1);
  123.   zclose(zf);
  124.   return(ret != NOTPBM);
  125. }
  126.  
  127. Image *pbmLoad(fullname, name, verbose)
  128.      char         *fullname, *name;
  129.      unsigned int  verbose;
  130. { ZFILE        *zf;
  131.   Image        *image;
  132.   unsigned int  x, y;
  133.   int           width, height;
  134.   unsigned int  linelen;
  135.   byte          srcmask, destmask;
  136.   byte         *destptr, *destline;
  137.   int           src;
  138.   unsigned int  numbytes, numread;
  139.  
  140.   if (! (zf= zopen(fullname)))
  141.     return(NULL);
  142.  
  143.   switch (isPBM(zf, name, &width, &height, verbose)) {
  144.   case NOTPBM:
  145.     zclose(zf);
  146.     return(NULL);
  147.     
  148.   case PBMNORMAL:
  149.     image= newBitImage(width, height);
  150.     linelen= (width / 8) + (width % 8 ? 1 : 0);
  151.     destline= image->data;
  152.     for (y= 0; y < height; y++) {
  153.       destptr= destline;
  154.       destmask= 0x80;
  155.       for (x= 0; x < width; x++) {
  156.     do {
  157.       if ((src= pbmReadChar(zf)) < 0) {
  158.         printf("%s: Short image\n", fullname);
  159.         zclose(zf);
  160.         exit(1);
  161.       }
  162.       if (IntTable[src] == NOTINT) {
  163.         printf("%s: Bad image data\n", fullname);
  164.         zclose(zf);
  165.         exit(1);
  166.       }
  167.     } while (IntTable[src] < 0);
  168.     
  169.     switch (IntTable[src]) {
  170.     case 1:
  171.       *destptr |= destmask;
  172.     case 0:
  173.       if (! (destmask >>= 1)) {
  174.         destmask= 0x80;
  175.         destptr++;
  176.       }
  177.       break;
  178.     default:
  179.       printf("%s: Bad image data\n", fullname);
  180.       zclose(zf);
  181.       exit(1);
  182.     }
  183.       }
  184.       destline += linelen;
  185.     }
  186.     break;
  187.  
  188.   case PBMCOMPACT:
  189.     image= newBitImage(width, height);
  190.     destline= image->data;
  191.     linelen= (width / 8) + (width % 8 ? 1 : 0);
  192.     srcmask= 0x80;
  193.     destmask= 0x80;
  194.     if ((src= zgetc(zf)) == EOF) {
  195.       printf("%s: Short image\n", fullname);
  196.       zclose(zf);
  197.       exit(1);
  198.     }
  199.     numread= 1;
  200.     numbytes= width * height;
  201.     numbytes= (numbytes / 8) + (numbytes % 8 ? 1 : 0);
  202.     for (y= 0; y < height; y++) {
  203.       destptr= destline;
  204.       destmask= 0x80;
  205.       for (x= 0; x < width; x++) {
  206.     if (src & srcmask)
  207.       *destptr |= destmask;
  208.     if (! (destmask >>= 1)) {
  209.       destmask= 0x80;
  210.       destptr++;
  211.     }
  212.     if (! (srcmask >>= 1)) {
  213.       srcmask= 0x80;
  214.       if ((numread < numbytes) && ((src= zgetc(zf)) == EOF)) {
  215.         printf("%s: Short image\n", fullname);
  216.         zclose(zf);
  217.         exit(1);
  218.       }
  219.       numread++;
  220.     }
  221.       }
  222.       destline += linelen;
  223.     }
  224.     break;
  225.   }
  226.   image->title= dupString(name);
  227.   return(image);
  228. }
  229.