home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / rexx / library2 / gbmrexx / gbm / gbmpgm.c < prev    next >
C/C++ Source or Header  |  1993-08-27  |  6KB  |  273 lines

  1. /*
  2.  
  3. GBMPGM.C  Poskanzers PGM format
  4.  
  5. Reads as 8 bit grey image.
  6. Writes grey equivelent of passed in 8 bit colour data (no palette written).
  7. Output options: r,g,b,k (default: k)
  8.  
  9. */
  10.  
  11. /*...sincludes:0:*/
  12. #include <stdio.h>
  13. #include <ctype.h>
  14. #include <stddef.h>
  15. #include <stdlib.h>
  16. #include <string.h>
  17. #include <memory.h>
  18. #include <malloc.h>
  19. #ifdef AIX
  20. #include <unistd.h>
  21. #else
  22. #include <io.h>
  23. #endif
  24. #include <fcntl.h>
  25. #include <sys/types.h>
  26. #include <sys/stat.h>
  27. #include "standard.h"
  28. #include "gbm.h"
  29.  
  30. /*...vgbm\46\h:0:*/
  31. /*...e*/
  32.  
  33. /*...suseful:0:*/
  34. #define    low_byte(w)    ((byte)  ((w)&0x00ff)    )
  35. #define    high_byte(w)    ((byte) (((w)&0xff00)>>8))
  36. #define    make_word(a,b)    (((word)a) + (((word)b) << 8))
  37. /*...e*/
  38. /*...ssame:0:*/
  39. static BOOLEAN same(char *s1, char *s2, int n)
  40.     {
  41.     for ( ; n--; s1++, s2++ )
  42.         if ( tolower(*s1) != tolower(*s2) )
  43.             return ( FALSE );
  44.     return ( TRUE );
  45.     }
  46. /*...e*/
  47. /*...sfind_word:0:*/
  48. static char *find_word(char *str, char *substr)
  49.     {
  50.     char    buf [100+1], *s;
  51.     int    len = strlen(substr);
  52.  
  53.     for ( s  = strtok(strcpy(buf, str), " \t,");
  54.           s != NULL;
  55.           s  = strtok(NULL, " \t,") )
  56.         if ( same(s, substr, len) && s [len] == '\0' )
  57.             return ( str + (s - buf) );
  58.     return ( NULL );
  59.     }
  60. /*...e*/
  61. /*...smake_output_palette:0:*/
  62. #define    SW4(a,b,c,d)    ((a)*8+(b)*4+(c)*2+(d))
  63.  
  64. static BOOLEAN make_output_palette(GBMRGB gbmrgb [], byte grey [], char *opt)
  65.     {
  66.     BOOLEAN    k = ( find_word(opt, "k") != NULL );
  67.     BOOLEAN    r = ( find_word(opt, "r") != NULL );
  68.     BOOLEAN    g = ( find_word(opt, "g") != NULL );
  69.     BOOLEAN    b = ( find_word(opt, "b") != NULL );
  70.     int    i;
  71.  
  72.     switch ( SW4(k,r,g,b) )
  73.         {
  74.         case SW4(0,0,0,0):
  75.             /* Default is the same as "k" */
  76.         case SW4(1,0,0,0):
  77.             for ( i = 0; i < 0x100; i++ )
  78.                 grey [i] = (byte) ( ((word) gbmrgb [i].r *  77 +
  79.                              (word) gbmrgb [i].g * 151 +
  80.                              (word) gbmrgb [i].b *  28) >> 8 );
  81.             return ( TRUE );
  82.         case SW4(0,1,0,0):
  83.             for ( i = 0; i < 0x100; i++ )
  84.                 grey [i] = gbmrgb [i].r;
  85.             return ( TRUE );
  86.         case SW4(0,0,1,0):
  87.             for ( i = 0; i < 0x100; i++ )
  88.                 grey [i] = gbmrgb [i].g;
  89.             return ( TRUE );
  90.         case SW4(0,0,0,1):
  91.             for ( i = 0; i < 0x100; i++ )
  92.                 grey [i] = gbmrgb [i].b;
  93.             return ( TRUE );
  94.         }
  95.     return ( FALSE );
  96.     }
  97. /*...e*/
  98. /*...sposk stuff:0:*/
  99. /*...sread_byte:0:*/
  100. static byte read_byte(int fd)
  101.     {
  102.     byte    b = 0;
  103.  
  104.     read(fd, (char *) &b, 1);
  105.     return ( b );
  106.     }
  107. /*...e*/
  108. /*...sread_char:0:*/
  109. static char read_char(int fd)
  110.     {
  111.     char    c;
  112.  
  113.     while ( (c = read_byte(fd)) == '#' )
  114.         /* Discard to end of line */
  115.         while ( (c = read_byte(fd)) != '\n' )
  116.             ;
  117.     return ( c );
  118.     }
  119. /*...e*/
  120. /*...sread_num:0:*/
  121. static int read_num(int fd)
  122.     {
  123.     char    c;
  124.     int    num;
  125.  
  126.     while ( isspace(c = read_char(fd)) )
  127.         ;
  128.     num = c - '0';
  129.     while ( isdigit(c = read_char(fd)) )
  130.         num = num * 10 + (c - '0');
  131.     return ( num );
  132.     }
  133. /*...e*/
  134. /*...sread_posk_header:0:*/
  135. static void read_posk_header(int fd, int *h1, int *h2, int *w, int *h, int *m)
  136.     {
  137.     lseek(fd, 0L, SEEK_SET);
  138.     *h1 = read_byte(fd);
  139.     *h2 = read_byte(fd);
  140.     *w  = read_num(fd);
  141.     *h  = read_num(fd);
  142.     *m  = read_num(fd);
  143.     }
  144. /*...e*/
  145. /*...e*/
  146.  
  147. static GBMFT pgm_gbmft =
  148.     {
  149.     "Greymap",
  150.     "Portable Greyscale-map (binary P5 type)",
  151.     "PGM",
  152.     GBM_FT_R8|
  153.     GBM_FT_W8,
  154.     };
  155.  
  156. #define    GBM_ERR_PGM_BAD_M    ((GBM_ERR) 100)
  157.  
  158. /*...spgm_qft:0:*/
  159. GBM_ERR pgm_qft(GBMFT *gbmft)
  160.     {
  161.     *gbmft = pgm_gbmft;
  162.     return ( GBM_ERR_OK );
  163.     }
  164. /*...e*/
  165. /*...spgm_rhdr:0:*/
  166. GBM_ERR pgm_rhdr(char *fn, int fd, GBM *gbm, char *opt)
  167.     {
  168.     int    h1, h2, w, h, m;
  169.  
  170.     fn=fn; opt=opt; /* Suppress 'unref arg' compiler warnings */
  171.  
  172.     read_posk_header(fd, &h1, &h2, &w, &h, &m);
  173.     if ( h1 != 'P' || h2 != '5' )
  174.         return ( GBM_ERR_BAD_MAGIC );
  175.  
  176.     if ( w <= 0 || h <= 0 )
  177.         return ( GBM_ERR_BAD_SIZE );
  178.  
  179.     if ( m <= 1 || m >= 0x100 )
  180.         return ( GBM_ERR_PGM_BAD_M );
  181.  
  182.     gbm -> w   = w;
  183.     gbm -> h   = h;
  184.     gbm -> bpp = 8;
  185.  
  186.     return ( GBM_ERR_OK );
  187.     }
  188. /*...e*/
  189. /*...spgm_rpal:0:*/
  190. GBM_ERR pgm_rpal(int fd, GBM *gbm, GBMRGB *gbmrgb)
  191.     {
  192.     int    h1, h2, w, h, m, i;
  193.  
  194.     gbm=gbm; /* Suppress 'unref arg' compiler warning */
  195.  
  196.     read_posk_header(fd, &h1, &h2, &w, &h, &m);
  197.     for ( i = 0; i < m; i++ )
  198.         gbmrgb [i].r =
  199.         gbmrgb [i].g =
  200.         gbmrgb [i].b = (byte) (i * 0xff / (m - 1));
  201.  
  202.     return ( GBM_ERR_OK );
  203.     }
  204. /*...e*/
  205. /*...spgm_rdata:0:*/
  206. GBM_ERR pgm_rdata(int fd, GBM *gbm, byte *data)
  207.     {
  208.     int    h1, h2, w, h, m, i, stride;
  209.     byte    *p;
  210.  
  211.     read_posk_header(fd, &h1, &h2, &w, &h, &m);
  212.  
  213.     stride = ((gbm -> w + 3) & ~3);
  214.     p = data + ((gbm -> h - 1) * stride);
  215.     for ( i = gbm -> h - 1; i >= 0; i-- )
  216.         {
  217.         read(fd, p, gbm -> w);
  218.         p -= stride;
  219.         }
  220.     return ( GBM_ERR_OK );
  221.     }
  222. /*...e*/
  223. /*...spgm_w:0:*/
  224. GBM_ERR pgm_w(char *fn, int fd, GBM *gbm, GBMRGB *gbmrgb, byte *data, char *opt)
  225.     {
  226.     char    s [100+1];
  227.     int    i, j, stride;
  228.     byte    grey [0x100];
  229.     byte    *p, *linebuf;
  230.  
  231.     fn=fn; opt=opt; /* Suppress 'unref arg' compiler warnings */
  232.  
  233.     if ( gbm -> bpp != 8 )
  234.         return ( GBM_ERR_NOT_SUPP );
  235.  
  236.     if ( !make_output_palette(gbmrgb, grey, opt) )
  237.         return ( GBM_ERR_BAD_OPTION );
  238.  
  239.     if ( (linebuf = malloc(gbm -> w)) == NULL )
  240.         return ( GBM_ERR_MEM );
  241.  
  242.     sprintf(s,
  243.         "P5\n# Written by Generalised Bitmap Module\n%d %d 255\n",
  244.         gbm -> w, gbm -> h);
  245.     write(fd, s, strlen(s));
  246.  
  247.     stride = ((gbm -> w + 3) & ~3);
  248.     p = data + ((gbm -> h - 1) * stride);
  249.     for ( i = gbm -> h - 1; i >= 0; i-- )
  250.         {
  251.         for ( j = 0; j < gbm -> w; j++ )
  252.             linebuf [j] = grey [p [j]];
  253.         write(fd, linebuf, gbm -> w);
  254.         p -= stride;
  255.         }
  256.  
  257.     free(linebuf);
  258.  
  259.     return ( GBM_ERR_OK );
  260.     }
  261. /*...e*/
  262. /*...spgm_err:0:*/
  263. char *pgm_err(GBM_ERR rc)
  264.     {
  265.     switch ( (int) rc )
  266.         {
  267.         case GBM_ERR_PGM_BAD_M:
  268.             return ( "bad maximum pixel intensity" );
  269.         }
  270.     return ( NULL );
  271.     }
  272. /*...e*/
  273.