Color Management: don't apply display transform on Non-Color images
[blender.git] / intern / opencolorio / ocio_capi_stub.cpp
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2012 Blender Foundation.
19  * All rights reserved.
20  *
21  * Contributor(s): Brecht van Lommel
22  *
23  * ***** END GPL LICENSE BLOCK *****
24  */
25
26 #include <string.h>
27
28 #include "MEM_guardedalloc.h"
29 #include "BLI_math_color.h"
30
31 namespace OCIO_NAMESPACE {};
32
33 #include "ocio_capi.h"
34
35 #define CONFIG_DEFAULT           ((ConstConfigRcPtr*)1)
36
37 #define PROCESSOR_LINEAR_TO_SRGB ((ConstProcessorRcPtr*)1)
38 #define PROCESSOR_SRGB_TO_LINEAR ((ConstProcessorRcPtr*)2)
39 #define PROCESSOR_UNKNOWN        ((ConstProcessorRcPtr*)3)
40
41 #define COLORSPACE_LINEAR        ((ConstColorSpaceRcPtr*)1)
42 #define COLORSPACE_SRGB          ((ConstColorSpaceRcPtr*)2)
43
44 typedef struct PackedImageDescription {
45         float *data;
46         long width;
47         long height;
48         long numChannels;
49         long chanStrideBytes;
50         long xStrideBytes;
51         long yStrideBytes;
52 } PackedImageDescription;
53
54 ConstConfigRcPtr *OCIO_getCurrentConfig(void)
55 {
56         return CONFIG_DEFAULT;
57 }
58
59 ConstConfigRcPtr *OCIO_getDefaultConfig(void)
60 {
61         return CONFIG_DEFAULT;
62 }
63
64 void OCIO_setCurrentConfig(const ConstConfigRcPtr *)
65 {
66 }
67
68 ConstConfigRcPtr *OCIO_configCreateFromEnv(void)
69 {
70         return CONFIG_DEFAULT;
71 }
72
73 ConstConfigRcPtr *OCIO_configCreateFromFile(const char *)
74 {
75         return CONFIG_DEFAULT;
76 }
77
78 void OCIO_configRelease(ConstConfigRcPtr *)
79 {
80 }
81
82 int OCIO_configGetNumColorSpaces(ConstConfigRcPtr *)
83 {
84         return 2;
85 }
86
87 const char *OCIO_configGetColorSpaceNameByIndex(ConstConfigRcPtr *, int index)
88 {
89         if (index == 0)
90                 return "Linear";
91         else if (index == 1)
92                 return "sRGB";
93         
94         return NULL;
95 }
96
97 ConstColorSpaceRcPtr *OCIO_configGetColorSpace(ConstConfigRcPtr *, const char *name)
98 {
99         if (strcmp(name, "scene_linear") == 0)
100                 return COLORSPACE_LINEAR;
101         else if (strcmp(name, "color_picking") == 0)
102                 return COLORSPACE_SRGB;
103         else if (strcmp(name, "texture_paint") == 0)
104                 return COLORSPACE_LINEAR;
105         else if (strcmp(name, "default_byte") == 0)
106                 return COLORSPACE_SRGB;
107         else if (strcmp(name, "default_float") == 0)
108                 return COLORSPACE_LINEAR;
109         else if (strcmp(name, "default_sequencer") == 0)
110                 return COLORSPACE_SRGB;
111         else if (strcmp(name, "Linear") == 0)
112                 return COLORSPACE_LINEAR;
113         else if (strcmp(name, "sRGB") == 0)
114                 return COLORSPACE_SRGB;
115
116         return NULL;
117 }
118
119 int OCIO_configGetIndexForColorSpace(ConstConfigRcPtr *config, const char *name)
120 {
121         ConstColorSpaceRcPtr *cs = OCIO_configGetColorSpace(config, name);
122
123         if (cs == COLORSPACE_LINEAR)
124                 return 0;
125         else if (cs == COLORSPACE_SRGB)
126                 return 1;
127
128         return -1;
129 }
130
131 const char *OCIO_configGetDefaultDisplay(ConstConfigRcPtr *)
132 {
133         return "sRGB";
134 }
135
136 int OCIO_configGetNumDisplays(ConstConfigRcPtr* config)
137 {
138         return 1;
139 }
140
141 const char *OCIO_configGetDisplay(ConstConfigRcPtr *, int index)
142 {
143         if (index == 0)
144                 return "sRGB";
145         
146         return NULL;
147 }
148
149 const char *OCIO_configGetDefaultView(ConstConfigRcPtr *, const char *)
150 {
151         return "Default";
152 }
153
154 int OCIO_configGetNumViews(ConstConfigRcPtr *, const char *)
155 {
156         return 1;
157 }
158
159 const char *OCIO_configGetView(ConstConfigRcPtr *, const char *, int index)
160 {
161         if (index == 0)
162                 return "Default";
163
164         return NULL;
165 }
166
167 const char *OCIO_configGetDisplayColorSpaceName(ConstConfigRcPtr *, const char *, const char *)
168 {
169         return "sRGB";
170 }
171
172 int OCIO_colorSpaceIsInvertible(ConstColorSpaceRcPtr *cs)
173 {
174         return 1;
175 }
176
177 int OCIO_colorSpaceIsData(ConstColorSpaceRcPtr *cs)
178 {
179         return 0;
180 }
181
182 void OCIO_colorSpaceRelease(ConstColorSpaceRcPtr *cs)
183 {
184 }
185
186 ConstProcessorRcPtr *OCIO_configGetProcessorWithNames(ConstConfigRcPtr *config, const char *srcName, const char *dstName)
187 {
188         ConstColorSpaceRcPtr *cs_src = OCIO_configGetColorSpace(config, srcName);
189         ConstColorSpaceRcPtr *cs_dst = OCIO_configGetColorSpace(config, dstName);
190
191         if (cs_src == COLORSPACE_LINEAR && cs_dst == COLORSPACE_SRGB)
192                 return PROCESSOR_LINEAR_TO_SRGB;
193         else if (cs_src == COLORSPACE_SRGB && cs_dst == COLORSPACE_LINEAR)
194                 return PROCESSOR_SRGB_TO_LINEAR;
195
196         return 0;
197 }
198
199 ConstProcessorRcPtr *OCIO_configGetProcessor(ConstConfigRcPtr *, ConstTransformRcPtr *tfm)
200 {
201         return (ConstProcessorRcPtr*)tfm;
202 }
203
204 void OCIO_processorApply(ConstProcessorRcPtr *processor, PackedImageDesc *img)
205 {
206         /* OCIO_TODO stride not respected, channels must be 3 or 4 */
207         PackedImageDescription *desc = (PackedImageDescription*)img;
208         int channels = desc->numChannels;
209         float *pixels = desc->data;
210         int width = desc->width;
211         int height = desc->height;
212         int x, y;
213
214         for (y = 0; y < height; y++) {
215                 for (x = 0; x < width; x++) {
216                         float *pixel = pixels + channels * (y * width + x);
217
218                         if (channels == 4)
219                                 OCIO_processorApplyRGBA(processor, pixel);
220                         else if (channels == 3)
221                                 OCIO_processorApplyRGB(processor, pixel);
222                 }
223         }
224 }
225
226 void OCIO_processorApply_predivide(ConstProcessorRcPtr *processor, PackedImageDesc *img)
227 {
228         /* OCIO_TODO stride not respected, channels must be 3 or 4 */
229         PackedImageDescription *desc = (PackedImageDescription*)img;
230         int channels = desc->numChannels;
231         float *pixels = desc->data;
232         int width = desc->width;
233         int height = desc->height;
234         int x, y;
235
236         for (y = 0; y < height; y++) {
237                 for (x = 0; x < width; x++) {
238                         float *pixel = pixels + channels * (y * width + x);
239
240                         if (channels == 4)
241                                 OCIO_processorApplyRGBA_predivide(processor, pixel);
242                         else if (channels == 3)
243                                 OCIO_processorApplyRGB(processor, pixel);
244                 }
245         }
246 }
247
248 void OCIO_processorApplyRGB(ConstProcessorRcPtr *processor, float *pixel)
249 {
250         if (processor == PROCESSOR_LINEAR_TO_SRGB)
251                 linearrgb_to_srgb_v3_v3(pixel, pixel);
252         else if (processor == PROCESSOR_SRGB_TO_LINEAR)
253                 srgb_to_linearrgb_v3_v3(pixel, pixel);
254 }
255
256 void OCIO_processorApplyRGBA(ConstProcessorRcPtr *processor, float *pixel)
257 {
258         if (processor == PROCESSOR_LINEAR_TO_SRGB)
259                 linearrgb_to_srgb_v4(pixel, pixel);
260         else if (processor == PROCESSOR_SRGB_TO_LINEAR)
261                 srgb_to_linearrgb_v4(pixel, pixel);
262 }
263
264 void OCIO_processorApplyRGBA_predivide(ConstProcessorRcPtr *processor, float *pixel)
265 {
266         if (pixel[3] == 1.0f || pixel[3] == 0.0f) {
267                 OCIO_processorApplyRGBA(processor, pixel);
268         }
269         else {
270                 float alpha, inv_alpha;
271
272                 alpha = pixel[3];
273                 inv_alpha = 1.0f / alpha;
274
275                 pixel[0] *= inv_alpha;
276                 pixel[1] *= inv_alpha;
277                 pixel[2] *= inv_alpha;
278
279                 OCIO_processorApplyRGBA(processor, pixel);
280
281                 pixel[0] *= alpha;
282                 pixel[1] *= alpha;
283                 pixel[2] *= alpha;
284         }
285 }
286
287 void OCIO_processorRelease(ConstProcessorRcPtr *)
288 {
289 }
290
291 const char *OCIO_colorSpaceGetName(ConstColorSpaceRcPtr *cs)
292 {
293         if (cs == COLORSPACE_LINEAR)
294                 return "Linear";
295         else if (cs == COLORSPACE_SRGB)
296                 return "sRGB";
297         
298         return NULL;
299 }
300
301 const char *OCIO_colorSpaceGetDescription(ConstColorSpaceRcPtr *)
302 {
303         return "";
304 }
305
306 const char *OCIO_colorSpaceGetFamily(ConstColorSpaceRcPtr *)
307 {
308         return "";
309 }
310
311 DisplayTransformRcPtr *OCIO_createDisplayTransform(void)
312 {
313         return (DisplayTransformRcPtr*)PROCESSOR_LINEAR_TO_SRGB;
314 }
315
316 void OCIO_displayTransformSetInputColorSpaceName(DisplayTransformRcPtr *, const char *)
317 {
318 }
319
320 void OCIO_displayTransformSetDisplay(DisplayTransformRcPtr *, const char *)
321 {
322 }
323
324 void OCIO_displayTransformSetView(DisplayTransformRcPtr *, const char *)
325 {
326 }
327
328 void OCIO_displayTransformSetDisplayCC(DisplayTransformRcPtr *, ConstTransformRcPtr *)
329 {
330 }
331
332 void OCIO_displayTransformSetLinearCC(DisplayTransformRcPtr *, ConstTransformRcPtr *)
333 {
334 }
335
336 void OCIO_displayTransformRelease(DisplayTransformRcPtr *)
337 {
338 }
339
340 PackedImageDesc *OCIO_createPackedImageDesc(float *data, long width, long height, long numChannels,
341                                             long chanStrideBytes, long xStrideBytes, long yStrideBytes)
342 {
343         PackedImageDescription *desc = (PackedImageDescription*)MEM_callocN(sizeof(PackedImageDescription), "PackedImageDescription");
344
345         desc->data = data;
346         desc->width = width;
347         desc->height = height;
348         desc->numChannels = numChannels;
349         desc->chanStrideBytes = chanStrideBytes;
350         desc->xStrideBytes = xStrideBytes;
351         desc->yStrideBytes = yStrideBytes;
352
353         return (PackedImageDesc*)desc;
354 }
355
356 void OCIO_packedImageDescRelease(PackedImageDesc* id)
357 {
358         MEM_freeN(id);
359 }
360
361 ExponentTransformRcPtr *OCIO_createExponentTransform(void)
362 {
363         return (ExponentTransformRcPtr*)PROCESSOR_UNKNOWN;
364 }
365
366 void OCIO_exponentTransformSetValue(ExponentTransformRcPtr *, const float *)
367 {
368 }
369
370 void OCIO_exponentTransformRelease(ExponentTransformRcPtr *)
371 {
372 }
373
374 MatrixTransformRcPtr *OCIO_createMatrixTransform(void)
375 {
376         return (MatrixTransformRcPtr*)PROCESSOR_UNKNOWN;
377 }
378
379 void OCIO_matrixTransformSetValue(MatrixTransformRcPtr *, const float *, const float *)
380 {
381 }
382
383 void OCIO_matrixTransformRelease(MatrixTransformRcPtr *)
384 {
385 }
386
387 void OCIO_matrixTransformScale(float * , float * , const float *)
388 {
389 }
390