mirror of
https://github.com/dankamongmen/notcurses
synced 2025-03-09 17:19:03 -04:00
add ncblit_rgb_packed(), ncblit_rgb_loose() #1634
This commit is contained in:
parent
3a29fb7991
commit
84c7aca04e
4
NEWS.md
4
NEWS.md
@ -1,6 +1,10 @@
|
|||||||
This document attempts to list user-visible changes and any major internal
|
This document attempts to list user-visible changes and any major internal
|
||||||
rearrangements of Notcurses.
|
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)
|
* 2.2.10 (2021-05-05)
|
||||||
* Added `NCVISUAL_OPTION_CHILDPLANE` to interpret the `n` field of
|
* Added `NCVISUAL_OPTION_CHILDPLANE` to interpret the `n` field of
|
||||||
`ncvisual_options` as a parent plane.
|
`ncvisual_options` as a parent plane.
|
||||||
|
10
USAGE.md
10
USAGE.md
@ -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,
|
int ncblit_rgba(const void* data, int linesize,
|
||||||
const struct ncvisual_options* vopts);
|
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.
|
// Same as ncblit_rgba(), but for BGRx.
|
||||||
int ncblit_bgrx(const void* data, int linesize,
|
int ncblit_bgrx(const void* data, int linesize,
|
||||||
const struct ncvisual_options* vopts);
|
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,
|
API int ncblit_bgrx(const void* data, int linesize,
|
||||||
const struct ncvisual_options* vopts);
|
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
|
// The ncpixel API facilitates direct management of the pixels within an
|
||||||
// ncvisual (ncvisuals keep a backing store of 32-bit RGBA pixels, and render
|
// ncvisual (ncvisuals keep a backing store of 32-bit RGBA pixels, and render
|
||||||
// them down to terminal graphics in ncvisual_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){
|
if(vopts->leny <= 0 || vopts->lenx <= 0){
|
||||||
return -1;
|
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){
|
if(rdata == NULL){
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -1146,7 +1146,9 @@ memdup(const void* src, size_t len){
|
|||||||
return ret;
|
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
|
// 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
|
// 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;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* bgra_to_rgba(const void* data, int rows, int rowstride, int cols){
|
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
|
if(*rowstride % 4){ // must be a multiple of 4 bytes
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
uint32_t* ret = malloc(rowstride * rows);
|
if(*rowstride < cols * 4){
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
uint32_t* ret = malloc(4 * cols * rows);
|
||||||
if(ret){
|
if(ret){
|
||||||
for(int y = 0 ; y < rows ; ++y){
|
for(int y = 0 ; y < rows ; ++y){
|
||||||
for(int x = 0 ; x < cols ; ++x){
|
for(int x = 0 ; x < cols ; ++x){
|
||||||
const uint32_t* src = (const uint32_t*)data + (rowstride / 4) * y + x;
|
const uint32_t* src = (const uint32_t*)data + (*rowstride / 4) * y + x;
|
||||||
uint32_t* dst = ret + (rowstride / 4) * y + x;
|
uint32_t* dst = ret + cols * y + x;
|
||||||
ncpixel_set_a(dst, 0xff);
|
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 + cols * y + x;
|
||||||
|
ncpixel_set_a(dst, alpha);
|
||||||
ncpixel_set_r(dst, ncpixel_b(*src));
|
ncpixel_set_r(dst, ncpixel_b(*src));
|
||||||
ncpixel_set_g(dst, ncpixel_g(*src));
|
ncpixel_set_g(dst, ncpixel_g(*src));
|
||||||
ncpixel_set_b(dst, ncpixel_r(*src));
|
ncpixel_set_b(dst, ncpixel_r(*src));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*rowstride = cols * 4;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user