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

  1. /*
  2.  
  3. GBMPPM.C  Poskanzers PPM format
  4.  
  5. Reads and writes 24 bit RGB.
  6.  
  7. */
  8.  
  9. /*...sincludes:0:*/
  10. #include <stdio.h>
  11. #include <ctype.h>
  12. #include <stddef.h>
  13. #include <stdlib.h>
  14. #include <string.h>
  15. #include <memory.h>
  16. #include <malloc.h>
  17. #ifdef AIX
  18. #include <unistd.h>
  19. #else
  20. #include <io.h>
  21. #endif
  22. #include <fcntl.h>
  23. #include <sys/types.h>
  24. #include <sys/stat.h>
  25. #include "standard.h"
  26. #include "gbm.h"
  27.  
  28. /*...vgbm\46\h:0:*/
  29. /*...e*/
  30.  
  31. /*...suseful:0:*/
  32. #define    low_byte(w)    ((byte)  ((w)&0x00ff)    )
  33. #define    high_byte(w)    ((byte) (((w)&0xff00)>>8))
  34. #define    make_word(a,b)    (((word)a) + (((word)b) << 8))
  35. /*...e*/
  36. /*...sposk stuff:0:*/
  37. /*...sread_byte:0:*/
  38. static byte read_byte(int fd)
  39.     {
  40.     byte    b = 0;
  41.  
  42.     read(fd, (char *) &b, 1);
  43.     return ( b );
  44.     }
  45. /*...e*/
  46. /*...sread_char:0:*/
  47. static char read_char(int fd)
  48.     {
  49.     char    c;
  50.  
  51.     while ( (c = read_byte(fd)) == '#' )
  52.         /* Discard to end of line */
  53.         while ( (c = read_byte(fd)) != '\n' )
  54.             {;}
  55.     return ( c );
  56.     }
  57. /*...e*/
  58. /*...sread_num:0:*/
  59. static int read_num(int fd)
  60.     {
  61.     char    c;
  62.     int    num;
  63.  
  64.     while ( isspace(c = read_char(fd)) )
  65.         {}
  66.     num = c - '0';
  67.     while ( isdigit(c = read_char(fd)) )
  68.         num = num * 10 + (c - '0');
  69.     return ( num );
  70.     }
  71. /*...e*/
  72. /*...sread_posk_header:0:*/
  73. static void read_posk_header(int fd, int *h1, int *h2, int *w, int *h, int *m)
  74.     {
  75.     lseek(fd, 0L, SEEK_SET);
  76.     *h1 = read_byte(fd);
  77.     *h2 = read_byte(fd);
  78.     *w  = read_num(fd);
  79.     *h  = read_num(fd);
  80.     *m  = read_num(fd);
  81.     }
  82. /*...e*/
  83. /*...e*/
  84.  
  85. static GBMFT ppm_gbmft =
  86.     {
  87.     "Pixmap",
  88.     "Portable Pixel-map (binary P6 type)",
  89.     "PPM",
  90.     GBM_FT_R24|
  91.     GBM_FT_W24,
  92.     };
  93.  
  94. #define    GBM_ERR_PPM_BAD_M    ((GBM_ERR) 200)
  95.  
  96. /*...srgb_bgr:0:*/
  97. static void rgb_bgr(byte *p, byte *q, int n)
  98.     {
  99.     while ( n-- )
  100.         {
  101.         byte    r = *p++;
  102.         byte    g = *p++;
  103.         byte    b = *p++;
  104.  
  105.         *q++ = b;
  106.         *q++ = g;
  107.         *q++ = r;
  108.         }
  109.     }
  110. /*...e*/
  111.  
  112. /*...sppm_qft:0:*/
  113. GBM_ERR ppm_qft(GBMFT *gbmft)
  114.     {
  115.     *gbmft = ppm_gbmft;
  116.     return ( GBM_ERR_OK );
  117.     }
  118. /*...e*/
  119. /*...sppm_rhdr:0:*/
  120. GBM_ERR ppm_rhdr(char *fn, int fd, GBM *gbm, char *opt)
  121.     {
  122.     int    h1, h2, w, h, m;
  123.  
  124.     fn=fn; opt=opt; /* Suppress 'unref arg' compiler warnings */
  125.  
  126.     read_posk_header(fd, &h1, &h2, &w, &h, &m);
  127.     if ( h1 != 'P' || h2 != '6' )
  128.         return ( GBM_ERR_BAD_MAGIC );
  129.  
  130.     if ( w <= 0 || h <= 0 )
  131.         return ( GBM_ERR_BAD_SIZE );
  132.  
  133.     if ( m <= 1 || m >= 0x100 )
  134.         return ( GBM_ERR_PPM_BAD_M );
  135.  
  136.     gbm -> w   = w;
  137.     gbm -> h   = h;
  138.     gbm -> bpp = 24;
  139.  
  140.     return ( GBM_ERR_OK );
  141.     }
  142. /*...e*/
  143. /*...sppm_rpal:0:*/
  144. GBM_ERR ppm_rpal(int fd, GBM *gbm, GBMRGB *gbmrgb)
  145.     {
  146.     fd=fd; gbm=gbm; gbmrgb=gbmrgb; /* Suppress 'unref arg' compiler warnings */
  147.  
  148.     return ( GBM_ERR_OK );
  149.     }
  150. /*...e*/
  151. /*...sppm_rdata:0:*/
  152. GBM_ERR ppm_rdata(int fd, GBM *gbm, byte *data)
  153.     {
  154.     int    h1, h2, w, h, m, i, stride;
  155.     byte    *p;
  156.  
  157.     read_posk_header(fd, &h1, &h2, &w, &h, &m);
  158.  
  159.     stride = ((gbm -> w * 3 + 3) & ~3);
  160.     p = data + ((gbm -> h - 1) * stride);
  161.     for ( i = gbm -> h - 1; i >= 0; i-- )
  162.         {
  163.         read(fd, p, gbm -> w * 3);
  164.         rgb_bgr(p, p, gbm -> w);
  165.         p -= stride;
  166.         }
  167.     return ( GBM_ERR_OK );
  168.     }
  169. /*...e*/
  170. /*...sppm_w:0:*/
  171. GBM_ERR ppm_w(char *fn, int fd, GBM *gbm, GBMRGB *gbmrgb, byte *data, char *opt)
  172.     {
  173.     char    s [100+1];
  174.     int    i, stride;
  175.     byte    *p, *linebuf;
  176.  
  177.     fn=fn; gbmrgb=gbmrgb; opt=opt; /* Suppress 'unref arg' compiler warnings */
  178.  
  179.     if ( gbm -> bpp != 24 )
  180.         return ( GBM_ERR_NOT_SUPP );
  181.  
  182.     if ( (linebuf = malloc(gbm -> w * 3)) == NULL )
  183.         return ( GBM_ERR_MEM );
  184.  
  185.     sprintf(s,
  186.         "P6\n# Written by Generalised Bitmap Module\n%d %d 255\n",
  187.         gbm -> w, gbm -> h);
  188.     write(fd, s, strlen(s));
  189.  
  190.     stride = ((gbm -> w * 3 + 3) & ~3);
  191.     p = data + ((gbm -> h - 1) * stride);
  192.     for ( i = gbm -> h - 1; i >= 0; i-- )
  193.         {
  194.         rgb_bgr(p, linebuf, gbm -> w);
  195.         write(fd, linebuf, gbm -> w * 3);
  196.         p -= stride;
  197.         }
  198.  
  199.     free(linebuf);
  200.  
  201.     return ( GBM_ERR_OK );
  202.     }
  203. /*...e*/
  204. /*...sppm_err:0:*/
  205. char *ppm_err(GBM_ERR rc)
  206.     {
  207.     switch ( (int) rc )
  208.         {
  209.         case GBM_ERR_PPM_BAD_M:
  210.             return ( "bad maximum pixel intensity" );
  211.         }
  212.     return ( NULL );
  213.     }
  214. /*...e*/
  215.