Blender  V2.59
cineon_dpx.c
Go to the documentation of this file.
00001 /*
00002  *
00003  * ***** BEGIN GPL LICENSE BLOCK *****
00004  *
00005  * This program is free software; you can redistribute it and/or
00006  * modify it under the terms of the GNU General Public License
00007  * as published by the Free Software Foundation; either version 2
00008  * of the License, or (at your option) any later version. 
00009  *
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  * GNU General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU General Public License
00016  * along with this program; if not, write to the Free Software Foundation,
00017  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00018  *
00019  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
00020  * All rights reserved.
00021  *
00022  * The Original Code is: all of this file.
00023  *
00024  * Contributor(s): none yet.
00025  *
00026  * ***** END GPL LICENSE BLOCK *****
00027  * cineon.c
00028  * contributors: joeedh
00029  * I hearby donate this code and all rights to the Blender Foundation.
00030  * $Id: cineon_dpx.c 36594 2011-05-10 13:11:36Z campbellbarton $
00031  */
00032 
00038 #include <stdio.h>
00039 #include <string.h> /*for memcpy*/
00040 
00041 #include "logImageLib.h"
00042 #include "cineonlib.h"
00043 #include "dpxlib.h"
00044 
00045 #include "IMB_imbuf_types.h"
00046 #include "IMB_imbuf.h"
00047 #include "IMB_filetype.h"
00048 
00049 #include "BKE_global.h"
00050 
00051 #include "MEM_guardedalloc.h"
00052 
00053 #if 0
00054 static void cineon_conversion_parameters(LogImageByteConversionParameters *params)
00055 {
00056 //      params->blackPoint = scene?scene->r.cineonblack:95;
00057 //      params->whitePoint = scene?scene->r.cineonwhite:685;
00058 //      params->gamma = scene?scene->r.cineongamma:1.7f;
00059 //      params->doLogarithm = scene?scene->r.subimtype & R_CINEON_LOG:0;
00060         
00061         params->blackPoint = 95;
00062         params->whitePoint = 685;
00063         params->gamma = 1.0f;
00064         params->doLogarithm = 0;
00065 }
00066 #endif
00067 
00068 static struct ImBuf *imb_load_dpx_cineon(unsigned char *mem, int use_cineon, int size, int flags)
00069 {
00070         ImBuf *ibuf;
00071         LogImageFile *image;
00072         int x, y;
00073         unsigned short *row, *upix;
00074         int width, height, depth;
00075         float *frow;
00076 
00077         logImageSetVerbose((G.f & G_DEBUG) ? 1:0);
00078         
00079         image = logImageOpenFromMem(mem, size, use_cineon);
00080         
00081         if (!image) {
00082                 printf("no image!\n");
00083                 return NULL;
00084         }
00085         
00086         logImageGetSize(image, &width, &height, &depth);
00087         
00088         if (depth != 3) { /*need to do greyscale loading eventually.*/
00089                 logImageClose(image);
00090                 return NULL;
00091         }
00092         
00093         if (width == 0 && height == 0) {
00094                 logImageClose(image);
00095                 return NULL;
00096         }
00097         
00098         ibuf = IMB_allocImBuf(width, height, 32, IB_rectfloat | flags);
00099 
00100         row = MEM_mallocN(sizeof(unsigned short)*width*depth, "row in cineon_dpx.c");
00101         frow = ibuf->rect_float+width*height*4;
00102         
00103         for (y = 0; y < height; y++) {
00104                 logImageGetRowBytes(image, row, y); /* checks image->params.doLogarithm and convert */
00105                 upix = row;
00106                 frow -= width*4;
00107                 
00108                 for (x=0; x<width; x++) {
00109                         *(frow++) = ((float)*(upix++)) / 65535.0f;
00110                         *(frow++) = ((float)*(upix++)) / 65535.0f;
00111                         *(frow++) = ((float)*(upix++)) / 65535.0f;
00112                         *(frow++) = 1.0f;
00113                 }
00114                 frow -= width*4;
00115         }
00116 
00117         MEM_freeN(row);
00118         logImageClose(image);
00119         
00120         if (flags & IB_rect) {
00121                 IMB_rect_from_float(ibuf);
00122         }
00123         return ibuf;
00124 }
00125 
00126 static int imb_save_dpx_cineon(ImBuf *ibuf, const char *filename, int use_cineon, int flags)
00127 {
00128         LogImageByteConversionParameters conversion;
00129         const int width= ibuf->x;
00130         const int height= ibuf->y;
00131         const int depth= 3;
00132         LogImageFile* logImage;
00133         unsigned short* line, *pixel;
00134         int i, j;
00135         float *fline;
00136         float *fbuf;
00137         int is_alloc= 0;
00138         
00139         (void)flags; /* unused */
00140 
00141         // cineon_conversion_parameters(&conversion);
00142         logImageGetByteConversionDefaults(&conversion);
00143 
00144         /*
00145          * Get the drawable for the current image...
00146          */
00147 
00148         fbuf= IMB_float_profile_ensure(ibuf, conversion.doLogarithm ? IB_PROFILE_LINEAR_RGB : IB_PROFILE_NONE, &is_alloc);
00149 
00150         if (fbuf == NULL) { /* in the unlikely event that converting to a float buffer fails */
00151                 return 0;
00152         }
00153         
00154         logImageSetVerbose((G.f & G_DEBUG) ? 1:0);
00155         logImage = logImageCreate(filename, use_cineon, width, height, depth);
00156 
00157         if (!logImage) return 0;
00158         
00159         if(logImageSetByteConversion(logImage, &conversion)==0) {
00160                 printf("error setting args\n");
00161         }
00162 
00163         line = MEM_mallocN(sizeof(unsigned short)*depth*width, "line");
00164         
00165         /*note that image is flipped when sent to logImageSetRowBytes (see last passed parameter).*/
00166         for (j = 0; j < height; ++j) {
00167                 fline = &fbuf[width*j*4];
00168                 for (i=0; i<width; i++) {
00169                         float *fpix, fpix2[3];
00170                         /*we have to convert to cinepaint's 16-bit-per-channel here*/
00171                         pixel = &line[i*depth];
00172                         fpix = &fline[i*4];
00173                         memcpy(fpix2, fpix, sizeof(float)*3);
00174                         
00175                         if (fpix2[0]>=1.0f) fpix2[0] = 1.0f; else if (fpix2[0]<0.0f) fpix2[0]= 0.0f;
00176                         if (fpix2[1]>=1.0f) fpix2[1] = 1.0f; else if (fpix2[1]<0.0f) fpix2[1]= 0.0f;
00177                         if (fpix2[2]>=1.0f) fpix2[2] = 1.0f; else if (fpix2[2]<0.0f) fpix2[2]= 0.0f;
00178                         
00179                         pixel[0] = (unsigned short)(fpix2[0] * 65535.0f); /*float-float math is faster*/
00180                         pixel[1] = (unsigned short)(fpix2[1] * 65535.0f);
00181                         pixel[2] = (unsigned short)(fpix2[2] * 65535.0f);
00182                 }
00183                 logImageSetRowBytes(logImage, (const unsigned short*)line, height-1-j);
00184         }
00185         logImageClose(logImage);
00186 
00187         MEM_freeN(line);
00188         
00189         if(is_alloc) {
00190                 MEM_freeN(fbuf);
00191         }
00192         
00193         return 1;
00194 }
00195 
00196 int imb_savecineon(struct ImBuf *buf, const char *myfile, int flags)
00197 {
00198         return imb_save_dpx_cineon(buf, myfile, 1, flags);
00199 }
00200 
00201  
00202 int imb_is_cineon(unsigned char *buf)
00203 {
00204         return cineonIsMemFileCineon(buf);
00205 }
00206 
00207 ImBuf *imb_loadcineon(unsigned char *mem, size_t size, int flags)
00208 {
00209         if(imb_is_cineon(mem))
00210                 return imb_load_dpx_cineon(mem, 1, size, flags);
00211         return NULL;
00212 }
00213 
00214 int imb_save_dpx(struct ImBuf *buf, const char *myfile, int flags)
00215 {
00216         return imb_save_dpx_cineon(buf, myfile, 0, flags);
00217 }
00218 
00219 int imb_is_dpx(unsigned char *buf)
00220 {
00221         return dpxIsMemFileCineon(buf);
00222 }
00223 
00224 ImBuf *imb_loaddpx(unsigned char *mem, size_t size, int flags)
00225 {
00226         if(imb_is_dpx(mem))
00227                 return imb_load_dpx_cineon(mem, 0, size, flags);
00228         return NULL;
00229 }