[capabilites] remove redundant notcurses_canpixel()

This commit is contained in:
nick black 2021-03-25 18:17:34 -04:00 committed by Nick Black
parent b13544122e
commit 828cce634a
7 changed files with 275 additions and 239 deletions

View File

@ -10,6 +10,8 @@ rearrangements of Notcurses.
* Added `NCVISUAL_OPTION_HORALIGNED` flag for `ncvisual_render()`.
* Added the `nctabbed` widget for multiplexing planes data with navigational
tabs. Courtesy Łukasz Drukała, in his first contribution.
* Removed **notcurses_canpixel()**, which was obsoleted by
**notcurses_check_pixel_support()**.
* 2.2.3 (2021-03-08)
* Implemented **EXPERIMENTAL** `NCBLIT_PIXEL` for terminals reporting Sixel

View File

@ -298,9 +298,6 @@ bool notcurses_canchangecolor(const struct notcurses* nc);
// Is our encoding UTF-8? Requires LANG being set to a UTF-8 locale.
bool notcurses_canutf8(const struct notcurses* nc);
// Can we blit pixel graphics?
bool notcurses_canpixel(const struct notcurses* nc);
// Can we draw sextants? This requires Unicode 13.
bool notcurses_cansextants(const struct notcurses* nc);

View File

@ -255,6 +255,10 @@ aspect-preserving **NCBLIT_2x1** will be returned. If sextants are available
(see **notcurses_cansextant**), this will be **NCBLIT_3x2**, or otherwise
**NCBLIT_2x2**.
**notcurses_check_pixel_support** returns 1 if bitmap support (via any
mechanism) is detected; **NCBLIT_PIXEL** can be used after such a return.
It returns 0 a lack of bitmap support was confirmed, and -1 on error.
# NOTES
Multimedia decoding requires that Notcurses be built with either FFmpeg or

View File

@ -1243,9 +1243,6 @@ API bool notcurses_cansextant(const struct notcurses* nc);
// Can we reliably use Unicode Braille?
API bool notcurses_canbraille(const struct notcurses* nc);
// Can we blit to pixel graphics?
API bool notcurses_canpixel(const struct notcurses* nc);
// This function must successfully return before NCBLIT_PIXEL is available.
// Returns -1 on error, 0 for no support, or 1 if pixel output is supported.
// Must not be called concurrently with either input or rasterization.

View File

