From cde75505ea90066e92f5a4b7a3078c82b956e42e Mon Sep 17 00:00:00 2001 From: Nick Black Date: Mon, 8 Mar 2021 03:30:17 -0500 Subject: [PATCH] Work around OpenImageIO bswap definition #1392 Recent OpenImageIO (on Fedora Rawhide, at least) export a bswap symbol, causing us no end of pain. Perform a massive rearrangement to deal with this annoyance, splitting oiio.c into C++ and C contents. Closes #1392. --- src/lib/internal.h | 16 +++--- src/lib/visual-details.h | 21 ++++++-- src/media/oiio-indep.c | 107 +++++++++++++++++++++++++++++++++++++++ src/media/oiio.cpp | 104 +++---------------------------------- src/media/oiio.h | 29 +++++++++++ 5 files changed, 167 insertions(+), 110 deletions(-) create mode 100644 src/media/oiio-indep.c create mode 100644 src/media/oiio.h diff --git a/src/lib/internal.h b/src/lib/internal.h index 46e90e184..1a18c54b2 100644 --- a/src/lib/internal.h +++ b/src/lib/internal.h @@ -739,14 +739,6 @@ rgba_blitter(const struct notcurses* nc, const struct ncvisual_options* opts) { return rgba_blitter_low(&nc->tcache, scale, maydegrade, opts ? opts->blitter : NCBLIT_DEFAULT); } -static inline int -rgba_blit_dispatch(ncplane* nc, const struct blitset* bset, int placey, - int placex, int linesize, const void* data, int begy, - int begx, int leny, int lenx, bool blendcolors){ - return bset->blit(nc, placey, placex, linesize, data, begy, begx, - leny, lenx, blendcolors); -} - // 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 // cell to the bottom/right of the center. @@ -1225,6 +1217,14 @@ int sixel_blit(ncplane* nc, int placey, int placex, int linesize, int term_fg_rgb8(bool RGBflag, const char* setaf, int colors, FILE* out, unsigned r, unsigned g, unsigned b); +static inline int +rgba_blit_dispatch(ncplane* nc, const struct blitset* bset, int placey, + int placex, int linesize, const void* data, int begy, + int begx, int leny, int lenx, bool blendcolors){ + return bset->blit(nc, placey, placex, linesize, data, begy, begx, + leny, lenx, blendcolors); +} + typedef struct ncvisual_implementation { int (*visual_init)(int loglevel); void (*visual_printbanner)(const struct notcurses* nc); diff --git a/src/lib/visual-details.h b/src/lib/visual-details.h index 99c0fff36..3db24a87d 100644 --- a/src/lib/visual-details.h +++ b/src/lib/visual-details.h @@ -1,9 +1,16 @@ #ifndef NOTCURSES_VISUAL_DETAILS #define NOTCURSES_VISUAL_DETAILS +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include #include "builddef.h" -#include "notcurses/notcurses.h" +struct blitset; struct ncplane; struct ncvisual_details; @@ -16,8 +23,8 @@ typedef struct ncvisual { bool owndata; // we own data iff owndata == true } ncvisual; -static inline auto -ncvisual_set_data(ncvisual* ncv, uint32_t* data, bool owned) -> void { +static inline void +ncvisual_set_data(ncvisual* ncv, uint32_t* data, bool owned){ if(ncv->owndata){ free(ncv->data); } @@ -26,7 +33,7 @@ ncvisual_set_data(ncvisual* ncv, uint32_t* data, bool owned) -> void { } static inline void -scale_visual(const ncvisual* ncv, int* disprows, int* dispcols) { +scale_visual(const ncvisual* ncv, int* disprows, int* dispcols){ float xratio = (float)(*dispcols) / ncv->cols; if(xratio * ncv->rows > *disprows){ xratio = (float)(*disprows) / ncv->rows; @@ -35,4 +42,10 @@ scale_visual(const ncvisual* ncv, int* disprows, int* dispcols) { *dispcols = xratio * (ncv->cols); } +void ncvisual_destroy(struct ncvisual* ncv); + +#ifdef __cplusplus +} +#endif + #endif diff --git a/src/media/oiio-indep.c b/src/media/oiio-indep.c new file mode 100644 index 000000000..502335122 --- /dev/null +++ b/src/media/oiio-indep.c @@ -0,0 +1,107 @@ +#include "builddef.h" +#ifdef USE_OIIO +#include "visual-details.h" +#include "internal.h" +#include "oiio.h" + +int oiio_blit_dispatch(struct ncplane* nc, const struct blitset* bset, + int placey, int placex, int linesize, + const void* data, int begy, int begx, + int leny, int lenx, bool blendcolors){ + if(rgba_blit_dispatch(nc, bset, placey, placex, linesize, data, begy, begx, + leny, lenx, blendcolors) < 0){ + return -1; + } + return 0; +} + +int oiio_stream(struct notcurses* nc, ncvisual* ncv, float timescale, + streamcb streamer, const struct ncvisual_options* vopts, + void* curry){ + (void)timescale; // FIXME + int frame = 1; + struct timespec begin; // time we started + clock_gettime(CLOCK_MONOTONIC, &begin); + ncplane* newn = NULL; + struct ncvisual_options activevopts; + memcpy(&activevopts, vopts, sizeof(*vopts)); + int ncerr; + do{ + // decay the blitter explicitly, so that the callback knows the blitter it + // was actually rendered with + const struct blitset* bset = rgba_blitter(nc, &activevopts); + if(bset){ + activevopts.blitter = bset->geom; + } + if((newn = ncvisual_render(nc, ncv, &activevopts)) == NULL){ + if(activevopts.n != vopts->n){ + ncplane_destroy(activevopts.n); + } + return -1; + } + if(activevopts.n != newn){ + activevopts.n = newn; + } + // currently OIIO is so slow for videos that there's no real point in + // any kind of delay FIXME + struct timespec now; + clock_gettime(CLOCK_MONOTONIC, &now); + int r; + if(streamer){ + r = streamer(ncv, &activevopts, &now, curry); + }else{ + r = ncvisual_simple_streamer(ncv, &activevopts, &now, curry); + } + if(r){ + if(activevopts.n != vopts->n){ + ncplane_destroy(activevopts.n); + } + return r; + } + ++frame; + }while((ncerr = oiio_decode(ncv)) == 0); + if(activevopts.n != vopts->n){ + ncplane_destroy(activevopts.n); + } + if(ncerr == 1){ + return 0; + } + return -1; +} + +char* oiio_subtitle(const ncvisual* ncv) { // no support in OIIO + (void)ncv; + return NULL; +} + +void oiio_details_seed(ncvisual* ncv) { + (void)ncv; + // FIXME? +} + +int oiio_init(int loglevel __attribute__ ((unused))) { + // FIXME set OIIO global attribute "debug" based on loglevel + // FIXME check OIIO_VERSION_STRING components against linked openimageio_version() + return 0; // allow success here +} + +static const ncvisual_implementation oiio_impl = { + .visual_init = oiio_init, + .visual_printbanner = oiio_printbanner, + .visual_blit = oiio_blit, + .visual_create = oiio_create, + .visual_from_file = oiio_from_file, + .visual_details_seed = oiio_details_seed, + .visual_details_destroy = oiio_details_destroy, + .visual_decode = oiio_decode, + .visual_decode_loop = oiio_decode_loop, + .visual_stream = oiio_stream, + .visual_subtitle = oiio_subtitle, + .visual_resize = oiio_resize, + .canopen_images = true, + .canopen_videos = false, +}; + +const ncvisual_implementation* local_visual_implementation = &oiio_impl; + +#endif diff --git a/src/media/oiio.cpp b/src/media/oiio.cpp index 0182cc0e4..70e6c20b1 100644 --- a/src/media/oiio.cpp +++ b/src/media/oiio.cpp @@ -5,8 +5,8 @@ #include #include #include -#include "internal.h" #include "visual-details.h" +#include "oiio.h" typedef struct ncvisual_details { std::unique_ptr image; // must be close()d @@ -15,8 +15,7 @@ typedef struct ncvisual_details { uint64_t framenum; } ncvisual_details; -static inline auto -oiio_details_init(void) -> ncvisual_details* { +auto oiio_details_init(void) -> ncvisual_details* { auto deets = new ncvisual_details{}; if(deets){ deets->image = nullptr; @@ -27,8 +26,7 @@ oiio_details_init(void) -> ncvisual_details* { return deets; } -static inline auto -oiio_details_destroy(ncvisual_details* deets) -> void { +auto oiio_details_destroy(ncvisual_details* deets) -> void { if(deets->image){ deets->image->close(); } @@ -173,71 +171,11 @@ int oiio_blit(struct ncvisual* ncv, int rows, int cols, data = ncv->data; stride = ncv->rowstride; } - if(rgba_blit_dispatch(n, bset, placey, placex, stride, data, begy, begx, - leny, lenx, blendcolors) < 0){ - return -1; - } + return oiio_blit_dispatch(n, bset, placey, placex, stride, data, + begy, begx, leny, lenx, blendcolors); return 0; } -auto oiio_stream(notcurses* nc, ncvisual* ncv, float timescale, - streamcb streamer, const struct ncvisual_options* vopts, void* curry) -> int { - (void)timescale; // FIXME - int frame = 1; - struct timespec begin; // time we started - clock_gettime(CLOCK_MONOTONIC, &begin); - ncplane* newn = nullptr; - ncvisual_options activevopts; - memcpy(&activevopts, vopts, sizeof(*vopts)); - int ncerr; - do{ - // decay the blitter explicitly, so that the callback knows the blitter it - // was actually rendered with - auto bset = rgba_blitter(nc, &activevopts); - if(bset){ - activevopts.blitter = bset->geom; - } - if((newn = ncvisual_render(nc, ncv, &activevopts)) == NULL){ - if(activevopts.n != vopts->n){ - ncplane_destroy(activevopts.n); - } - return -1; - } - if(activevopts.n != newn){ - activevopts.n = newn; - } - // currently OIIO is so slow for videos that there's no real point in - // any kind of delay FIXME - struct timespec now; - clock_gettime(CLOCK_MONOTONIC, &now); - int r; - if(streamer){ - r = streamer(ncv, &activevopts, &now, curry); - }else{ - r = ncvisual_simple_streamer(ncv, &activevopts, &now, curry); - } - if(r){ - if(activevopts.n != vopts->n){ - ncplane_destroy(activevopts.n); - } - return r; - } - ++frame; - }while((ncerr = oiio_decode(ncv)) == 0); - if(activevopts.n != vopts->n){ - ncplane_destroy(activevopts.n); - } - if(ncerr == 1){ - return 0; - } - return -1; -} - -char* oiio_subtitle(const ncvisual* ncv) { // no support in OIIO - (void)ncv; - return nullptr; -} - // FIXME before we can enable this, we need build an OIIO::APPBUFFER-style // ImageBuf in ncvisual in ncvisual_from_rgba(). /* @@ -258,39 +196,9 @@ auto ncvisual_rotate(ncvisual* ncv, double rads) -> int { } */ -auto oiio_details_seed(ncvisual* ncv) -> void { - (void)ncv; - // FIXME? -} - -int oiio_init(int loglevel __attribute__ ((unused))) { - // FIXME set OIIO global attribute "debug" based on loglevel - // FIXME check OIIO_VERSION_STRING components against linked openimageio_version() - return 0; // allow success here -} - // FIXME would be nice to have OIIO::attributes("libraries") in here -void oiio_printbanner(const notcurses* nc __attribute__ ((unused))){ +void oiio_printbanner(const struct notcurses* nc __attribute__ ((unused))){ printf(" openimageio %s\n", OIIO_VERSION_STRING); } -const static ncvisual_implementation oiio_impl = { - .visual_init = oiio_init, - .visual_printbanner = oiio_printbanner, - .visual_blit = oiio_blit, - .visual_create = oiio_create, - .visual_from_file = oiio_from_file, - .visual_details_seed = oiio_details_seed, - .visual_details_destroy = oiio_details_destroy, - .visual_decode = oiio_decode, - .visual_decode_loop = oiio_decode_loop, - .visual_stream = oiio_stream, - .visual_subtitle = oiio_subtitle, - .visual_resize = oiio_resize, - .canopen_images = true, - .canopen_videos = false, -}; - -const ncvisual_implementation* local_visual_implementation = &oiio_impl; - #endif diff --git a/src/media/oiio.h b/src/media/oiio.h new file mode 100644 index 000000000..6dd6de38a --- /dev/null +++ b/src/media/oiio.h @@ -0,0 +1,29 @@ +#ifndef MEDIA_OIIO +#define MEDIA_OIIO + +#ifdef __cplusplus +extern "C" { +#endif + +int oiio_decode(struct ncvisual* nc); +struct ncvisual_details* oiio_details_init(void); +void oiio_printbanner(const struct notcurses* nc); +int oiio_blit(struct ncvisual* ncv, int rows, int cols, + struct ncplane* n, const struct blitset* bset, + int placey, int placex, int begy, int begx, + int leny, int lenx, bool blendcolors); +ncvisual* oiio_from_file(const char* filename); +void oiio_details_destroy(struct ncvisual_details* deets); +int oiio_decode_loop(ncvisual* ncv); +int oiio_resize(ncvisual* nc, int rows, int cols); +struct ncvisual* oiio_create(void); +int oiio_blit_dispatch(struct ncplane* nc, const struct blitset* bset, + int placey, int placex, int linesize, + const void* data, int begy, int begx, + int leny, int lenx, bool blendcolors); + +#ifdef __cplusplus +} +#endif + +#endif