home *** CD-ROM | disk | FTP | other *** search
- #include <stdlib.h>
- #include "common.h"
- #include "getpixel.h"
-
- static commonInfo *comInfo;
- static unsigned char *rr, *gg, *bb, *aa;
-
- static int cs0, cs1, elems, alpx, palp;
- static BOOL ismono;
- static int bufp, yline;
- static unsigned char *buffer[MAXPLANE];
- static int had_alpha, buffer_size = 0;
-
- static int _cc;
- static short _pp[] = { 0, 0x55, 0xaa, 0xff };
- #define pigment(c) (((_cc = ((c) & 0xf0)) == 0xf0) ? 0xff : _cc)
- #define pigment2(c) (_pp[((c) & 0xc0) >> 6])
- /*
- static int pigment(int cc)
- {
- int n = cc & 0xf0;
- if (n == 0xf0) n = 0xff;
- return n;
- }
-
- static int pigment2(int cc)
- {
- static unsigned char tone[] = { 0, 0x55, 0xaa, 0xff };
- return tone[cc >> 6];
- }
- */
-
-
- int initGetPixel(commonInfo *cinf)
- {
- comInfo = cinf;
- if (comInfo->cspace == NX_OneIsBlackColorSpace)
- cs0 = 0xff, cs1 = 0;
- else
- cs0 = 0, cs1 = 0xff;
- ismono = (comInfo->numcolors == 1);
- palp = 0;
- if (comInfo->alpha) {
- elems = 4;
- alpx = ismono ? 1 : 3;
- }else {
- elems = 3;
- alpx = 0;
- }
- if (comInfo->width > buffer_size) {
- int i;
- unsigned char *p;
- if (comInfo->width > MAXWidth)
- return Err_SAV_IMPL;
- if (buffer_size > 0) free((void *)buffer[0]);
- buffer_size = (comInfo->width + 7) & 0xfff8;
- p = (unsigned char *)malloc(buffer_size * 4);
- if (p == NULL) {
- buffer_size = 0;
- return Err_MEMORY;
- }
- for (i = 0; i < 4; i++) {
- buffer[i] = p;
- p += buffer_size;
- }
- }
- return 0;
- }
-
- void resetPixel(unsigned char **planes, int y)
- {
- had_alpha = 0;
- rr = planes[0];
- if (!comInfo->isplanar)
- aa = gg = bb = rr;
- else if (ismono) {
- gg = bb = rr;
- aa = planes[alpx];
- }else {
- gg = planes[1];
- bb = planes[2];
- aa = planes[alpx];
- }
- if (y > 0) {
- int w = comInfo->xbytes * y;
- rr += w;
- gg += w;
- bb += w;
- aa += w;
- }
- yline = y;
- bufp = MAXWidth;
- }
-
- static int alphaToWhite(int c, int a)
- {
- int n;
- if (a == AlphaOpaque) return c;
- n = 255 - a + ((c * a) >> 8); /* (256-c)*((256-a)/256)+c */
- return (n >= 255) ? 255 : n;
- }
-
- void compositeColors(int clr[], const int bkg[], int a)
- {
- int i, d, n;
- float ratio;
-
- if (a == AlphaOpaque) return; /* Do Nothing */
- if (a == AlphaTransp) {
- for (i = 0; i < 3; i++)
- clr[i] = bkg[i];
- return;
- }
- ratio = (255 - a) / 255.0;
- for (i = 0; i < 3; i++) {
- if ((d = bkg[i] - clr[i]) == 0) continue;
- n = d * ratio + clr[i];
- clr[i] = (n <= 0) ? 0 : ((n >= 255) ? 255 : n);
- }
- }
-
- int getPalPixel(int *r, int *g, int *b)
- {
- unsigned char *p;
-
- if (palp >= comInfo->palsteps)
- return -1;
- p = comInfo->palette[palp++];
- switch (comInfo->bits) {
- case 1:
- *r = p[RED] ? 0xff : 0;
- *g = p[GREEN] ? 0xff : 0;
- *b = p[BLUE] ? 0xff : 0;
- break;
- case 2:
- *r = pigment2(p[RED]);
- *g = pigment2(p[GREEN]);
- *b = pigment2(p[BLUE]);
- break;
- case 4:
- *r = pigment(p[RED]);
- *g = pigment(p[GREEN]);
- *b = pigment(p[BLUE]);
- break;
- case 8:
- default:
- *r = p[RED];
- *g = p[GREEN];
- *b = p[BLUE];
- break;
- }
- return 0;
- }
-
- static int getNextLine(void)
- {
- int i, x, mask, xbytes;
-
- if (++yline > comInfo->height)
- return -1; /* End of Image */
- bufp = 0;
- xbytes = comInfo->xbytes;
-
- if (comInfo->isplanar) {
- if (comInfo->bits == 1) {
- for (x = 0; x < xbytes; x++) {
- for (mask = 0x80; mask; mask >>= 1) {
- buffer[RED][bufp] = (*rr & mask)? cs1 : cs0;
- buffer[GREEN][bufp] = (*gg & mask)? cs1 : cs0;
- buffer[BLUE][bufp] = (*bb & mask)? cs1 : cs0;
- bufp++;
- }
- rr++, gg++, bb++;
- }
- if (alpx) {
- bufp = 0;
- for (x = 0; x < xbytes; x++) {
- for (mask = 0x80; mask; mask >>= 1)
- buffer[ALPHA][bufp++] = (*aa & mask)? 0xff : 0;
- aa++;
- }
- }
- }else if (comInfo->bits == 2) {
- for (x = 0; x < xbytes; x++) {
- for (i = 0; i < 8; i += 2) {
- buffer[RED][bufp] = pigment2(*rr << i);
- buffer[GREEN][bufp] = pigment2(*gg << i);
- buffer[BLUE][bufp] = pigment2(*bb << i);
- bufp++;
- }
- rr++, gg++, bb++;
- }
- if (alpx) {
- bufp = 0;
- for (x = 0; x < xbytes; x++) {
- for (i = 0; i < 8; i += 2)
- buffer[ALPHA][bufp++] = pigment2(*aa << i);
- aa++;
- }
- }
- }else if (comInfo->bits == 4) {
- for (x = 0; x < xbytes; x++) {
- buffer[RED][bufp] = pigment(*rr);
- buffer[GREEN][bufp] = pigment(*gg);
- buffer[BLUE][bufp] = pigment(*bb);
- bufp++;
- buffer[RED][bufp] = pigment(*rr++ << 4);
- buffer[GREEN][bufp] = pigment(*gg++ << 4);
- buffer[BLUE][bufp] = pigment(*bb++ << 4);
- bufp++;
- }
- if (alpx) {
- bufp = 0;
- for (x = 0; x < xbytes; x++) {
- buffer[ALPHA][bufp++] = pigment(*aa);
- buffer[ALPHA][bufp++] = pigment(*aa++ << 4);
- }
- }
- }else /* 8 */ {
- for (x = 0; x < xbytes; x++) {
- buffer[RED][x] = *rr++;
- buffer[GREEN][x] = *gg++;
- buffer[BLUE][x] = *bb++;
- }
- if (alpx) {
- for (x = 0; x < xbytes; x++)
- buffer[ALPHA][x] = *aa++;
- }
- }
- }else if (ismono) { /* meshed mono */
- if (comInfo->bits == 1) {
- for (x = 0; x < xbytes; x++) {
- for (mask = 0x80; mask; mask >>= 1) {
- buffer[0][bufp] = buffer[1][bufp] = buffer[2][bufp]
- = (*rr & mask)? cs1 : cs0;
- if (alpx) {
- mask >>= 1;
- buffer[ALPHA][bufp] = (*rr & mask)? cs1 : cs0;
- }
- bufp++;
- }
- rr++;
- }
- }else if (comInfo->bits == 2) {
- for (x = 0; x < xbytes; x++) {
- for (i = 0; i < 8; i += 2) {
- buffer[0][bufp] = buffer[1][bufp] = buffer[2][bufp]
- = pigment2(*rr << i);
- if (alpx) {
- i += 2;
- buffer[ALPHA][bufp] = pigment2(*rr << i);
- }
- bufp++;
- }
- rr++;
- }
- }else if (comInfo->bits == 4) {
- if (alpx) {
- for (bufp = 0; bufp < xbytes; bufp++) {
- buffer[0][bufp] = buffer[1][bufp] = buffer[2][bufp]
- = pigment(*rr);
- buffer[ALPHA][bufp] = pigment(*rr++ << 4);
- }
- }else {
- int sft = 0;
- x = 0;
- for (bufp = 0; ; bufp++) {
- buffer[0][bufp] = buffer[1][bufp] = buffer[2][bufp]
- = pigment(sft ? (*rr << 4) : *rr);
- if (sft) {
- sft = 0, rr++;
- if (++x >= xbytes) break;
- }else
- sft = 1;
- }
- }
- }else /* 8 */ {
- for (bufp = 0; bufp < xbytes; bufp++) {
- buffer[0][bufp] = buffer[1][bufp]
- = buffer[2][bufp] = *rr++;
- if (alpx) buffer[ALPHA][bufp] = *rr++;
- }
- }
- }else { /* meshed color */
- if (comInfo->bits == 1) {
- i = x = 0;
- mask = 0x80;
- for ( ; ; ) {
- buffer[i][bufp] = (*rr & mask)? cs1 : cs0;
- if (++i >= elems)
- i = 0, bufp++;
- if ((mask >>= 1) == 0) {
- mask = 0x80, rr++;
- if (++x >= xbytes) break;
- }
- }
- }else if (comInfo->bits == 2) {
- i = x = 0;
- mask = 0;
- for ( ; ; ) {
- buffer[i][bufp] = pigment2(*rr << mask);
- if (++i >= elems)
- i = 0, bufp++;
- if ((mask += 2) == 8) {
- mask = 0, rr++;
- if (++x >= xbytes) break;
- }
- }
- }else if (comInfo->bits == 4) {
- int sft = 0;
- i = x = 0;
- for ( ; ; ) {
- buffer[i][bufp] = pigment(sft ? (*rr << 4) : *rr);
- if (++i >= elems)
- i = 0, bufp++;
- if (sft) {
- sft = 0, rr++;
- if (++x >= xbytes) break;
- }else
- sft = 1;
- }
- }else /* 8 */ {
- for (x = 0; x < xbytes; x += elems) {
- for (i = 0; i < elems; i++)
- buffer[i][bufp] = *rr++;
- bufp++;
- }
- }
- }
- bufp = 0;
- return 0;
- }
-
- int getPixel(int *r, int *g, int *b, int *a)
- {
- int av;
-
- if (bufp >= comInfo->width) {
- if (getNextLine() != 0)
- return -1;
- }
- if (alpx && (av = buffer[ALPHA][bufp]) < AlphaOpaque) {
- had_alpha = 1;
- if (av == AlphaTransp)
- *r = *g = *b = 255; /* white */
- else {
- *r = alphaToWhite(buffer[RED][bufp], av);
- *g = alphaToWhite(buffer[GREEN][bufp], av);
- *b = alphaToWhite(buffer[BLUE][bufp], av);
- }
- *a = av;
- }else {
- *r = buffer[RED][bufp];
- *g = buffer[GREEN][bufp];
- *b = buffer[BLUE][bufp];
- *a = AlphaOpaque;
- }
- if (++bufp >= comInfo->width)
- return 1;
- return 0;
- }
-
- int getPixelA(int *elm)
- {
- if (bufp >= comInfo->width) {
- if (getNextLine() != 0)
- return -1;
- }
- elm[RED] = buffer[RED][bufp];
- elm[GREEN] = buffer[GREEN][bufp];
- elm[BLUE] = buffer[BLUE][bufp];
- if (alpx) {
- if ((elm[ALPHA] = buffer[ALPHA][bufp]) < AlphaOpaque)
- had_alpha = 1;
- }else
- elm[ALPHA] = AlphaOpaque;
- if (++bufp >= comInfo->width)
- return 1;
- return 0;
- }
-
- int hadAlpha(void)
- {
- return had_alpha;
- }
-