home *** CD-ROM | disk | FTP | other *** search
/ Big Green CD 8 / BGCD_8_Dev.iso / NEXTSTEP / Graphics / ToyViewer-2.6a / src / bmpimage.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-02-17  |  5.0 KB  |  244 lines

  1. #include <stdio.h>
  2. #include <libc.h>
  3.  
  4. #include "bmp.h"
  5.  
  6. static xdelta, ydelta, compmode;
  7.  
  8. static int bmpGetPalette(FILE *fp, bmpHeader *bh)
  9.      /* ¥±¥ò¥ˆ¥¨⁄ù˘²⁄ë„⁄ú⁄˙⁄‰⁄˛˛˛®Ł⁄˛¹Ł˘‹¥¢¥²¥ò¥„⁄ù bh->palette⁄¸´ï˘¡£
  10.     ¥¤¥Ø¡…⁄˛»¡¢⁄“⁄Ł⁄½24¥½¥ˆ¥¨¥«¥Ø¡…⁄˛»⁄¸⁄ˇ NULL ⁄‹˘⁄º¡£
  11.     ˚á⁄Œˆ˝⁄ˇ¡¢¹fi‚ø⁄˛¬ò„ñ 0, ¥¤¥Ø¡…⁄˛¬ò„ñ⁄ˇ‚¶®ł(!=0)¡£ */
  12. {
  13.     int    i, color;
  14.     paltype    *pal = NULL;
  15.     unsigned char *p;
  16.  
  17.     bh->palette = NULL;
  18.     if (bh->bits == 24)    /* 24¥½¥ˆ¥¨¥«¥Ø¡…⁄ˇ¥±¥ò¥ˆ¥¨²¾˝â */
  19.         return 0;
  20.     color = 1 << bh->bits;
  21.     pal = (paltype *)malloc(sizeof(paltype) * color);
  22.     if (bh->type == OS2) {
  23.         for (i = 0; i < color; i++) {
  24.             p = pal[i];
  25.             p[BLUE] = getc(fp);
  26.             p[GREEN] = getc(fp);
  27.             p[RED] = getc(fp);
  28.         }
  29.     }else { /* WIN3 */
  30.         for (i = 0; i < color; i++) {
  31.             p = pal[i];
  32.             p[BLUE] = getc(fp);
  33.             p[GREEN] = getc(fp);
  34.             p[RED] = getc(fp);
  35.             (void) getc(fp);
  36.         }
  37.     }
  38.     bh->palette = pal;
  39.     if (feof(fp) || fseek(fp, bh->bitoffset, SEEK_SET) < 0)
  40.         return Err_SHORT;
  41.     return 0;
  42. }
  43.  
  44. static int get1dot(FILE *fp, int wid, unsigned char *ln)
  45. {
  46.     int x, cnt, cc, mask;
  47.  
  48.     if (feof(fp))
  49.         return -1;
  50.     for (x = 0, cnt = 0; x < wid; cnt++) {
  51.         cc = getc(fp);
  52.         for (mask = 0x80; mask; mask >>= 1)
  53.             ln[x++] = (cc & mask) ? 1 : 0;
  54.     }
  55.     for ( ; cnt & 0x03; cnt++)
  56.         (void) getc(fp);
  57.     return 0;
  58. }
  59.  
  60. static int get4dots(FILE *fp, int wid, unsigned char *ln)
  61. {
  62.     int x, cnt, cc;
  63.  
  64.     if (feof(fp))
  65.         return -1;
  66.     for (x = 0, cnt = 0; x < wid; cnt++) {
  67.         cc = getc(fp);
  68.         ln[x++] = cc >> 4;
  69.         ln[x++] = (cc & 0x0f);
  70.     }
  71.     for ( ; cnt & 0x03; cnt++)
  72.         (void) getc(fp);
  73.     return 0;
  74. }
  75.  
  76. static int get8dots(FILE *fp, int wid, unsigned char *ln)
  77. {
  78.     int cnt;
  79.  
  80.     if (feof(fp))
  81.         return -1;
  82.     for (cnt = 0; cnt < wid; cnt++)
  83.         ln[cnt] = getc(fp);
  84.     for ( ; cnt & 0x03; cnt++)
  85.         (void) getc(fp);
  86.     return 0;
  87. }
  88.  
  89. static int rledots(FILE *fp, int wid, unsigned char *ln)
  90. {
  91.     int    i, j, k, cc, count;
  92.     int    half[2];
  93.  
  94.     if (feof(fp))
  95.         return -1;
  96.     for (i = 0; i < wid; i++)
  97.         ln[i] = 0;
  98.     if (ydelta > 0) {
  99.         ydelta--;
  100.         return 0;
  101.     }
  102.     count = wid;
  103.     if (xdelta > 0) {
  104.         if (xdelta > count) {
  105.             xdelta = 0;
  106.             return 0;
  107.         }
  108.         count -= xdelta;
  109.         ln += xdelta;
  110.     }
  111.     xdelta = 0;
  112.     for ( ; ; ) {
  113.         i = getc(fp);
  114.         if (i) { /* Codec Mode */
  115.             if (i > count) i = count;
  116.             count -= i;
  117.             cc = getc(fp);
  118.             if (compmode == RLE8) {
  119.                 while (i-- > 0)
  120.                     *ln++ = cc;
  121.             }else {
  122.                 half[0] = cc >> 4;
  123.                 half[1] = cc & 0x0f;
  124.                 for (k = 0; i-- > 0; k ^= 1)
  125.                     *ln++ = half[k];
  126.             }
  127.             continue;
  128.         }
  129.         /* Absolute Mode */
  130.         j = getc(fp);
  131.         if (j == 0 || j == 1) /* EOL / EOF */
  132.             break; /* return */
  133.         if (j == 2) {  /* Delta Mode */
  134.             xdelta = getc(fp);  /* X-offset */
  135.             ydelta = getc(fp);  /* Y-offset */
  136.             if (ydelta == 0) {
  137.                 count -= xdelta;
  138.                 ln += xdelta;
  139.                 xdelta = 0;
  140.             }else {
  141.                 xdelta += wid - count;
  142.                 ydelta--;
  143.                 break; /* return */
  144.             }
  145.         }else {
  146.             if (j > count) j = count;
  147.             count -= j;
  148.             if (compmode == RLE8) {
  149.                 k = j & 1;    /* 16-bit packing */
  150.                 while (j-- > 0)
  151.                     *ln++ = getc(fp);
  152.             }else {
  153.                 k = (j + 1) & 2; /* 16-bit packing */
  154.                 while (j-- > 0) {
  155.                     cc = getc(fp);
  156.                     *ln++ = cc >> 4;
  157.                     if (j-- <= 0)
  158.                         break;
  159.                     *ln++ = cc & 0x0f;
  160.                 }
  161.             }
  162.             if (k)
  163.                 (void) getc(fp);
  164.         }
  165.     }
  166.     return 0;
  167. }
  168.  
  169.  
  170. int bmpGetImage(FILE *fp, bmpHeader *bh, int *bits, unsigned char **planes)
  171.      /*    ¥à¥¡¥⁄¥º⁄«⁄Ø¥⁄¥Æ¡…¥‚¥˙¡…¥¿⁄ù˘²⁄뉗⁄•¡¢R,G,B ⁄˛£‡⁄˜⁄˛¥â¥ò¡…¥ú⁄˛¹Ł˘‹
  172.     ¥¢¥²¥ò¥„⁄ù planes[0]~[2] ⁄¸¥»¥ˆ¥¨⁄„⁄º¡£‡˘¿§⁄¸²‹˝â⁄˚¥¾¥fl¥»¥º¿û⁄ˇ
  173.     bits ⁄¸˘⁄ò⁄Ø⁄ò⁄º¡£mh⁄¸⁄ˇ¥ã¥ˆ¥¹¬ö˚ú⁄ù»ã˜Œ⁄„⁄º¡£ */    
  174. {
  175.     int    x, wid, y, w;
  176.     int    colbit = 8, colnum = 0;
  177.     int    err = 0;
  178.     BOOL    isgray = NO;
  179.     int     (*getNdots)(FILE *, int, unsigned char *) = get8dots;
  180.  
  181.     if (bh->comp) {
  182.         if (bh->comp == RLE8)
  183.             colnum = 256;
  184.         else if (bh->comp == RLE4)
  185.             colnum = 16;
  186.         else
  187.             return Err_IMPLEMENT;
  188.         compmode = bh->comp;
  189.         getNdots = rledots;
  190.     }else {
  191.         compmode = NoComp;
  192.         if (bh->bits == 1)
  193.             getNdots = get1dot;
  194.         else if (bh->bits == 4)
  195.             getNdots = get4dots;
  196.         else if (bh->bits == 8)
  197.             getNdots = get8dots;
  198.         colnum = 1 << bh->bits;
  199.     } /* else bits == 24 */
  200.  
  201.     if ((err = bmpGetPalette(fp, bh)) != 0)
  202.         return err;
  203.     if (colnum && bh->bits < 24) {
  204.         colbit = howManyBits(bh->palette, colnum);
  205.         isgray = isGray(bh->palette, colnum);
  206.     }
  207.     wid = byte_length(colbit, bh->x);
  208.     err = allocImage(planes, bh->x, bh->y, colbit, (isgray ? 1 : 3));
  209.     if (err)
  210.         return err;
  211.     if (bh->bits <= 8) {
  212.         unsigned char    line[MAXWidth];
  213.         unsigned char    *map[MAXPLANE];
  214.         *bits = colbit;
  215.         for (y = bh->y - 1; y >= 0; y--) {
  216.             if (getNdots(fp, bh->x, line) < 0)
  217.                 return Err_SHORT;
  218.             map[0] = planes[0] + (w = wid * y);
  219.             map[1] = planes[1] + w;
  220.             map[2] = planes[2] + w;
  221.             expandImage(map, line, (const paltype *)bh->palette, 
  222.                     colbit, bh->x, isgray, -1);
  223.         }
  224.     }else {
  225.         unsigned char    *rr, *gg, *bb;
  226.         *bits = 8;
  227.         for (y = bh->y - 1; y >= 0; y--) {
  228.             if (feof(fp))
  229.                 return Err_SHORT;
  230.             rr = planes[0] + (w = wid * y);
  231.             gg = planes[1] + w;
  232.             bb = planes[2] + w;
  233.             for (x = 0; x < wid; x++) {
  234.                 *bb++ = getc(fp);
  235.                 *gg++ = getc(fp);
  236.                 *rr++ = getc(fp);
  237.             }
  238.             for (x *= 3 ; x & 0x03; x++)
  239.                 (void) getc(fp);
  240.         }
  241.     }
  242.     return 0;
  243. }
  244.