image-source: Support JXR on Windows

master
jpark37 2022-05-08 03:59:21 -07:00
parent 4af20cf080
commit 23f3b1da9f
1 changed files with 41 additions and 23 deletions

View File

@ -24,7 +24,7 @@ struct image_source {
bool active;
bool restart_gif;
gs_image_file3_t if3;
gs_image_file4_t if4;
};
static time_t get_modified_timestamp(const char *filename)
@ -46,23 +46,23 @@ static void image_source_load(struct image_source *context)
char *file = context->file;
obs_enter_graphics();
gs_image_file3_free(&context->if3);
gs_image_file4_free(&context->if4);
obs_leave_graphics();
if (file && *file) {
debug("loading texture '%s'", file);
context->file_timestamp = get_modified_timestamp(file);
gs_image_file3_init(&context->if3, file,
gs_image_file4_init(&context->if4, file,
context->linear_alpha
? GS_IMAGE_ALPHA_PREMULTIPLY_SRGB
: GS_IMAGE_ALPHA_PREMULTIPLY);
context->update_time_elapsed = 0;
obs_enter_graphics();
gs_image_file3_init_texture(&context->if3);
gs_image_file4_init_texture(&context->if4);
obs_leave_graphics();
if (!context->if3.image2.image.loaded)
if (!context->if4.image3.image2.image.loaded)
warn("failed to load texture '%s'", file);
}
}
@ -70,7 +70,7 @@ static void image_source_load(struct image_source *context)
static void image_source_unload(struct image_source *context)
{
obs_enter_graphics();
gs_image_file3_free(&context->if3);
gs_image_file4_free(&context->if4);
obs_leave_graphics();
}
@ -120,13 +120,13 @@ static void restart_gif(void *data)
{
struct image_source *context = data;
if (context->if3.image2.image.is_animated_gif) {
context->if3.image2.image.cur_frame = 0;
context->if3.image2.image.cur_loop = 0;
context->if3.image2.image.cur_time = 0;
if (context->if4.image3.image2.image.is_animated_gif) {
context->if4.image3.image2.image.cur_frame = 0;
context->if4.image3.image2.image.cur_loop = 0;
context->if4.image3.image2.image.cur_time = 0;
obs_enter_graphics();
gs_image_file3_update_texture(&context->if3);
gs_image_file4_update_texture(&context->if4);
obs_leave_graphics();
context->restart_gif = false;
@ -162,20 +162,22 @@ static void image_source_destroy(void *data)
static uint32_t image_source_getwidth(void *data)
{
struct image_source *context = data;
return context->if3.image2.image.cx;
return context->if4.image3.image2.image.cx;
}
static uint32_t image_source_getheight(void *data)
{
struct image_source *context = data;
return context->if3.image2.image.cy;
return context->if4.image3.image2.image.cy;
}
static void image_source_render(void *data, gs_effect_t *effect)
{
struct image_source *context = data;
if (!context->if3.image2.image.texture)
struct gs_image_file *const image = &context->if4.image3.image2.image;
gs_texture_t *const texture = image->texture;
if (!texture)
return;
const bool previous = gs_framebuffer_srgb_enabled();
@ -185,11 +187,9 @@ static void image_source_render(void *data, gs_effect_t *effect)
gs_blend_function(GS_BLEND_ONE, GS_BLEND_INVSRCALPHA);
gs_eparam_t *const param = gs_effect_get_param_by_name(effect, "image");
gs_effect_set_texture_srgb(param, context->if3.image2.image.texture);
gs_effect_set_texture_srgb(param, texture);
gs_draw_sprite(context->if3.image2.image.texture, 0,
context->if3.image2.image.cx,
context->if3.image2.image.cy);
gs_draw_sprite(texture, 0, image->cx, image->cy);
gs_blend_state_pop();
@ -216,7 +216,7 @@ static void image_source_tick(void *data, float seconds)
if (obs_source_showing(context->source)) {
if (!context->active) {
if (context->if3.image2.image.is_animated_gif)
if (context->if4.image3.image2.image.is_animated_gif)
context->last_time = frame_time;
context->active = true;
}
@ -233,13 +233,14 @@ static void image_source_tick(void *data, float seconds)
return;
}
if (context->last_time && context->if3.image2.image.is_animated_gif) {
if (context->last_time &&
context->if4.image3.image2.image.is_animated_gif) {
uint64_t elapsed = frame_time - context->last_time;
bool updated = gs_image_file3_tick(&context->if3, elapsed);
bool updated = gs_image_file4_tick(&context->if4, elapsed);
if (updated) {
obs_enter_graphics();
gs_image_file3_update_texture(&context->if3);
gs_image_file4_update_texture(&context->if4);
obs_leave_graphics();
}
}
@ -248,11 +249,18 @@ static void image_source_tick(void *data, float seconds)
}
static const char *image_filter =
#ifdef _WIN32
"All formats (*.bmp *.tga *.png *.jpeg *.jpg *.jxr *.gif *.psd *.webp);;"
#else
"All formats (*.bmp *.tga *.png *.jpeg *.jpg *.gif *.psd *.webp);;"
#endif
"BMP Files (*.bmp);;"
"Targa Files (*.tga);;"
"PNG Files (*.png);;"
"JPEG Files (*.jpeg *.jpg);;"
#ifdef _WIN32
"JXR Files (*.jxr);;"
#endif
"GIF Files (*.gif);;"
"PSD Files (*.psd);;"
"WebP Files (*.webp);;"
@ -289,7 +297,7 @@ static obs_properties_t *image_source_properties(void *data)
uint64_t image_source_get_memory_usage(void *data)
{
struct image_source *s = data;
return s->if3.image2.mem_usage;
return s->if4.image3.image2.mem_usage;
}
static void missing_file_callback(void *src, const char *new_path, void *data)
@ -323,6 +331,15 @@ static obs_missing_files_t *image_source_missingfiles(void *data)
return files;
}
static enum gs_color_space
image_source_get_color_space(void *data, size_t count,
const enum gs_color_space *preferred_spaces)
{
struct image_source *const s = data;
gs_image_file4_t *const if4 = &s->if4;
return if4->image3.image2.image.texture ? if4->space : GS_CS_SRGB;
}
static struct obs_source_info image_source_info = {
.id = "image_source",
.type = OBS_SOURCE_TYPE_INPUT,
@ -342,6 +359,7 @@ static struct obs_source_info image_source_info = {
.get_properties = image_source_properties,
.icon_type = OBS_ICON_TYPE_IMAGE,
.activate = image_source_activate,
.video_get_color_space = image_source_get_color_space,
};
OBS_DECLARE_MODULE()