Skip to content

Commit

Permalink
Add support for new pixelformat ABGR/BGRA
Browse files Browse the repository at this point in the history
  • Loading branch information
saitoha committed Mar 6, 2016
1 parent 78113b8 commit f73bc45
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 29 deletions.
2 changes: 2 additions & 0 deletions include/sixel.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,8 @@ typedef int SIXELSTATUS;
#define SIXEL_PIXELFORMAT_BGR888 (SIXEL_FORMATTYPE_COLOR | 0x06) /* 24bpp */
#define SIXEL_PIXELFORMAT_ARGB8888 (SIXEL_FORMATTYPE_COLOR | 0x10) /* 32bpp */
#define SIXEL_PIXELFORMAT_RGBA8888 (SIXEL_FORMATTYPE_COLOR | 0x11) /* 32bpp */
#define SIXEL_PIXELFORMAT_ABGR8888 (SIXEL_FORMATTYPE_COLOR | 0x12) /* 32bpp */
#define SIXEL_PIXELFORMAT_BGRA8888 (SIXEL_FORMATTYPE_COLOR | 0x13) /* 32bpp */
#define SIXEL_PIXELFORMAT_G1 (SIXEL_FORMATTYPE_GRAYSCALE | 0x00) /* 1bpp grayscale */
#define SIXEL_PIXELFORMAT_G2 (SIXEL_FORMATTYPE_GRAYSCALE | 0x01) /* 2bpp grayscale */
#define SIXEL_PIXELFORMAT_G4 (SIXEL_FORMATTYPE_GRAYSCALE | 0x02) /* 4bpp grayscale */
Expand Down
115 changes: 86 additions & 29 deletions src/frame.c
Original file line number Diff line number Diff line change
Expand Up @@ -249,16 +249,15 @@ sixel_frame_get_loop_no(sixel_frame_t /* in */ *frame) /* frame object */
}


