home *** CD-ROM | disk | FTP | other *** search
/ Big Green CD 8 / BGCD_8_Dev.iso / NEXTSTEP / Graphics / ToyViewer-2.6a / src / getpixel.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-09-30  |  8.0 KB  |  386 lines

  1. #include <stdlib.h>
  2. #include "common.h"
  3. #include "getpixel.h"
  4.  
  5. static commonInfo *comInfo;
  6. static unsigned char *rr, *gg, *bb, *aa;
  7.  
  8. static int cs0, cs1, elems, alpx, palp;
  9. static BOOL ismono;
  10. static int bufp, yline;
  11. static unsigned char *buffer[MAXPLANE];
  12. static int had_alpha, buffer_size = 0;
  13.  
  14. static int _cc;
  15. static short _pp[] = { 0, 0x55, 0xaa, 0xff };
  16. #define pigment(c)    (((_cc = ((c) & 0xf0)) == 0xf0) ? 0xff : _cc)
  17. #define pigment2(c)    (_pp[((c) & 0xc0) >> 6])
  18. /*
  19.     static int pigment(int cc)
  20.     {
  21.     int n = cc & 0xf0;
  22.     if (n == 0xf0) n = 0xff;
  23.     return n;
  24.     }
  25.  
  26.     static int pigment2(int cc)
  27.     {
  28.     static unsigned char tone[] = { 0, 0x55, 0xaa, 0xff };
  29.     return tone[cc >> 6];
  30.     }
  31. */
  32.  
  33.  
  34. int initGetPixel(commonInfo *cinf)
  35. {
  36.     comInfo = cinf;
  37.     if (comInfo->cspace == NX_OneIsBlackColorSpace)
  38.         cs0 = 0xff, cs1 = 0;
  39.     else
  40.         cs0 = 0, cs1 = 0xff;
  41.     ismono = (comInfo->numcolors == 1);
  42.     palp = 0;
  43.     if (comInfo->alpha) {
  44.         elems = 4;
  45.         alpx = ismono ? 1 : 3;
  46.     }else {
  47.         elems = 3;
  48.         alpx = 0;
  49.     }
  50.     if (comInfo->width > buffer_size) {
  51.         int i;
  52.         unsigned char *p;
  53.         if (comInfo->width > MAXWidth)
  54.             return Err_SAV_IMPL;
  55.         if (buffer_size > 0) free((void *)buffer[0]);
  56.         buffer_size = (comInfo->width + 7) & 0xfff8;
  57.         p = (unsigned char *)malloc(buffer_size * 4);
  58.         if (p == NULL) {
  59.             buffer_size = 0;
  60.             return Err_MEMORY;
  61.         }
  62.         for (i = 0; i < 4; i++) {
  63.             buffer[i] = p;
  64.             p += buffer_size;
  65.         }
  66.     }
  67.     return 0;
  68. }
  69.  
  70. void resetPixel(unsigned char **planes, int y)
  71. {
  72.     had_alpha = 0;
  73.     rr = planes[0];
  74.     if (!comInfo->isplanar)
  75.         aa = gg = bb = rr;
  76.     else if (ismono) {
  77.         gg = bb = rr;
  78.         aa = planes[alpx];
  79.     }else {
  80.         gg = planes[1];
  81.         bb = planes[2];
  82.         aa = planes[alpx];
  83.     }
  84.     if (y > 0) {
  85.         int w = comInfo->xbytes * y;
  86.         rr += w;
  87.         gg += w;
  88.         bb += w;
  89.         aa += w;
  90.     }
  91.     yline = y;
  92.     bufp = MAXWidth;
  93. }
  94.  
  95. static int alphaToWhite(int c, int a)
  96. {
  97.     int n;
  98.     if (a == AlphaOpaque) return c;
  99.     n = 255 - a + ((c * a) >> 8);    /* (256-c)*((256-a)/256)+c */
  100.     return (n >= 255) ? 255 : n;
  101. }
  102.  
  103. void compositeColors(int clr[], const int bkg[], int a)
  104. {
  105.     int i, d, n;
  106.     float ratio;
  107.  
  108.     if (a == AlphaOpaque) return;    /* Do Nothing */
  109.     if (a == AlphaTransp) {
  110.         for (i = 0; i < 3; i++)
  111.             clr[i] = bkg[i];
  112.         return;
  113.     }
  114.     ratio = (255 - a) / 255.0;
  115.     for (i = 0; i < 3; i++) {
  116.         if ((d = bkg[i] - clr[i]) == 0) continue;
  117.         n = d * ratio + clr[i];
  118.         clr[i] = (n <= 0) ? 0 : ((n >= 255) ? 255 : n);
  119.     }
  120. }
  121.  
  122. int getPalPixel(int *r, int *g, int *b)
  123. {
  124.     unsigned char *p;
  125.  
  126.     if (palp >= comInfo->palsteps)
  127.         return -1;
  128.     p = comInfo->palette[palp++];
  129.     switch (comInfo->bits) {
  130.     case 1:
  131.         *r = p[RED] ? 0xff : 0;
  132.         *g = p[GREEN] ? 0xff : 0;
  133.         *b = p[BLUE] ? 0xff : 0;
  134.         break;
  135.     case 2:
  136.         *r = pigment2(p[RED]);
  137.         *g = pigment2(p[GREEN]);
  138.         *b = pigment2(p[BLUE]);
  139.         break;
  140.     case 4:
  141.         *r = pigment(p[RED]);
  142.         *g = pigment(p[GREEN]);
  143.         *b = pigment(p[BLUE]);
  144.         break;
  145.     case 8:
  146.     default:
  147.         *r = p[RED];
  148.         *g = p[GREEN];
  149.         *b = p[BLUE];
  150.         break;
  151.     }
  152.     return 0;
  153. }
  154.  
  155. static int getNextLine(void)
  156. {
  157.     int i, x, mask, xbytes;
  158.  
  159.     if (++yline > comInfo->height)
  160.         return -1;    /* End of Image */
  161.     bufp = 0;
  162.     xbytes = comInfo->xbytes;
  163.  
  164.     if (comInfo->isplanar) {
  165.         if (comInfo->bits == 1) {
  166.         for (x = 0; x < xbytes; x++) {
  167.             for (mask = 0x80; mask; mask >>= 1) {
  168.             buffer[RED][bufp]   = (*rr & mask)? cs1 : cs0;
  169.             buffer[GREEN][bufp] = (*gg & mask)? cs1 : cs0;
  170.             buffer[BLUE][bufp]  = (*bb & mask)? cs1 : cs0;
  171.             bufp++;
  172.             }
  173.             rr++, gg++, bb++;
  174.         }
  175.         if (alpx) {
  176.             bufp = 0;
  177.             for (x = 0; x < xbytes; x++) {
  178.             for (mask = 0x80; mask; mask >>= 1)
  179.                 buffer[ALPHA][bufp++]  = (*aa & mask)? 0xff : 0;
  180.             aa++;
  181.             }
  182.         }
  183.         }else if (comInfo->bits == 2) {
  184.         for (x = 0; x < xbytes; x++) {
  185.             for (i = 0; i < 8; i += 2) {
  186.             buffer[RED][bufp]   = pigment2(*rr << i);
  187.             buffer[GREEN][bufp] = pigment2(*gg << i);
  188.             buffer[BLUE][bufp]  = pigment2(*bb << i);
  189.             bufp++;
  190.             }
  191.             rr++, gg++, bb++;
  192.         }
  193.         if (alpx) {
  194.             bufp = 0;
  195.             for (x = 0; x < xbytes; x++) {
  196.             for (i = 0; i < 8; i += 2)
  197.                 buffer[ALPHA][bufp++] = pigment2(*aa << i);
  198.             aa++;
  199.             }
  200.         }
  201.         }else if (comInfo->bits == 4) {
  202.         for (x = 0; x < xbytes; x++) {
  203.             buffer[RED][bufp]   = pigment(*rr);
  204.             buffer[GREEN][bufp] = pigment(*gg);
  205.             buffer[BLUE][bufp]  = pigment(*bb);
  206.             bufp++;
  207.             buffer[RED][bufp]   = pigment(*rr++ << 4);
  208.             buffer[GREEN][bufp] = pigment(*gg++ << 4);
  209.             buffer[BLUE][bufp]  = pigment(*bb++ << 4);
  210.             bufp++;
  211.         }
  212.         if (alpx) {
  213.             bufp = 0;
  214.             for (x = 0; x < xbytes; x++) {
  215.             buffer[ALPHA][bufp++]  = pigment(*aa);
  216.             buffer[ALPHA][bufp++]  = pigment(*aa++ << 4);
  217.             }
  218.         }
  219.         }else /* 8 */ {
  220.         for (x = 0; x < xbytes; x++) {
  221.             buffer[RED][x]   = *rr++;
  222.             buffer[GREEN][x] = *gg++;
  223.             buffer[BLUE][x]  = *bb++;
  224.         }
  225.         if (alpx) {
  226.             for (x = 0; x < xbytes; x++)
  227.             buffer[ALPHA][x]  = *aa++;
  228.         }
  229.         }
  230.     }else if (ismono) { /* meshed mono */
  231.         if (comInfo->bits == 1) {
  232.         for (x = 0; x < xbytes; x++) {
  233.             for (mask = 0x80; mask; mask >>= 1) {
  234.             buffer[0][bufp] = buffer[1][bufp] = buffer[2][bufp]
  235.                 = (*rr & mask)? cs1 : cs0;
  236.             if (alpx) {
  237.                 mask >>= 1;
  238.                 buffer[ALPHA][bufp] = (*rr & mask)? cs1 : cs0;
  239.             }
  240.             bufp++;
  241.             }
  242.             rr++;
  243.         }
  244.         }else if (comInfo->bits == 2) {
  245.         for (x = 0; x < xbytes; x++) {
  246.             for (i = 0; i < 8; i += 2) {
  247.             buffer[0][bufp] = buffer[1][bufp] = buffer[2][bufp]
  248.                 = pigment2(*rr << i);
  249.             if (alpx) {
  250.                 i += 2;
  251.                 buffer[ALPHA][bufp] = pigment2(*rr << i);
  252.             }
  253.             bufp++;
  254.             }
  255.             rr++;
  256.         }
  257.         }else if (comInfo->bits == 4) {
  258.         if (alpx) {
  259.             for (bufp = 0; bufp < xbytes; bufp++) {
  260.             buffer[0][bufp] = buffer[1][bufp] = buffer[2][bufp]
  261.                     = pigment(*rr);
  262.             buffer[ALPHA][bufp] = pigment(*rr++ << 4);
  263.             }
  264.         }else {
  265.             int sft = 0;
  266.             x = 0;
  267.             for (bufp = 0; ; bufp++) {
  268.             buffer[0][bufp] = buffer[1][bufp] = buffer[2][bufp]
  269.                     = pigment(sft ? (*rr << 4) : *rr);
  270.             if (sft) {
  271.                 sft = 0, rr++;
  272.                 if (++x >= xbytes) break;
  273.             }else
  274.                 sft = 1;
  275.             }
  276.         }
  277.         }else /* 8 */ {
  278.         for (bufp = 0; bufp < xbytes; bufp++) {
  279.             buffer[0][bufp] = buffer[1][bufp]
  280.                     = buffer[2][bufp] = *rr++;
  281.             if (alpx) buffer[ALPHA][bufp] = *rr++;
  282.         }
  283.         }
  284.     }else { /* meshed color */
  285.         if (comInfo->bits == 1) {
  286.         i = x = 0;
  287.         mask = 0x80;
  288.         for ( ; ; ) {
  289.             buffer[i][bufp] = (*rr & mask)? cs1 : cs0;
  290.             if (++i >= elems)
  291.             i = 0, bufp++;
  292.             if ((mask >>= 1) == 0) {
  293.             mask = 0x80, rr++;
  294.             if (++x >= xbytes) break;
  295.             }
  296.         }
  297.         }else if (comInfo->bits == 2) {
  298.         i = x = 0;
  299.         mask = 0;
  300.         for ( ; ; ) {
  301.             buffer[i][bufp] = pigment2(*rr << mask);
  302.             if (++i >= elems)
  303.             i = 0, bufp++;
  304.             if ((mask += 2) == 8) {
  305.             mask = 0, rr++;
  306.             if (++x >= xbytes) break;
  307.             }
  308.         }
  309.         }else if (comInfo->bits == 4) {
  310.         int sft = 0;
  311.         i = x = 0;
  312.         for ( ; ; ) {
  313.             buffer[i][bufp] = pigment(sft ? (*rr << 4) : *rr);
  314.             if (++i >= elems)
  315.             i = 0, bufp++;
  316.             if (sft) {
  317.                 sft = 0, rr++;
  318.             if (++x >= xbytes) break;
  319.             }else
  320.                 sft = 1;
  321.         }
  322.         }else /* 8 */ {
  323.         for (x = 0; x < xbytes; x += elems) {
  324.             for (i = 0; i < elems; i++)
  325.             buffer[i][bufp] = *rr++;
  326.             bufp++;
  327.         }
  328.         }
  329.     }
  330.     bufp = 0;
  331.     return 0;
  332. }
  333.  
  334. int getPixel(int *r, int *g, int *b, int *a)
  335. {
  336.     int av;
  337.  
  338.     if (bufp >= comInfo->width) {
  339.         if (getNextLine() != 0)
  340.             return -1;
  341.     }
  342.     if (alpx && (av = buffer[ALPHA][bufp]) < AlphaOpaque) {
  343.         had_alpha = 1;
  344.         if (av == AlphaTransp)
  345.             *r = *g = *b = 255;    /* white */
  346.         else {
  347.             *r = alphaToWhite(buffer[RED][bufp], av);
  348.             *g = alphaToWhite(buffer[GREEN][bufp], av);
  349.             *b = alphaToWhite(buffer[BLUE][bufp], av);
  350.         }
  351.         *a = av;
  352.     }else {
  353.         *r = buffer[RED][bufp];
  354.         *g = buffer[GREEN][bufp];
  355.         *b = buffer[BLUE][bufp];
  356.         *a = AlphaOpaque;
  357.     }
  358.     if (++bufp >= comInfo->width)
  359.         return 1;
  360.     return 0;
  361. }
  362.  
  363. int getPixelA(int *elm)
  364. {
  365.     if (bufp >= comInfo->width) {
  366.         if (getNextLine() != 0)
  367.             return -1;
  368.     }
  369.     elm[RED]   = buffer[RED][bufp];
  370.     elm[GREEN] = buffer[GREEN][bufp];
  371.     elm[BLUE]  = buffer[BLUE][bufp];
  372.     if (alpx) {
  373.         if ((elm[ALPHA] = buffer[ALPHA][bufp]) < AlphaOpaque)
  374.             had_alpha = 1;
  375.     }else
  376.         elm[ALPHA] = AlphaOpaque;
  377.     if (++bufp >= comInfo->width)
  378.         return 1;
  379.     return 0;
  380. }
  381.  
  382. int hadAlpha(void)
  383. {
  384.     return had_alpha;
  385. }
  386.