home *** CD-ROM | disk | FTP | other *** search
/ Big Green CD 8 / BGCD_8_Dev.iso / NEXTSTEP / Graphics / ToyViewer-2.6a / src / imfunc.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-01-22  |  5.8 KB  |  278 lines

  1. #include  <stdio.h>
  2. #include  <libc.h>
  3. #include  <objc/objc.h>
  4. #include  "common.h"
  5.  
  6. int optimalBits(unsigned char *pattern, int num)
  7. /* How many bits are needed to represent given patterns */
  8. {
  9.     int i, x;
  10.  
  11.     if (num > 16) return 8;
  12.     if (num == 1) { /* 1 bit; only one color */
  13.         if (pattern[0] || pattern[0xff]) return 1;
  14.     }else if (num == 2) { /* 1 bit */
  15.         if (pattern[0] && pattern[0xff]) return 1;
  16.     }
  17.     if (num <= 4) { /* 2 bits */
  18.         for (i = 1; i <= 0xfe; i++)
  19.             if (pattern[i] && (i != 0x55 && i != 0xaa))
  20.                 goto BIT4;
  21.         return 2;
  22.     }
  23. BIT4:    /* num <= 16 -- 4 bits */
  24.     for (i = 1; i <= 0xfe; i++)
  25.         if (pattern[i]
  26.             && ((x = i & 0x0f) != 0 && x != 0x0f && x != i >> 4))
  27.                 return 8;
  28.     return 4;
  29. }
  30.  
  31. int howManyBits(paltype *pal, int n)
  32. /* How many bits are needed to display colors of the palette ? */
  33. {
  34.     int i, c, num;
  35.     unsigned char *p, buf[256];
  36.  
  37.     for (i = 0; i < 256; i++) buf[i] = 0;
  38.     num = 0;
  39.     for (i = 0; i < n; i++) {
  40.         p = pal[i];
  41.         for (c = 0; c < 3; c++)
  42.         if (buf[p[c]] == 0) {
  43.             buf[p[c]] = 1;
  44.             if (++num > 16) return 8;
  45.         }
  46.     }
  47.     return optimalBits(buf, num);
  48. }
  49.  
  50. BOOL isGray(paltype *pal, int n)
  51. /* Is Gray-scaled all colors of the palette ? */
  52. {
  53.     int i;
  54.     unsigned char *p;
  55.  
  56.     if (pal == NULL)
  57.         return NO;
  58.     for (i = 0; i < n; i++) {
  59.         p = pal[i];
  60.         if (p[0] != p[1] || p[1] != p[2])
  61.             return NO;
  62.     }
  63.     return YES;
  64. }
  65.  
  66.  
  67. int allocImage(unsigned char **planes,
  68.     int width, int height, int repbits, int pnum)
  69. {
  70.     int i, xbyte, wd;
  71.     unsigned char *p;
  72.  
  73.     xbyte = byte_length(repbits, width);
  74.     wd = xbyte * height;
  75.     if ((p = (unsigned char *)malloc(wd * pnum)) == NULL)
  76.         return Err_MEMORY;
  77.     for (i = 0; i < pnum; i++) {
  78.         planes[i] = p;
  79.         p += wd;
  80.     }
  81.     if (pnum < 5) planes[pnum] = NULL;
  82.     return 0;
  83. }
  84.  
  85.  
  86. void expandImage(unsigned char **planes, unsigned char *buf,
  87.     const paltype *pal, int repbits, int width, BOOL isgray, int transp)
  88. {
  89.     int x, n;
  90.     unsigned char    *rr, *gg, *bb;
  91.     const unsigned char    *p;
  92.  
  93.     if (isgray) {
  94.         rr = planes[0];
  95.     
  96.         if (repbits == 1) {
  97.             for (x = 0; x < width; x++) {
  98.                 *rr = pal[buf[x]][RED] & 0x80;
  99.                 for (n = 1; n < 8; n++) {
  100.                     if (++x >= width) break;
  101.                     *rr |= (pal[buf[x]][RED] & 0x80) >> n;
  102.                 }
  103.                 rr++;
  104.             }
  105.         }else if (repbits == 2) {
  106.             for (x = 0; x < width; x++) {
  107.                 *rr = pal[buf[x]][RED] & 0xc0;
  108.                 for (n = 2; n < 8; n += 2) {
  109.                     if (++x >= width) break;
  110.                     *rr |= (pal[buf[x]][RED] & 0xc0) >> n;
  111.                 }
  112.                 rr++;
  113.             }
  114.         }else if (repbits == 4) {
  115.             for (x = 0; x < width; x++) {
  116.                 *rr = pal[buf[x]][RED] & 0xf0;
  117.                 if (++x >= width) break;
  118.                 *rr++ |= pal[buf[x]][RED] >> 4;
  119.             }
  120.         }else /* 8 */ {
  121.             for (x = 0; x < width; x++)
  122.                 *rr++ = pal[buf[x]][RED];
  123.         }
  124.     }else { /* Color */
  125.  
  126.         rr = planes[0];
  127.         gg = planes[1];
  128.         bb = planes[2];
  129.     
  130.         if (repbits == 1) {
  131.             for (x = 0; x < width; x++) {
  132.                 p = pal[buf[x]];
  133.                 *rr = p[RED] & 0x80;
  134.                 *gg = p[GREEN] & 0x80;
  135.                 *bb = p[BLUE] & 0x80;
  136.                 for (n = 1; n < 8; n++) {
  137.                     if (++x >= width) break;
  138.                     p = pal[buf[x]];
  139.                     *rr |= (p[RED] & 0x80) >> n;
  140.                     *gg |= (p[GREEN] & 0x80) >> n;
  141.                     *bb |= (p[BLUE] & 0x80) >> n;
  142.                 }
  143.                 rr++, gg++, bb++;
  144.             }
  145.         }else if (repbits == 2) {
  146.             for (x = 0; x < width; x++) {
  147.                 p = pal[buf[x]];
  148.                 *rr = p[RED] & 0xc0;
  149.                 *gg = p[GREEN] & 0xc0;
  150.                 *bb = p[BLUE] & 0xc0;
  151.                 for (n = 2; n < 8; n += 2) {
  152.                     if (++x >= width) break;
  153.                     p = pal[buf[x]];
  154.                     *rr |= (p[RED] & 0xc0) >> n;
  155.                     *gg |= (p[GREEN] & 0xc0) >> n;
  156.                     *bb |= (p[BLUE] & 0xc0) >> n;
  157.                 }
  158.                 rr++, gg++, bb++;
  159.             }
  160.         }else if (repbits == 4) {
  161.             for (x = 0; x < width; x++) {
  162.                 p = pal[buf[x]];
  163.                 *rr = p[RED] & 0xf0;
  164.                 *gg = p[GREEN] & 0xf0;
  165.                 *bb = p[BLUE] & 0xf0;
  166.                 if (++x >= width) break;
  167.                 p = pal[buf[x]];
  168.                 *rr++ |= p[RED] >> 4;
  169.                 *gg++ |= p[GREEN] >> 4;
  170.                 *bb++ |= p[BLUE] >> 4;
  171.             }
  172.         }else /* 8 */ {
  173.             for (x = 0; x < width; x++) {
  174.                 p = pal[buf[x]];
  175.                 *rr++ = p[RED];
  176.                 *gg++ = p[GREEN];
  177.                 *bb++ = p[BLUE];
  178.             }
  179.         }
  180.     }
  181.  
  182.     if (transp >= 0) {
  183.         rr = planes[isgray ? 1 : 3];
  184.     
  185.         if (repbits == 1) {
  186.             for (x = 0; x < width; x++) {
  187.                 *rr = (buf[x] == transp) ? 0 : 0x80;
  188.                 for (n = 1; n < 8; n++) {
  189.                     if (++x >= width) break;
  190.                     if (buf[x] != transp)
  191.                         *rr |= 0x80 >> n;
  192.                 }
  193.                 rr++;
  194.             }
  195.         }else if (repbits == 2) {
  196.             for (x = 0; x < width; x++) {
  197.                 *rr = (buf[x] == transp) ? 0 : 0xc0;
  198.                 for (n = 2; n < 8; n += 2) {
  199.                     if (++x >= width) break;
  200.                     if (buf[x] != transp)
  201.                         *rr |= 0xc0 >> n;
  202.                 }
  203.                 rr++;
  204.             }
  205.         }else if (repbits == 4) {
  206.             for (x = 0; x < width; x++) {
  207.                 *rr = (buf[x] == transp) ? 0 : 0xf0;
  208.                 if (++x >= width) break;
  209.                 if (buf[x] != transp)
  210.                     *rr |= 0x0f;
  211.                 rr++;
  212.             }
  213.         }else /* 8 */ {
  214.             for (x = 0; x < width; x++)
  215.                 *rr++ = (buf[x] == transp) ? 0 : 0xff;
  216.         }
  217.     }
  218. }
  219.  
  220. void packImage(unsigned char *dst, unsigned char *src, int width, int bits)
  221. {
  222.     int x, n;
  223.  
  224.     if (bits == 1) {
  225.         for (x = 0; x < width; x++) {
  226.             *dst = *src++ & 0x80;
  227.             for (n = 1; n < 8; n++) {
  228.                 if (++x >= width) break;
  229.                 *dst |= (*src++ & 0x80) >> n;
  230.             }
  231.             dst++;
  232.         }
  233.     }else if (bits == 2) {
  234.         for (x = 0; x < width; x++) {
  235.             *dst = *src++ & 0xc0;
  236.             for (n = 2; n < 8; n += 2) {
  237.                 if (++x >= width) break;
  238.                 *dst |= (*src++ & 0xc0) >> n;
  239.             }
  240.             dst++;
  241.         }
  242.     }else if (bits == 4) {
  243.         for (x = 0; x < width; x++) {
  244.             *dst = *src++ & 0xf0;
  245.             if (++x >= width) break;
  246.             *dst++ |= *src++ >> 4;
  247.         }
  248.     }else /* bits == 8 */ {
  249.         for (x = 0; x < width; x++)
  250.             *dst++ = *src++;
  251.     }
  252. }
  253.  
  254. void packWorkingImage(const commonInfo *newinf, int pl,
  255.     unsigned char **working, unsigned char **planes)
  256. {
  257.     int    pn, y;
  258.     unsigned char *pp, *ww;
  259.  
  260.     for (pn = 0; pn < pl; pn++) {
  261.         for (y = 0; y < newinf->height; y++) {
  262.         ww = working[pn] + y * newinf->width;
  263.         pp = planes[pn] + y * newinf->xbytes;
  264.         packImage(pp, ww, newinf->width, newinf->bits);
  265.         }
  266.     }
  267. }
  268.  
  269. paltype *copyPalette(paltype *pal, int pnum)
  270. {
  271.     paltype *np;
  272.  
  273.     if ((np = (paltype *)malloc(sizeof(paltype) * pnum)) == NULL)
  274.         return NULL;
  275.     memcpy(np, pal, sizeof(paltype) * pnum);
  276.     return np;
  277. }
  278.