add ncblit_rgb_packed(), ncblit_rgb_loose() #1634

pull/1637/head
nick black 3 years ago
parent 3a29fb7991
commit 84c7aca04e
No known key found for this signature in database
GPG Key ID: 5F43400C21CBFACC

@ -1,6 +1,10 @@
This document attempts to list user-visible changes and any major internal
rearrangements of Notcurses.
* 2.2.11 (not yet released)
* Added `ncblit_rgb_loose()` and `ncblit_rgb_packed()` helpers for blitting
32bpp RGBx and 24bpp RGB.
* 2.2.10 (2021-05-05)
* Added `NCVISUAL_OPTION_CHILDPLANE` to interpret the `n` field of
`ncvisual_options` as a parent plane.

@ -1565,6 +1565,16 @@ Raw streams of RGBA or BGRx data can be blitted directly to an ncplane:
int ncblit_rgba(const void* data, int linesize,
const struct ncvisual_options* vopts);
// Same as ncblit_rgba(), but for RGBx, with 'alpha' supplied as an alpha value
// throughout, 0 <= 'alpha' <= 255. linesize ought be a multiple of 4.
int ncblit_rgb_loose(const void* data, int linesize,
const struct ncvisual_options* vopts, int alpha);
// Same as ncblit_rgba(), but for RGB, with 'alpha' supplied as an alpha value
// throughout, 0 <= 'alpha' <= 255. linesize ought be a multiple of 3.
int ncblit_rgb_packed(const void* data, int linesize,
const struct ncvisual_options* vopts, int alpha);
// Same as ncblit_rgba(), but for BGRx.
int ncblit_bgrx(const void* data, int linesize,
const struct ncvisual_options* vopts);

@ -2610,6 +2610,16 @@ API int ncblit_rgba(const void* data, int linesize,
API int ncblit_bgrx(const void* data, int linesize,
const struct ncvisual_options* vopts);
// Supply an alpha value [0..255] to be applied throughout. linesize must be
// a multiple of 3 for this RGB data.
API int ncblit_rgb_packed(const void* data, int linesize,
const struct ncvisual_options* vopts, int alpha);
// Supply an alpha value [0..255] to be applied throughout. linesize must be
// a multiple of 4 for this RGBx data.
API int ncblit_rgb_loose(const void* data, int linesize,
const struct ncvisual_options* vopts, int alpha);
// The ncpixel API facilitates direct management of the pixels within an
// ncvisual (ncvisuals keep a backing store of 32-bit RGBA pixels, and render
// them down to terminal graphics in ncvisual_render()).

@ -965,7 +965,35 @@ int ncblit_bgrx(const void* data, int linesize, const struct ncvisual_options* v
if(vopts->leny <= 0 || vopts->lenx <= 0){
return -1;
}
void* rdata = bgra_to_rgba(data, vopts->leny, linesize, vopts->lenx);
void* rdata = bgra_to_rgba(data, vopts->leny, &linesize, vopts->lenx, 0xff);
if(rdata == NULL){
return -1;
}
int r = ncblit_rgba(rdata, linesize, vopts);
free(rdata);
return r;
}
int ncblit_rgb_loose(const void* data, int linesize,
const struct ncvisual_options* vopts, int alpha){
if(vopts->leny <= 0 || vopts->lenx <= 0){
return -1;
}
void* rdata = rgb_loose_to_rgba(data, vopts->leny, &linesize, vopts->lenx, alpha);
if(rdata == NULL){
return -1;
}
int r = ncblit_rgba(rdata, linesize, vopts);
free(rdata);
return r;
}
int ncblit_rgb_packed(const void* data, int linesize,
const struct ncvisual_options* vopts, int alpha){
if(vopts->leny <= 0 || vopts->lenx <= 0){
return -1;
}
void* rdata = rgb_packed_to_rgba(data, vopts->leny, &linesize, vopts->lenx, alpha);
if(rdata == NULL){
return -1;
}

@ -1146,7 +1146,9 @@ memdup(const void* src, size_t len){
return ret;
}
ALLOC void* bgra_to_rgba(const void* data, int rows, int rowstride, int cols);
ALLOC void* bgra_to_rgba(const void* data, int rows, int* rowstride, int cols, int alpha);
ALLOC void* rgb_loose_to_rgba(const void* data, int rows, int* rowstride, int cols, int alpha);
ALLOC void* rgb_packed_to_rgba(const void* data, int rows, int* rowstride, int cols, int alpha);
// find the "center" cell of two lengths. in the case of even rows/columns, we
// place the center on the top/left. in such a case there will be one more

@ -212,23 +212,75 @@ int ncvisual_blitter_geom(const notcurses* nc, const ncvisual* n,
return ret;
}
void* bgra_to_rgba(const void* data, int rows, int rowstride, int cols){
if(rowstride % 4){ // must be a multiple of 4 bytes
void* rgb_loose_to_rgba(const void* data, int rows, int* rowstride, int cols, int alpha){
if(*rowstride % 4){ // must be a multiple of 4 bytes
return NULL;
}
uint32_t* ret = malloc(rowstride * rows);
if(*rowstride < cols * 4){
return NULL;
}
uint32_t* ret = malloc(4 * cols * rows);
if(ret){
for(int y = 0 ; y < rows ; ++y){
for(int x = 0 ; x < cols ; ++x){
const uint32_t* src = (const uint32_t*)data + (*rowstride / 4) * y + x;
uint32_t* dst = ret + cols * y + x;
ncpixel_set_a(dst, alpha);
ncpixel_set_r(dst, ncpixel_r(*src));
ncpixel_set_g(dst, ncpixel_g(*src));
ncpixel_set_b(dst, ncpixel_b(*src));
}
}
}
*rowstride = cols * 4;
return ret;
}
void* rgb_packed_to_rgba(const void* data, int rows, int* rowstride, int cols, int alpha){
if(*rowstride % 3){ // must be a multiple of 3 bytes
return NULL;
}
if(*rowstride < cols * 3){
return NULL;
}
uint32_t* ret = malloc(4 * cols * rows);
if(ret){
for(int y = 0 ; y < rows ; ++y){
for(int x = 0 ; x < cols ; ++x){
const unsigned char* src = (const unsigned char*)data + *rowstride * y + x;
uint32_t* dst = ret + cols * y + x;
ncpixel_set_a(dst, alpha);
ncpixel_set_r(dst, src[0]);
ncpixel_set_g(dst, src[1]);
ncpixel_set_b(dst, src[2]);
}
}
}
*rowstride = cols * 4;
return ret;
}
void* bgra_to_rgba(const void* data, int rows, int* rowstride, int cols, int alpha){
if(*rowstride % 4){ // must be a multiple of 4 bytes
return NULL;
}
if(*rowstride < cols * 4){
return NULL;
}
uint32_t* ret = malloc(4 * cols * rows);
if(ret){
for(int y = 0 ; y < rows ; ++y){
for(int x = 0 ; x < cols ; ++x){
const uint32_t* src = (const uint32_t*)data + (rowstride / 4) * y + x;
uint32_t* dst = ret + (rowstride / 4) * y + x;
ncpixel_set_a(dst, 0xff);
const uint32_t* src = (const uint32_t*)data + (*rowstride / 4) * y + x;
uint32_t* dst = ret + cols * y + x;
ncpixel_set_a(dst, alpha);
ncpixel_set_r(dst, ncpixel_b(*src));
ncpixel_set_g(dst, ncpixel_g(*src));
ncpixel_set_b(dst, ncpixel_r(*src));
}
}
}
*rowstride = cols * 4;
return ret;
}

Loading…
Cancel
Save