diff options
Diffstat (limited to 'src/modules/evas/image_savers')
4 files changed, 185 insertions, 3 deletions
diff --git a/src/modules/evas/image_savers/avif/evas_image_save_avif.c b/src/modules/evas/image_savers/avif/evas_image_save_avif.c new file mode 100644 index 0000000000..61fefcefc7 --- /dev/null +++ b/src/modules/evas/image_savers/avif/evas_image_save_avif.c @@ -0,0 +1,181 @@ +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <stdio.h> + +#include <avif/avif.h> + +#include "evas_common_private.h" +#include "evas_private.h" + + +static int +save_image_avif(RGBA_Image *im, const char *file, int quality) +{ + FILE *f; + avifRGBImage rgb; + avifRWData output; + avifImage *image; + avifEncoder * encoder; + avifPixelFormat format; + avifResult res; + size_t size; + int threads_count; + int quantizer; + int color; + int transfer; + int matrix; + int ret = 0; + + if (!im || !im->image.data || !file || !*file) + return 0; + + f = fopen(file, "wb"); + if (!f) + return ret; + + if (quality < 60) + { + format = AVIF_PIXEL_FORMAT_YUV420; +#if (AVIF_VERSION < 704) + matrix = AVIF_NCLX_MATRIX_COEFFICIENTS_BT601; + color = AVIF_NCLX_COLOUR_PRIMARIES_BT601; +#else + matrix = AVIF_MATRIX_COEFFICIENTS_BT601; + color = AVIF_COLOR_PRIMARIES_BT601; +#endif + } + else if (quality >= 90) + { + format = AVIF_PIXEL_FORMAT_YUV444; +#if (AVIF_VERSION < 704) + matrix = AVIF_NCLX_MATRIX_COEFFICIENTS_BT709; + color = AVIF_NCLX_COLOUR_PRIMARIES_BT709; +#else + matrix = AVIF_MATRIX_COEFFICIENTS_BT709; + color = AVIF_COLOR_PRIMARIES_BT709; +#endif + } + else + { + format = AVIF_PIXEL_FORMAT_YUV422; +#if (AVIF_VERSION < 704) + matrix = AVIF_NCLX_MATRIX_COEFFICIENTS_BT709; + color = AVIF_NCLX_COLOUR_PRIMARIES_BT709; +#else + matrix = AVIF_MATRIX_COEFFICIENTS_BT709; + color = AVIF_COLOR_PRIMARIES_BT709; +#endif + } + +#if (AVIF_VERSION < 704) + transfer = AVIF_NCLX_TRANSFER_CHARACTERISTICS_SRGB; +#else + transfer = AVIF_TRANSFER_CHARACTERISTICS_SRGB; +#endif + + image = avifImageCreate(im->cache_entry.w, im->cache_entry.h, 8, format); + if (!image) + goto close_f; + +#if (AVIF_VERSION < 704) + image->nclx.colourPrimaries = color; + image->nclx.transferCharacteristics = transfer; + image->nclx.matrixCoefficients = matrix; +#else + image->colorPrimaries = color; + image->transferCharacteristics = transfer; + image->matrixCoefficients = matrix; +#endif + image->yuvRange = AVIF_RANGE_FULL; + + avifRGBImageSetDefaults(&rgb, image); +#ifdef WORDS_BIGENDIAN + rgb.format = AVIF_RGB_FORMAT_ARGB; +#else + rgb.format = AVIF_RGB_FORMAT_BGRA; +#endif + rgb.depth = 8; + rgb.pixels = (uint8_t *)im->image.data; + rgb.rowBytes = 4 * im->cache_entry.w; + avifImageRGBToYUV(image, &rgb); + + output.data = NULL; + output.size = 0; + encoder = avifEncoderCreate(); + if (!encoder) + goto destroy_image; + + threads_count = 1; + if (eina_cpu_count() > 2) + threads_count = eina_cpu_count() - 1; + + quantizer = ((100 - quality) * AVIF_QUANTIZER_WORST_QUALITY) / 100; + + encoder->maxThreads = threads_count; + encoder->minQuantizer = quantizer; + encoder->maxQuantizer = quantizer; + res = avifEncoderWrite(encoder, image, &output); + + if (res != AVIF_RESULT_OK) + goto destroy_encoder; + + size = fwrite(output.data, output.size, 1, f); + if (size != output.size) + goto destroy_encoder; + + ret = 1; + + destroy_encoder: + avifEncoderDestroy(encoder); + avifRWDataFree(&output); + destroy_image: + avifImageDestroy(image); + close_f: + fclose(f); + + return ret; +} + +static int evas_image_save_file_avif(RGBA_Image *im, const char *file, const char *key EINA_UNUSED, + int quality, int compress EINA_UNUSED, const char *encoding EINA_UNUSED) +{ + return save_image_avif(im, file, quality); +} + + +static Evas_Image_Save_Func evas_image_save_avif_func = +{ + evas_image_save_file_avif +}; + +static int +module_open(Evas_Module *em) +{ + if (!em) return 0; + em->functions = (void *)(&evas_image_save_avif_func); + return 1; +} + +static void +module_close(Evas_Module *em EINA_UNUSED) +{ +} + +static Evas_Module_Api evas_modapi = +{ + EVAS_MODULE_API_VERSION, + "avif", + "none", + { + module_open, + module_close + } +}; + +EVAS_MODULE_DEFINE(EVAS_MODULE_TYPE_IMAGE_SAVER, image_saver, avif); + +#ifndef EVAS_STATIC_BUILD_AVIF +EVAS_EINA_MODULE_DEFINE(image_saver, avif); +#endif diff --git a/src/modules/evas/image_savers/meson.build b/src/modules/evas/image_savers/meson.build index 6e1e346d06..e30a05fe3b 100644 --- a/src/modules/evas/image_savers/meson.build +++ b/src/modules/evas/image_savers/meson.build @@ -9,8 +9,9 @@ foreach loader_inst : evas_image_savers_file evas_package_modules = join_paths(dir_lib, 'evas', 'modules') mod_install_dir = join_paths(evas_package_modules, 'image_savers', loader, version_name) shared_module('shared_saver_'+loader, file, + c_args : package_c_args, include_directories : config_dir, - dependencies : [eina, evas] + loader_deps, + dependencies : [eina, evas, eet, evas_ext_none_static_deps] + loader_deps, install : true, install_dir : mod_install_dir, name_suffix : sys_mod_extension diff --git a/src/modules/evas/image_savers/png/evas_image_save_png.c b/src/modules/evas/image_savers/png/evas_image_save_png.c index 1aeec12c8a..95693ccc83 100644 --- a/src/modules/evas/image_savers/png/evas_image_save_png.c +++ b/src/modules/evas/image_savers/png/evas_image_save_png.c @@ -184,7 +184,7 @@ save_image_png(RGBA_Image *im, const char *file, int do_compress, int interlace) return 0; } -static int +static int evas_image_save_file_png(RGBA_Image *im, const char *file, const char *key EINA_UNUSED, int quality EINA_UNUSED, int do_compress, const char *encoding EINA_UNUSED) { diff --git a/src/modules/evas/image_savers/tiff/evas_image_save_tiff.c b/src/modules/evas/image_savers/tiff/evas_image_save_tiff.c index c6dbda8ebe..3e06b112b0 100644 --- a/src/modules/evas/image_savers/tiff/evas_image_save_tiff.c +++ b/src/modules/evas/image_savers/tiff/evas_image_save_tiff.c @@ -45,7 +45,7 @@ save_image_tiff(RGBA_Image *im, const char *file, int compress EINA_UNUSED, int /* By default uses patent-free use COMPRESSION_DEFLATE, * another lossless compression technique */ TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_DEFLATE); - + if (has_alpha) { uint16 extras[] = { EXTRASAMPLE_ASSOCALPHA }; |