rename ncvisual_open_plane->ncvisual_from_file() #560

This commit is contained in:
nick black 2020-05-04 04:55:10 -04:00 committed by Nick Black
parent 7e9cc29f8e
commit 39548acc3a
15 changed files with 168 additions and 57 deletions

View File

@ -5,6 +5,8 @@ rearrangements of Notcurses.
* `notcurses_lex_margins()` has been added to lex margins expressed in either * `notcurses_lex_margins()` has been added to lex margins expressed in either
of two canonical formats. Hopefully this will lead to more programs of two canonical formats. Hopefully this will lead to more programs
supporting margins. supporting margins.
* `ncvisual_open_plane()` has been renamed `ncvisual_from_file()`. The former
has been retained as a deprecated alias. It will be removed by 1.6/2.0.
* 1.3.3 (2020-04-26) * 1.3.3 (2020-04-26)
* The `ncdplot` type has been added for plots based on `double`s rather than * The `ncdplot` type has been added for plots based on `double`s rather than

View File

@ -2375,7 +2375,7 @@ struct ncvisual* ncplane_visual_open(struct ncplane* nc, const char* file, nc_er
// new plane will be exactly that large. Otherwise, the plane will be as large // new plane will be exactly that large. Otherwise, the plane will be as large
// as possible (given the visible screen), either maintaining aspect ratio // as possible (given the visible screen), either maintaining aspect ratio
// (NCSCALE_SCALE) or abandoning it (NCSCALE_STRETCH). // (NCSCALE_SCALE) or abandoning it (NCSCALE_STRETCH).
struct ncvisual* ncvisual_open_plane(struct notcurses* nc, const char* file, nc_err_e* err, int y, int x, ncscale_e style); struct ncvisual* ncvisual_from_file(struct notcurses* nc, const char* file, nc_err_e* err, int y, int x, ncscale_e style);
// Destroy an ncvisual. Rendered elements will not be disrupted, but the visual // Destroy an ncvisual. Rendered elements will not be disrupted, but the visual
// can be neither decoded nor rendered any further. // can be neither decoded nor rendered any further.
@ -2440,3 +2440,19 @@ char* ncvisual_subtitle(const struct ncvisual* ncv);
int ncplane_rotate_cw(struct ncplane* n); int ncplane_rotate_cw(struct ncplane* n);
int ncplane_rotate_ccw(struct ncplane* n); int ncplane_rotate_ccw(struct ncplane* n);
``` ```
It is also possible to seed an `ncvisual` directly from memory, without involving
a file. Both RGBA and BGRA 8bpc arrangements can be used.
```c
// Prepare an ncvisual, and its underlying plane, based off RGBA content in
// memory at 'rgba'. 'rgba' must be a flat array of 32-bit 8bpc RGBA pixels.
// These must be arranged in 'rowstride' * 4b lines, where the first 'cols'
// * 4b are actual data. There must be 'rows' lines. The total size of 'rgba'
// must thus be at least (rows * rowstride * 4) bytes, of which (rows * cols
// * 4) bytes are actual data. The resulting plane will be 'rows' / 2 x 'cols'.
ncvisual* ncvisual_from_rgba(notcurses* nc, const void* rgba, int rows, int rowstride, int cols);
// ncvisual_from_rgba(), but for BGRA.
ncvisual* ncvisual_from_bgra(notcurses* nc, const void* bgra, int rows, int rowstride, int cols);
```

View File

@ -24,10 +24,14 @@ typedef int (*streamcb)(struct notcurses*, struct ncvisual*, void*);
**struct ncvisual* ncplane_visual_open(struct ncplane* nc, const char* file, **struct ncvisual* ncplane_visual_open(struct ncplane* nc, const char* file,
nc_err_e* err);** nc_err_e* err);**
**struct ncvisual* ncvisual_open_plane(struct notcurses* nc, const char* file, **struct ncvisual* ncvisual_from_file(struct notcurses* nc, const char* file,
nc_err_e* err, int y, int x, nc_err_e* err, int y, int x,
ncscale_e style);** ncscale_e style);**
**struct ncvisual* ncvisual_from_rgba(struct notcurses* nc, const void* rgba, int rows, int rowstride, int cols);**
**struct ncvisual* ncvisual_from_bgra(struct notcurses* nc, const void* bgra, int rows, int rowstride, int cols);**
**void ncvisual_destroy(struct ncvisual* ncv);** **void ncvisual_destroy(struct ncvisual* ncv);**
**nc_err_e ncvisual_decode(struct ncvisual* nc);** **nc_err_e ncvisual_decode(struct ncvisual* nc);**
@ -60,6 +64,18 @@ or **begx** are an error. It is an error to specify any region beyond the
boundaries of the frame. Supplying zero for either **leny** or **lenx** will boundaries of the frame. Supplying zero for either **leny** or **lenx** will
result in a zero-area rendering. result in a zero-area rendering.
It is possible to create an **ncvisual** from memory, rather than from a
disk, but only using raw RGBA/BGRA 8bpc content. For RGBA, use
**ncvisual_from_rgba**. For BGRA, use **ncvisual_from_bgra**. Both require
a number of **rows**, a number of image columns **cols**, and a virtual row
length of **rowstride** columns. The input data must provide 32 bits per
pixel, and thus must be at least **rowstride** * **rows** * 4 bytes, of
which a **cols** * **rows** * 4-byte subset is used. It is not possible to
**mmap(2)** an image file and use it directly--decompressed, decoded data
is necessary. The resulting plane will be **rows** / 2 rows, and **cols**
columns. It will not be necessary to call **ncvisual_decode**, but it is
still necessary to call **ncvisual_render**.
Both **ncplane_rotate_cw** and **ncplane_rotate_ccw** execute a rotation of Both **ncplane_rotate_cw** and **ncplane_rotate_ccw** execute a rotation of
π/2 radians, in the clockwise or counterclockwise direction respectively. π/2 radians, in the clockwise or counterclockwise direction respectively.
@ -71,7 +87,7 @@ be returned for multiple frames, or might not.
**notcurses_canopen** returns true if this functionality is enabled, or false **notcurses_canopen** returns true if this functionality is enabled, or false
if Notcurses was not built with multimedia support. **ncplane_visual_open** and if Notcurses was not built with multimedia support. **ncplane_visual_open** and
**ncvisual_open_plane** return an **ncvisual** object on success, or **NULL** **ncvisual_from_file** return an **ncvisual** object on success, or **NULL**
on failure. Success from these functions indicates that the specified **file** on failure. Success from these functions indicates that the specified **file**
was opened, and enough data was read to make a firm codec identification. It was opened, and enough data was read to make a firm codec identification. It
does not mean that the entire file is properly-formed. On failure, **err** does not mean that the entire file is properly-formed. On failure, **err**

View File

@ -41,7 +41,7 @@ namespace ncpp
explicit Visual (const char *file, nc_err_e* ncerr, int y, int x, NCScale scale) explicit Visual (const char *file, nc_err_e* ncerr, int y, int x, NCScale scale)
{ {
visual = ncvisual_open_plane (get_notcurses (), file, ncerr, y, x, static_cast<ncscale_e>(scale)); visual = ncvisual_from_file (get_notcurses (), file, ncerr, y, x, static_cast<ncscale_e>(scale));
if (visual == nullptr) if (visual == nullptr)
throw init_error ("notcurses failed to create a new visual"); throw init_error ("notcurses failed to create a new visual");
} }

View File

@ -2031,7 +2031,7 @@ ncplane_double_box_sized(struct ncplane* n, uint32_t attr, uint64_t channels,
API struct ncvisual* ncplane_visual_open(struct ncplane* nc, const char* file, API struct ncvisual* ncplane_visual_open(struct ncplane* nc, const char* file,
nc_err_e* ncerr); nc_err_e* ncerr);
// How to scale the visual in ncvisual_open_plane(). NCSCALE_NONE will open a // How to scale the visual in ncvisual_from_file(). NCSCALE_NONE will open a
// plane tailored to the visual's exact needs, which is probably larger than the // plane tailored to the visual's exact needs, which is probably larger than the
// visible screen (but might be smaller). NCSCALE_SCALE scales a visual larger // visible screen (but might be smaller). NCSCALE_SCALE scales a visual larger
// than the visible screen down, maintaining aspect ratio. NCSCALE_STRETCH // than the visible screen down, maintaining aspect ratio. NCSCALE_STRETCH
@ -2048,9 +2048,33 @@ typedef enum {
// new plane will be exactly that large. Otherwise, the plane will be as large // new plane will be exactly that large. Otherwise, the plane will be as large
// as possible (given the visible screen), either maintaining aspect ratio // as possible (given the visible screen), either maintaining aspect ratio
// (NCSCALE_SCALE) or abandoning it (NCSCALE_STRETCH). // (NCSCALE_SCALE) or abandoning it (NCSCALE_STRETCH).
API struct ncvisual* ncvisual_open_plane(struct notcurses* nc, const char* file, API struct ncvisual* ncvisual_from_file(struct notcurses* nc, const char* file,
nc_err_e* ncerr, int y, int x, nc_err_e* ncerr, int y, int x,
ncscale_e style); ncscale_e style);
// Remove by 1.6/2.0 FIXME
static inline struct ncvisual*
ncvisual_open_plane(struct notcurses* nc, const char* file, nc_err_e* ncerr,
int y, int x, ncscale_e style) __attribute__ ((deprecated));
static inline struct ncvisual*
ncvisual_open_plane(struct notcurses* nc, const char* file, nc_err_e* ncerr,
int y, int x, ncscale_e style){
return ncvisual_from_file(nc, file, ncerr, y, x, style);
}
// Prepare an ncvisual, and its underlying plane, based off RGBA content in
// memory at 'rgba'. 'rgba' must be a flat array of 32-bit 8bpc RGBA pixels.
// These must be arranged in 'rowstride' * 4b lines, where the first 'cols'
// * 4b are actual data. There must be 'rows' lines. The total size of 'rgba'
// must thus be at least (rows * rowstride * 4) bytes, of which (rows * cols
// * 4) bytes are actual data. The resulting plane will be 'rows' / 2 x 'cols'.
API struct ncvisual* ncvisual_from_rgba(struct notcurses* nc, const void* rgba,
int rows, int rowstride, int cols);
// ncvisual_from_rgba(), but 'bgra' is arranged as BGRA.
API struct ncvisual* ncvisual_from_bgra(struct notcurses* nc, const void* bgra,
int rows, int rowstride, int cols);
// Return the plane to which this ncvisual is bound. // Return the plane to which this ncvisual is bound.
API struct ncplane* ncvisual_plane(struct ncvisual* ncv); API struct ncplane* ncvisual_plane(struct ncvisual* ncv);
@ -2715,6 +2739,14 @@ API int ncsubproc_destroy(struct ncsubproc* n);
// future compatability (provide 0 for no artificail bound). // future compatability (provide 0 for no artificail bound).
API int ncplane_qrcode(struct ncplane* n, int maxversion, const void* data, size_t len); API int ncplane_qrcode(struct ncplane* n, int maxversion, const void* data, size_t len);
// Promote an ncplane 'n' to an ncvisual. The plane should not be associated
// with an existing ncvisual, and may contain only spaces, half blocks, and
// full blocks. The latter will be checked, and any other glyph will result
// in a NULL being returned. This function exists so that planes can be
// subjected to ncvisual transformations. If possible, it's usually better
// to create the ncvisual from memory using ncvisual_from_rgba().
API struct ncvisual* ncvisual_from_plane(struct ncplane* n);
#undef API #undef API
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -285,7 +285,9 @@ typedef enum {
NCSCALE_SCALE, NCSCALE_SCALE,
NCSCALE_STRETCH, NCSCALE_STRETCH,
} ncscale_e; } ncscale_e;
struct ncvisual* ncvisual_open_plane(struct notcurses* nc, const char* file, nc_err_e* err, int y, int x, ncscale_e style); struct ncvisual* ncvisual_from_file(struct notcurses* nc, const char* file, nc_err_e* err, int y, int x, ncscale_e style);
struct ncvisual* ncvisual_from_rgba(struct notcurses* nc, const void* rgba, int rows, int rowstride, int cols);
struct ncvisual* ncvisual_from_bgra(struct notcurses* nc, const void* bgra, int rows, int rowstride, int cols);
struct ncplane* ncvisual_plane(struct ncvisual* ncv); struct ncplane* ncvisual_plane(struct ncvisual* ncv);
void ncvisual_destroy(struct ncvisual* ncv); void ncvisual_destroy(struct ncvisual* ncv);
nc_err_e ncvisual_decode(struct ncvisual* nc); nc_err_e ncvisual_decode(struct ncvisual* nc);

View File

@ -20,7 +20,7 @@ chunli_draw(struct notcurses* nc, const char* ext, int count, const cell* b){
notcurses_refresh(nc, &dimy, &dimx); notcurses_refresh(nc, &dimy, &dimx);
snprintf(file, sizeof(file), "chunli%d.%s", i + 1, ext); snprintf(file, sizeof(file), "chunli%d.%s", i + 1, ext);
chuns[i].path = find_data(file); chuns[i].path = find_data(file);
chuns[i].ncv = ncvisual_open_plane(nc, chuns[i].path, &err, 0, 0, NCSCALE_NONE); chuns[i].ncv = ncvisual_from_file(nc, chuns[i].path, &err, 0, 0, NCSCALE_NONE);
if(chuns[i].ncv == NULL){ if(chuns[i].ncv == NULL){
return -1; return -1;
} }
@ -66,7 +66,7 @@ int chunli_demo(struct notcurses* nc){
snprintf(file, sizeof(file), "chunli%02d.png", i); snprintf(file, sizeof(file), "chunli%02d.png", i);
char* path = find_data(file); char* path = find_data(file);
nc_err_e err; nc_err_e err;
struct ncvisual* ncv = ncvisual_open_plane(nc, path, &err, 0, 0, NCSCALE_NONE); struct ncvisual* ncv = ncvisual_from_file(nc, path, &err, 0, 0, NCSCALE_NONE);
if(ncv == NULL){ if(ncv == NULL){
free(path); free(path);
break; break;

View File

@ -27,7 +27,7 @@ const char eagle1[] =
static int static int
outzoomed_map(struct notcurses* nc, const char* map){ outzoomed_map(struct notcurses* nc, const char* map){
nc_err_e ncerr; nc_err_e ncerr;
struct ncvisual* ncv = ncvisual_open_plane(nc, map, &ncerr, 0, 0, NCSCALE_SCALE); struct ncvisual* ncv = ncvisual_from_file(nc, map, &ncerr, 0, 0, NCSCALE_SCALE);
if(ncv == NULL){ if(ncv == NULL){
return -1; return -1;
} }
@ -50,7 +50,7 @@ zoom_map(struct notcurses* nc, const char* map){
// and begin opening it on larger and larger planes that fit on the screen // and begin opening it on larger and larger planes that fit on the screen
// less and less. eventually, reach our natural NCSCALE_NONE size and begin // less and less. eventually, reach our natural NCSCALE_NONE size and begin
// scrolling through the map, whooooooooosh. // scrolling through the map, whooooooooosh.
struct ncvisual* ncv = ncvisual_open_plane(nc, map, &ncerr, 0, 0, NCSCALE_NONE); struct ncvisual* ncv = ncvisual_from_file(nc, map, &ncerr, 0, 0, NCSCALE_NONE);
if(ncv == NULL){ if(ncv == NULL){
return NULL; return NULL;
} }

View File

@ -187,7 +187,7 @@ int luigi_demo(struct notcurses* nc){
if(fname == NULL){ if(fname == NULL){
return -1; return -1;
} }
wmncv = ncvisual_open_plane(nc, fname, &ncerr, 0, 0, NCSCALE_NONE); wmncv = ncvisual_from_file(nc, fname, &ncerr, 0, 0, NCSCALE_NONE);
free(fname); free(fname);
if(wmncv == NULL){ if(wmncv == NULL){
return -1; return -1;

View File

@ -39,9 +39,11 @@ const char* oiio_version(void);
#include "notcurses/notcurses.h" #include "notcurses/notcurses.h"
#include "egcpool.h" #include "egcpool.h"
struct SwsContext;
struct esctrie; struct esctrie;
// we can't define multipart ncvisual here, because OIIO requires C++ syntax,
// and we can't go throwing C++ syntax into this header. so it goes.
// A plane is memory for some rectilinear virtual window, plus current cursor // A plane is memory for some rectilinear virtual window, plus current cursor
// state for that window. A notcurses context describes a single terminal, and // state for that window. A notcurses context describes a single terminal, and
// has a z-order of planes (I see no advantage to maintaining a poset, and we // has a z-order of planes (I see no advantage to maintaining a poset, and we
@ -634,6 +636,8 @@ enforce_utf8(void){
return true; return true;
} }
struct ncvisual* ncvisual_create(float timescale);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -10,16 +10,6 @@ struct AVCodecParameters;
struct AVPacket; struct AVPacket;
typedef struct ncvisual { typedef struct ncvisual {
struct AVFormatContext* fmtctx;
struct AVCodecContext* codecctx; // video codec context
struct AVCodecContext* subtcodecctx; // subtitle codec context
struct AVFrame* frame;
struct AVFrame* oframe;
struct AVCodec* codec;
struct AVCodecParameters* cparams;
struct AVCodec* subtcodec;
struct AVPacket* packet;
struct SwsContext* swsctx;
int packet_outstanding; int packet_outstanding;
int dstwidth, dstheight; int dstwidth, dstheight;
int stream_index; // match against this following av_read_frame() int stream_index; // match against this following av_read_frame()
@ -33,6 +23,16 @@ typedef struct ncvisual {
ncscale_e style; // none, scale, or stretch ncscale_e style; // none, scale, or stretch
struct notcurses* ncobj; // set iff this ncvisual "owns" its ncplane struct notcurses* ncobj; // set iff this ncvisual "owns" its ncplane
#ifdef USE_FFMPEG #ifdef USE_FFMPEG
struct AVFormatContext* fmtctx;
struct AVCodecContext* codecctx; // video codec context
struct AVCodecContext* subtcodecctx; // subtitle codec context
struct AVFrame* frame;
struct AVFrame* oframe;
struct AVCodec* codec;
struct AVCodecParameters* cparams;
struct AVCodec* subtcodec;
struct AVPacket* packet;
struct SwsContext* swsctx;
AVSubtitle subtitle; AVSubtitle subtitle;
#endif #endif
} ncvisual; } ncvisual;
@ -42,6 +42,16 @@ ncplane* ncvisual_plane(ncvisual* ncv){
return ncv->ncp; return ncv->ncp;
} }
ncvisual* ncvisual_create(float timescale){
ncvisual* ret = malloc(sizeof(*ret));
if(ret == NULL){
return NULL;
}
memset(ret, 0, sizeof(*ret));
ret->timescale = timescale;
return ret;
}
void ncvisual_destroy(ncvisual* ncv){ void ncvisual_destroy(ncvisual* ncv){
if(ncv){ if(ncv){
avcodec_close(ncv->codecctx); avcodec_close(ncv->codecctx);
@ -64,17 +74,6 @@ bool notcurses_canopen(const notcurses* nc __attribute__ ((unused))){
return true; return true;
} }
static ncvisual*
ncvisual_create(float timescale){
ncvisual* ret = malloc(sizeof(*ret));
if(ret == NULL){
return NULL;
}
memset(ret, 0, sizeof(*ret));
ret->timescale = timescale;
return ret;
}
/* static void /* static void
print_frame_summary(const AVCodecContext* cctx, const AVFrame* f){ print_frame_summary(const AVCodecContext* cctx, const AVFrame* f){
char pfmt[128]; char pfmt[128];
@ -386,7 +385,7 @@ ncvisual* ncplane_visual_open(ncplane* nc, const char* filename, nc_err_e* ncerr
return ncv; return ncv;
} }
ncvisual* ncvisual_open_plane(notcurses* nc, const char* filename, ncvisual* ncvisual_from_file(notcurses* nc, const char* filename,
nc_err_e* ncerr, int y, int x, ncscale_e style){ nc_err_e* ncerr, int y, int x, ncscale_e style){
ncvisual* ncv = ncvisual_open(filename, ncerr); ncvisual* ncv = ncvisual_open(filename, ncerr);
if(ncv == NULL){ if(ncv == NULL){
@ -509,6 +508,12 @@ int ncvisual_init(int loglevel){
// FIXME could also use av_log_set_callback() and capture the message... // FIXME could also use av_log_set_callback() and capture the message...
return 0; return 0;
} }
ncvisual* ncvisual_from_rgba(notcurses* nc, const void* rgba, int rows, int rowstride, int cols){
}
ncvisual* ncvisual_from_bgra(notcurses* nc, const void* bgra, int rows, int rowstride, int cols){
}
#else // built without ffmpeg #else // built without ffmpeg
#ifndef USE_OIIO // built without ffmpeg or oiio #ifndef USE_OIIO // built without ffmpeg or oiio
bool notcurses_canopen(const notcurses* nc __attribute__ ((unused))){ bool notcurses_canopen(const notcurses* nc __attribute__ ((unused))){
@ -551,7 +556,7 @@ ncvisual* ncplane_visual_open(ncplane* nc, const char* filename, nc_err_e* ncerr
return NULL; return NULL;
} }
ncvisual* ncvisual_open_plane(notcurses* nc, const char* filename, ncvisual* ncvisual_from_file(notcurses* nc, const char* filename,
nc_err_e* ncerr, int y, int x, ncscale_e style){ nc_err_e* ncerr, int y, int x, ncscale_e style){
(void)nc; (void)nc;
(void)filename; (void)filename;
@ -577,5 +582,22 @@ void ncvisual_destroy(ncvisual* ncv){
(void)ncv; (void)ncv;
} }
ncvisual* ncvisual_from_rgba(notcurses* nc, const void* rgba, int rows, int rowstride, int cols){
(void)nc;
(void)rgba;
(void)rows;
(void)rowstride;
(void)cols;
return NULL;
}
ncvisual* ncvisual_from_bgra(notcurses* nc, const void* bgra, int rows, int rowstride, int cols){
(void)nc;
(void)bgra;
(void)rows;
(void)rowstride;
(void)cols;
return NULL;
}
#endif #endif
#endif #endif

View File

@ -35,8 +35,7 @@ bool notcurses_canopen(const notcurses* nc __attribute__ ((unused))){
return true; return true;
} }
static ncvisual* ncvisual* ncvisual_create(float timescale){
ncvisual_create(const char* filename, float timescale){
auto ret = new ncvisual; auto ret = new ncvisual;
if(ret == nullptr){ if(ret == nullptr){
return nullptr; return nullptr;
@ -52,7 +51,7 @@ ncvisual_create(const char* filename, float timescale){
ret->ncobj = nullptr; ret->ncobj = nullptr;
ret->frame = nullptr; ret->frame = nullptr;
ret->raw = nullptr; ret->raw = nullptr;
ret->filename = strdup(filename); ret->filename = nullptr;
return ret; return ret;
} }
@ -63,10 +62,16 @@ ncvisual_open(const char* filename, nc_err_e* err){
*err = NCERR_NOMEM; *err = NCERR_NOMEM;
return nullptr; return nullptr;
} }
if((ncv->filename = strdup(filename)) == nullptr){
*err = NCERR_NOMEM;
delete ncv;
return nullptr;
}
ncv->image = OIIO::ImageInput::open(filename); ncv->image = OIIO::ImageInput::open(filename);
if(!ncv->image){ if(!ncv->image){
// fprintf(stderr, "Couldn't create %s (%s)\n", filename, strerror(errno)); // fprintf(stderr, "Couldn't create %s (%s)\n", filename, strerror(errno));
*err = NCERR_DECODE; *err = NCERR_DECODE;
ncvisual_destroy(ncv);
return nullptr; return nullptr;
} }
/*const auto &spec = ncv->image->spec_dimensions(); /*const auto &spec = ncv->image->spec_dimensions();
@ -89,8 +94,8 @@ ncvisual* ncplane_visual_open(ncplane* nc, const char* filename, nc_err_e* ncerr
return ncv; return ncv;
} }
ncvisual* ncvisual_open_plane(notcurses* nc, const char* filename, ncvisual* ncvisual_from_file(notcurses* nc, const char* filename, nc_err_e* ncerr,
nc_err_e* ncerr, int y, int x, ncscale_e style){ int y, int x, ncscale_e style){
ncvisual* ncv = ncvisual_open(filename, ncerr); ncvisual* ncv = ncvisual_open(filename, ncerr);
if(ncv == nullptr){ if(ncv == nullptr){
return nullptr; return nullptr;
@ -291,7 +296,9 @@ int ncvisual_init(int loglevel){
void ncvisual_destroy(ncvisual* ncv){ void ncvisual_destroy(ncvisual* ncv){
if(ncv){ if(ncv){
ncv->image->close(); if(ncv->image){
ncv->image->close();
}
if(ncv->ncobj){ if(ncv->ncobj){
ncplane_destroy(ncv->ncp); ncplane_destroy(ncv->ncp);
} }
@ -305,4 +312,9 @@ const char* oiio_version(void){
return OIIO_VERSION_STRING; return OIIO_VERSION_STRING;
} }
ncvisual* ncvisual_open_rgba(notcurses* nc, const void* rgba, int rows, int rowstride, int cols){
}
ncvisual* ncvisual_open_bgra(notcurses* nc, const void* bgra, int rows, int rowstride, int cols){
}
#endif #endif

View File

@ -1,5 +1,10 @@
#include "internal.h" #include "internal.h"
// ncvisual functionality independent of the underlying engine
ncvisual* ncvisual_from_plane(ncplane* n){ ncvisual* ncvisual_from_plane(ncplane* n){
return NULL; // FIXME int dimy, dimx;
ncplane_dim_yx(n, &dimy, &dimx);
ncvisual* ncv = ncvisual_create(1);
return ncv;
} }

View File

@ -1,26 +1,26 @@
#include "main.h" #include "main.h"
void RotateCW(struct notcurses* nc, struct ncplane* n) { void RotateCW(struct notcurses* nc, struct ncvisual* n) {
CHECK(0 == notcurses_render(nc)); CHECK(0 == notcurses_render(nc));
CHECK(0 == ncplane_rotate_cw(n)); CHECK(0 == ncvisual_rotate_cw(n));
CHECK(0 == notcurses_render(nc)); CHECK(0 == notcurses_render(nc));
CHECK(0 == ncplane_rotate_cw(n)); CHECK(0 == ncvisual_rotate_cw(n));
CHECK(0 == notcurses_render(nc)); CHECK(0 == notcurses_render(nc));
CHECK(0 == ncplane_rotate_cw(n)); CHECK(0 == ncvisual_rotate_cw(n));
CHECK(0 == notcurses_render(nc)); CHECK(0 == notcurses_render(nc));
CHECK(0 == ncplane_rotate_cw(n)); CHECK(0 == ncvisual_rotate_cw(n));
CHECK(0 == notcurses_render(nc)); CHECK(0 == notcurses_render(nc));
} }
void RotateCCW(struct notcurses* nc, struct ncplane* n) { void RotateCCW(struct notcurses* nc, struct ncvisual* n) {
CHECK(0 == notcurses_render(nc)); CHECK(0 == notcurses_render(nc));
CHECK(0 == ncplane_rotate_ccw(n)); CHECK(0 == ncvisual_rotate_ccw(n));
CHECK(0 == notcurses_render(nc)); CHECK(0 == notcurses_render(nc));
CHECK(0 == ncplane_rotate_ccw(n)); CHECK(0 == ncvisual_rotate_ccw(n));
CHECK(0 == notcurses_render(nc)); CHECK(0 == notcurses_render(nc));
CHECK(0 == ncplane_rotate_ccw(n)); CHECK(0 == ncvisual_rotate_ccw(n));
CHECK(0 == notcurses_render(nc)); CHECK(0 == notcurses_render(nc));
CHECK(0 == ncplane_rotate_ccw(n)); CHECK(0 == ncvisual_rotate_ccw(n));
CHECK(0 == notcurses_render(nc)); CHECK(0 == notcurses_render(nc));
} }

View File

@ -27,7 +27,7 @@ TEST_CASE("Multimedia") {
nc_err_e ncerr = NCERR_SUCCESS; nc_err_e ncerr = NCERR_SUCCESS;
int dimy, dimx; int dimy, dimx;
ncplane_dim_yx(ncp_, &dimy, &dimx); ncplane_dim_yx(ncp_, &dimy, &dimx);
auto ncv = ncvisual_open_plane(nc_, find_data("changes.jpg"), &ncerr, 0, 0, NCSCALE_STRETCH); auto ncv = ncvisual_from_file(nc_, find_data("changes.jpg"), &ncerr, 0, 0, NCSCALE_STRETCH);
REQUIRE(ncv); REQUIRE(ncv);
REQUIRE(NCERR_SUCCESS == ncerr); REQUIRE(NCERR_SUCCESS == ncerr);
ncerr = ncvisual_decode(ncv); ncerr = ncvisual_decode(ncv);
@ -110,7 +110,7 @@ TEST_CASE("Multimedia") {
nc_err_e ncerr = NCERR_SUCCESS; nc_err_e ncerr = NCERR_SUCCESS;
int dimy, dimx; int dimy, dimx;
ncplane_dim_yx(ncp_, &dimy, &dimx); ncplane_dim_yx(ncp_, &dimy, &dimx);
auto ncv = ncvisual_open_plane(nc_, find_data("notcursesI.avi"), &ncerr, 0, 0, NCSCALE_STRETCH); auto ncv = ncvisual_from_file(nc_, find_data("notcursesI.avi"), &ncerr, 0, 0, NCSCALE_STRETCH);
REQUIRE(ncv); REQUIRE(ncv);
CHECK(NCERR_SUCCESS == ncerr); CHECK(NCERR_SUCCESS == ncerr);
ncerr = ncvisual_decode(ncv); ncerr = ncvisual_decode(ncv);