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 "widgets/bauhaus.h"
43#include "system/macros.h"
44#include "system/mem_alloc.h"
46#include <glib/gstdio.h>
48#include "metadata/exif.h"
51#include "common/conf.h"
53
54#include <inttypes.h>
55#include <setjmp.h>
56#include <stdio.h>
57#include <stdlib.h>
58// this fixes a rather annoying, long time bug in libjpeg :(
59#undef HAVE_STDLIB_H
60#undef HAVE_STDDEF_H
61#include <jpeglib.h>
63#undef HAVE_STDLIB_H
64#undef HAVE_STDDEF_H
65
66DT_MODULE(2)
67
68typedef struct dt_imageio_jpeg_t
69{
72 struct jpeg_source_mgr src;
73 struct jpeg_destination_mgr dest;
74 struct jpeg_decompress_struct dinfo;
75 struct jpeg_compress_struct cinfo;
76 FILE *f;
78
83
84
85// error functions
91
93
94static void dt_imageio_jpeg_error_exit(j_common_ptr cinfo)
95{
97 (*cinfo->err->output_message)(cinfo);
98 longjmp(myerr->setjmp_buffer, 1);
99}
100
101/*
102 * Since an ICC profile can be larger than the maximum size of a JPEG marker
103 * (64K), we need provisions to split it into multiple markers. The format
104 * defined by the ICC specifies one or more APP2 markers containing the
105 * following data:
106 * Identifying string ASCII "ICC_PROFILE\0" (12 bytes)
107 * Marker sequence number 1 for first APP2, 2 for next, etc (1 byte)
108 * Number of markers Total number of APP2's used (1 byte)
109 * Profile data (remainder of APP2 data)
110 * Decoders should use the marker sequence numbers to reassemble the profile,
111 * rather than assuming that the APP2 markers appear in the correct sequence.
112 */
113
114#define ICC_MARKER (JPEG_APP0 + 2) /* JPEG marker code for ICC */
115#define ICC_OVERHEAD_LEN 14 /* size of non-profile data in APP2 */
116#define MAX_BYTES_IN_MARKER 65533 /* maximum data len of a JPEG marker */
117#define MAX_DATA_BYTES_IN_MARKER (MAX_BYTES_IN_MARKER - ICC_OVERHEAD_LEN)
118
119
120/*
121 * This routine writes the given ICC profile data into a JPEG file.
122 * It *must* be called AFTER calling jpeg_start_compress() and BEFORE
123 * the first call to jpeg_write_scanlines().
124 * (This ordering ensures that the APP2 marker(s) will appear after the
125 * SOI and JFIF or Adobe markers, but before all else.)
126 */
127
128static void write_icc_profile(j_compress_ptr cinfo, const JOCTET *icc_data_ptr, unsigned int icc_data_len)
129{
130 int cur_marker = 1; /* per spec, counting starts at 1 */
131
132 /* Calculate the number of markers we'll need, rounding up of course */
133 unsigned int num_markers = icc_data_len / MAX_DATA_BYTES_IN_MARKER;
134 if(num_markers * MAX_DATA_BYTES_IN_MARKER != icc_data_len) num_markers++;
135
136 while(icc_data_len > 0)
137 {
138 /* length of profile to put in this marker */
139 unsigned int length = icc_data_len;
140 if(length > MAX_DATA_BYTES_IN_MARKER)
142 icc_data_len -= length;
143
144 /* Write the JPEG marker header (APP2 code and marker length) */
145 jpeg_write_m_header(cinfo, ICC_MARKER, (unsigned int)(length + ICC_OVERHEAD_LEN));
146
147 /* Write the marker identifying string "ICC_PROFILE" (null-terminated).
148 * We code it in this less-than-transparent way so that the code works
149 * even if the local character set is not ASCII.
150 */
151 jpeg_write_m_byte(cinfo, 0x49);
152 jpeg_write_m_byte(cinfo, 0x43);
153 jpeg_write_m_byte(cinfo, 0x43);
154 jpeg_write_m_byte(cinfo, 0x5F);
155 jpeg_write_m_byte(cinfo, 0x50);
156 jpeg_write_m_byte(cinfo, 0x52);
157 jpeg_write_m_byte(cinfo, 0x4F);
158 jpeg_write_m_byte(cinfo, 0x46);
159 jpeg_write_m_byte(cinfo, 0x49);
160 jpeg_write_m_byte(cinfo, 0x4C);
161 jpeg_write_m_byte(cinfo, 0x45);
162 jpeg_write_m_byte(cinfo, 0x0);
163
164 /* Add the sequencing info */
165 jpeg_write_m_byte(cinfo, cur_marker);
166 jpeg_write_m_byte(cinfo, (int)num_markers);
167
168 /* Add the profile data */
169 while(length--)
170 {
171 jpeg_write_m_byte(cinfo, *icc_data_ptr);
172 icc_data_ptr++;
173 }
174 cur_marker++;
175 }
176}
177
178
179#if 0
180/*
181 * Prepare for reading an ICC profile
182 */
183
184void
185setup_read_icc_profile (j_decompress_ptr cinfo)
186{
187 /* Tell the library to keep any APP2 data it may find */
188 jpeg_save_markers(cinfo, ICC_MARKER, 0xFFFF);
189}
190
191
192/*
193 * Handy subroutine to test whether a saved marker is an ICC profile marker.
194 */
195
196static boolean
197marker_is_icc (jpeg_saved_marker_ptr marker)
198{
199 return
200 marker->marker == ICC_MARKER &&
201 marker->data_length >= ICC_OVERHEAD_LEN &&
202 /* verify the identifying string */
203 GETJOCTET(marker->data[0]) == 0x49 &&
204 GETJOCTET(marker->data[1]) == 0x43 &&
205 GETJOCTET(marker->data[2]) == 0x43 &&
206 GETJOCTET(marker->data[3]) == 0x5F &&
207 GETJOCTET(marker->data[4]) == 0x50 &&
208 GETJOCTET(marker->data[5]) == 0x52 &&
209 GETJOCTET(marker->data[6]) == 0x4F &&
210 GETJOCTET(marker->data[7]) == 0x46 &&
211 GETJOCTET(marker->data[8]) == 0x49 &&
212 GETJOCTET(marker->data[9]) == 0x4C &&
213 GETJOCTET(marker->data[10]) == 0x45 &&
214 GETJOCTET(marker->data[11]) == 0x0;
215}
216
217
218/*
219 * See if there was an ICC profile in the JPEG file being read;
220 * if so, reassemble and return the profile data.
221 *
222 * TRUE is returned if an ICC profile was found, FALSE if not.
223 * If TRUE is returned, *icc_data_ptr is set to point to the
224 * returned data, and *icc_data_len is set to its length.
225 *
226 * IMPORTANT: the data at **icc_data_ptr has been allocated with malloc()
227 * and must be freed by the caller with g_free() when the caller no longer
228 * needs it. (Alternatively, we could write this routine to use the
229 * IJG library's memory allocator, so that the data would be freed implicitly
230 * at jpeg_finish_decompress() time. But it seems likely that many apps
231 * will prefer to have the data stick around after decompression finishes.)
232 *
233 * NOTE: if the file contains invalid ICC APP2 markers, we just silently
234 * return FALSE. You might want to issue an error message instead.
235 */
236
237boolean
238read_icc_profile (j_decompress_ptr cinfo,
239 JOCTET **icc_data_ptr,
240 unsigned int *icc_data_len)
241{
242 int num_markers = 0;
243#define MAX_SEQ_NO 255 /* sufficient since marker numbers are bytes */
244 char marker_present[MAX_SEQ_NO+1]; /* 1 if marker found */
245 unsigned int data_length[MAX_SEQ_NO+1]; /* size of profile data in marker */
246 unsigned int data_offset[MAX_SEQ_NO+1]; /* offset for data in marker */
247
248 *icc_data_ptr = NULL; /* avoid confusion if FALSE return */
249 *icc_data_len = 0;
250
251 /* This first pass over the saved markers discovers whether there are
252 * any ICC markers and verifies the consistency of the marker numbering.
253 */
254
255 for(int seq_no = 1; seq_no <= MAX_SEQ_NO; seq_no++)
256 marker_present[seq_no] = 0;
257
258 for(jpeg_saved_marker_ptr marker = cinfo->marker_list; !IS_NULL_PTR(marker); marker = marker->next)
259 {
260 if(marker_is_icc(marker))
261 {
262 if(num_markers == 0)
263 num_markers = GETJOCTET(marker->data[13]);
264 else if(num_markers != GETJOCTET(marker->data[13]))
265 return FALSE; /* inconsistent num_markers fields */
266 const int seq_no = GETJOCTET(marker->data[12]);
267 if(seq_no <= 0 || seq_no > num_markers)
268 return FALSE; /* bogus sequence number */
269 if(marker_present[seq_no])
270 return FALSE; /* duplicate sequence numbers */
271 marker_present[seq_no] = 1;
272 data_length[seq_no] = marker->data_length - ICC_OVERHEAD_LEN;
273 }
274 }
275
276 if(num_markers == 0)
277 return FALSE;
278
279 /* Check for missing markers, count total space needed,
280 * compute offset of each marker's part of the data.
281 */
282
283 unsigned int total_length = 0;
284 for(int seq_no = 1; seq_no <= num_markers; seq_no++)
285 {
286 if(marker_present[seq_no] == 0)
287 return FALSE; /* missing sequence number */
288 data_offset[seq_no] = total_length;
289 total_length += data_length[seq_no];
290 }
291
292 if(total_length <= 0)
293 return FALSE; /* found only empty markers? */
294
295 /* Allocate space for assembled data */
296 JOCTET *icc_data = (JOCTET *)calloc(total_length, sizeof(JOCTET));
297 if(IS_NULL_PTR(icc_data))
298 return FALSE; /* oops, out of memory */
299
300 /* and fill it in */
301 for(jpeg_saved_marker_ptr marker = cinfo->marker_list; !IS_NULL_PTR(marker); marker = marker->next)
302 {
303 if(marker_is_icc(marker))
304 {
305 const int seq_no = GETJOCTET(marker->data[12]);
306 JOCTET *dst_ptr = icc_data + data_offset[seq_no];
307 JOCTET FAR *src_ptr = marker->data + ICC_OVERHEAD_LEN;
308 unsigned int length = data_length[seq_no];
309 while (length--)
310 {
311 *dst_ptr++ = *src_ptr++;
312 }
313 }
314 }
315
316 *icc_data_ptr = icc_data;
317 *icc_data_len = total_length;
318
319 return TRUE;
320}
321#endif
322#undef ICC_MARKER
323#undef ICC_OVERHEAD_LEN
324#undef MAX_BYTES_IN_MARKER
325#undef MAX_DATA_BYTES_IN_MARKER
326#undef MAX_SEQ_NO
327
328
329int write_image(dt_imageio_module_data_t *jpg_tmp, const char *filename, const void *in_tmp,
330 dt_colorspaces_color_profile_type_t over_type, const char *over_filename,
331 void *exif, int exif_len, int32_t imgid, int num, int total, struct dt_dev_pixelpipe_t *pipe,
332 const gboolean export_masks)
333{
334 dt_imageio_jpeg_t *jpg = (dt_imageio_jpeg_t *)jpg_tmp;
335 const uint8_t *in = (const uint8_t *)in_tmp;
336 struct dt_imageio_jpeg_error_mgr jerr;
337
338 jpg->cinfo.err = jpeg_std_error(&jerr.pub);
339 jerr.pub.error_exit = dt_imageio_jpeg_error_exit;
340 if(setjmp(jerr.setjmp_buffer))
341 {
342 jpeg_destroy_compress(&(jpg->cinfo));
343 return 1;
344 }
345 jpeg_create_compress(&(jpg->cinfo));
346 FILE *f = g_fopen(filename, "wb");
347 if(IS_NULL_PTR(f)) return 1;
348 jpeg_stdio_dest(&(jpg->cinfo), f);
349
350 jpg->cinfo.image_width = jpg->global.width;
351 jpg->cinfo.image_height = jpg->global.height;
352 jpg->cinfo.input_components = 3;
353 jpg->cinfo.in_color_space = JCS_RGB;
354 jpeg_set_defaults(&(jpg->cinfo));
355 jpeg_set_quality(&(jpg->cinfo), jpg->quality, TRUE);
356 if(jpg->quality > 90) jpg->cinfo.comp_info[0].v_samp_factor = 1;
357 if(jpg->quality > 92) jpg->cinfo.comp_info[0].h_samp_factor = 1;
358 if(jpg->quality > 95) jpg->cinfo.dct_method = JDCT_FLOAT;
359 if(jpg->quality < 50) jpg->cinfo.dct_method = JDCT_IFAST;
360 if(jpg->quality < 80) jpg->cinfo.smoothing_factor = 20;
361 if(jpg->quality < 60) jpg->cinfo.smoothing_factor = 40;
362 if(jpg->quality < 40) jpg->cinfo.smoothing_factor = 60;
363 jpg->cinfo.optimize_coding = 1;
364
365 const int resolution = dt_conf_get_int("metadata/resolution");
366 jpg->cinfo.density_unit = 1;
367 jpg->cinfo.X_density = resolution;
368 jpg->cinfo.Y_density = resolution;
369
370 jpeg_start_compress(&(jpg->cinfo), TRUE);
371
372 cmsHPROFILE out_profile = dt_colorspaces_get_output_profile(imgid, &over_type, over_filename)->profile;
373 uint32_t len = 0;
374 cmsSaveProfileToMem(out_profile, NULL, &len);
375 if(len > 0)
376 {
377 unsigned char *buf = malloc(sizeof(unsigned char) * len);
378 if(buf)
379 {
380 cmsSaveProfileToMem(out_profile, buf, &len);
381 write_icc_profile(&(jpg->cinfo), buf, len);
382 dt_free(buf);
383 }
384 }
385
386 uint8_t *row = dt_pixelpipe_cache_alloc_align_cache(sizeof(uint8_t) * 3 * jpg->global.width, 0);
387 const uint8_t *buf;
388 while(row && jpg->cinfo.next_scanline < jpg->cinfo.image_height)
389 {
390 JSAMPROW tmp[1];
391 buf = in + (size_t)jpg->cinfo.next_scanline * jpg->cinfo.image_width * 4;
392 for(int i = 0; i < jpg->global.width; i++)
393 for(int k = 0; k < 3; k++) row[3 * i + k] = buf[4 * i + k];
394 tmp[0] = row;
395 jpeg_write_scanlines(&(jpg->cinfo), tmp, 1);
396 }
397 jpeg_finish_compress(&(jpg->cinfo));
399 jpeg_destroy_compress(&(jpg->cinfo));
400 fclose(f);
401
402 dt_exif_write_blob(exif, exif_len, filename, 1);
403
404 return 0;
405}
406
407static int __attribute__((__unused__)) read_header(const char *filename, dt_imageio_jpeg_t *jpg)
408{
409 jpg->f = g_fopen(filename, "rb");
410 if(IS_NULL_PTR(jpg->f)) return 1;
411
412 struct dt_imageio_jpeg_error_mgr jerr;
413 jpg->dinfo.err = jpeg_std_error(&jerr.pub);
414 jerr.pub.error_exit = dt_imageio_jpeg_error_exit;
415 if(setjmp(jerr.setjmp_buffer))
416 {
417 jpeg_destroy_decompress(&(jpg->dinfo));
418 fclose(jpg->f);
419 return 1;
420 }
421 jpeg_create_decompress(&(jpg->dinfo));
422 jpeg_stdio_src(&(jpg->dinfo), jpg->f);
423 // jpg->dinfo.buffered_image = TRUE;
424 jpeg_read_header(&(jpg->dinfo), TRUE);
425 jpg->global.width = jpg->dinfo.image_width;
426 jpg->global.height = jpg->dinfo.image_height;
427 return 0;
428}
429
431{
432 dt_imageio_jpeg_t *jpg = (dt_imageio_jpeg_t *)jpg_tmp;
433 struct dt_imageio_jpeg_error_mgr jerr;
434 jpg->dinfo.err = jpeg_std_error(&jerr.pub);
435 jerr.pub.error_exit = dt_imageio_jpeg_error_exit;
436 if(setjmp(jerr.setjmp_buffer))
437 {
438 jpeg_destroy_decompress(&(jpg->dinfo));
439 fclose(jpg->f);
440 return 1;
441 }
442 (void)jpeg_start_decompress(&(jpg->dinfo));
443 JSAMPROW row_pointer[1];
444 row_pointer[0] = (uint8_t *)dt_pixelpipe_cache_alloc_align_cache(
445 (size_t)jpg->dinfo.output_width * jpg->dinfo.num_components, 0);
446 uint8_t *tmp = out;
447 while(row_pointer[0] && jpg->dinfo.output_scanline < jpg->dinfo.image_height)
448 {
449 if(jpeg_read_scanlines(&(jpg->dinfo), row_pointer, 1) != 1) return 1;
450 if(jpg->dinfo.num_components < 3)
451 for(JDIMENSION i = 0; i < jpg->dinfo.image_width; i++)
452 for(int k = 0; k < 3; k++) tmp[4 * i + k] = row_pointer[0][jpg->dinfo.num_components * i + 0];
453 else
454 for(JDIMENSION i = 0; i < jpg->dinfo.image_width; i++)
455 for(int k = 0; k < 3; k++) tmp[4 * i + k] = row_pointer[0][3 * i + k];
456 tmp += 4 * jpg->global.width;
457 }
458 if(setjmp(jerr.setjmp_buffer))
459 {
460 jpeg_destroy_decompress(&(jpg->dinfo));
461 dt_pixelpipe_cache_free_align(row_pointer[0]);
462 fclose(jpg->f);
463 return 1;
464 }
465 (void)jpeg_finish_decompress(&(jpg->dinfo));
466 jpeg_destroy_decompress(&(jpg->dinfo));
467 dt_pixelpipe_cache_free_align(row_pointer[0]);
468 fclose(jpg->f);
469 return 0;
470}
471
473{
474 return sizeof(dt_imageio_module_data_t) + sizeof(int);
475}
476
477void *legacy_params(dt_imageio_module_format_t *self, const void *const old_params,
478 const size_t old_params_size, const int old_version, const int new_version,
479 size_t *new_size)
480{
481 if(old_version == 1 && new_version == 2)
482 {
483 typedef struct dt_imageio_jpeg_v1_t
484 {
485 int max_width, max_height;
486 int width, height;
487 char style[128];
488 int quality;
489 struct jpeg_source_mgr src;
490 struct jpeg_destination_mgr dest;
491 struct jpeg_decompress_struct dinfo;
492 struct jpeg_compress_struct cinfo;
493 FILE *f;
494 } dt_imageio_jpeg_v1_t;
495
496 const dt_imageio_jpeg_v1_t *o = (dt_imageio_jpeg_v1_t *)old_params;
498
499 n->global.max_width = o->max_width;
500 n->global.max_height = o->max_height;
501 n->global.width = o->width;
502 n->global.height = o->height;
503 g_strlcpy(n->global.style, o->style, sizeof(o->style));
504 n->quality = o->quality;
505 n->src = o->src;
506 n->dest = o->dest;
507 n->dinfo = o->dinfo;
508 n->cinfo = o->cinfo;
509 n->f = o->f;
510 *new_size = self->params_size(self);
511 return n;
512 }
513 return NULL;
514}
515
517{
518 // adjust this if more params are stored (subsampling etc)
520 d->quality = dt_conf_get_int("plugins/imageio/format/jpeg/quality");
521 if(d->quality <= 0 || d->quality > 100) d->quality = 100;
522 return d;
523}
524
526{
527 dt_free(params);
528}
529
530int set_params(dt_imageio_module_format_t *self, const void *params, const int size)
531{
532 if(size != self->params_size(self)) return 1;
533 const dt_imageio_jpeg_t *d = (dt_imageio_jpeg_t *)params;
535 dt_bauhaus_slider_set(g->quality, d->quality);
536 return 0;
537}
538
540{
541 return 8;
542}
543
548
550{
551 return "image/jpeg";
552}
553
555{
556 return "jpg";
557}
558
563
565{
566}
567
571
572// =============================================================================
573// gui stuff:
574// =============================================================================
575
576const char *name()
577{
578 return _("JPEG (8-bit)");
579}
580
581static void quality_changed(GtkWidget *slider, gpointer user_data)
582{
583 const int quality = (int)dt_bauhaus_slider_get(slider);
584 dt_conf_set_int("plugins/imageio/format/jpeg/quality", quality);
585}
586
588{
590 self->gui_data = g;
591 // construct gui with jpeg specific options:
592 GtkWidget *box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, DT_GUI_BOX_SPACING);
593 self->widget = box;
594 // quality slider
596 dt_confgen_get_int("plugins/imageio/format/jpeg/quality", DT_MIN),
597 dt_confgen_get_int("plugins/imageio/format/jpeg/quality", DT_MAX),
598 1,
599 dt_confgen_get_int("plugins/imageio/format/jpeg/quality", DT_DEFAULT),
600 0);
601 dt_bauhaus_widget_set_label(g->quality, N_("quality"));
602 dt_bauhaus_slider_set_default(g->quality, dt_confgen_get_int("plugins/imageio/format/jpeg/quality", DT_DEFAULT));
603 dt_bauhaus_slider_set(g->quality, dt_conf_get_int("plugins/imageio/format/jpeg/quality"));
604 gtk_box_pack_start(GTK_BOX(box), GTK_WIDGET(g->quality), TRUE, TRUE, 0);
605 g_signal_connect(G_OBJECT(g->quality), "value-changed", G_CALLBACK(quality_changed), NULL);
606 // TODO: add more options: subsample dreggn
607}
608
610{
611 dt_free(self->gui_data);
612}
613
615{
617 dt_bauhaus_slider_set(g->quality, dt_confgen_get_int("plugins/imageio/format/jpeg/quality", DT_DEFAULT));
618}
619
620// clang-format off
621// modelines: These editor modelines have been set for all relevant files by tools/update_modelines.py
622// vim: shiftwidth=2 expandtab tabstop=2 cindent
623// kate: tab-indents: off; indent-width 2; replace-tabs on; indent-mode cstyle; remove-trailing-spaces modified;
624// 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:1491
float dt_bauhaus_slider_get(GtkWidget *widget)
Definition bauhaus.c:3280
void dt_bauhaus_slider_set(GtkWidget *widget, float pos)
Definition bauhaus.c:3331
void dt_bauhaus_widget_set_label(GtkWidget *widget, const char *label)
Definition bauhaus.c:1504
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:1632
typedef void((*dt_cache_allocate_t)(void *userdata, dt_cache_entry_t *entry))
const float f
The colour-profile module's API: which profiles exist, and how to apply one.
struct _GtkWidget GtkWidget
GtkWidget, opaque, spelled exactly as GTK spells it.
Definition colorspaces.h:98
const dt_colormatrix_t dt_aligned_pixel_t out
static const int row
void dt_conf_set_int(const char *name, int val)
int dt_conf_get_int(const char *name)
Integer for name, clamped to the bounds declared in the XML.
int dt_confgen_get_int(const char *name, dt_confgen_value_kind_t kind)
@ DT_DEFAULT
Definition conf.h:135
@ DT_MAX
Definition conf.h:137
@ DT_MIN
Definition conf.h:136
struct dt_bauhaus_t * dt_bauhaus_get_global(void)
Definition darktable.c:646
int dt_exif_write_blob(uint8_t *blob, uint32_t size, const char *path, const int compressed)
Definition exif.cc:2057
What a photograph says about itself: the EXIF, IPTC and XMP tags a camera and a cataloguer write,...
#define DT_GUI_MODULE(x)
int bpp
@ IMAGEIO_RGB
@ IMAGEIO_INT8
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:44
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)
const char * mime(dt_imageio_module_data_t *data)
Definition jpeg.c:549
size_t params_size(dt_imageio_module_format_t *self)
Definition jpeg.c:472
struct dt_imageio_jpeg_error_mgr dt_imageio_jpeg_error_mgr
struct dt_imageio_jpeg_t dt_imageio_jpeg_t
#define ICC_MARKER
Definition jpeg.c:114
void gui_reset(dt_imageio_module_format_t *self)
Definition jpeg.c:614
static void dt_imageio_jpeg_error_exit(j_common_ptr cinfo)
Definition jpeg.c:94
void gui_init(dt_imageio_module_format_t *self)
Definition jpeg.c:587
const char * extension(dt_imageio_module_data_t *data)
Definition jpeg.c:554
int read_image(dt_imageio_module_data_t *jpg_tmp, uint8_t *out)
Definition jpeg.c:430
int set_params(dt_imageio_module_format_t *self, const void *params, const int size)
Definition jpeg.c:530
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:329
const char * name()
Definition jpeg.c:576
void cleanup(dt_imageio_module_format_t *self)
Definition jpeg.c:568
int levels(dt_imageio_module_data_t *p)
Definition jpeg.c:544
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:477
void free_params(dt_imageio_module_format_t *self, dt_imageio_module_data_t *params)
Definition jpeg.c:525
struct dt_imageio_jpeg_error_mgr * dt_imageio_jpeg_error_ptr
Definition jpeg.c:92
void init(dt_imageio_module_format_t *self)
Definition jpeg.c:564
void * get_params(dt_imageio_module_format_t *self)
Definition jpeg.c:516
static void write_icc_profile(j_compress_ptr cinfo, const JOCTET *icc_data_ptr, unsigned int icc_data_len)
Definition jpeg.c:128
void gui_cleanup(dt_imageio_module_format_t *self)
Definition jpeg.c:609
#define MAX_DATA_BYTES_IN_MARKER
Definition jpeg.c:117
static void quality_changed(GtkWidget *slider, gpointer user_data)
Definition jpeg.c:581
#define ICC_OVERHEAD_LEN
Definition jpeg.c:115
float *const restrict const size_t k
#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 macros.h:96
#define dt_free(ptr)
g_free() ptr and set it to NULL, skipping both if it is already NULL.
Definition mem_alloc.h:171
uint32_t width
Definition mipmap_cache.c:0
uint32_t height
Definition mipmap_cache.c:1
size_t size
Definition mipmap_cache.c:3
dt_mipmap_buffer_dsc_flags flags
Definition mipmap_cache.c:4
#define DT_MODULE(MODVER)
Instantiate the version handshake every module must export. Use once, at file scope,...
#define dt_pixelpipe_cache_alloc_align_cache(size, id)
#define dt_pixelpipe_cache_free_align(mem)
dt_colorspaces_color_profile_type_t
float dt_aligned_pixel_simd_t __attribute__((vector_size(16), aligned(16)))
Apply one channel's tone curve to each of the three colour channels, or pass the channel through unto...
Definition simd.h:55
cmsHPROFILE profile
the actual profile; NULL for the three category entries
struct jpeg_error_mgr pub
Definition jpeg.c:88
GtkWidget * quality
Definition jpeg.c:81
struct jpeg_decompress_struct dinfo
Definition jpeg.c:74
dt_imageio_module_data_t global
Definition jpeg.c:70
struct jpeg_compress_struct cinfo
Definition jpeg.c:75
GModule *GtkWidget * widget
#define DT_GUI_BOX_SPACING