48#include <webp/encode.h>
84#define _stringify(a) #a
85#define stringify(a) _stringify(a)
89 "out_of_memory: out of memory allocating objects",
90 "bitstream_out_of_memory: out of memory re-allocating byte buffer",
91 "null_parameter: null parameter passed to function",
92 "invalid_configuration: configuration is invalid",
93 "bad_dimension: bad picture dimension. maximum width and height "
94 "allowed is " stringify(WEBP_MAX_DIMENSION)
" pixels.",
95 "partition0_overflow: partition #0 is too big to fit 512k.\n"
96 "to reduce the size of this partition, try using less segments "
97 "with the -segments option, and eventually reduce the number of "
98 "header bits using -partition_limit. more details are available "
99 "in the manual (`man cwebp`)",
100 "partition_overflow: partition is too big to fit 16M",
101 "bad_write: picture writer returned an i/o error",
102 "file_too_big: file would be too big to fit in 4G",
103 "user_abort: encoding abort requested by user"
110 return "Unknown error. Consider open an issue to ansel to update the webp error list.";
125 void *exif,
int exif_len, int32_t imgid,
int num,
int total,
struct dt_dev_pixelpipe_t *pipe,
126 const gboolean export_masks)
132 WebPMemoryWriter writer;
133 WebPMemoryWriterInit(&writer);
134 WebPData icc_profile;
135 WebPDataInit(&icc_profile);
137 WebPDataInit(&bitstream);
138 WebPData assembled_data;
139 WebPDataInit(&assembled_data);
140 WebPMux *mux = WebPMuxNew();
147 if(!WebPConfigPreset(&config, webp_data->
hint, (
float)webp_data->
quality))
goto out;
151 config.image_hint = webp_data->
hint;
157 config.partition_limit = 70;
158 if(!WebPValidateConfig(&config))
160 fprintf(stderr,
"[webp export] error validating encoder configuration\n");
167 cmsSaveProfileToMem(out_profile, NULL, &len);
170 buf = (uint8_t *)g_malloc(len);
173 cmsSaveProfileToMem(out_profile, buf, &len);
174 icc_profile.bytes = buf;
175 icc_profile.size = len;
176 err = WebPMuxSetChunk(mux,
"ICCP", &icc_profile, 0);
177 if(err != WEBP_MUX_OK)
179 fprintf(stderr,
"[webp export] error adding ICC profile to WebP stream\n");
185 fprintf(stderr,
"[webp export] error allocating ICC profile buffer\n");
191 if(!WebPPictureInit(&pic))
goto out;
194 pic.use_argb = !!(config.lossless);
195 pic.writer = WebPMemoryWrite;
196 pic.custom_ptr = &writer;
198 WebPPictureImportRGBX(&pic, (
const uint8_t *)in_tmp, webp_data->
global.
width * 4);
206 WebPPictureSharpARGBToYUVA(&pic);
209 if(!WebPEncode(&config, &pic))
211 fprintf(stderr,
"[webp export] error during encoding (error: %d - %s)\n",
216 bitstream.bytes = writer.mem;
217 bitstream.size = writer.size;
218 err = WebPMuxSetImage(mux, &bitstream, 0);
219 if(err != WEBP_MUX_OK)
221 fprintf(stderr,
"[webp export] error adding image to WebP stream\n");
226 err = WebPMuxAssemble(mux, &assembled_data);
227 if(err != WEBP_MUX_OK)
229 fprintf(stderr,
"[webp export] error assembling the WebP file\n");
233 out = g_fopen(filename,
"w+b");
236 fprintf(stderr,
"[webp export] error creating file %s\n", filename);
239 if(fwrite(assembled_data.bytes, assembled_data.size, 1,
out) != 1)
241 fprintf(stderr,
"[webp export] error writing %" G_GSIZE_FORMAT
" bytes to file %s\n", assembled_data.size, filename);
248 WebPPictureFree(&pic);
249 WebPMemoryWriterClear(&writer);
251 WebPDataClear(&assembled_data);
264 const size_t old_params_size,
const int old_version,
const int new_version,
267 if(old_version == 1 && new_version == 2)
269 typedef struct dt_imageio_webp_v1_t
271 int max_width, max_height;
277 } dt_imageio_webp_v1_t;
279 dt_imageio_webp_v1_t *o = (dt_imageio_webp_v1_t *)old_params;
283 n->global.max_height = o->max_height;
284 n->global.width = o->width;
285 n->global.height = o->height;
286 g_strlcpy(
n->global.style, o->style,
sizeof(o->style));
287 n->comp_type = o->comp_type;
288 n->quality = o->quality;
290 *new_size = self->params_size(self);
310 if(
size != self->params_size(self))
return 1;
347 return _(
"WebP (8-bit)");
356 gtk_widget_set_sensitive(GTK_WIDGET(user_data),
FALSE);
358 gtk_widget_set_sensitive(GTK_WIDGET(user_data),
TRUE);
377 const int comp_type =
dt_conf_get_int(
"plugins/imageio/format/webp/comp_type");
378 const int quality =
dt_conf_get_int(
"plugins/imageio/format/webp/quality");
399 gtk_widget_set_tooltip_text(gui->
quality, _(
"applies only to lossy setting"));
411 gtk_widget_set_tooltip_text(gui->
hint,
412 _(
"image characteristics hint for the underlying encoder.\n"
413 "picture : digital picture, like portrait, inner shot\n"
414 "photo : outdoor photograph, with natural lighting\n"
415 "graphic : discrete tone image (graph, map-tile etc)"));
void dt_bauhaus_slider_set_default(GtkWidget *widget, float def)
float dt_bauhaus_slider_get(GtkWidget *widget)
int dt_bauhaus_combobox_get(GtkWidget *widget)
void dt_bauhaus_slider_set(GtkWidget *widget, float pos)
void dt_bauhaus_combobox_set(GtkWidget *widget, const int pos)
void dt_bauhaus_widget_set_label(GtkWidget *widget, const char *label)
GtkWidget * dt_bauhaus_slider_new_with_range(dt_bauhaus_t *bh, dt_gui_module_t *self, float min, float max, float step, float defval, int digits)
GtkWidget * dt_bauhaus_combobox_new(dt_bauhaus_t *bh, dt_gui_module_t *self)
void dt_bauhaus_slider_set_format(GtkWidget *widget, const char *format)
void dt_bauhaus_combobox_add(GtkWidget *widget, const char *text)
static const dt_aligned_pixel_simd_t const dt_adaptation_t const float p
const dt_colorspaces_color_profile_t * dt_colorspaces_get_output_profile(const int32_t imgid, dt_colorspaces_color_profile_type_t *over_type, const char *over_filename)
dt_colorspaces_color_profile_type_t
const dt_colormatrix_t dt_aligned_pixel_t out
void dt_conf_set_int(const char *name, int val)
int dt_conf_get_int(const char *name)
int dt_confgen_get_int(const char *name, dt_confgen_value_kind_t kind)
#define DT_MODULE(MODVER)
#define IS_NULL_PTR(p)
C is way too permissive with !=, == and if(var) checks, which can mean too many things depending on w...
int dt_exif_write_blob(uint8_t *blob, uint32_t size, const char *path, const int compressed)
#define DT_GUI_BOX_SPACING
@ FORMAT_FLAGS_SUPPORT_XMP
dt_mipmap_buffer_dsc_flags flags
struct _GtkWidget GtkWidget
struct dt_bauhaus_t * bauhaus
dt_imageio_module_data_t global
const char * mime(dt_imageio_module_data_t *data)
size_t params_size(dt_imageio_module_format_t *self)
void gui_reset(dt_imageio_module_format_t *self)
void gui_init(dt_imageio_module_format_t *self)
const char * extension(dt_imageio_module_data_t *data)
static const char *const EncoderError[]
int set_params(dt_imageio_module_format_t *self, const void *params, const int size)
void cleanup(dt_imageio_module_format_t *self)
int levels(dt_imageio_module_data_t *p)
void * legacy_params(dt_imageio_module_format_t *self, const void *const old_params, const size_t old_params_size, const int old_version, const int new_version, size_t *new_size)
void free_params(dt_imageio_module_format_t *self, dt_imageio_module_data_t *params)
const char * get_error_str(int err)
static void compression_changed(GtkWidget *widget, gpointer user_data)
void init(dt_imageio_module_format_t *self)
void * get_params(dt_imageio_module_format_t *self)
void gui_cleanup(dt_imageio_module_format_t *self)
static void hint_combobox_changed(GtkWidget *widget, gpointer user_data)
int write_image(dt_imageio_module_data_t *webp, const char *filename, const void *in_tmp, dt_colorspaces_color_profile_type_t over_type, const char *over_filename, void *exif, int exif_len, int32_t imgid, int num, int total, struct dt_dev_pixelpipe_t *pipe, const gboolean export_masks)
static void quality_changed(GtkWidget *slider, gpointer user_data)