Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
png.c
Go to the documentation of this file.
1/*
2 This file is part of darktable,
3 Copyright (C) 2009-2012 johannes hanika.
4 Copyright (C) 2010 Christian Himpel.
5 Copyright (C) 2011 Henrik Andersson.
6 Copyright (C) 2011 Tim Harder.
7 Copyright (C) 2011-2017, 2019-2020 Tobias Ellinghaus.
8 Copyright (C) 2012-2014, 2020-2021 Pascal Obry.
9 Copyright (C) 2012 Richard Wonka.
10 Copyright (C) 2013 Jérémy Rosen.
11 Copyright (C) 2013 Pascal de Bruijn.
12 Copyright (C) 2013 Simon Spannagel.
13 Copyright (C) 2013 Thomas Pryds.
14 Copyright (C) 2013-2014 Ulrich Pegelow.
15 Copyright (C) 2014-2016 Roman Lebedev.
16 Copyright (C) 2017 Matthieu Moy.
17 Copyright (C) 2017 Simon Raffeiner.
18 Copyright (C) 2019, 2022, 2025-2026 Aurélien PIERRE.
19 Copyright (C) 2019 Philippe Weyland.
20 Copyright (C) 2020 Diederik Ter Rahe.
21 Copyright (C) 2020-2021 Hubert Kowalski.
22 Copyright (C) 2021 Ralf Brown.
23 Copyright (C) 2022 Martin Bařinka.
24 Copyright (C) 2022 Miloš Komarčević.
25 Copyright (C) 2024 Alynx Zhou.
26
27 darktable is free software: you can redistribute it and/or modify
28 it under the terms of the GNU General Public License as published by
29 the Free Software Foundation, either version 3 of the License, or
30 (at your option) any later version.
31
32 darktable is distributed in the hope that it will be useful,
33 but WITHOUT ANY WARRANTY; without even the implied warranty of
34 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
35 GNU General Public License for more details.
36
37 You should have received a copy of the GNU General Public License
38 along with darktable. If not, see <http://www.gnu.org/licenses/>.
39*/
40
41#ifdef HAVE_CONFIG_H
42#include "config.h"
43#endif
44
45#include <inttypes.h>
46#include <png.h>
47#include <stdio.h>
48#include <stdlib.h>
49#include <zlib.h>
50
51#include "bauhaus/bauhaus.h"
52#include "common/colorspaces.h"
53#include "common/darktable.h"
54#include "common/imageio.h"
56#include "control/conf.h"
57#include "gui/gtk.h"
59
60DT_MODULE(3)
61
62typedef struct dt_imageio_png_t
63{
65 int bpp;
67 FILE *f;
68 png_structp png_ptr;
69 png_infop info_ptr;
71
77
78/* Write EXIF data to PNG file.
79 * Code copied from DigiKam's libs/dimg/loaders/pngloader.cpp.
80 * The EXIF embedding is defined by ImageMagicK.
81 * It is documented in the ExifTool page:
82 * http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/PNG.html
83 *
84 * ..and in turn copied from ufraw. thanks to udi and colleagues
85 * for making useful code much more readable and discoverable ;)
86 */
87
88static void PNGwriteRawProfile(png_struct *ping, png_info *ping_info, char *profile_type, guint8 *profile_data,
89 png_uint_32 length)
90{
91 png_textp text;
92 long i;
93 guint8 *sp;
94 png_charp dp;
95 png_uint_32 allocated_length, description_length;
96
97 const guint8 hex[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
98 text = png_malloc(ping, sizeof(png_text));
99 description_length = strlen(profile_type);
100 allocated_length = length * 2 + (length >> 5) + 20 + description_length;
101
102 text[0].text = png_malloc(ping, allocated_length);
103 text[0].key = png_malloc(ping, 80);
104 text[0].key[0] = '\0';
105
106 g_strlcat(text[0].key, "Raw profile type ", 80);
107 g_strlcat(text[0].key, profile_type, 80);
108
109 sp = profile_data;
110 dp = text[0].text;
111 *dp++ = '\n';
112
113 g_strlcpy(dp, profile_type, allocated_length);
114
115 dp += description_length;
116 *dp++ = '\n';
117 *dp = '\0';
118
119 g_snprintf(dp, allocated_length - strlen(text[0].text), "%8lu ", (unsigned long int)length);
120
121 dp += 8;
122
123 for(i = 0; i < (long)length; i++)
124 {
125 if(i % 36 == 0) *dp++ = '\n';
126
127 *(dp++) = hex[((*sp >> 4) & 0x0f)];
128 *(dp++) = hex[((*sp++) & 0x0f)];
129 }
130
131 *dp++ = '\n';
132 *dp = '\0';
133 text[0].text_length = (dp - text[0].text);
134 text[0].compression = -1;
135
136 if(text[0].text_length <= allocated_length) png_set_text(ping, ping_info, text, 1);
137
138 png_free(ping, text[0].text);
139 png_free(ping, text[0].key);
140 png_free(ping, text);
141}
142
143int write_image(dt_imageio_module_data_t *p_tmp, const char *filename, const void *ivoid,
144 dt_colorspaces_color_profile_type_t over_type, const char *over_filename,
145 void *exif, int exif_len, int32_t imgid, int num, int total, struct dt_dev_pixelpipe_t *pipe,
146 const gboolean export_masks)
147{
149 const int width = p->global.width, height = p->global.height;
150 FILE *f = g_fopen(filename, "wb");
151 if(IS_NULL_PTR(f)) return 1;
152
153 png_structp png_ptr;
154 png_infop info_ptr;
155
156 png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
157 if(IS_NULL_PTR(png_ptr))
158 {
159 fclose(f);
160 return 1;
161 }
162
163 info_ptr = png_create_info_struct(png_ptr);
164 if(IS_NULL_PTR(info_ptr))
165 {
166 fclose(f);
167 png_destroy_write_struct(&png_ptr, NULL);
168 return 1;
169 }
170
171 if(setjmp(png_jmpbuf(png_ptr)))
172 {
173 fclose(f);
174 png_destroy_write_struct(&png_ptr, &info_ptr);
175 return 1;
176 }
177
178 png_init_io(png_ptr, f);
179
180 png_set_compression_level(png_ptr, p->compression);
181 png_set_compression_mem_level(png_ptr, 8);
182 png_set_compression_strategy(png_ptr, Z_DEFAULT_STRATEGY);
183 png_set_compression_window_bits(png_ptr, 15);
184 png_set_compression_method(png_ptr, 8);
185 png_set_compression_buffer_size(png_ptr, 8192);
186
187 png_set_IHDR(png_ptr, info_ptr, width, height, p->bpp, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE,
188 PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
189
190 // metadata has to be written before the pixels
191
192 // embed icc profile
193 cmsHPROFILE out_profile = dt_colorspaces_get_output_profile(imgid, &over_type, over_filename)->profile;
194 uint32_t len = 0;
195 cmsSaveProfileToMem(out_profile, NULL, &len);
196 if(len > 0)
197 {
198 char *buf = malloc(sizeof(char) * len);
199 if(buf)
200 {
201 cmsSaveProfileToMem(out_profile, buf, &len);
202 char name[512] = { 0 };
203 dt_colorspaces_get_profile_name(out_profile, "en", "US", name, sizeof(name));
204
205 png_set_iCCP(png_ptr, info_ptr, *name ? name : "icc", 0,
206#if(PNG_LIBPNG_VER < 10500)
207 (png_charp)buf,
208#else
209 (png_const_bytep)buf,
210#endif
211 len);
212 dt_free(buf);
213 }
214 }
215
216 // write exif data
217 if(exif && exif_len > 0)
218 {
219 /* The legacy tEXt chunk storage scheme implies the "Exif\0\0" APP1 prefix */
220 uint8_t *buf = malloc(exif_len + 6);
221 if(buf)
222 {
223 memcpy(buf, "Exif\0\0", 6);
224 memcpy(buf + 6, exif, exif_len);
225 PNGwriteRawProfile(png_ptr, info_ptr, "exif", buf, exif_len + 6);
226 dt_free(buf);
227 }
228 }
229
230 png_write_info(png_ptr, info_ptr);
231
232 /*
233 * Get rid of filler (OR ALPHA) bytes, pack XRGB/RGBX/ARGB/RGBA into
234 * RGB (4 channels -> 3 channels). The second parameter is not used.
235 */
236 png_set_filler(png_ptr, 0, PNG_FILLER_AFTER);
237
238 png_bytep *row_pointers = dt_pixelpipe_cache_alloc_align_cache(sizeof(png_bytep) * height, 0);
239
240 if(p->bpp > 8)
241 {
242 /* swap bytes of 16 bit files to most significant bit first */
243 png_set_swap(png_ptr);
244
245 for(unsigned i = 0; i < height; i++) row_pointers[i] = (png_bytep)((uint16_t *)ivoid + (size_t)4 * i * width);
246 }
247 else
248 {
249 for(unsigned i = 0; i < height; i++) row_pointers[i] = (uint8_t *)ivoid + (size_t)4 * i * width;
250 }
251
252 png_write_image(png_ptr, row_pointers);
253
254 dt_pixelpipe_cache_free_align(row_pointers);
255
256 png_write_end(png_ptr, info_ptr);
257 png_destroy_write_struct(&png_ptr, &info_ptr);
258 fclose(f);
259 return 0;
260}
261
262static int __attribute__((__unused__)) read_header(const char *filename, dt_imageio_module_data_t *p_tmp)
263{
264 dt_imageio_png_t *png = (dt_imageio_png_t *)p_tmp;
265 png->f = g_fopen(filename, "rb");
266
267 if(IS_NULL_PTR(png->f)) return 1;
268
269#define NUM_BYTES_CHECK (8)
270
271 png_byte dat[NUM_BYTES_CHECK];
272
273 size_t cnt = fread(dat, 1, NUM_BYTES_CHECK, png->f);
274
275 if(cnt != NUM_BYTES_CHECK || png_sig_cmp(dat, (png_size_t)0, NUM_BYTES_CHECK))
276 {
277 fclose(png->f);
278 return 1;
279 }
280
281 png->png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
282
283 if(IS_NULL_PTR(png->png_ptr))
284 {
285 fclose(png->f);
286 return 1;
287 }
288
289 png->info_ptr = png_create_info_struct(png->png_ptr);
290 if(IS_NULL_PTR(png->info_ptr))
291 {
292 fclose(png->f);
293 png_destroy_read_struct(&png->png_ptr, NULL, NULL);
294 return 1;
295 }
296
297 if(setjmp(png_jmpbuf(png->png_ptr)))
298 {
299 fclose(png->f);
300 png_destroy_read_struct(&png->png_ptr, &png->info_ptr, NULL);
301 return 1;
302 }
303
304 png_init_io(png->png_ptr, png->f);
305
306 // we checked some bytes
307 png_set_sig_bytes(png->png_ptr, NUM_BYTES_CHECK);
308
309 // image info
310 png_read_info(png->png_ptr, png->info_ptr);
311
312 uint32_t bit_depth = png_get_bit_depth(png->png_ptr, png->info_ptr);
313 uint32_t color_type = png_get_color_type(png->png_ptr, png->info_ptr);
314
315 // image input transformations
316
317 // palette => rgb
318 if(color_type == PNG_COLOR_TYPE_PALETTE) png_set_palette_to_rgb(png->png_ptr);
319
320 // 1, 2, 4 bit => 8 bit
321 if(color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) png_set_expand_gray_1_2_4_to_8(png->png_ptr);
322
323 // strip alpha channel
324 if(color_type & PNG_COLOR_MASK_ALPHA) png_set_strip_alpha(png->png_ptr);
325
326 // grayscale => rgb
327 if(color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
328 png_set_gray_to_rgb(png->png_ptr);
329
330 // png->bytespp = 3*bit_depth/8;
331 png->global.width = png_get_image_width(png->png_ptr, png->info_ptr);
332 png->global.height = png_get_image_height(png->png_ptr, png->info_ptr);
333
334 return 0;
335
336#undef NUM_BYTES_CHECK
337}
338
339#if 0
340int dt_imageio_png_read_assure_8(dt_imageio_png_t *png)
341{
342 if (setjmp(png_jmpbuf(png->png_ptr)))
343 {
344 fclose(png->f);
345 png_destroy_read_struct(&png->png_ptr, NULL, NULL);
346 return 1;
347 }
348 uint32_t bit_depth = png_get_bit_depth(png->png_ptr, png->info_ptr);
349 // strip down to 8 bit channels
350 if (bit_depth == 16)
351 png_set_strip_16(png->png_ptr);
352
353 return 0;
354}
355#endif
356
358{
359 dt_imageio_png_t *png = (dt_imageio_png_t *)p_tmp;
360 if(setjmp(png_jmpbuf(png->png_ptr)))
361 {
362 fclose(png->f);
363 png_destroy_read_struct(&png->png_ptr, &png->info_ptr, NULL);
364 return 1;
365 }
366
367 png_bytep row_pointer = (png_bytep)out;
368 unsigned long rowbytes = png_get_rowbytes(png->png_ptr, png->info_ptr);
369
370 for(int y = 0; y < png->global.height; y++)
371 {
372 png_read_row(png->png_ptr, row_pointer, NULL);
373 row_pointer += rowbytes;
374 }
375
376 png_read_end(png->png_ptr, png->info_ptr);
377 png_destroy_read_struct(&png->png_ptr, &png->info_ptr, NULL);
378
379 fclose(png->f);
380 return 0;
381}
382
384{
385 return sizeof(dt_imageio_module_data_t) + 2 * sizeof(int);
386}
387
388void *legacy_params(dt_imageio_module_format_t *self, const void *const old_params, const size_t old_params_size,
389 const int old_version, const int new_version, size_t *new_size)
390{
391 if(old_version == 1 && new_version == 3)
392 {
393 typedef struct dt_imageio_png_v1_t
394 {
395 int max_width, max_height;
396 int width, height;
397 char style[128];
398 int bpp;
399 FILE *f;
400 png_structp png_ptr;
401 png_infop info_ptr;
402 } dt_imageio_png_v1_t;
403
404 dt_imageio_png_v1_t *o = (dt_imageio_png_v1_t *)old_params;
406
407 n->global.max_width = o->max_width;
408 n->global.max_height = o->max_height;
409 n->global.width = o->width;
410 n->global.height = o->height;
411 g_strlcpy(n->global.style, o->style, sizeof(o->style));
412 n->bpp = o->bpp;
413 n->compression = Z_BEST_COMPRESSION;
414 n->f = o->f;
415 n->png_ptr = o->png_ptr;
416 n->info_ptr = o->info_ptr;
417 *new_size = self->params_size(self);
418 return n;
419 }
420 else if(old_version == 2 && new_version == 3)
421 {
422 typedef struct dt_imageio_png_v2_t
423 {
424 int max_width, max_height;
425 int width, height;
426 char style[128];
427 gboolean style_append;
428 int bpp;
429 FILE *f;
430 png_structp png_ptr;
431 png_infop info_ptr;
432 } dt_imageio_png_v2_t;
433
434 dt_imageio_png_v2_t *o = (dt_imageio_png_v2_t *)old_params;
436
437 n->global.max_width = o->max_width;
438 n->global.max_height = o->max_height;
439 n->global.width = o->width;
440 n->global.height = o->height;
441 g_strlcpy(n->global.style, o->style, sizeof(o->style));
442 n->bpp = o->bpp;
443 n->compression = Z_BEST_COMPRESSION;
444 n->f = o->f;
445 n->png_ptr = o->png_ptr;
446 n->info_ptr = o->info_ptr;
447 *new_size = self->params_size(self);
448 return n;
449 }
450 return NULL;
451}
452
454{
455 dt_imageio_png_t *d = (dt_imageio_png_t *)calloc(1, sizeof(dt_imageio_png_t));
456 const char *bpp = dt_conf_get_string_const("plugins/imageio/format/png/bpp");
457 d->bpp = atoi(bpp);
458 if(d->bpp != 8 && d->bpp != 16)
459 d->bpp = 8;
460
461 // PNG compression level might actually be zero!
462 if(!dt_conf_key_exists("plugins/imageio/format/png/compression"))
463 d->compression = 5;
464 else
465 {
466 d->compression = dt_conf_get_int("plugins/imageio/format/png/compression");
467 if(d->compression < 0 || d->compression > 9) d->compression = 5;
468 }
469
470 return d;
471}
472
474{
475 dt_free(params);
476}
477
478int set_params(dt_imageio_module_format_t *self, const void *params, const int size)
479{
480 if(size != self->params_size(self)) return 1;
481 const dt_imageio_png_t *d = (dt_imageio_png_t *)params;
483 if(d->bpp < 12)
484 dt_bauhaus_combobox_set(g->bit_depth, 0);
485 else
486 dt_bauhaus_combobox_set(g->bit_depth, 1);
487 dt_conf_set_int("plugins/imageio/format/png/bpp", d->bpp);
488 dt_bauhaus_slider_set(g->compression, d->compression);
489 dt_conf_set_int("plugins/imageio/format/png/compression", d->compression);
490 return 0;
491}
492
494{
495 return ((dt_imageio_png_t *)p)->bpp;
496}
497
499{
500 return IMAGEIO_RGB | (((dt_imageio_png_t *)p)->bpp == 8 ? IMAGEIO_INT8 : IMAGEIO_INT16);
501}
502
504{
505 return "image/png";
506}
507
509{
510 return "png";
511}
512
513const char *name()
514{
515 return _("PNG (8/16-bit)");
516}
517
518static void bit_depth_changed(GtkWidget *widget, gpointer user_data)
519{
520 const int bpp = (dt_bauhaus_combobox_get(widget) == 0 ? 8 : 16);
521 dt_conf_set_int("plugins/imageio/format/png/bpp", bpp);
522}
523
524static void compression_level_changed(GtkWidget *slider, gpointer user_data)
525{
526 const int compression = (int)dt_bauhaus_slider_get(slider);
527 dt_conf_set_int("plugins/imageio/format/png/compression", compression);
528}
529
531{
532}
533
537
539{
541 self->gui_data = (void *)gui;
542 const char *conf_bpp = dt_conf_get_string_const("plugins/imageio/format/png/bpp");
543 int bpp = atoi(conf_bpp);
544
545 // PNG compression level might actually be zero!
546 int compression = 5;
547 if(dt_conf_key_exists("plugins/imageio/format/png/compression"))
548 compression = dt_conf_get_int("plugins/imageio/format/png/compression");
549
550 self->widget = gtk_box_new(GTK_ORIENTATION_VERTICAL, DT_GUI_BOX_SPACING);
551
552 // Bit depth combo box
554 dt_bauhaus_widget_set_label(gui->bit_depth, N_("bit depth"));
555 dt_bauhaus_combobox_add(gui->bit_depth, _("8 bit"));
556 dt_bauhaus_combobox_add(gui->bit_depth, _("16 bit"));
557 if(bpp == 16)
559 else {
560 bpp = 8; // We know only about 8 or 16 bits, at least for now
562 }
563 gtk_box_pack_start(GTK_BOX(self->widget), gui->bit_depth, TRUE, TRUE, 0);
564 g_signal_connect(G_OBJECT(gui->bit_depth), "value-changed", G_CALLBACK(bit_depth_changed), NULL);
565
566 // Compression level slider
568 dt_confgen_get_int("plugins/imageio/format/png/compression", DT_MIN),
569 dt_confgen_get_int("plugins/imageio/format/png/compression", DT_MAX),
570 1,
571 dt_confgen_get_int("plugins/imageio/format/png/compression", DT_DEFAULT),
572 0);
573 dt_bauhaus_widget_set_label(gui->compression, N_("compression"));
574 dt_bauhaus_slider_set(gui->compression, compression);
575 gtk_box_pack_start(GTK_BOX(self->widget), GTK_WIDGET(gui->compression), TRUE, TRUE, 0);
576 g_signal_connect(G_OBJECT(gui->compression), "value-changed", G_CALLBACK(compression_level_changed), NULL);
577}
578
580{
581 dt_free(self->gui_data);
582}
583
585{
587 dt_bauhaus_combobox_set(gui->bit_depth, 0); // 8bpp
588 dt_bauhaus_slider_set(gui->compression, dt_confgen_get_int("plugins/imageio/format/png/compression", DT_DEFAULT));
589}
590
595
596// clang-format off
597// modelines: These editor modelines have been set for all relevant files by tools/update_modelines.py
598// vim: shiftwidth=2 expandtab tabstop=2 cindent
599// kate: tab-indents: off; indent-width 2; replace-tabs on; indent-mode cstyle; remove-trailing-spaces modified;
600// clang-format on
#define TRUE
Definition ashift_lsd.c:162
uint32_t bit_depth
Definition avif.c:97
float dt_bauhaus_slider_get(GtkWidget *widget)
Definition bauhaus.c:3483
int dt_bauhaus_combobox_get(GtkWidget *widget)
Definition bauhaus.c:2347
void dt_bauhaus_slider_set(GtkWidget *widget, float pos)
Definition bauhaus.c:3506
void dt_bauhaus_combobox_set(GtkWidget *widget, const int pos)
Definition bauhaus.c:2301
void dt_bauhaus_widget_set_label(GtkWidget *widget, const char *label)
Definition bauhaus.c:1653
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)
Definition bauhaus.c:1780
GtkWidget * dt_bauhaus_combobox_new(dt_bauhaus_t *bh, dt_gui_module_t *self)
Definition bauhaus.c:1842
void dt_bauhaus_combobox_add(GtkWidget *widget, const char *text)
Definition bauhaus.c:2016
int width
Definition bilateral.h:1
int height
Definition bilateral.h:1
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)
void dt_colorspaces_get_profile_name(cmsHPROFILE p, const char *language, const char *country, char *name, size_t len)
dt_colorspaces_color_profile_type_t
Definition colorspaces.h:81
const dt_aligned_pixel_t f
const dt_colormatrix_t dt_aligned_pixel_t out
char * key
@ DT_DEFAULT
Definition conf.h:96
@ DT_MAX
Definition conf.h:98
@ DT_MIN
Definition conf.h:97
int dt_conf_key_exists(const char *key)
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)
const char * dt_conf_get_string_const(const char *name)
darktable_t darktable
Definition darktable.c:181
#define dt_pixelpipe_cache_alloc_align_cache(size, id)
Definition darktable.h:433
#define DT_MODULE(MODVER)
Definition darktable.h:140
float dt_aligned_pixel_simd_t __attribute__((vector_size(16), aligned(16)))
Enable aggressive floating-point arithmetic optimizations, in denormals handling. Set through user pr...
Definition darktable.h:524
#define dt_free(ptr)
Definition darktable.h:456
#define dt_pixelpipe_cache_free_align(mem)
Definition darktable.h:453
#define IS_NULL_PTR(p)
C is way too permissive with !=, == and if(var) checks, which can mean too many things depending on w...
Definition darktable.h:281
#define DT_GUI_BOX_SPACING
Definition gtk.h:109
#define DT_GUI_MODULE(x)
int bpp
@ IMAGEIO_INT16
Definition imageio.h:64
@ IMAGEIO_RGB
Definition imageio.h:70
@ IMAGEIO_INT8
Definition imageio.h:62
@ FORMAT_FLAGS_SUPPORT_XMP
int read_header(const char *filename, dt_imageio_png_t *png)
Definition imageio_png.c:45
size_t size
Definition mipmap_cache.c:3
dt_mipmap_buffer_dsc_flags flags
Definition mipmap_cache.c:4
const char * mime(dt_imageio_module_data_t *data)
Definition png.c:503
size_t params_size(dt_imageio_module_format_t *self)
Definition png.c:383
static void bit_depth_changed(GtkWidget *widget, gpointer user_data)
Definition png.c:518
void gui_reset(dt_imageio_module_format_t *self)
Definition png.c:584
#define NUM_BYTES_CHECK
void gui_init(dt_imageio_module_format_t *self)
Definition png.c:538
static void compression_level_changed(GtkWidget *slider, gpointer user_data)
Definition png.c:524
const char * extension(dt_imageio_module_data_t *data)
Definition png.c:508
int set_params(dt_imageio_module_format_t *self, const void *params, const int size)
Definition png.c:478
const char * name()
Definition png.c:513
void cleanup(dt_imageio_module_format_t *self)
Definition png.c:534
int read_image(dt_imageio_module_data_t *p_tmp, uint8_t *out)
Definition png.c:357
int levels(dt_imageio_module_data_t *p)
Definition png.c:498
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)
Definition png.c:388
void free_params(dt_imageio_module_format_t *self, dt_imageio_module_data_t *params)
Definition png.c:473
int write_image(dt_imageio_module_data_t *p_tmp, const char *filename, const void *ivoid, 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)
Definition png.c:143
static void PNGwriteRawProfile(png_struct *ping, png_info *ping_info, char *profile_type, guint8 *profile_data, png_uint_32 length)
Definition png.c:88
void init(dt_imageio_module_format_t *self)
Definition png.c:530
void * get_params(dt_imageio_module_format_t *self)
Definition png.c:453
void gui_cleanup(dt_imageio_module_format_t *self)
Definition png.c:579
struct _GtkWidget GtkWidget
Definition splash.h:29
struct dt_bauhaus_t * bauhaus
Definition darktable.h:778
GModule *GtkWidget * widget
GtkWidget * compression
Definition png.c:75
GtkWidget * bit_depth
Definition png.c:74
int compression
Definition png.c:66
png_infop info_ptr
Definition imageio_png.h:41
png_structp png_ptr
Definition imageio_png.h:40
dt_imageio_module_data_t global
Definition png.c:64