Skip to content

Commit 661ee38

Browse files
committed
FEAT: added support to encode/decode images as uncompressed BMP with alpha channel (32bit)
Implements: metaeducation/rebol-issues#2345
1 parent ecab380 commit 661ee38

File tree

2 files changed

+33
-13
lines changed

2 files changed

+33
-13
lines changed

src/core/u-bmp.c

+32-11
Original file line numberDiff line numberDiff line change
@@ -425,6 +425,14 @@ void Unmap_Bytes(void *srcp, REBYTE **dstp, char *map) {
425425
i = w * 3;
426426
break;
427427

428+
case 32:
429+
for (i = 0; i<w; i++) {
430+
*dp++ = TO_PIXEL_COLOR(cp[2], cp[1], cp[0], cp[3]);
431+
cp += 4;
432+
}
433+
i = w * 4;
434+
break;
435+
428436
default:
429437
codi->error = CODI_ERR_BIT_LEN;
430438
goto error;
@@ -538,14 +546,16 @@ void Unmap_Bytes(void *srcp, REBYTE **dstp, char *map) {
538546
REBCNT *dp;
539547
BITMAPFILEHEADER bmfh;
540548
BITMAPINFOHEADER bmih;
549+
REBOOL hasalpha;
541550

542551
w = codi->w;
543552
h = codi->h;
553+
hasalpha = codi->alpha;
544554

545555
memset(&bmfh, 0, sizeof(bmfh));
546556
bmfh.bfType[0] = 'B';
547557
bmfh.bfType[1] = 'M';
548-
bmfh.bfSize = 14 + 40 + h * WADJUST(w);
558+
bmfh.bfSize = 14 + 40 + h * (hasalpha ? w * 4: WADJUST(w));
549559
bmfh.bfOffBits = 14 + 40;
550560

551561
// Create binary string:
@@ -558,7 +568,7 @@ void Unmap_Bytes(void *srcp, REBYTE **dstp, char *map) {
558568
bmih.biWidth = w;
559569
bmih.biHeight = h;
560570
bmih.biPlanes = 1;
561-
bmih.biBitCount = 24;
571+
bmih.biBitCount = hasalpha ? 32 : 24;
562572
bmih.biCompression = 0;
563573
bmih.biSizeImage = 0;
564574
bmih.biXPelsPerMeter = 0;
@@ -571,16 +581,27 @@ void Unmap_Bytes(void *srcp, REBYTE **dstp, char *map) {
571581
dp += w * h - w;
572582

573583
for (y = 0; y<h; y++) {
574-
for (i = 0; i<w; i++) {
575-
v = (REBYTE*)dp++;
576-
cp[0] = v[C_B];
577-
cp[1] = v[C_G];
578-
cp[2] = v[C_R];
579-
cp += 3;
584+
if (hasalpha) {
585+
for (i = 0; i<w; i++) {
586+
v = (REBYTE*)dp++;
587+
cp[0] = v[C_B];
588+
cp[1] = v[C_G];
589+
cp[2] = v[C_R];
590+
cp[3] = v[C_A];
591+
cp += 4;
592+
}
593+
} else {
594+
for (i = 0; i<w; i++) {
595+
v = (REBYTE*)dp++;
596+
cp[0] = v[C_B];
597+
cp[1] = v[C_G];
598+
cp[2] = v[C_R];
599+
cp += 3;
600+
}
601+
i = w * 3;
602+
while (i++ % 4)
603+
*cp++ = 0;
580604
}
581-
i = w * 3;
582-
while (i++ % 4)
583-
*cp++ = 0;
584605
dp -= 2 * w;
585606
}
586607
}

src/tests/units/image-test.r3

+1-2
Original file line numberDiff line numberDiff line change
@@ -103,10 +103,9 @@ Rebol [
103103
if find words-of system/codecs 'bmp [
104104
--test-- "save/load BMP"
105105
img1: make image! [2x2 255.0.0.10]
106-
;@@ Current BMP save discards the transparency info!
107106
save %units/files/test.bmp img1
108107
img2: load %units/files/test.bmp
109-
--assert #{FF0000FFFF0000FFFF0000FFFF0000FF} = to binary! img2
108+
--assert #{FF00000AFF00000AFF00000AFF00000A} = to binary! img2
110109
]
111110

112111
~~~end-file~~~

0 commit comments

Comments
 (0)