Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
jpeg.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-2011 Henrik Andersson.
5 Copyright (C) 2010 Thierry Leconte.
6 Copyright (C) 2011, 2013 Pascal de Bruijn.
7 Copyright (C) 2011-2017, 2019-2020 Tobias Ellinghaus.
8 Copyright (C) 2012-2015, 2020-2021 Pascal Obry.
9 Copyright (C) 2012 Richard Wonka.
10 Copyright (C) 2013 Jérémy Rosen.
11 Copyright (C) 2013-2016 Roman Lebedev.
12 Copyright (C) 2013 Thomas Pryds.
13 Copyright (C) 2013-2014 Ulrich Pegelow.
14 Copyright (C) 2016 Matthieu Volat.
15 Copyright (C) 2019, 2022, 2025-2026 Aurélien PIERRE.
16 Copyright (C) 2019 Philippe Weyland.
17 Copyright (C) 2020 Diederik Ter Rahe.
18 Copyright (C) 2020 Heiko Bauke.
19 Copyright (C) 2020-2021 Hubert Kowalski.
20 Copyright (C) 2021-2022 Miloš Komarčević.
21 Copyright (C) 2022 Martin Bařinka.
22 Copyright (C) 2024 Alynx Zhou.
23
24 darktable is free software: you can redistribute it and/or modify
25 it under the terms of the GNU General Public License as published by
26 the Free Software Foundation, either version 3 of the License, or
27 (at your option) any later version.
28
29 darktable is distributed in the hope that it will be useful,
30 but WITHOUT ANY WARRANTY; without even the implied warranty of
31 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32 GNU General Public License for more details.
33
34 You should have received a copy of the GNU General Public License
35 along with darktable. If not, see <http://www.gnu.org/licenses/>.
36*/
37
38#ifdef HAVE_CONFIG_H
39#include "config.h"
40#endif
41#include "bauhaus/bauhaus.h"
42#include "common/colorspaces.h"
43#include "common/darktable.h"
44#include "common/exif.h"
45#include "common/imageio.h"
47#include "control/conf.h"
49#include "gui/gtk.h"
50
51#include <inttypes.h>
52#include <setjmp.h>
53#include <stdio.h>
54#include <stdlib.h>
55// this fixes a rather annoying, long time bug in libjpeg :(
56#undef HAVE_STDLIB_H
57#undef HAVE_STDDEF_H
58#include <jpeglib.h>
59#undef HAVE_STDLIB_H
60#undef HAVE_STDDEF_H
61
62DT_MODULE(2)
63
64typedef struct dt_imageio_jpeg_t
65{
68 struct jpeg_source_mgr src;
69 struct jpeg_destination_mgr dest;
70 struct jpeg_decompress_struct dinfo;
71 struct jpeg_compress_struct cinfo;
72 FILE *f;
74
79
80
81// error functions
83{
84 struct jpeg_error_mgr pub;
85 jmp_buf setjmp_buffer;
87
89
90static void dt_imageio_jpeg_error_exit(j_common_ptr cinfo)
91{
93 (*cinfo->err->output_message)(cinfo);
94 longjmp(myerr->setjmp_buffer, 1);
95}
96
97/*
98 * Since an ICC profile can be larger than the maximum size of a JPEG marker
99 * (64K), we need provisions to split it into multiple markers. The format
100 * defined by the ICC specifies one or more APP2 markers containing the
101 * following data:
102 * Identifying string ASCII "ICC_PROFILE\0" (12 bytes)
103 * Marker sequence number 1 for first APP2, 2 for next, etc (1 byte)
104 * Number of markers Total number of APP2's used (1 byte)
105 * Profile data (remainder of APP2 data)
106 * Decoders should use the marker sequence numbers to reassemble the profile,
107 * rather than assuming that the APP2 markers appear in the correct sequence.
108 */
109
110#define ICC_MARKER (JPEG_APP0 + 2) /* JPEG marker code for ICC */
111#define ICC_OVERHEAD_LEN 14 /* size of non-profile data in APP2 */
112#define MAX_BYTES_IN_MARKER 65533 /* maximum data len of a JPEG marker */
113#define MAX_DATA_BYTES_IN_MARKER (MAX_BYTES_IN_MARKER - ICC_OVERHEAD_LEN)
114
115
116/*
117 * This routine writes the given ICC profile data into a JPEG file.
118 * It *must* be called AFTER calling jpeg_start_compress() and BEFORE
119 * the first call to jpeg_write_scanlines().
120 * (This ordering ensures that the APP2 marker(s) will appear after the
121 * SOI and JFIF or Adobe markers, but before all else.)
122 */
123
124static void write_icc_profile(j_compress_ptr cinfo, const JOCTET *icc_data_ptr, unsigned int icc_data_len)
125{
126 int cur_marker = 1; /* per spec, counting starts at 1 */
127
128 /* Calculate the number of markers we'll need, rounding up of course */
129 unsigned int num_markers = icc_data_len / MAX_DATA_BYTES_IN_MARKER;
130 if(num_markers * MAX_DATA_BYTES_IN_MARKER != icc_data_len) num_markers++;
131
132 while(icc_data_len > 0)
133 {
134 /* length of profile to put in this marker */
135 unsigned int length = icc_data_len;
136 if(length > MAX_DATA_BYTES_IN_MARKER)
138 icc_data_len -= length;
139
140 /* Write the JPEG marker header (APP2 code and marker length) */
141 jpeg_write_m_header(cinfo, ICC_MARKER, (unsigned int)(length + ICC_OVERHEAD_LEN));
142
143 /* Write the marker identifying string "ICC_PROFILE" (null-terminated).
144 * We code it in this less-than-transparent way so that the code works
145 * even if the local character set is not ASCII.
146 */
147 jpeg_write_m_byte(cinfo, 0x49);
148 jpeg_write_m_byte(cinfo, 0x43);
149 jpeg_write_m_byte(cinfo, 0x43);
150 jpeg_write_m_byte(cinfo, 0x5F);
151 jpeg_write_m_byte(cinfo, 0x50);
152 jpeg_write_m_byte(cinfo, 0x52);
153 jpeg_write_m_byte(cinfo, 0x4F);
154 jpeg_write_m_byte(cinfo, 0x46);
155 jpeg_write_m_byte(cinfo, 0x49);
156 jpeg_write_m_byte(cinfo, 0x4C);
157 jpeg_write_m_byte(cinfo, 0x45);
158 jpeg_write_m_byte(cinfo, 0x0);
159
160 /* Add the sequencing info */
161 jpeg_write_m_byte(cinfo, cur_marker);
162 jpeg_write_m_byte(cinfo, (int)num_markers);
163
164 /* Add the profile data */
165 while(length--)
166 {
167 jpeg_write_m_byte(cinfo, *icc_data_ptr);
168 icc_data_ptr++;
169 }
170 cur_marker++;
171 }
172}
173
174
175#if 0
176/*
177 * Prepare for reading an ICC profile
178 */
179
180void
181setup_read_icc_profile (j_decompress_ptr cinfo)
182{
183 /* Tell the library to keep any APP2 data it may find */
184 jpeg_save_markers(cinfo, ICC_MARKER, 0xFFFF);
185}
186
187
188/*
189 * Handy subroutine to test whether a saved marker is an ICC profile marker.
190 */
191
192static boolean
193marker_is_icc (jpeg_saved_marker_ptr marker)
194{
195 return
196 marker->marker == ICC_MARKER &&
197 marker->data_length >= ICC_OVERHEAD_LEN &&
198 /* verify the identifying string */
199 GETJOCTET(marker->data[0]) == 0x49 &&
200 GETJOCTET(marker->data[1]) == 0x43 &&
201 GETJOCTET(marker->data[2]) == 0x43 &&
202 GETJOCTET(marker->data[3]) == 0x5F &&
203 GETJOCTET(marker->data[4]) == 0x50 &&
204 GETJOCTET(marker->data[5]) == 0x52 &&
205 GETJOCTET(marker->data[6]) == 0x4F &&
206 GETJOCTET(marker->data[7]) == 0x46 &&
207 GETJOCTET(marker->data[8]) == 0x49 &&
208 GETJOCTET(marker->data[9]) == 0x4C &&
209 GETJOCTET(marker->data[10]) == 0x45 &&
210 GETJOCTET(marker->data[11]) == 0x0;
211}
212
213
214/*
215 * See if there was an ICC profile in the JPEG file being read;
216 * if so, reassemble and return the profile data.
217 *
218 * TRUE is returned if an ICC profile was found, FALSE if not.
219 * If TRUE is returned, *icc_data_ptr is set to point to the
220 * returned data, and *icc_data_len is set to its length.
221 *
222 * IMPORTANT: the data at **icc_data_ptr has been allocated with malloc()
223 * and must be freed by the caller with g_free() when the caller no longer
224 * needs it. (Alternatively, we could write this routine to use the
225 * IJG library's memory allocator, so that the data would be freed implicitly
226 * at jpeg_finish_decompress() time. But it seems likely that many apps
227 * will prefer to have the data stick around after decompression finishes.)
228 *
229 * NOTE: if the file contains invalid ICC APP2 markers, we just silently
230 * return FALSE. You might want to issue an error message instead.
231 */
232
233boolean
234read_icc_profile (j_decompress_ptr cinfo,
235 JOCTET **icc_data_ptr,
236 unsigned int *icc_data_len)
237{
238 int num_markers = 0;
239#define MAX_SEQ_NO 255 /* sufficient since marker numbers are bytes */
240 char marker_present[MAX_SEQ_NO+1]; /* 1 if marker found */
241 unsigned int data_length[MAX_SEQ_NO+1]; /* size of profile data in marker */
242 unsigned int data_offset[MAX_SEQ_NO+1]; /* offset for data in marker */
243
244 *icc_data_ptr = NULL; /* avoid confusion if FALSE return */
245 *icc_data_len = 0;
246
247 /* This first pass over the saved markers discovers whether there are
248 * any ICC markers and verifies the consistency of the marker numbering.
249 */
250
251 for(int seq_no = 1; seq_no <= MAX_SEQ_NO; seq_no++)
252 marker_present[seq_no] = 0;
253
254 for(jpeg_saved_marker_ptr marker = cinfo->marker_list; !IS_NULL_PTR(marker); marker = marker->next)
255 {
256 if(marker_is_icc(marker))
257 {
258 if(num_markers == 0)
259 num_markers = GETJOCTET(marker->data[13]);
260 else if(num_markers != GETJOCTET(marker->data[13]))
261 return FALSE; /* inconsistent num_markers fields */
262 const int seq_no = GETJOCTET(marker->data[12]);
263 if(seq_no <= 0 || seq_no > num_markers)
264 return FALSE; /* bogus sequence number */
265 if(marker_present[seq_no])
266 return FALSE; /* duplicate sequence numbers */
267 marker_present[seq_no] = 1;
268 data_length[seq_no] = marker->data_length - ICC_OVERHEAD_LEN;
269 }
270 }
271
272 if(num_markers == 0)
273 return FALSE;
274
275 /* Check for missing markers, count total space needed,
276 * compute offset of each marker's part of the data.
277 */
278
279 unsigned int total_length = 0;
280 for(int seq_no = 1; seq_no <= num_markers; seq_no++)
281 {
282 if(marker_present[seq_no] == 0)
283 return FALSE; /* missing sequence number */
284 data_offset[seq_no] = total_length;
285 total_length += data_length[seq_no];
286 }
287
288 if(total_length <= 0)
289 return FALSE; /* found only empty markers? */
290
291 /* Allocate space for assembled data */
292 JOCTET *icc_data = (JOCTET *)calloc(total_length, sizeof(JOCTET));
293 if(IS_NULL_PTR(icc_data))
294 return FALSE; /* oops, out of memory */
295
296 /* and fill it in */
297 for(jpeg_saved_marker_ptr marker = cinfo->marker_list; !IS_NULL_PTR(marker); marker = marker->next)
298 {
299 if(marker_is_icc(marker))
300 {
301 const int seq_no = GETJOCTET(marker->data[12]);
302 JOCTET *dst_ptr = icc_data + data_offset[seq_no];
303 JOCTET FAR *src_ptr = marker->data + ICC_OVERHEAD_LEN;
304 unsigned int length = data_length[seq_no];
305 while (length--)
306 {
307 *dst_ptr++ = *src_ptr++;
308 }
309 }
310 }
311
312 *icc_data_ptr = icc_data;
313 *icc_data_len = total_length;
314
315 return TRUE;
316}
317#endif
318#undef ICC_MARKER
319#undef ICC_OVERHEAD_LEN
320#undef MAX_BYTES_IN_MARKER
321#undef MAX_DATA_BYTES_IN_MARKER
322#undef MAX_SEQ_NO
323
324
325int write_image(dt_imageio_module_data_t *jpg_tmp, const char *filename, const void *in_tmp,
326 dt_colorspaces_color_profile_type_t over_type, const char *over_filename,
327 void *exif, int exif_len, int32_t imgid, int num, int total, struct dt_dev_pixelpipe_t *pipe,
328 const gboolean export_masks)
329{
330 dt_imageio_jpeg_t *jpg = (dt_imageio_jpeg_t *)jpg_tmp;
331 const uint8_t *in = (const uint8_t *)in_tmp;
332 struct dt_imageio_jpeg_error_mgr jerr;
333
334 jpg->cinfo.err = jpeg_std_error(&jerr.pub);
335 jerr.pub.error_exit = dt_imageio_jpeg_error_exit;
336 if(setjmp(jerr.setjmp_buffer))
337 {
338 jpeg_destroy_compress(&(jpg->cinfo));
339 return 1;
340 }
341 jpeg_create_compress(&(jpg->cinfo));
342 FILE *f = g_fopen(filename, "wb");
343 if(IS_NULL_PTR(f)) return 1;
344 jpeg_stdio_dest(&(jpg->cinfo), f);
345
346 jpg->cinfo.image_width = jpg->global.width;
347 jpg->cinfo.image_height = jpg->global.height;
348 jpg->cinfo.input_components = 3;
349 jpg->cinfo.in_color_space = JCS_RGB;
350 jpeg_set_defaults(&(jpg->cinfo));
351 jpeg_set_quality(&(jpg->cinfo), jpg->quality, TRUE);
352 if(jpg->quality > 90) jpg->cinfo.comp_info[0].v_samp_factor = 1;
353 if(jpg->quality > 92) jpg->cinfo.comp_info[0].h_samp_factor = 1;
354 if(jpg->quality > 95) jpg->cinfo.dct_method = JDCT_FLOAT;
355 if(jpg->quality < 50) jpg->cinfo.dct_method = JDCT_IFAST;
356 if(jpg->quality < 80) jpg->cinfo.smoothing_factor = 20;
357 if(jpg->quality < 60) jpg->cinfo.smoothing_factor = 40;
358 if(jpg->quality < 40) jpg->cinfo.smoothing_factor = 60;
359 jpg->cinfo.optimize_coding = 1;
360
361 const int resolution = dt_conf_get_int("metadata/resolution");
362 jpg->cinfo.density_unit = 1;
363 jpg->cinfo.X_density = resolution;
364 jpg->cinfo.Y_density = resolution;
365
366 jpeg_start_compress(&(jpg->cinfo), TRUE);
367
368 cmsHPROFILE out_profile = dt_colorspaces_get_output_profile(imgid, &over_type, over_filename)->profile;
369 uint32_t len = 0;
370 cmsSaveProfileToMem(out_profile, NULL, &len);
371 if(len > 0)
372 {
373 unsigned char *buf = malloc(sizeof(unsigned char) * len);
374 if(buf)
375 {
376 cmsSaveProfileToMem(out_profile, buf, &len);
377 write_icc_profile(&(jpg->cinfo), buf, len);
378 dt_free(buf);
379 }
380 }
381
382 uint8_t *row = dt_pixelpipe_cache_alloc_align_cache(sizeof(uint8_t) * 3 * jpg->global.width, 0);
383 const uint8_t *buf;
384 while(row && jpg->cinfo.next_scanline < jpg->cinfo.image_height)
385 {
386 JSAMPROW tmp[1];
387 buf = in + (size_t)jpg->cinfo.next_scanline * jpg->cinfo.image_width * 4;
388 for(int i = 0; i < jpg->global.width; i++)
389 for(int k = 0; k < 3; k++) row[3 * i + k] = buf[4 * i + k];
390 tmp[0] = row;
391 jpeg_write_scanlines(&(jpg->cinfo), tmp, 1);
392 }
393 jpeg_finish_compress(&(jpg->cinfo));
395 jpeg_destroy_compress(&(jpg->cinfo));
396 fclose(f);
397
398 dt_exif_write_blob(exif, exif_len, filename, 1);
399
400 return 0;
401}
402
403static int __attribute__((__unused__)) read_header(const char *filename, dt_imageio_jpeg_t *jpg)
404{
405 jpg->f = g_fopen(filename, "rb");
406 if(IS_NULL_PTR(jpg->f)) return 1;
407
408 struct dt_imageio_jpeg_error_mgr jerr;
409 jpg->dinfo.err = jpeg_std_error(&jerr.pub);
410 jerr.pub.error_exit = dt_imageio_jpeg_error_exit;
411 if(setjmp(jerr.setjmp_buffer))
412 {
413 jpeg_destroy_decompress(&(jpg->dinfo));
414 fclose(jpg->f);
415 return 1;
416 }
417 jpeg_create_decompress(&(jpg->dinfo));
418 jpeg_stdio_src(&(jpg->dinfo), jpg->f);
419 // jpg->dinfo.buffered_image = TRUE;
420 jpeg_read_header(&(jpg->dinfo), TRUE);
421 jpg->global.width = jpg->dinfo.image_width;
422 jpg->global.height = jpg->dinfo.image_height;
423 return 0;
424}
425
427{
428 dt_imageio_jpeg_t *jpg = (dt_imageio_jpeg_t *)jpg_tmp;
429 struct dt_imageio_jpeg_error_mgr jerr;
430 jpg->dinfo.err = jpeg_std_error(&jerr.pub);
431 jerr.pub.error_exit = dt_imageio_jpeg_error_exit;
432 if(setjmp(jerr.setjmp_buffer))
433 {
434 jpeg_destroy_decompress(&(jpg->dinfo));
435 fclose(jpg->f);
436 return 1;
437 }
438 (void)jpeg_start_decompress(&(jpg->dinfo));
439 JSAMPROW row_pointer[1];
440 row_pointer[0] = (uint8_t *)dt_pixelpipe_cache_alloc_align_cache(
441 (size_t)jpg->dinfo.output_width * jpg->dinfo.num_components, 0);
442 uint8_t *tmp = out;
443 while(row_pointer[0] && jpg->dinfo.output_scanline < jpg->dinfo.image_height)
444 {
445 if(jpeg_read_scanlines(&(jpg->dinfo), row_pointer, 1) != 1) return 1;
446 if(jpg->dinfo.num_components < 3)
447 for(JDIMENSION i = 0; i < jpg->dinfo.image_width; i++)
448 for(int k = 0; k < 3; k++) tmp[4 * i + k] = row_pointer[0][jpg->dinfo.num_components * i + 0];
449 else
450 for(JDIMENSION i = 0; i < jpg->dinfo.image_width; i++)
451 for(int k = 0; k < 3; k++) tmp[4 * i + k] = row_pointer[0][3 * i + k];
452 tmp += 4 * jpg->global.width;
453 }
454 if(setjmp(jerr.setjmp_buffer))
455 {
456 jpeg_destroy_decompress(&(jpg->dinfo));
457 dt_pixelpipe_cache_free_align(row_pointer[0]);
458 fclose(jpg->f);
459 return 1;
460 }
461 (void)jpeg_finish_decompress(&(jpg->dinfo));
462 jpeg_destroy_decompress(&(jpg->dinfo));
463 dt_pixelpipe_cache_free_align(row_pointer[0]);
464 fclose(jpg->f);
465 return 0;
466}
467
469{
470 return sizeof(dt_imageio_module_data_t) + sizeof(int);
471}
472
473void *legacy_params(dt_imageio_module_format_t *self, const void *const old_params,
474 const size_t old_params_size, const int old_version, const int new_version,
475 size_t *new_size)
476{
477 if(old_version == 1 && new_version == 2)
478 {
479 typedef struct dt_imageio_jpeg_v1_t
480 {
481 int max_width, max_height;
482 int width, height;
483 char style[128];
484 int quality;
485 struct jpeg_source_mgr src;
486 struct jpeg_destination_mgr dest;
487 struct jpeg_decompress_struct dinfo;
488 struct jpeg_compress_struct cinfo;
489 FILE *f;
490 } dt_imageio_jpeg_v1_t;
491
492 const dt_imageio_jpeg_v1_t *o = (dt_imageio_jpeg_v1_t *)old_params;
494
495 n->global.max_width = o->max_width;
496 n->global.max_height = o->max_height;
497 n->global.width = o->width;
498 n->global.height = o->height;
499 g_strlcpy(n->global.style, o->style, sizeof(o->style));
500 n->quality = o->quality;
501 n->src = o->src;
502 n->dest = o->dest;
503 n->dinfo = o->dinfo;
504 n->cinfo = o->cinfo;
505 n->f = o->f;
506 *new_size = self->params_size(self);
507 return n;
508 }
509 return NULL;
510}
511
513{
514 // adjust this if more params are stored (subsampling etc)
516 d->quality = dt_conf_get_int("plugins/imageio/format/jpeg/quality");
517 if(d->quality <= 0 || d->quality > 100) d->quality = 100;
518 return d;
519}
520
522{
523 dt_free(params);
524}
525
526int set_params(dt_imageio_module_format_t *self, const void *params, const int size)
527{
528 if(size != self->params_size(self)) return 1;
529 const dt_imageio_jpeg_t *d = (dt_imageio_jpeg_t *)params;
531 dt_bauhaus_slider_set(g->quality, d->quality);
532 return 0;
533}
534
536{
537 return 8;
538}
539
544
546{
547 return "image/jpeg";
548}
549
551{
552 return "jpg";
553}
554
559
561{
562}
563
567
568// =============================================================================
569// gui stuff:
570// =============================================================================
571
572const char *name()
573{
574 return _("JPEG (8-bit)");
575}
576
577static void quality_changed(GtkWidget *slider, gpointer user_data)
578{
579 const int quality = (int)dt_bauhaus_slider_get(slider);
580 dt_conf_set_int("plugins/imageio/format/jpeg/quality", quality);
581}
582
584{
586 self->gui_data = g;
587 // construct gui with jpeg specific options:
588 GtkWidget *box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, DT_GUI_BOX_SPACING);
589 self->widget = box;
590 // quality slider
592 dt_confgen_get_int("plugins/imageio/format/jpeg/quality", DT_MIN),
593 dt_confgen_get_int("plugins/imageio/format/jpeg/quality", DT_MAX),
594 1,
595 dt_confgen_get_int("plugins/imageio/format/jpeg/quality", DT_DEFAULT),
596 0);
597 dt_bauhaus_widget_set_label(g->quality, N_("quality"));
598 dt_bauhaus_slider_set_default(g->quality, dt_confgen_get_int("plugins/imageio/format/jpeg/quality", DT_DEFAULT));
599 dt_bauhaus_slider_set(g->quality, dt_conf_get_int("plugins/imageio/format/jpeg/quality"));
600 gtk_box_pack_start(GTK_BOX(box), GTK_WIDGET(g->quality), TRUE, TRUE, 0);
601 g_signal_connect(G_OBJECT(g->quality), "value-changed", G_CALLBACK(quality_changed), NULL);
602 // TODO: add more options: subsample dreggn
603}
604
606{
607 dt_free(self->gui_data);
608}
609
611{
613 dt_bauhaus_slider_set(g->quality, dt_confgen_get_int("plugins/imageio/format/jpeg/quality", DT_DEFAULT));
614}
615
616// clang-format off
617// modelines: These editor modelines have been set for all relevant files by tools/update_modelines.py
618// vim: shiftwidth=2 expandtab tabstop=2 cindent
619// kate: tab-indents: off; indent-width 2; replace-tabs on; indent-mode cstyle; remove-trailing-spaces modified;
620// clang-format on
#define TRUE
Definition ashift_lsd.c:162
#define FALSE
Definition ashift_lsd.c:158
void dt_bauhaus_slider_set_default(GtkWidget *widget, float def)
Definition bauhaus.c:1640
float dt_bauhaus_slider_get(GtkWidget *widget)
Definition bauhaus.c:3483
void dt_bauhaus_slider_set(GtkWidget *widget, float pos)
Definition bauhaus.c:3506
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
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)
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
static const int row
typedef void((*dt_cache_allocate_t)(void *userdata, dt_cache_entry_t *entry))
@ DT_DEFAULT
Definition conf.h:96
@ DT_MAX
Definition conf.h:98
@ DT_MIN
Definition conf.h:97
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)
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
int dt_exif_write_blob(uint8_t *blob, uint32_t size, const char *path, const int compressed)
Definition exif.cc:1816
#define DT_GUI_BOX_SPACING
Definition gtk.h:109
#define DT_GUI_MODULE(x)
int bpp
@ IMAGEIO_RGB
Definition imageio.h:70
@ IMAGEIO_INT8
Definition imageio.h:62
static void setup_read_icc_profile(j_decompress_ptr cinfo)
#define MAX_SEQ_NO
static boolean marker_is_icc(jpeg_saved_marker_ptr marker)
static boolean read_icc_profile(j_decompress_ptr dinfo, JOCTET **icc_data_ptr, unsigned int *icc_data_len)
@ FORMAT_FLAGS_SUPPORT_XMP
int read_header(const char *filename, dt_imageio_png_t *png)
Definition imageio_png.c:45
const char * mime(dt_imageio_module_data_t *data)
Definition jpeg.c:545
size_t params_size(dt_imageio_module_format_t *self)
Definition jpeg.c:468
#define ICC_MARKER
Definition jpeg.c:110
void gui_reset(dt_imageio_module_format_t *self)
Definition jpeg.c:610
static void dt_imageio_jpeg_error_exit(j_common_ptr cinfo)
Definition jpeg.c:90
void gui_init(dt_imageio_module_format_t *self)
Definition jpeg.c:583
const char * extension(dt_imageio_module_data_t *data)
Definition jpeg.c:550
int read_image(dt_imageio_module_data_t *jpg_tmp, uint8_t *out)
Definition jpeg.c:426
int set_params(dt_imageio_module_format_t *self, const void *params, const int size)
Definition jpeg.c:526
int write_image(dt_imageio_module_data_t *jpg_tmp, 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)
Definition jpeg.c:325
const char * name()
Definition jpeg.c:572
void cleanup(dt_imageio_module_format_t *self)
Definition jpeg.c:564
int levels(dt_imageio_module_data_t *p)
Definition jpeg.c:540
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 jpeg.c:473
void free_params(dt_imageio_module_format_t *self, dt_imageio_module_data_t *params)
Definition jpeg.c:521
struct dt_imageio_jpeg_error_mgr * dt_imageio_jpeg_error_ptr
Definition jpeg.c:88
void init(dt_imageio_module_format_t *self)
Definition jpeg.c:560
void * get_params(dt_imageio_module_format_t *self)
Definition jpeg.c:512
static void write_icc_profile(j_compress_ptr cinfo, const JOCTET *icc_data_ptr, unsigned int icc_data_len)
Definition jpeg.c:124
void gui_cleanup(dt_imageio_module_format_t *self)
Definition jpeg.c:605
#define MAX_DATA_BYTES_IN_MARKER
Definition jpeg.c:113
static void quality_changed(GtkWidget *slider, gpointer user_data)
Definition jpeg.c:577
#define ICC_OVERHEAD_LEN
Definition jpeg.c:111
float *const restrict const size_t k
size_t size
Definition mipmap_cache.c:3
dt_mipmap_buffer_dsc_flags flags
Definition mipmap_cache.c:4
struct _GtkWidget GtkWidget
Definition splash.h:29
struct dt_bauhaus_t * bauhaus
Definition darktable.h:778
struct jpeg_error_mgr pub
GtkWidget * quality
Definition jpeg.c:77
struct jpeg_decompress_struct dinfo
dt_imageio_module_data_t global
Definition jpeg.c:66
struct jpeg_compress_struct cinfo
GModule *GtkWidget * widget