generalize ncvisual_inflate() to ncvisual_resize_noninterpolative() #1738

pull/1742/head
nick black 3 years ago
parent 9d47666dfe
commit 6fcaad3c5d
No known key found for this signature in database
GPG Key ID: 5F43400C21CBFACC

@ -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

@ -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…
Cancel
Save