/* strip alpha from RGBA/ARGB formatted pixbuf */
/* strip alpha from RGBA/ARGB/BGRA/ABGR formatted pixbuf */
SIXELAPI SIXELSTATUS
sixel_frame_strip_alpha(
sixel_frame_t /* in */ *frame,
unsigned char /* in */ *bgcolor
)
{
SIXELSTATUS status = SIXEL_FALSE;
int x;
int y;
int i;
unsigned char *src;
unsigned char *dst;
unsigned char alpha;
Expand All @@ -267,34 +266,92 @@ sixel_frame_strip_alpha(

src = dst = frame->pixels;

switch (frame->pixelformat) {
case SIXEL_PIXELFORMAT_RGBA8888:
case SIXEL_PIXELFORMAT_ARGB8888:
for (y = 0; y < frame->height; y++) {
for (x = 0; x < frame->width; x++) {
if (bgcolor) {
alpha = src[3];
*dst++ = (*src++ * alpha + bgcolor[0] * (0xff - alpha)) >> 8;
*dst++ = (*src++ * alpha + bgcolor[1] * (0xff - alpha)) >> 8;
*dst++ = (*src++ * alpha + bgcolor[2] * (0xff - alpha)) >> 8;
src++;
} else if (frame->pixelformat == SIXEL_PIXELFORMAT_ARGB8888){
src++; /* A */
*dst++ = *src++; /* R */
*dst++ = *src++; /* G */
*dst++ = *src++; /* B */
} else if (frame->pixelformat == SIXEL_PIXELFORMAT_RGBA8888){
*dst++ = *src++; /* R */
*dst++ = *src++; /* G */
*dst++ = *src++; /* B */
src++; /* A */
}
if (bgcolor) {
switch (frame->pixelformat) {
case SIXEL_PIXELFORMAT_ARGB8888:
for (i = 0; i < frame->height * frame->width; i++) {
alpha = src[0];
*dst++ = (*src++ * alpha + bgcolor[0] * (0xff - alpha)) >> 8;
*dst++ = (*src++ * alpha + bgcolor[1] * (0xff - alpha)) >> 8;
*dst++ = (*src++ * alpha + bgcolor[2] * (0xff - alpha)) >> 8;
src++;
}
frame->pixelformat = SIXEL_PIXELFORMAT_RGB888;
break;
case SIXEL_PIXELFORMAT_RGBA8888:
for (i = 0; i < frame->height * frame->width; i++) {
alpha = src[3];
*dst++ = (*src++ * alpha + bgcolor[0] * (0xff - alpha)) >> 8;
*dst++ = (*src++ * alpha + bgcolor[1] * (0xff - alpha)) >> 8;
*dst++ = (*src++ * alpha + bgcolor[2] * (0xff - alpha)) >> 8;
src++;
}
frame->pixelformat = SIXEL_PIXELFORMAT_RGB888;
break;
case SIXEL_PIXELFORMAT_ABGR8888:
for (i = 0; i < frame->height * frame->width; i++) {
alpha = src[0];
*dst++ = (src[3] * alpha + bgcolor[0] * (0xff - alpha)) >> 8;
*dst++ = (src[2] * alpha + bgcolor[1] * (0xff - alpha)) >> 8;
*dst++ = (src[1] * alpha + bgcolor[2] * (0xff - alpha)) >> 8;
src += 4;
}
frame->pixelformat = SIXEL_PIXELFORMAT_RGB888;
break;
case SIXEL_PIXELFORMAT_BGRA8888:
for (i = 0; i < frame->height * frame->width; i++) {
alpha = src[3];
*dst++ = (src[2] * alpha + bgcolor[0] * (0xff - alpha)) >> 8;
*dst++ = (src[1] * alpha + bgcolor[1] * (0xff - alpha)) >> 8;
*dst++ = (src[0] * alpha + bgcolor[2] * (0xff - alpha)) >> 8;
src += 4;
}
frame->pixelformat = SIXEL_PIXELFORMAT_RGB888;
break;
default:
break;
}
} else {
switch (frame->pixelformat) {
case SIXEL_PIXELFORMAT_ARGB8888:
for (i = 0; i < frame->height * frame->width; i++) {
src++; /* A */
*dst++ = *src++; /* R */
*dst++ = *src++; /* G */
*dst++ = *src++; /* B */
}
frame->pixelformat = SIXEL_PIXELFORMAT_RGB888;
break;
case SIXEL_PIXELFORMAT_RGBA8888:
for (i = 0; i < frame->height * frame->width; i++) {
*dst++ = *src++; /* R */
*dst++ = *src++; /* G */
*dst++ = *src++; /* B */
src++; /* A */
}
frame->pixelformat = SIXEL_PIXELFORMAT_RGB888;
break;
case SIXEL_PIXELFORMAT_ABGR8888:
for (i = 0; i < frame->height * frame->width; i++) {
*dst++ = src[3]; /* R */
*dst++ = src[2]; /* G */
*dst++ = src[1]; /* B */
src += 4;
}
frame->pixelformat = SIXEL_PIXELFORMAT_RGB888;
break;
case SIXEL_PIXELFORMAT_BGRA8888:
for (i = 0; i < frame->height * frame->width; i++) {
*dst++ = src[2]; /* R */
*dst++ = src[1]; /* G */
*dst++ = src[0]; /* B */
src += 4;
}
frame->pixelformat = SIXEL_PIXELFORMAT_RGB888;
break;
default:
break;
}
frame->pixelformat = SIXEL_PIXELFORMAT_RGB888;
break;
default:
break;
}

status = SIXEL_OK;
Expand Down
14 changes: 14 additions & 0 deletions src/pixelformat.c
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,16 @@ get_rgb(unsigned char const *data,
*g = (pixels >> 8) & 0xff;
*b = (pixels >> 0) & 0xff;
break;
case SIXEL_PIXELFORMAT_BGRA8888:
*r = (pixels >> 8) & 0xff;
*g = (pixels >> 16) & 0xff;
*b = (pixels >> 24) & 0xff;
break;
case SIXEL_PIXELFORMAT_ABGR8888:
*r = (pixels >> 0) & 0xff;
*g = (pixels >> 8) & 0xff;
*b = (pixels >> 16) & 0xff;
break;
case SIXEL_PIXELFORMAT_GA88:
*r = *g = *b = (pixels >> 8) & 0xff;
break;
Expand All @@ -119,6 +129,8 @@ sixel_helper_compute_depth(int pixelformat)
switch (pixelformat) {
case SIXEL_PIXELFORMAT_ARGB8888:
case SIXEL_PIXELFORMAT_RGBA8888:
case SIXEL_PIXELFORMAT_ABGR8888:
case SIXEL_PIXELFORMAT_BGRA8888:
depth = 4;
break;
case SIXEL_PIXELFORMAT_RGB888:
Expand Down Expand Up @@ -273,6 +285,8 @@ sixel_helper_normalize_pixelformat(
break;
case SIXEL_PIXELFORMAT_RGBA8888:
case SIXEL_PIXELFORMAT_ARGB8888:
case SIXEL_PIXELFORMAT_BGRA8888:
case SIXEL_PIXELFORMAT_ABGR8888:
expand_rgb(dst, src, width, height, src_pixelformat, 4);
*dst_pixelformat = SIXEL_PIXELFORMAT_RGB888;
break;
Expand Down
2 changes: 2 additions & 0 deletions src/writer.c
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,8 @@ write_png_to_file(
case SIXEL_PIXELFORMAT_BGR888:
case SIXEL_PIXELFORMAT_RGBA8888:
case SIXEL_PIXELFORMAT_ARGB8888:
case SIXEL_PIXELFORMAT_BGRA8888:
case SIXEL_PIXELFORMAT_ABGR8888:
pixels = new_pixels = sixel_allocator_malloc(allocator, width * height * 3);
if (new_pixels == NULL) {
status = SIXEL_BAD_ALLOCATION;
Expand Down

0 comments on commit f73bc45

Please sign in to comment.