Пример #1
0
void gs_image_file_init(gs_image_file_t *image, const char *file)
{
	size_t len;

	if (!image)
		return;

	memset(image, 0, sizeof(*image));

	if (!file)
		return;

	len = strlen(file);

	if (len > 4 && strcmp(file + len - 4, ".gif") == 0) {
		if (init_animated_gif(image, file))
			return;
	}

	image->texture_data = gs_create_texture_file_data(file,
			&image->format, &image->cx, &image->cy);

	image->loaded = !!image->texture_data;
	if (!image->loaded) {
		blog(LOG_WARNING, "Failed to load file '%s'", file);
		gs_image_file_free(image);
	}
}
Пример #2
0
static void color_grade_filter_update(void *data, obs_data_t *settings)
{
	struct lut_filter_data *filter = data;

	const char *path = obs_data_get_string(settings, SETTING_IMAGE_PATH);
	double clut_amount = obs_data_get_double(settings, SETTING_CLUT_AMOUNT);

	bfree(filter->file);
	if (path)
		filter->file = bstrdup(path);

	obs_enter_graphics();
	gs_image_file_free(&filter->image);
	obs_leave_graphics();

	gs_image_file_init(&filter->image, path);

	obs_enter_graphics();

	gs_image_file_init_texture(&filter->image);

	filter->target = filter->image.texture;
	filter->clut_amount = (float)clut_amount;

	char *effect_path = obs_module_file("color_grade_filter.effect");
	gs_effect_destroy(filter->effect);
	filter->effect = gs_effect_create_from_file(effect_path, NULL);
	bfree(effect_path);

	obs_leave_graphics();
}
Пример #3
0
static void color_grade_filter_destroy(void *data)
{
	struct lut_filter_data *filter = data;

	obs_enter_graphics();
	gs_effect_destroy(filter->effect);
	gs_image_file_free(&filter->image);
	obs_leave_graphics();

	bfree(filter->file);
	bfree(filter);
}
Пример #4
0
static void image_source_load(struct image_source *context)
{
	char *file = context->file;

	obs_enter_graphics();
	gs_image_file_free(&context->image);
	obs_leave_graphics();

	if (file && *file) {
		debug("loading texture '%s'", file);
		context->file_timestamp = get_modified_timestamp(file);
		gs_image_file_init(&context->image, file);
		context->update_time_elapsed = 0;

		obs_enter_graphics();
		gs_image_file_init_texture(&context->image);
		obs_leave_graphics();

		if (!context->image.loaded)
			warn("failed to load texture '%s'", file);
	}
}
Пример #5
0
static bool init_animated_gif(gs_image_file_t *image, const char *path)
{
	bool is_animated_gif = true;
	gif_result result;
	uint64_t max_size;
	size_t size;
	FILE *file;

	image->bitmap_callbacks.bitmap_create = bi_def_bitmap_create;
	image->bitmap_callbacks.bitmap_destroy = bi_def_bitmap_destroy;
	image->bitmap_callbacks.bitmap_get_buffer = bi_def_bitmap_get_buffer;
	image->bitmap_callbacks.bitmap_modified = bi_def_bitmap_modified;
	image->bitmap_callbacks.bitmap_set_opaque = bi_def_bitmap_set_opaque;
	image->bitmap_callbacks.bitmap_test_opaque = bi_def_bitmap_test_opaque;

	gif_create(&image->gif, &image->bitmap_callbacks);

	file = os_fopen(path, "rb");
	if (!file) {
		blog(LOG_WARNING, "Failed to open file '%s'", path);
		goto fail;
	}

	fseek(file, 0, SEEK_END);
	size = (size_t)os_ftelli64(file);
	fseek(file, 0, SEEK_SET);

	image->gif_data = bmalloc(size);
	fread(image->gif_data, 1, size, file);

	do {
		result = gif_initialise(&image->gif, size, image->gif_data);
		if (result < 0) {
			blog(LOG_WARNING, "Failed to initialize gif '%s', "
					"possible file corruption", path);
			goto fail;
		}
	} while (result != GIF_OK);

	if (image->gif.width > 4096 || image->gif.height > 4096) {
		blog(LOG_WARNING, "Bad texture dimensions (%dx%d) in '%s'",
				image->gif.width, image->gif.height, path);
		goto fail;
	}

	max_size = (uint64_t)image->gif.width * (uint64_t)image->gif.height *
		(uint64_t)image->gif.frame_count * 4LLU;

	if ((uint64_t)get_full_decoded_gif_size(image) != max_size) {
		blog(LOG_WARNING, "Gif '%s' overflowed maximum pointer size",
				path);
		goto fail;
	}

	image->is_animated_gif = (image->gif.frame_count > 1 && result >= 0);
	if (image->is_animated_gif) {
		gif_decode_frame(&image->gif, 0);

		image->animation_frame_cache = bzalloc(
				image->gif.frame_count * sizeof(uint8_t*));
		image->animation_frame_data = bzalloc(
				get_full_decoded_gif_size(image));

		for (unsigned int i = 0; i < image->gif.frame_count; i++) {
			if (gif_decode_frame(&image->gif, i) != GIF_OK)
				blog(LOG_WARNING, "Couldn't decode frame %u "
						"of '%s'", i, path);
		}

		gif_decode_frame(&image->gif, 0);

		image->cx = (uint32_t)image->gif.width;
		image->cy = (uint32_t)image->gif.height;
		image->format = GS_RGBA;
	} else {
		gif_finalise(&image->gif);
		bfree(image->gif_data);
		image->gif_data = NULL;
		is_animated_gif = false;
		goto not_animated;
	}

	image->loaded = true;

fail:
	if (!image->loaded)
		gs_image_file_free(image);
not_animated:
	if (file)
		fclose(file);

	return is_animated_gif;
}
Пример #6
0
static void image_source_unload(struct image_source *context)
{
	obs_enter_graphics();
	gs_image_file_free(&context->image);
	obs_leave_graphics();
}