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.