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