Skip to content

Commit

Permalink
CHANGE: ATRONIX: inverting alpha channel values and default white color
Browse files Browse the repository at this point in the history
Most system are using RGBA with A(alpha) = 255 as fully opaque and 0 as fully transparent. In Rebol2 and R3-alpha it was inverted, which causes many image related native code to flip the value on runtime.

In this state (compatible with Atronix branch), when the alpha value is not provided, it is added as 255 (0.0.0 is same like 0.0.0.255). This is a little bit illogical and question is if not to keep original behavior when setting/accessing image colors (and to be compatible with Rebol2, R3-alpha and Red instead).

This commit also changes default image color to be white instead of black as was introduced in Red language.

Contains also fix for: metaeducation/rebol-issues#2344
  • Loading branch information
Oldes committed Jan 14, 2019
1 parent 365be4a commit b1bc3c0
Show file tree
Hide file tree
Showing 9 changed files with 223 additions and 107 deletions.
1 change: 1 addition & 0 deletions src/core/t-gob.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ const REBCNT Gob_Flag_Words[] = {
CLEAR(gob, sizeof(REBGOB));
GOB_W(gob) = 100;
GOB_H(gob) = 100;
GOB_ALPHA(gob) = 255;
USE_GOB(gob);
if ((GC_Ballast -= Mem_Pools[GOB_POOL].wide) <= 0) SET_SIGNAL(SIG_RECYCLE);
return gob;
Expand Down
71 changes: 35 additions & 36 deletions src/core/t-image.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,10 @@
** Notes:
**
***********************************************************************/
/*
** It's a bit of a shame that alpha channels are represented with
** an inverted level compared to many standards. Alpha zero must
** be opaque in order for RGB tuples to be equal RGBA tuples.
** That is: 10.20.30 = 10.20.30.0
*/

#include "sys-core.h"

#define CLEAR_IMAGE(p, x, y) memset(p, 0, x * y * sizeof(u32))
#define CLEAR_IMAGE(p, x, y) memset(p, 0xFF, x * y * sizeof(u32))


/***********************************************************************
Expand Down Expand Up @@ -91,7 +85,10 @@
dp[C_R] = tup[0];
dp[C_G] = tup[1];
dp[C_B] = tup[2];
if (VAL_TUPLE_LEN(tuple) > 3) dp[C_A] = tup[3];
if (VAL_TUPLE_LEN(tuple) > 3)
dp[C_A] = tup[3];
else
dp[C_A] = 0xff;
}


Expand Down Expand Up @@ -119,9 +116,10 @@
/*
***********************************************************************/
{
if (only) // only RGB, do not touch Alpha
if (only) {// only RGB, do not touch Alpha
color &= 0xffffff;
for (; len > 0; len--, ip++) *ip = (*ip & 0xff000000) | color;
else
} else
for (; len > 0; len--) *ip++ = color;
}

Expand Down Expand Up @@ -239,11 +237,11 @@
{
if (len > (REBINT)size) len = size; // avoid over-run

// Convert from BGRA format to internal image (integer):
// Convert from RGBA format to internal image (integer):
for (; len > 0; len--, rgba += 4, bin += 4) {
rgba[C_B] = bin[0];
rgba[C_R] = bin[0];
rgba[C_G] = bin[1];
rgba[C_R] = bin[2];
rgba[C_B] = bin[2];
if (!only) rgba[C_A] = bin[3];
}
}
Expand Down Expand Up @@ -313,19 +311,20 @@

/***********************************************************************
**
*/ void Image_To_BGRA(REBYTE *rgba, REBYTE *bin, REBINT len)
*/ void Image_To_RGBA(REBYTE *rgba, REBYTE *bin, REBINT len)
/*
***********************************************************************/
{
// Convert from BGRA format to internal image (integer):
// Convert from internal image (integer) to RGBA binary order:
for (; len > 0; len--, rgba += 4, bin += 4) {
bin[0] = rgba[C_B];
bin[0] = rgba[C_R];
bin[1] = rgba[C_G];
bin[2] = rgba[C_R];
bin[2] = rgba[C_B];
bin[3] = rgba[C_A];
}
}


#ifdef ndef
INLINE REBCNT ARGB_To_BGR(REBCNT i)
{
Expand All @@ -346,7 +345,8 @@ INLINE REBCNT ARGB_To_BGR(REBCNT i)
REBCNT len;
REBCNT size;
REBCNT *data;

REBYTE* pixel;

Emit(mold, "IxI #{", VAL_IMAGE_WIDE(value), VAL_IMAGE_HIGH(value));

// Output RGB image:
Expand All @@ -355,8 +355,9 @@ INLINE REBCNT ARGB_To_BGR(REBCNT i)
up = Prep_Uni_Series(mold, (size * 6) + ((size - 1) / 10) + 1);

for (len = 0; len < size; len++) {
pixel = (REBYTE*)data++;
if ((len % 10) == 0) *up++ = LF;
up = Form_RGB_Uni(up, *data++);
up = Form_RGB_Uni(up, TO_RGBA_COLOR(pixel[C_R], pixel[C_G], pixel[C_B], pixel[C_A]));
}

// Output Alpha channel, if it has one:
Expand Down Expand Up @@ -386,13 +387,11 @@ INLINE REBCNT ARGB_To_BGR(REBCNT i)
{
REBSER *ser;

#ifdef XENDIAN_BIG
ser = Make_Quad(0, VAL_IMAGE_LEN(image));
ser->tail = VAL_IMAGE_LEN(image) * 4;
Image_To_BGRA(VAL_IMAGE_DATA(image), QUAD_HEAD(ser), VAL_IMAGE_LEN(image));
#else
ser = Copy_Bytes(VAL_IMAGE_DATA(image), VAL_IMAGE_LEN(image)*4);
#endif
REBINT len;
len = VAL_IMAGE_LEN(image) * 4;
ser = Make_Binary(len);
SERIES_TAIL(ser) = len;
Image_To_RGBA(VAL_IMAGE_DATA(image), QUAD_HEAD(ser), VAL_IMAGE_LEN(image));
return ser;
}

Expand All @@ -417,7 +416,7 @@ INLINE REBCNT ARGB_To_BGR(REBCNT i)
img = Make_Series(w * h + 1, sizeof(u32), FALSE);
LABEL_SERIES(img, "make image");
img->tail = w * h;
CLEAR(img->data, (img->tail + 1) * sizeof(u32));
CLEAR_IMAGE(img->data, w, h);
IMG_WIDE(img) = w;
IMG_HIGH(img) = h;
return img;
Expand Down Expand Up @@ -486,7 +485,7 @@ INLINE REBCNT ARGB_To_BGR(REBCNT i)
}
}
else if (IS_TUPLE(block)) {
Fill_Rect((REBCNT *)ip, TO_COLOR_TUPLE(block), w, w, h, TRUE);
Fill_Rect((REBCNT *)ip, TO_PIXEL_TUPLE(block), w, w, h, VAL_TUPLE_LEN(block) == 3);
block++;
if (IS_INTEGER(block)) {
Fill_Alpha_Rect((REBCNT *)ip, (REBYTE)VAL_INT32(block), w, w, h);
Expand Down Expand Up @@ -628,7 +627,7 @@ INLINE REBCNT ARGB_To_BGR(REBCNT i)
if (action == A_INSERT) {
if (index > tail) index = tail;
Expand_Series(VAL_SERIES(value), index, dup * part);
CLEAR(VAL_BIN(value) + (index * 4), dup * part * 4);
CLEAR_IMAGE(VAL_BIN(value) + (index * 4), dup, part);
Reset_Height(value);
tail = VAL_TAIL(value);
only = 0;
Expand All @@ -648,9 +647,9 @@ INLINE REBCNT ARGB_To_BGR(REBCNT i)
Fill_Alpha_Line(ip, (REBYTE)n, dup);
} else if (IS_TUPLE(arg)) { // RGB
if (IS_PAIR(count)) // rectangular fill
Fill_Rect((REBCNT *)ip, TO_COLOR_TUPLE(arg), w, dupx, dupy, only);
Fill_Rect((REBCNT *)ip, TO_PIXEL_TUPLE(arg), w, dupx, dupy, only);
else
Fill_Line((REBCNT *)ip, TO_COLOR_TUPLE(arg), dup, only);
Fill_Line((REBCNT *)ip, TO_PIXEL_TUPLE(arg), dup, only);
}
} else if (IS_IMAGE(arg)) {
Copy_Rect_Data(value, x, y, partx, party, arg, 0, 0); // dst dx dy w h src sx sy
Expand Down Expand Up @@ -719,7 +718,7 @@ INLINE REBCNT ARGB_To_BGR(REBCNT i)
if (IS_TUPLE(arg)) {
only = (REBOOL)(VAL_TUPLE_LEN(arg) < 4);
if (D_REF(5)) only = TRUE; // /only flag
p = Find_Color(ip, TO_COLOR_TUPLE(arg), len, only);
p = Find_Color(ip, TO_PIXEL_TUPLE(arg), len, only);
} else if (IS_INTEGER(arg)) {
n = VAL_INT32(arg);
if (n < 0 || n > 255) Trap_Range(arg);
Expand Down Expand Up @@ -762,7 +761,7 @@ INLINE REBCNT ARGB_To_BGR(REBCNT i)
p = (REBCNT *)VAL_IMAGE_HEAD(v);
i = VAL_IMAGE_WIDE(v)*VAL_IMAGE_HIGH(v);
for(; i > 0; i--) {
if (*p++ & 0xff000000) {
if (~*p++ & 0xff000000) {
// if (save) VAL_IMAGE_TRANSP(v) = VITT_ALPHA;
return TRUE;
}
Expand Down Expand Up @@ -1183,7 +1182,7 @@ INLINE REBCNT ARGB_To_BGR(REBCNT i)
len = MAX(len, 0);
src = VAL_IMAGE_DATA(data);

if (IS_PAIR(sel)) n = (VAL_PAIR_Y_INT(sel) * VAL_IMAGE_WIDE(data) + VAL_PAIR_X_INT(sel)) + 1;
if (IS_PAIR(sel)) n = ((VAL_PAIR_Y_INT(sel)-1) * VAL_IMAGE_WIDE(data) + (VAL_PAIR_X_INT(sel)-1)) + 1;
else if (IS_INTEGER(sel)) n = VAL_INT32(sel);
else if (IS_DECIMAL(sel)) n = (REBINT)VAL_DECIMAL(sel);
else if (IS_LOGIC(sel)) n = (VAL_LOGIC(sel) ? 1 : 2);
Expand Down Expand Up @@ -1229,11 +1228,11 @@ INLINE REBCNT ARGB_To_BGR(REBCNT i)

case SYM_RGB:
if (IS_TUPLE(val)) {
Fill_Line((REBCNT *)src, TO_COLOR_TUPLE(val), len, 1);
Fill_Line((REBCNT *)src, TO_PIXEL_TUPLE(val), len, 1);
} else if (IS_INTEGER(val)) {
n = VAL_INT32(val);
if (n < 0 || n > 255) return PE_BAD_RANGE;
Fill_Line((REBCNT *)src, TO_COLOR(n,n,n,0), len, 1);
Fill_Line((REBCNT *)src, TO_PIXEL_COLOR(n,n,n,0xff), len, 1);
} else if (IS_BINARY(val)) {
Bin_To_RGB(src, len, VAL_BIN_DATA(val), VAL_LEN(val) / 3);
} else return PE_BAD_SET;
Expand Down
39 changes: 14 additions & 25 deletions src/core/u-bmp.c
Original file line number Diff line number Diff line change
Expand Up @@ -374,8 +374,7 @@ void Unmap_Bytes(void *srcp, REBYTE **dstp, char *map) {
c = *cp++ & 0xff;
}
color = &ctab[(c&x) != 0];
*dp++ = ((int)color->rgbRed << 16) |
((int)color->rgbGreen << 8) | color->rgbBlue;
*dp++ = TO_PIXEL_COLOR(color->rgbRed, color->rgbGreen, color->rgbBlue, 0xff);
x >>= 1;
}
i = (w+7) / 8;
Expand All @@ -394,8 +393,7 @@ void Unmap_Bytes(void *srcp, REBYTE **dstp, char *map) {
goto error;
}
color = &ctab[x];
*dp++ = ((int)color->rgbRed << 16) |
((int)color->rgbGreen << 8) | color->rgbBlue;
*dp++ = TO_PIXEL_COLOR(color->rgbRed, color->rgbGreen, color->rgbBlue, 0xff);
}
i = (w+1) / 2;
break;
Expand All @@ -408,18 +406,13 @@ void Unmap_Bytes(void *srcp, REBYTE **dstp, char *map) {
goto error;
}
color = &ctab[c];
*dp++ = ((int)color->rgbRed << 16) |
((int)color->rgbGreen << 8) | color->rgbBlue;
*dp++ = TO_PIXEL_COLOR(color->rgbRed, color->rgbGreen, color->rgbBlue, 0xff);
}
break;

case 24:
for (i = 0; i<w; i++) {
#ifdef ENDIAN_BIG
*dp++=cp[0]|(cp[1]<<8)|(cp[2]<<16);
#else
*dp++ = (*(int *)cp) & 0xffffffL;
#endif
*dp++ = TO_PIXEL_COLOR(cp[2], cp[1], cp[0], 0xff);
cp += 3;
}
i = w * 3;
Expand Down Expand Up @@ -455,8 +448,7 @@ void Unmap_Bytes(void *srcp, REBYTE **dstp, char *map) {
}
else
color = &ctab[x&0x0f];
*dp++ = ((int)color->rgbRed << 16) |
((int)color->rgbGreen << 8) | color->rgbBlue;
*dp++ = TO_PIXEL_COLOR(color->rgbRed, color->rgbGreen, color->rgbBlue, 0xff);
}
j = (c+1) / 2;
while (j++%2)
Expand All @@ -473,8 +465,7 @@ void Unmap_Bytes(void *srcp, REBYTE **dstp, char *map) {
color = &ctab[x&0x0f];
else
color = &ctab[x>>4];
*dp++ = ((int)color->rgbRed << 16) |
((int)color->rgbGreen << 8) | color->rgbBlue;
*dp++ = TO_PIXEL_COLOR(color->rgbRed, color->rgbGreen, color->rgbBlue, 0xff);
}
}
}
Expand All @@ -496,8 +487,7 @@ void Unmap_Bytes(void *srcp, REBYTE **dstp, char *map) {
for (j = 0; j<c; j++) {
x = *cp++ & 0xff;
color = &ctab[x];
*dp++ = ((int)color->rgbRed << 16) |
((int)color->rgbGreen << 8) | color->rgbBlue;
*dp++ = TO_PIXEL_COLOR(color->rgbRed, color->rgbGreen, color->rgbBlue, 0xff);
}
while (j++ % 2)
cp++;
Expand All @@ -506,8 +496,7 @@ void Unmap_Bytes(void *srcp, REBYTE **dstp, char *map) {
x = *cp++ & 0xff;
for (j = 0; j<c; j++) {
color = &ctab[x];
*dp++ = ((int)color->rgbRed << 16) |
((int)color->rgbGreen << 8) | color->rgbBlue;
*dp++ = TO_PIXEL_COLOR(color->rgbRed, color->rgbGreen, color->rgbBlue, 0xff);
}
}
}
Expand Down Expand Up @@ -537,8 +526,8 @@ void Unmap_Bytes(void *srcp, REBYTE **dstp, char *map) {
{
REBINT i, y;
REBINT w, h;
REBYTE *cp;
REBCNT *dp, v;
REBYTE *cp, *v;
REBCNT *dp;
BITMAPFILEHEADER bmfh;
BITMAPINFOHEADER bmih;

Expand Down Expand Up @@ -575,10 +564,10 @@ void Unmap_Bytes(void *srcp, REBYTE **dstp, char *map) {

for (y = 0; y<h; y++) {
for (i = 0; i<w; i++) {
v = *dp++;
cp[0] = v & 0xff;
cp[1] = (v >> 8) & 0xff;
cp[2] = (v >> 16) & 0xff;
v = (REBYTE*)dp++;
cp[0] = v[C_B];
cp[1] = v[C_G];
cp[2] = v[C_R];
cp += 3;
}
i = w * 3;
Expand Down
2 changes: 1 addition & 1 deletion src/core/u-gif.c
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ void Chrom_Key_Alpha(REBVAL *v,REBCNT col,REBINT blitmode) {
}
top_stack--;
rp = colortab + 3 * *top_stack;
*dp++ = rp[2] | (rp[1] << 8) | (rp[0] << 16);
*dp++ = TO_PIXEL_COLOR(rp[0], rp[1], rp[2], 0xff);
x++;
}
if (interlaced) {
Expand Down
2 changes: 1 addition & 1 deletion src/core/u-jpg.c
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ void jpeg_load( char *buffer, int nbytes, char *output )
output = ( char * )dp;
for ( j=0; j<cinfo.image_width; j++ ) {
cp -= 3;
*--dp = cp[ 2 ] | ( cp[ 1 ] << 8 ) | ( ( uinteger32 )cp[ 0 ] << 16 );
*--dp = cp[ 2 ] | ( cp[ 1 ] << 8 ) | ( ( uinteger32 )cp[ 0 ] << 16 ) | 0xff000000;
}
}
else
Expand Down
Loading

0 comments on commit b1bc3c0

Please sign in to comment.