This is getpixel.c in view mode; [Download] [Up]
#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; }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.