![]() |
Ansel 0.0
A darktable fork - bloat + design vision
|
#include "system/macros.h"#include "system/mem_alloc.h"#include "system/openmp.h"#include "colorprofiles/printprof.h"#include "lcms2.h"#include <glib.h>
Include dependency graph for printprof.c:Go to the source code of this file.
Functions | |
| static cmsUInt32Number | ComputeOutputFormatDescriptor (cmsUInt32Number dwInput, int OutColorSpace, int bps) |
| static cmsUInt32Number | ComputeFormatDescriptor (int OutColorSpace, int bps) |
| int | dt_apply_printer_profile (void **in, uint32_t width, uint32_t height, int bpp, cmsHPROFILE hInProfile, cmsHPROFILE hOutProfile, int intent, gboolean black_point_compensation) |
Convert an interleaved RGB buffer from hInProfile to hOutProfile, replacing the caller's buffer with a freshly allocated 8 bpp result. | |
|
static |
Definition at line 39 of file printprof.c.
Referenced by dt_apply_printer_profile().
|
static |
Definition at line 31 of file printprof.c.
Referenced by dt_apply_printer_profile().
| int dt_apply_printer_profile | ( | void ** | in, |
| uint32_t | width, | ||
| uint32_t | height, | ||
| int | bpp, | ||
| cmsHPROFILE | hInProfile, | ||
| cmsHPROFILE | hOutProfile, | ||
| int | intent, | ||
| gboolean | black_point_compensation | ||
| ) |
Convert an interleaved RGB buffer from hInProfile to hOutProfile, replacing the caller's buffer with a freshly allocated 8 bpp result.
Builds a one-shot transform (RGB in, bpp == 8 ? 1 : 2 bytes per channel; always 1 byte per channel out), runs it one image row per cmsDoTransform() call over an OpenMP-parallel row loop, then destroys the transform. On success the incoming buffer is released and in is repointed at the result.
The routine takes an image of 8 or 16 bpp but always returns an 8 bpp result. It is indeed better to apply the profile to a 16-bit input, but we do not need more than 8 bits out for printing — and the caller relies on exactly that: _export_image() exports at 16 bpp precisely when a printer profile is to be applied, at 8 bpp otherwise, and in both cases the buffer that reaches the PDF is 8 bpp.
The output colour space is read from the printer profile (cmsGetColorSpace()), but the channel count and the byte count of the output format descriptor are hard-coded to 3 and 1, and the destination buffer is sized 3 * width * height to match. Only three-channel, RGB-like printer profiles are therefore handled. Planarity is inherited from the input descriptor, which is always interleaved, so the result is always interleaved too.
Both handles are BORROWED for the duration of the call: neither is closed, duplicated nor retained. lcms2 has no cmsDupProfile() and a transform does not keep a reference to its source profiles, so the handles only have to stay valid until cmsCreateTransform() returns — which happens inside this call.
No lock is taken here. A caller passing a handle that belongs to the application-wide profile list must hold dt_colorspaces_lock_profiles() across the call, because the DT_COLORSPACE_DISPLAY entry's handle can be closed and replaced underneath it.
Thread: the print job is queued on DT_JOB_QUEUE_USER_EXPORT, so this runs on an export worker thread and never on the GUI thread. Inside the call, the single transform handle is shared by every OpenMP thread of the row loop; no cmsFLAGS_NOCACHE is requested.
| in | In/out. On entry, the caller's interleaved RGB buffer of width × height pixels at bpp bits per channel. On success, the old buffer is freed with dt_free() and *in is overwritten with a newly allocated 3 * width * height byte buffer that the caller then owns (the sole caller releases it with dt_free()). On failure *in is left exactly as it was and still belongs to the caller. |
| width | Image width in pixels. |
| height | Image height in pixels. |
| bpp | Bits per channel of the input buffer: 8 or 16. Anything that is not exactly 8 is treated as 16. |
| hInProfile | Source profile — the profile the input buffer is already encoded in. |
| hOutProfile | Destination (printer) profile. |
| intent | Rendering intent, passed straight to cmsCreateTransform() with no translation. dt_iop_color_intent_t and the lcms2 INTENT_* macros share their numeric values (perceptual 0, relative colorimetric 1, saturation 2, absolute colorimetric 3), which is why either spelling works and why introducing a value in one of them alone would silently mean something else here. |
| black_point_compensation | TRUE adds cmsFLAGS_BLACKPOINTCOMPENSATION to the transform; nothing else about the conversion changes. |
cmsCreateTransform() returning NULL (reported on stderr as "error printer profile may be
corrupted"). Both failure paths return before the buffer is touched. g_free() — while the replacement comes from plain malloc(). The sole caller likewise allocates the incoming buffer with malloc() and releases the result with dt_free(), so the two allocators are used interchangeably all along this path. Definition at line 47 of file printprof.c.
References __OMP_PARALLEL_FOR__, bpp, ComputeFormatDescriptor(), ComputeOutputFormatDescriptor(), dt_free, height, IS_NULL_PTR, k, out, and width.
Referenced by _export_image().