Blender V2.61 - r43446

cineon_dpx.c

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