mirror of
https://github.com/dankamongmen/notcurses
synced 2025-03-09 17:19:03 -04:00
generalize ncvisual_inflate() to ncvisual_resize_noninterpolative() #1738
This commit is contained in:
parent
9d47666dfe
commit
6fcaad3c5d
3
NEWS.md
3
NEWS.md
@ -8,6 +8,9 @@ rearrangements of Notcurses.
|
||||
scaling was not performed without a linked multimedia backend).
|
||||
* `NCVISUAL_OPTION_BLEND` used with `NCBLIT_PIXEL` will now, when the Kitty
|
||||
graphics protocol is in use, cut the alpha of each pixel in half.
|
||||
* `ncvisual_inflate()` has been rewritten as a wrapper around the new
|
||||
function `ncvisual_resize_noninterpolative()`, and deprecated. It will be
|
||||
removed for ABI3. Godspeed, `ncvisual_inflate()`; we hardly knew ye.
|
||||
|
||||
* 2.3.2 (2021-06-03)
|
||||
* Fixed a bug affecting certain scalings of `ncvisual` objects created from
|
||||
|
6
USAGE.md
6
USAGE.md
@ -3127,9 +3127,9 @@ int ncvisual_rotate(struct ncvisual* n, double rads);
|
||||
// transformation, unless the size is unchanged.
|
||||
int ncvisual_resize(struct ncvisual* n, int rows, int cols);
|
||||
|
||||
// Inflate each pixel in the image to 'scale'x'scale' pixels. It is an error
|
||||
// if 'scale' is less than 1. The original color is retained.
|
||||
int ncvisual_inflate(struct ncvisual* n, int scale);
|
||||
// Scale the visual to 'rows' X 'columns' pixels, using non-interpolative
|
||||
// (naive) scaling. No new colors will be introduced as a result.
|
||||
int ncvisual_resize_noninterpolative(struct ncvisual* n, int rows, int cols);
|
||||
|
||||
// Polyfill at the specified location within the ncvisual 'n', using 'rgba'.
|
||||
int ncvisual_polyfill_yx(struct ncvisual* n, int y, int x, uint32_t rgba);
|
||||
|
@ -78,7 +78,7 @@ typedef int (*streamcb)(struct notcurses*, struct ncvisual*, void*);
|
||||
|
||||
**int ncvisual_resize(struct ncvisual* ***n***, int ***rows***, int ***cols***);**
|
||||
|
||||
**int ncvisual_inflate(struct ncvisual* ***n***, int ***scale***);**
|
||||
**int ncvisual_resize_noninterpolative(struct ncvisual* ***n***, int ***rows***, int ***cols***);**
|
||||
|
||||
**int ncvisual_polyfill_yx(struct ncvisual* ***n***, int ***y***, int ***x***, uint32_t ***rgba***);**
|
||||
|
||||
@ -114,13 +114,13 @@ per frame. **ncvisual_decode_loop** will return to the first frame,
|
||||
as if **ncvisual_decode** had never been called.
|
||||
|
||||
Once the visual is loaded, it can be transformed using **ncvisual_rotate**,
|
||||
**ncvisual_resize**, and **ncvisual_inflate**. These are persistent operations,
|
||||
unlike any scaling that takes place at render time. If a subtitle is associated
|
||||
with the frame, it can be acquired with **ncvisual_subtitle**.
|
||||
**ncvisual_resize** uses the media layer's best scheme to enlarge or shrink the
|
||||
original data, typically involving some interpolation. **ncvisual_inflate**
|
||||
maps each pixel to ***scale***x***scale*** pixels square, retaining the
|
||||
original color; it is an error if ***scale*** is less than one.
|
||||
**ncvisual_resize**, and **ncvisual_resize_noninterpolative**. These are
|
||||
persistent operations, unlike any scaling that takes place at render time. If a
|
||||
subtitle is associated with the frame, it can be acquired with
|
||||
**ncvisual_subtitle**. **ncvisual_resize** uses the media layer's best scheme
|
||||
to enlarge or shrink the original data, typically involving some interpolation.
|
||||
**ncvisual_resize_noninterpolative** performs a naive linear sampling,
|
||||
retaining only original colors.
|
||||
|
||||
**ncvisual_from_rgba** and **ncvisual_from_bgra** both require a number of
|
||||
***rows***, a number of image columns **cols**, and a virtual row length of
|
||||
@ -228,9 +228,8 @@ instance **NCSCALE_SCALE_HIRES** and a large image), more rows and columns will
|
||||
result in more effective resolution.
|
||||
|
||||
A string can be transformed to a scaling mode with **notcurses_lex_scalemode**,
|
||||
recognizing **stretch**, **scalehi**, **hires**, **scale**, **inflate**, and
|
||||
**none**. Conversion in the opposite direction is performed with
|
||||
**notcurses_str_scalemode**.
|
||||
recognizing **stretch**, **scalehi**, **hires**, **scale**, and **none**.
|
||||
Conversion in the opposite direction is performed with **notcurses_str_scalemode**.
|
||||
|
||||
Assuming a cell is twice as tall as it is wide, **NCBLIT_1x1** (and indeed
|
||||
any NxN blitter) will stretch an image by a factor of 2 in the vertical
|
||||
|
@ -2530,9 +2530,9 @@ API int ncvisual_rotate(struct ncvisual* n, double rads)
|
||||
API int ncvisual_resize(struct ncvisual* n, int rows, int cols)
|
||||
__attribute__ ((nonnull (1)));
|
||||
|
||||
// Inflate each pixel in the image to 'scale'x'scale' pixels. It is an error
|
||||
// if 'scale' is less than 1. The original color is retained.
|
||||
API int ncvisual_inflate(struct ncvisual* n, int scale)
|
||||
// Scale the visual to 'rows' X 'columns' pixels, using non-interpolative
|
||||
// (naive) scaling. No new colors will be introduced as a result.
|
||||
API int ncvisual_resize_noninterpolative(struct ncvisual* n, int rows, int cols)
|
||||
__attribute__ ((nonnull (1)));
|
||||
|
||||
// Polyfill at the specified location within the ncvisual 'n', using 'rgba'.
|
||||
@ -4269,6 +4269,12 @@ channels_set_bg_default(uint64_t* channels){
|
||||
return ncchannels_set_bg_default(channels);
|
||||
}
|
||||
|
||||
// Inflate each pixel in the image to 'scale'x'scale' pixels. It is an error
|
||||
// if 'scale' is less than 1. The original color is retained.
|
||||
// Deprecated; use ncvisual_resize_noninterpolative(), which this now wraps.
|
||||
API __attribute__ ((deprecated)) int ncvisual_inflate(struct ncvisual* n, int scale)
|
||||
__attribute__ ((nonnull (1)));
|
||||
|
||||
typedef ncpalette palette256;
|
||||
|
||||
typedef nccell cell; // FIXME backwards-compat, remove in ABI3
|
||||
|
@ -1620,6 +1620,7 @@ resize_bitmap(const uint32_t* bmap, int srows, int scols, size_t sstride,
|
||||
if(dstride < dcols * sizeof(*bmap)){
|
||||
return NULL;
|
||||
}
|
||||
// FIXME if parameters match current setup, do nothing, and return bmap
|
||||
size_t size = drows * dstride;
|
||||
uint32_t* ret = (uint32_t*)malloc(size);
|
||||
if(ret == NULL){
|
||||
|
@ -640,18 +640,7 @@ ncvisual* ncvisual_from_bgra(const void* bgra, int rows, int rowstride, int cols
|
||||
|
||||
int ncvisual_resize(ncvisual* nc, int rows, int cols){
|
||||
if(!visual_implementation){
|
||||
size_t dstride = pad_for_image(cols * 4);
|
||||
uint32_t* r = resize_bitmap(nc->data, nc->pixy, nc->pixx, nc->rowstride,
|
||||
rows, cols, dstride);
|
||||
if(r == NULL){
|
||||
return -1;
|
||||
}
|
||||
ncvisual_set_data(nc, r, true);
|
||||
nc->rowstride = dstride;
|
||||
nc->pixy = rows;
|
||||
nc->pixx = cols;
|
||||
ncvisual_details_seed(nc);
|
||||
return 0;
|
||||
return ncvisual_resize_noninterpolative(nc, rows, cols);
|
||||
}
|
||||
if(visual_implementation->visual_resize(nc, rows, cols)){
|
||||
return -1;
|
||||
@ -659,6 +648,21 @@ int ncvisual_resize(ncvisual* nc, int rows, int cols){
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ncvisual_resize_noninterpolative(ncvisual* n, int rows, int cols){
|
||||
size_t dstride = pad_for_image(cols * 4);
|
||||
uint32_t* r = resize_bitmap(n->data, n->pixy, n->pixx, n->rowstride,
|
||||
rows, cols, dstride);
|
||||
if(r == NULL){
|
||||
return -1;
|
||||
}
|
||||
ncvisual_set_data(n, r, true);
|
||||
n->rowstride = dstride;
|
||||
n->pixy = rows;
|
||||
n->pixx = cols;
|
||||
ncvisual_details_seed(n);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// by the end, disprows/dispcols refer to the number of source rows/cols (in
|
||||
// pixels), which will be mapped to a region of cells scaled by the encodings).
|
||||
// the blit will begin at placey/placex (in terms of cells). begy/begx define
|
||||
@ -1119,16 +1123,5 @@ int ncvisual_inflate(ncvisual* n, int scale){
|
||||
if(scale <= 0){
|
||||
return -1;
|
||||
}
|
||||
size_t dstride = pad_for_image(4 * n->pixx * scale);
|
||||
uint32_t* inflaton = resize_bitmap(n->data, n->pixy, n->pixx, n->rowstride,
|
||||
n->pixy * scale, n->pixx * scale, dstride);
|
||||
if(inflaton == NULL){
|
||||
return -1;
|
||||
}
|
||||
ncvisual_set_data(n, inflaton, true);
|
||||
n->pixy *= scale;
|
||||
n->pixx *= scale;
|
||||
n->rowstride = dstride;
|
||||
ncvisual_details_seed(n);
|
||||
return 0;
|
||||
return ncvisual_resize_noninterpolative(n, n->pixy * scale, n->pixx * scale);
|
||||
}
|
||||
|
@ -272,7 +272,7 @@ TEST_CASE("Bitmaps") {
|
||||
ncplane_set_base(bigp, "x", 0, white);
|
||||
CHECK(vopts.n == ncvisual_render(nc_, ncv, &vopts));
|
||||
CHECK(0 == notcurses_render(nc_));
|
||||
CHECK(0 == ncvisual_inflate(ncv, 4));
|
||||
CHECK(0 == ncvisual_resize_noninterpolative(ncv, ncv->pixy * 4, ncv->pixx * 4));
|
||||
CHECK(4 * nc_->tcache.cellpixy == ncv->pixy);
|
||||
CHECK(4 * nc_->tcache.cellpixx == ncv->pixx);
|
||||
vopts.y = 1;
|
||||
@ -345,7 +345,7 @@ TEST_CASE("Bitmaps") {
|
||||
vopts.scaling = NCSCALE_SCALE;
|
||||
ncvisual_render(nc_, ncv, &vopts);
|
||||
CHECK(4 == ncplane_dim_x(vopts.n));
|
||||
ncvisual_inflate(ncv, 4);
|
||||
CHECK(0 == ncvisual_resize_noninterpolative(ncv, ncv->pixy * 4, ncv->pixx * 4));
|
||||
vopts.n = nullptr;
|
||||
vopts.y = 2;
|
||||
vopts.x = 5;
|
||||
|
@ -136,7 +136,7 @@ TEST_CASE("Visual") {
|
||||
};
|
||||
auto newn = ncvisual_render(nc_, ncv, &vopts);
|
||||
CHECK(0 == notcurses_render(nc_));
|
||||
CHECK(0 == ncvisual_inflate(ncv, 3));
|
||||
CHECK(0 == ncvisual_resize_noninterpolative(ncv, ncv->pixy * 3, ncv->pixx * 3));
|
||||
CHECK(6 == ncv->pixy);
|
||||
CHECK(6 == ncv->pixx);
|
||||
for(int y = 0 ; y < 3 ; ++y){
|
||||
@ -772,7 +772,7 @@ TEST_CASE("Visual") {
|
||||
CHECK(0 == ncvisual_blitter_geom(nc_, ncv, &opts, &odimy, &odimx, nullptr, nullptr, nullptr));
|
||||
CHECK(ncvisual_render(nc_, ncv, &opts));
|
||||
CHECK(0 == notcurses_render(nc_));
|
||||
CHECK(0 == ncvisual_inflate(ncv, 2));
|
||||
CHECK(0 == ncvisual_resize_noninterpolative(ncv, ncv->pixy * 2, ncv->pixx * 2));
|
||||
CHECK(0 == ncvisual_blitter_geom(nc_, ncv, &opts, &ndimy, &ndimx, nullptr, nullptr, nullptr));
|
||||
CHECK(ndimy == odimy * 2);
|
||||
CHECK(ndimx == odimx * 2);
|
||||
|
Loading…
x
Reference in New Issue
Block a user