1 /*
2     This file is part of darktable,
3     Copyright (C) 2014-2020 darktable developers.
4 
5     darktable is free software: you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation, either version 3 of the License, or
8     (at your option) any later version.
9 
10     darktable is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14 
15     You should have received a copy of the GNU General Public License
16     along with darktable.  If not, see <http://www.gnu.org/licenses/>.
17 */
18 
19 #include "common/printprof.h"
20 #include "common/colorspaces.h"
21 #include "lcms2.h"
22 #include <glib.h>
23 #include <unistd.h>
24 
ComputeOutputFormatDescriptor(cmsUInt32Number dwInput,int OutColorSpace,int bps)25 static cmsUInt32Number ComputeOutputFormatDescriptor (cmsUInt32Number dwInput, int OutColorSpace, int bps)
26 {
27     int IsPlanar  = T_PLANAR(dwInput);
28     int Channels  = 3;
29     int IsFlt     = 0;
30     return (FLOAT_SH(IsFlt)|COLORSPACE_SH(OutColorSpace)|PLANAR_SH(IsPlanar)|CHANNELS_SH(Channels)|BYTES_SH(bps));
31 }
32 
ComputeFormatDescriptor(int OutColorSpace,int bps)33 static cmsUInt32Number ComputeFormatDescriptor (int OutColorSpace, int bps)
34 {
35   int IsPlanar  = 0;
36   int Channels  = 3;
37   int IsFlt = 0;
38   return (FLOAT_SH(IsFlt)|COLORSPACE_SH(OutColorSpace)|PLANAR_SH(IsPlanar)|CHANNELS_SH(Channels)|BYTES_SH(bps));
39 }
40 
dt_apply_printer_profile(void ** in,uint32_t width,uint32_t height,int bpp,cmsHPROFILE hInProfile,cmsHPROFILE hOutProfile,int intent,gboolean black_point_compensation)41 int dt_apply_printer_profile(void **in, uint32_t width, uint32_t height, int bpp, cmsHPROFILE hInProfile,
42                              cmsHPROFILE hOutProfile, int intent, gboolean black_point_compensation)
43 {
44   cmsHTRANSFORM hTransform;
45   cmsUInt32Number wInput, wOutput;
46   int OutputColorSpace;
47 
48   if(!hOutProfile || !hInProfile)
49     return 1;
50 
51   wInput = ComputeFormatDescriptor (PT_RGB, (bpp==8?1:2));
52 
53   OutputColorSpace = _cmsLCMScolorSpace(cmsGetColorSpace(hOutProfile));
54   wOutput = ComputeOutputFormatDescriptor(wInput, OutputColorSpace, 1);
55 
56   hTransform = cmsCreateTransform
57     (hInProfile,  wInput,
58      hOutProfile, wOutput,
59      intent,
60      black_point_compensation ? cmsFLAGS_BLACKPOINTCOMPENSATION : 0);
61 
62   if (!hTransform)
63   {
64     fprintf(stderr, "error printer profile may be corrupted\n");
65     return 1;
66   }
67 
68   void *out = (void *)malloc((size_t)3 * width * height);
69 
70   if (bpp == 8)
71   {
72     const uint8_t *ptr_in = (uint8_t *)*in;
73     uint8_t *ptr_out = (uint8_t *)out;
74 
75 #ifdef _OPENMP
76 #pragma omp parallel for schedule(static) default(none) shared(ptr_in, ptr_out, hTransform, height, width)
77 #endif
78     for (int k=0; k<height; k++)
79       cmsDoTransform(hTransform, (const void *)&ptr_in[k*width*3], (void *)&ptr_out[k*width*3], width);
80   }
81   else
82   {
83     const uint16_t *ptr_in = (uint16_t *)*in;
84     uint8_t *ptr_out = (uint8_t *)out;
85 
86 #ifdef _OPENMP
87 #pragma omp parallel for schedule(static) default(none) shared(ptr_in, ptr_out, hTransform, height, width)
88 #endif
89     for (int k=0; k<height; k++)
90       cmsDoTransform(hTransform, (const void *)&ptr_in[k*width*3], (void *)&ptr_out[k*width*3], width);
91   }
92 
93   cmsDeleteTransform(hTransform);
94 
95   free(*in);
96   *in = out;
97 
98   return 0;
99 }
100 
101 // modelines: These editor modelines have been set for all relevant files by tools/update_modelines.sh
102 // vim: shiftwidth=2 expandtab tabstop=2 cindent
103 // kate: tab-indents: off; indent-width 2; replace-tabs on; indent-mode cstyle; remove-trailing-spaces modified;
104