Color Management, Stage 2: Switch color pipeline to use OpenColorIO
[blender.git] / source / blender / imbuf / intern / cineon / cineon_dpx.c
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) 2001-2002 by NaN Holding BV.
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s): none yet.
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  * cineon.c
27  * contributors: joeedh
28  * I hearby donate this code and all rights to the Blender Foundation.
29  */
30
31 /** \file blender/imbuf/intern/cineon/cineon_dpx.c
32  *  \ingroup imbcineon
33  */
34
35  
36 #include <stdio.h>
37 #include <string.h> /*for memcpy*/
38
39 #include "logImageLib.h"
40 #include "cineonlib.h"
41 #include "dpxlib.h"
42
43 #include "IMB_imbuf_types.h"
44 #include "IMB_imbuf.h"
45 #include "IMB_filetype.h"
46
47 #include "IMB_colormanagement.h"
48 #include "IMB_colormanagement_intern.h"
49
50 #include "BKE_global.h"
51
52 #include "MEM_guardedalloc.h"
53
54 #if 0
55 static void cineon_conversion_parameters(LogImageByteConversionParameters *params)
56 {
57 //      params->blackPoint = scene?scene->r.cineonblack:95;
58 //      params->whitePoint = scene?scene->r.cineonwhite:685;
59 //      params->gamma = scene?scene->r.cineongamma:1.7f;
60 //      params->doLogarithm = scene?scene->r.subimtype & R_CINEON_LOG:0;
61         
62         params->blackPoint = 95;
63         params->whitePoint = 685;
64         params->gamma = 1.0f;
65         params->doLogarithm = 0;
66 }
67 #endif
68
69 static ImBuf *imb_load_dpx_cineon(unsigned char *mem, int use_cineon, int size, int flags, char colorspace[IM_MAX_SPACE])
70 {
71         ImBuf *ibuf;
72         LogImageFile *image;
73         int x, y;
74         unsigned short *row, *upix;
75         int width, height, depth;
76         float *frow;
77
78         colorspace_set_default_role(colorspace, IM_MAX_SPACE, COLOR_ROLE_DEFAULT_FLOAT);
79
80         logImageSetVerbose((G.debug & G_DEBUG) ? 1:0);
81         
82         image = logImageOpenFromMem(mem, size, use_cineon);
83         
84         if (!image) {
85                 printf("no image!\n");
86                 return NULL;
87         }
88         
89         logImageGetSize(image, &width, &height, &depth);
90         
91         if (depth != 3) { /*need to do grayscale loading eventually.*/
92                 logImageClose(image);
93                 return NULL;
94         }
95         
96         if (width == 0 && height == 0) {
97                 logImageClose(image);
98                 return NULL;
99         }
100         
101         ibuf = IMB_allocImBuf(width, height, 32, IB_rectfloat | flags);
102
103         row = MEM_mallocN(sizeof(unsigned short)*width*depth, "row in cineon_dpx.c");
104         frow = ibuf->rect_float+width*height*4;
105         
106         for (y = 0; y < height; y++) {
107                 logImageGetRowBytes(image, row, y); /* checks image->params.doLogarithm and convert */
108                 upix = row;
109                 frow -= width*4;
110                 
111                 for (x=0; x<width; x++) {
112                         *(frow++) = ((float)*(upix++)) / 65535.0f;
113                         *(frow++) = ((float)*(upix++)) / 65535.0f;
114                         *(frow++) = ((float)*(upix++)) / 65535.0f;
115                         *(frow++) = 1.0f;
116                 }
117                 frow -= width*4;
118         }
119
120         MEM_freeN(row);
121         logImageClose(image);
122         
123         if (flags & IB_rect) {
124                 IMB_rect_from_float(ibuf);
125         }
126         return ibuf;
127 }
128
129 static int imb_save_dpx_cineon(ImBuf *ibuf, const char *filename, int use_cineon, int flags)
130 {
131         LogImageByteConversionParameters conversion;
132         const int width= ibuf->x;
133         const int height= ibuf->y;
134         const int depth= 3;
135         LogImageFile* logImage;
136         unsigned short* line, *pixel;
137         int i, j;
138         float *fline;
139         float *fbuf;
140         int is_alloc= 0;
141         
142         (void)flags; /* unused */
143
144         // cineon_conversion_parameters(&conversion);
145         logImageGetByteConversionDefaults(&conversion);
146
147         /*
148          * Get the drawable for the current image...
149          */
150
151         fbuf= IMB_float_profile_ensure(ibuf, conversion.doLogarithm ? IB_PROFILE_LINEAR_RGB : IB_PROFILE_NONE, &is_alloc);
152
153         if (fbuf == NULL) { /* in the unlikely event that converting to a float buffer fails */
154                 return 0;
155         }
156         
157         logImageSetVerbose((G.debug & G_DEBUG) ? 1:0);
158         logImage = logImageCreate(filename, use_cineon, width, height, depth);
159
160         if (!logImage) return 0;
161         
162         if (logImageSetByteConversion(logImage, &conversion)==0) {
163                 printf("error setting args\n");
164         }
165
166         line = MEM_mallocN(sizeof(unsigned short)*depth*width, "line");
167         
168         /*note that image is flipped when sent to logImageSetRowBytes (see last passed parameter).*/
169         for (j = 0; j < height; ++j) {
170                 fline = &fbuf[width*j*4];
171                 for (i=0; i<width; i++) {
172                         float *fpix, fpix2[3];
173                         /*we have to convert to cinepaint's 16-bit-per-channel here*/
174                         pixel = &line[i*depth];
175                         fpix = &fline[i*4];
176                         memcpy(fpix2, fpix, sizeof(float)*3);
177                         
178                         if (fpix2[0]>=1.0f) fpix2[0] = 1.0f; else if (fpix2[0]<0.0f) fpix2[0]= 0.0f;
179                         if (fpix2[1]>=1.0f) fpix2[1] = 1.0f; else if (fpix2[1]<0.0f) fpix2[1]= 0.0f;
180                         if (fpix2[2]>=1.0f) fpix2[2] = 1.0f; else if (fpix2[2]<0.0f) fpix2[2]= 0.0f;
181                         
182                         pixel[0] = (unsigned short)(fpix2[0] * 65535.0f); /*float-float math is faster*/
183                         pixel[1] = (unsigned short)(fpix2[1] * 65535.0f);
184                         pixel[2] = (unsigned short)(fpix2[2] * 65535.0f);
185                 }
186                 logImageSetRowBytes(logImage, (const unsigned short*)line, height-1-j);
187         }
188         logImageClose(logImage);
189
190         MEM_freeN(line);
191         
192         if (is_alloc) {
193                 MEM_freeN(fbuf);
194         }
195         
196         return 1;
197 }
198
199 int imb_savecineon(struct ImBuf *buf, const char *myfile, int flags)
200 {
201         return imb_save_dpx_cineon(buf, myfile, 1, flags);
202 }
203
204  
205 int imb_is_cineon(unsigned char *buf)
206 {
207         return cineonIsMemFileCineon(buf);
208 }
209
210 ImBuf *imb_loadcineon(unsigned char *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE])
211 {
212         if (imb_is_cineon(mem))
213                 return imb_load_dpx_cineon(mem, 1, size, flags, colorspace);
214         return NULL;
215 }
216
217 int imb_save_dpx(struct ImBuf *buf, const char *myfile, int flags)
218 {
219         return imb_save_dpx_cineon(buf, myfile, 0, flags);
220 }
221
222 int imb_is_dpx(unsigned char *buf)
223 {
224         return dpxIsMemFileCineon(buf);
225 }
226
227 ImBuf *imb_loaddpx(unsigned char *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE])
228 {
229         if (imb_is_dpx(mem))
230                 return imb_load_dpx_cineon(mem, 0, size, flags, colorspace);
231         return NULL;
232 }