@ -47,7 +47,7 @@ int yield_demo(struct notcurses* nc){
// run closer to twenty seconds. 11/50 it is, then. pixels are different.
// it would be nice to hit this all with a rigor stick. yes, the 1 makes
// all the difference in cells v pixels. FIXME
const long threshold_painted = total * (10 + !notcurses_canpixel(nc)) / 50;
const long threshold_painted = total * (10 + (notcurses_check_pixel_support(nc) <= 0)) / 50;
const int MAXITER = 256;
timespec_div(&demodelay, MAXITER, &scaled);
long tfilled = 0;

View File

@ -2042,10 +2042,6 @@ bool notcurses_canchangecolor(const notcurses* nc){
return true;
}
bool notcurses_canpixel(const notcurses* nc){
return nc->tcache.sixel_supported;
}
palette256* palette256_new(notcurses* nc){
palette256* p = malloc(sizeof(*p));
if(p){

View File

@ -9,237 +9,21 @@ TEST_CASE("Visual") {
auto n_ = notcurses_stdplane(nc_);
REQUIRE(n_);
#ifndef NOTCURSES_USE_MULTIMEDIA
SUBCASE("VisualDisabled"){
REQUIRE(!notcurses_canopen_images(nc_));
REQUIRE(!notcurses_canopen_videos(nc_));
}
#else
SUBCASE("ImagesEnabled"){
REQUIRE(notcurses_canopen_images(nc_));
}
SUBCASE("LoadImageCreatePlane") {
int dimy, dimx;
ncplane_dim_yx(ncp_, &dimy, &dimx);
auto ncv = ncvisual_from_file(find_data("changes.jpg"));
REQUIRE(ncv);
/*CHECK(dimy * 2 == frame->height);
CHECK(dimx == frame->width); FIXME */
struct ncvisual_options opts{};
opts.scaling = NCSCALE_STRETCH;
auto newn = ncvisual_render(nc_, ncv, &opts);
CHECK(newn);
CHECK(0 == notcurses_render(nc_));
CHECK(1 == ncvisual_decode(ncv));
ncplane_destroy(newn);
// check that NCVISUAL_OPTION_HORALIGNED works in all three cases
SUBCASE("VisualAligned") {
const uint32_t pixels[4] = { htole(0xffff0000), htole(0xff00ff00), htole(0xff00000ff), htole(0xffffffff) };
ncvisual_options vopts = {
.y = 0,
.x = NCALIGN_LEFT,
.leny = 2,
.lenx = 2,
.flags = NCVISUAL_OPTION_HORALIGNED,
};
auto ncv = ncvisual_from_rgba(pixels, 2, 2 * sizeof(*pixels), 2);
REQUIRE(nullptr != ncv);
ncvisual_destroy(ncv);
}
SUBCASE("LoadImage") {
int dimy, dimx;
ncplane_dim_yx(ncp_, &dimy, &dimx);
auto ncv = ncvisual_from_file(find_data("changes.jpg"));
REQUIRE(ncv);
/*CHECK(dimy * 2 == frame->height);
CHECK(dimx == frame->width); FIXME */
struct ncvisual_options opts{};
opts.scaling = NCSCALE_STRETCH;
opts.n = ncp_;
CHECK(ncvisual_render(nc_, ncv, &opts));
CHECK(0 == notcurses_render(nc_));
CHECK(1 == ncvisual_decode(ncv));
ncvisual_destroy(ncv);
}
SUBCASE("PlaneDuplicate") {
int dimy, dimx;
ncplane_dim_yx(ncp_, &dimy, &dimx);
auto ncv = ncvisual_from_file(find_data("changes.jpg"));
REQUIRE(ncv);
/*CHECK(dimy * 2 == frame->height);
CHECK(dimx == frame->width); FIXME */
struct ncvisual_options opts{};
opts.n = ncp_;
opts.scaling = NCSCALE_STRETCH;
CHECK(ncvisual_render(nc_, ncv, &opts));
void* needle = malloc(1);
REQUIRE(nullptr != needle);
struct ncplane* newn = ncplane_dup(ncp_, needle);
int ndimx, ndimy;
REQUIRE(nullptr != newn);
ncvisual_destroy(ncv);
ncplane_erase(ncp_);
// should still have the image
CHECK(0 == notcurses_render(nc_));
ncplane_dim_yx(newn, &ndimy, &ndimx);
CHECK(ndimy == dimy);
CHECK(ndimx == dimx);
}
SUBCASE("LoadVideoASCII") {
if(notcurses_canopen_videos(nc_)){
int dimy, dimx;
ncplane_dim_yx(ncp_, &dimy, &dimx);
auto ncv = ncvisual_from_file(find_data("notcursesIII.mkv"));
REQUIRE(ncv);
for(;;){ // run at the highest speed we can
int ret = ncvisual_decode(ncv);
if(1 == ret){
break;
}
CHECK(0 == ret);
struct ncvisual_options opts{};
opts.scaling = NCSCALE_STRETCH;
opts.n = ncp_;
opts.blitter = NCBLIT_1x1;
CHECK(ncvisual_render(nc_, ncv, &opts));
CHECK(0 == notcurses_render(nc_));
}
ncvisual_destroy(ncv);
}
}
SUBCASE("LoadVideoHalfblocks") {
if(notcurses_canopen_videos(nc_)){
int dimy, dimx;
ncplane_dim_yx(ncp_, &dimy, &dimx);
auto ncv = ncvisual_from_file(find_data("notcursesIII.mkv"));
REQUIRE(ncv);
for(;;){ // run at the highest speed we can
int ret = ncvisual_decode(ncv);
if(1 == ret){
break;
}
CHECK(0 == ret);
struct ncvisual_options opts{};
opts.scaling = NCSCALE_STRETCH;
opts.n = ncp_;
opts.blitter = NCBLIT_2x1;
CHECK(ncvisual_render(nc_, ncv, &opts));
CHECK(0 == notcurses_render(nc_));
}
ncvisual_destroy(ncv);
}
}
// quadblitter is default for NCSCALE_STRETCH
SUBCASE("LoadVideoQuadblitter") {
if(notcurses_canopen_videos(nc_)){
int dimy, dimx;
ncplane_dim_yx(ncp_, &dimy, &dimx);
auto ncv = ncvisual_from_file(find_data("notcursesIII.mkv"));
REQUIRE(ncv);
for(;;){ // run at the highest speed we can
int ret = ncvisual_decode(ncv);
if(1 == ret){
break;
}
CHECK(0 == ret);
struct ncvisual_options opts{};
opts.scaling = NCSCALE_STRETCH;
opts.n = ncp_;
opts.blitter = NCBLIT_2x2;
CHECK(ncvisual_render(nc_, ncv, &opts));
CHECK(0 == notcurses_render(nc_));
}
ncvisual_destroy(ncv);
}
}
SUBCASE("LoadVideoSexblitter") {
if(notcurses_canopen_videos(nc_)){
int dimy, dimx;
ncplane_dim_yx(ncp_, &dimy, &dimx);
auto ncv = ncvisual_from_file(find_data("notcursesIII.mkv"));
REQUIRE(ncv);
for(;;){ // run at the highest speed we can
int ret = ncvisual_decode(ncv);
if(1 == ret){
break;
}
CHECK(0 == ret);
struct ncvisual_options opts{};
opts.scaling = NCSCALE_STRETCH;
opts.n = ncp_;
opts.blitter = NCBLIT_3x2;
CHECK(ncvisual_render(nc_, ncv, &opts));
CHECK(0 == notcurses_render(nc_));
}
ncvisual_destroy(ncv);
}
}
SUBCASE("LoadVideoBraille") {
if(notcurses_canopen_videos(nc_)){
int dimy, dimx;
ncplane_dim_yx(ncp_, &dimy, &dimx);
auto ncv = ncvisual_from_file(find_data("notcursesIII.mkv"));
REQUIRE(ncv);
for(;;){ // run at the highest speed we can
int ret = ncvisual_decode(ncv);
if(1 == ret){
break;
}
CHECK(0 == ret);
struct ncvisual_options opts{};
opts.scaling = NCSCALE_STRETCH;
opts.n = ncp_;
opts.blitter = NCBLIT_BRAILLE;
CHECK(ncvisual_render(nc_, ncv, &opts));
CHECK(0 == notcurses_render(nc_));
}
ncvisual_destroy(ncv);
}
}
SUBCASE("LoopVideo") {
if(notcurses_canopen_videos(nc_)){
int dimy, dimx;
ncplane_dim_yx(ncp_, &dimy, &dimx);
auto ncv = ncvisual_from_file(find_data("notcursesIII.mkv"));
REQUIRE(ncv);
int ret;
while((ret = ncvisual_decode(ncv)) == 0){
;
}
// FIXME verify that it is last frame?
CHECK(1 == ret);
ret = ncvisual_decode_loop(ncv);
CHECK(1 == ret);
struct ncplane* ncp = ncvisual_render(nc_, ncv, nullptr);
CHECK(nullptr != ncp);
ncplane_destroy(ncp);
// FIXME verify that it is first frame, not last?
ret = ncvisual_decode_loop(ncv);
CHECK(0 == ret);
ncp = ncvisual_render(nc_, ncv, nullptr);
CHECK(nullptr != ncp);
ncplane_destroy(ncp);
ncvisual_destroy(ncv);
}
}
SUBCASE("LoadVideoCreatePlane") {
if(notcurses_canopen_videos(nc_)){
int dimy, dimx;
ncplane_dim_yx(ncp_, &dimy, &dimx);
auto ncv = ncvisual_from_file(find_data("notcursesIII.mkv"));
REQUIRE(ncv);
CHECK(0 == ncvisual_decode(ncv));
/*CHECK(dimy * 2 == frame->height);
CHECK(dimx == frame->width); FIXME */
struct ncvisual_options opts{};
opts.scaling = NCSCALE_STRETCH;
auto newn = ncvisual_render(nc_, ncv, &opts);
CHECK(newn);
CHECK(0 == notcurses_render(nc_));
ncplane_destroy(newn);
ncvisual_destroy(ncv);
}
}
#endif
SUBCASE("LoadRGBAFromMemory") {
int dimy, dimx;
ncplane_dim_yx(ncp_, &dimy, &dimx);
@ -647,5 +431,261 @@ TEST_CASE("Visual") {
}
}
#ifndef NOTCURSES_USE_MULTIMEDIA
SUBCASE("VisualDisabled"){
REQUIRE(!notcurses_canopen_images(nc_));
REQUIRE(!notcurses_canopen_videos(nc_));
}
#else
SUBCASE("ImagesEnabled"){
REQUIRE(notcurses_canopen_images(nc_));
}
SUBCASE("LoadImageCreatePlane") {
int dimy, dimx;
ncplane_dim_yx(ncp_, &dimy, &dimx);
auto ncv = ncvisual_from_file(find_data("changes.jpg"));
REQUIRE(ncv);
/*CHECK(dimy * 2 == frame->height);
CHECK(dimx == frame->width); FIXME */
struct ncvisual_options opts{};
opts.scaling = NCSCALE_STRETCH;
auto newn = ncvisual_render(nc_, ncv, &opts);
CHECK(newn);
CHECK(0 == notcurses_render(nc_));
CHECK(1 == ncvisual_decode(ncv));
ncplane_destroy(newn);
ncvisual_destroy(ncv);
}
SUBCASE("LoadImage") {
int dimy, dimx;
ncplane_dim_yx(ncp_, &dimy, &dimx);
auto ncv = ncvisual_from_file(find_data("changes.jpg"));
REQUIRE(ncv);
/*CHECK(dimy * 2 == frame->height);
CHECK(dimx == frame->width); FIXME */
struct ncvisual_options opts{};
opts.scaling = NCSCALE_STRETCH;
opts.n = ncp_;
CHECK(ncvisual_render(nc_, ncv, &opts));
CHECK(0 == notcurses_render(nc_));
CHECK(1 == ncvisual_decode(ncv));
ncvisual_destroy(ncv);
}
SUBCASE("PlaneDuplicate") {
int dimy, dimx;
ncplane_dim_yx(ncp_, &dimy, &dimx);
auto ncv = ncvisual_from_file(find_data("changes.jpg"));
REQUIRE(ncv);
/*CHECK(dimy * 2 == frame->height);
CHECK(dimx == frame->width); FIXME */
struct ncvisual_options opts{};
opts.n = ncp_;
opts.scaling = NCSCALE_STRETCH;
CHECK(ncvisual_render(nc_, ncv, &opts));
void* needle = malloc(1);
REQUIRE(nullptr != needle);
struct ncplane* newn = ncplane_dup(ncp_, needle);
int ndimx, ndimy;
REQUIRE(nullptr != newn);
ncvisual_destroy(ncv);
ncplane_erase(ncp_);
// should still have the image
CHECK(0 == notcurses_render(nc_));
ncplane_dim_yx(newn, &ndimy, &ndimx);
CHECK(ndimy == dimy);
CHECK(ndimx == dimx);
}
SUBCASE("LoadVideoASCII") {
if(notcurses_canopen_videos(nc_)){
int dimy, dimx;
ncplane_dim_yx(ncp_, &dimy, &dimx);
auto ncv = ncvisual_from_file(find_data("notcursesIII.mkv"));
REQUIRE(ncv);
for(;;){ // run at the highest speed we can
int ret = ncvisual_decode(ncv);
if(1 == ret){
break;
}
CHECK(0 == ret);
struct ncvisual_options opts{};
opts.scaling = NCSCALE_STRETCH;
opts.n = ncp_;
opts.blitter = NCBLIT_1x1;
CHECK(ncvisual_render(nc_, ncv, &opts));
CHECK(0 == notcurses_render(nc_));
}
ncvisual_destroy(ncv);
}
}
SUBCASE("LoadVideoHalfblocks") {
if(notcurses_canopen_videos(nc_)){
int dimy, dimx;
ncplane_dim_yx(ncp_, &dimy, &dimx);
auto ncv = ncvisual_from_file(find_data("notcursesIII.mkv"));
REQUIRE(ncv);
for(;;){ // run at the highest speed we can
int ret = ncvisual_decode(ncv);
if(1 == ret){
break;
}
CHECK(0 == ret);
struct ncvisual_options opts{};
opts.scaling = NCSCALE_STRETCH;
opts.n = ncp_;
opts.blitter = NCBLIT_2x1;
CHECK(ncvisual_render(nc_, ncv, &opts));
CHECK(0 == notcurses_render(nc_));
}
ncvisual_destroy(ncv);
}
}
// quadblitter is default for NCSCALE_STRETCH
SUBCASE("LoadVideoQuadblitter") {
if(notcurses_canopen_videos(nc_)){
int dimy, dimx;
ncplane_dim_yx(ncp_, &dimy, &dimx);
auto ncv = ncvisual_from_file(find_data("notcursesIII.mkv"));
REQUIRE(ncv);
for(;;){ // run at the highest speed we can
int ret = ncvisual_decode(ncv);
if(1 == ret){
break;
}
CHECK(0 == ret);
struct ncvisual_options opts{};
opts.scaling = NCSCALE_STRETCH;
opts.n = ncp_;
opts.blitter = NCBLIT_2x2;
CHECK(ncvisual_render(nc_, ncv, &opts));
CHECK(0 == notcurses_render(nc_));
}
ncvisual_destroy(ncv);
}
}
SUBCASE("LoadVideoSexblitter") {
if(notcurses_canopen_videos(nc_)){
int dimy, dimx;
ncplane_dim_yx(ncp_, &dimy, &dimx);
auto ncv = ncvisual_from_file(find_data("notcursesIII.mkv"));
REQUIRE(ncv);
for(;;){ // run at the highest speed we can
int ret = ncvisual_decode(ncv);
if(1 == ret){
break;
}
CHECK(0 == ret);
struct ncvisual_options opts{};
opts.scaling = NCSCALE_STRETCH;
opts.n = ncp_;
opts.blitter = NCBLIT_3x2;
CHECK(ncvisual_render(nc_, ncv, &opts));
CHECK(0 == notcurses_render(nc_));
}
ncvisual_destroy(ncv);
}
}
SUBCASE("LoadVideoBraille") {
if(notcurses_canopen_videos(nc_)){
int dimy, dimx;
ncplane_dim_yx(ncp_, &dimy, &dimx);
auto ncv = ncvisual_from_file(find_data("notcursesIII.mkv"));
REQUIRE(ncv);
for(;;){ // run at the highest speed we can
int ret = ncvisual_decode(ncv);
if(1 == ret){
break;
}
CHECK(0 == ret);
struct ncvisual_options opts{};
opts.scaling = NCSCALE_STRETCH;
opts.n = ncp_;
opts.blitter = NCBLIT_BRAILLE;
CHECK(ncvisual_render(nc_, ncv, &opts));
CHECK(0 == notcurses_render(nc_));
}
ncvisual_destroy(ncv);
}
}
SUBCASE("LoadVideoPixel") {
if(notcurses_check_pixel_support(nc_) > 0){
if(notcurses_canopen_videos(nc_)){
int dimy, dimx;
ncplane_dim_yx(ncp_, &dimy, &dimx);
auto ncv = ncvisual_from_file(find_data("notcursesIII.mkv"));
REQUIRE(ncv);
for(;;){ // run at the highest speed we can
int ret = ncvisual_decode(ncv);
if(1 == ret){
break;
}
CHECK(0 == ret);
struct ncvisual_options opts{};
opts.scaling = NCSCALE_STRETCH;
opts.n = ncp_;
opts.blitter = NCBLIT_BRAILLE;
CHECK(ncvisual_render(nc_, ncv, &opts));
CHECK(0 == notcurses_render(nc_));
}
ncvisual_destroy(ncv);
}
}
}
SUBCASE("LoopVideo") {
if(notcurses_canopen_videos(nc_)){
int dimy, dimx;
ncplane_dim_yx(ncp_, &dimy, &dimx);
auto ncv = ncvisual_from_file(find_data("notcursesIII.mkv"));
REQUIRE(ncv);
int ret;
while((ret = ncvisual_decode(ncv)) == 0){
;
}
// FIXME verify that it is last frame?
CHECK(1 == ret);
ret = ncvisual_decode_loop(ncv);
CHECK(1 == ret);
struct ncplane* ncp = ncvisual_render(nc_, ncv, nullptr);
CHECK(nullptr != ncp);
ncplane_destroy(ncp);
// FIXME verify that it is first frame, not last?
ret = ncvisual_decode_loop(ncv);
CHECK(0 == ret);
ncp = ncvisual_render(nc_, ncv, nullptr);
CHECK(nullptr != ncp);
ncplane_destroy(ncp);
ncvisual_destroy(ncv);
}
}
SUBCASE("LoadVideoCreatePlane") {
if(notcurses_canopen_videos(nc_)){
int dimy, dimx;
ncplane_dim_yx(ncp_, &dimy, &dimx);
auto ncv = ncvisual_from_file(find_data("notcursesIII.mkv"));
REQUIRE(ncv);
CHECK(0 == ncvisual_decode(ncv));
/*CHECK(dimy * 2 == frame->height);
CHECK(dimx == frame->width); FIXME */
struct ncvisual_options opts{};
opts.scaling = NCSCALE_STRETCH;
auto newn = ncvisual_render(nc_, ncv, &opts);
CHECK(newn);
CHECK(0 == notcurses_render(nc_));
ncplane_destroy(newn);
ncvisual_destroy(ncv);
}
}
#endif
CHECK(!notcurses_stop(nc_));
}