diff options
Diffstat (limited to 'source/blender/imbuf/intern/cineon/cineon_dpx.c')
-rw-r--r-- | source/blender/imbuf/intern/cineon/cineon_dpx.c | 228 |
1 files changed, 101 insertions, 127 deletions
diff --git a/source/blender/imbuf/intern/cineon/cineon_dpx.c b/source/blender/imbuf/intern/cineon/cineon_dpx.c index 7705af13b1e..d20c6dec9d3 100644 --- a/source/blender/imbuf/intern/cineon/cineon_dpx.c +++ b/source/blender/imbuf/intern/cineon/cineon_dpx.c @@ -4,11 +4,11 @@ * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. + * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License @@ -20,25 +20,24 @@ * * The Original Code is: all of this file. * - * Contributor(s): none yet. + * Contributor(s): Julien Enche. * * ***** END GPL LICENSE BLOCK ***** * cineon.c - * contributors: joeedh + * contributors: joeedh, Julien Enche * I hearby donate this code and all rights to the Blender Foundation. + * $Id$ */ /** \file blender/imbuf/intern/cineon/cineon_dpx.c * \ingroup imbcineon */ - -#include <stdio.h> -#include <string.h> /*for memcpy*/ -#include "logImageLib.h" -#include "cineonlib.h" -#include "dpxlib.h" +#include <stdio.h> +#include <string.h> +#include <math.h> +#include "logImageCore.h" #include "IMB_imbuf_types.h" #include "IMB_imbuf.h" @@ -51,167 +50,142 @@ #include "MEM_guardedalloc.h" -#if 0 -static void cineon_conversion_parameters(LogImageByteConversionParameters *params) -{ -// params->blackPoint = scene?scene->r.cineonblack:95; -// params->whitePoint = scene?scene->r.cineonwhite:685; -// params->gamma = scene?scene->r.cineongamma:1.7f; -// params->doLogarithm = scene?scene->r.subimtype & R_CINEON_LOG:0; - - params->blackPoint = 95; - params->whitePoint = 685; - params->gamma = 1.0f; - params->doLogarithm = 0; -} -#endif - -static ImBuf *imb_load_dpx_cineon(unsigned char *mem, int use_cineon, int size, int flags, char colorspace[IM_MAX_SPACE]) +static struct ImBuf *imb_load_dpx_cineon(unsigned char *mem, size_t size, int use_cineon, int flags, + char colorspace[IM_MAX_SPACE]) { ImBuf *ibuf; LogImageFile *image; - int x, y; - unsigned short *row, *upix; int width, height, depth; - float *frow; colorspace_set_default_role(colorspace, IM_MAX_SPACE, COLOR_ROLE_DEFAULT_FLOAT); - logImageSetVerbose((G.debug & G_DEBUG) ? 1:0); - - image = logImageOpenFromMem(mem, size, use_cineon); - - if (!image) { - printf("no image!\n"); - return NULL; + logImageSetVerbose((G.f & G_DEBUG) ? 1 : 0); + + image = logImageOpenFromMemory(mem, size); + + if (image == 0) { + printf("DPX/Cineon: error opening image.\n"); + return 0; } - + logImageGetSize(image, &width, &height, &depth); - - if (depth != 3) { /*need to do grayscale loading eventually.*/ + + if (width == 0 || height == 0) { logImageClose(image); - return NULL; + return 0; } - - if (width == 0 && height == 0) { + + ibuf = IMB_allocImBuf(width, height, 32, IB_rectfloat | flags); + if (ibuf == 0) { logImageClose(image); - return NULL; + return 0; } - - ibuf = IMB_allocImBuf(width, height, 32, IB_rectfloat | flags); - row = MEM_mallocN(sizeof(unsigned short)*width*depth, "row in cineon_dpx.c"); - frow = ibuf->rect_float+width*height*4; - - for (y = 0; y < height; y++) { - logImageGetRowBytes(image, row, y); /* checks image->params.doLogarithm and convert */ - upix = row; - frow -= width*4; - - for (x=0; x<width; x++) { - *(frow++) = ((float)*(upix++)) / 65535.0f; - *(frow++) = ((float)*(upix++)) / 65535.0f; - *(frow++) = ((float)*(upix++)) / 65535.0f; - *(frow++) = 1.0f; - } - frow -= width*4; + if (logImageGetDataRGBA(image, ibuf->rect_float, 1) != 0) { + /* Conversion not possible (probably because the format is unsupported) */ + logImageClose(image); + MEM_freeN(ibuf); + return 0; } - MEM_freeN(row); logImageClose(image); - - if (flags & IB_rect) { + ibuf->ftype = use_cineon ? CINEON : DPX; + IMB_flipy(ibuf); + + if (flags & IB_rect) IMB_rect_from_float(ibuf); - } + return ibuf; } static int imb_save_dpx_cineon(ImBuf *ibuf, const char *filename, int use_cineon, int flags) { - LogImageByteConversionParameters conversion; - const int width= ibuf->x; - const int height= ibuf->y; - const int depth= 3; - LogImageFile* logImage; - unsigned short* line, *pixel; - int i, j; - float *fline; + LogImageFile *logImage; float *fbuf; - int is_alloc= 0; + float *fbuf_ptr; + unsigned char *rect_ptr; + int x, y, depth, bitspersample, rvalue; + + if (flags & IB_mem) { + printf("DPX/Cineon: saving in memory is not supported.\n"); + return 0; + } - (void)flags; /* unused */ + logImageSetVerbose((G.f & G_DEBUG) ? 1 : 0); - // cineon_conversion_parameters(&conversion); - logImageGetByteConversionDefaults(&conversion); + depth = (ibuf->planes + 7) >> 3; + if (depth > 4 || depth < 3) { + printf("DPX/Cineon: unsupported depth: %d for file: '%s'\n", depth, filename); + return 0; + } - /* - * Get the drawable for the current image... - */ + if (ibuf->ftype & CINEON_10BIT) + bitspersample = 10; + else if (ibuf->ftype & CINEON_12BIT) + bitspersample = 12; + else if (ibuf->ftype & CINEON_16BIT) + bitspersample = 16; + else + bitspersample = 8; - fbuf= IMB_float_profile_ensure(ibuf, conversion.doLogarithm ? IB_PROFILE_LINEAR_RGB : IB_PROFILE_NONE, &is_alloc); + logImage = logImageCreate(filename, use_cineon, ibuf->x, ibuf->y, bitspersample, (depth == 4), + (ibuf->ftype & CINEON_LOG), -1, -1, -1, "Blender"); - if (fbuf == NULL) { /* in the unlikely event that converting to a float buffer fails */ + if (logImage == 0) { + printf("DPX/Cineon: error creating file.\n"); return 0; } - - logImageSetVerbose((G.debug & G_DEBUG) ? 1:0); - logImage = logImageCreate(filename, use_cineon, width, height, depth); - if (!logImage) return 0; - - if (logImageSetByteConversion(logImage, &conversion)==0) { - printf("error setting args\n"); + if (ibuf->rect_float != 0 && bitspersample != 8) { + /* don't use the float buffer to save 8 bpp picture to prevent color banding + (there's no dithering algorithm behing the logImageSetDataRGBA function) */ + IMB_flipy(ibuf); + rvalue = (logImageSetDataRGBA(logImage, ibuf->rect_float, 1) == 0); + IMB_flipy(ibuf); } - - line = MEM_mallocN(sizeof(unsigned short)*depth*width, "line"); - - /*note that image is flipped when sent to logImageSetRowBytes (see last passed parameter).*/ - for (j = 0; j < height; ++j) { - fline = &fbuf[width*j*4]; - for (i=0; i<width; i++) { - float *fpix, fpix2[3]; - /*we have to convert to cinepaint's 16-bit-per-channel here*/ - pixel = &line[i*depth]; - fpix = &fline[i*4]; - memcpy(fpix2, fpix, sizeof(float)*3); - - if (fpix2[0]>=1.0f) fpix2[0] = 1.0f; else if (fpix2[0]<0.0f) fpix2[0]= 0.0f; - if (fpix2[1]>=1.0f) fpix2[1] = 1.0f; else if (fpix2[1]<0.0f) fpix2[1]= 0.0f; - if (fpix2[2]>=1.0f) fpix2[2] = 1.0f; else if (fpix2[2]<0.0f) fpix2[2]= 0.0f; - - pixel[0] = (unsigned short)(fpix2[0] * 65535.0f); /*float-float math is faster*/ - pixel[1] = (unsigned short)(fpix2[1] * 65535.0f); - pixel[2] = (unsigned short)(fpix2[2] * 65535.0f); + else { + if (ibuf->rect == 0) + IMB_rect_from_float(ibuf); + + fbuf = (float *)MEM_mallocN(ibuf->x * ibuf->y * 4 * sizeof(float), "fbuf in imb_save_dpx_cineon"); + if (fbuf == 0) { + printf("DPX/Cineon: error allocating memory.\n"); + logImageClose(logImage); + return 0; } - logImageSetRowBytes(logImage, (const unsigned short*)line, height-1-j); - } - logImageClose(logImage); - - MEM_freeN(line); - - if (is_alloc) { + for (y = 0; y < ibuf->y; y++) { + for (x = 0; x < ibuf->x; x++) { + fbuf_ptr = fbuf + 4 * ((ibuf->y - y - 1) * ibuf->x + x); + rect_ptr = (unsigned char *)ibuf->rect + 4 * (y * ibuf->x + x); + fbuf_ptr[0] = (float)rect_ptr[0] / 255.0f; + fbuf_ptr[1] = (float)rect_ptr[1] / 255.0f; + fbuf_ptr[2] = (float)rect_ptr[2] / 255.0f; + fbuf_ptr[3] = (depth == 4) ? ((float)rect_ptr[3] / 255.0f) : 1.0f; + } + } + rvalue = (logImageSetDataRGBA(logImage, fbuf, 0) == 0); MEM_freeN(fbuf); } - - return 1; + + logImageClose(logImage); + return rvalue; } -int imb_savecineon(struct ImBuf *buf, const char *myfile, int flags) +int imb_save_cineon(struct ImBuf *buf, const char *myfile, int flags) { return imb_save_dpx_cineon(buf, myfile, 1, flags); } - int imb_is_cineon(unsigned char *buf) { - return cineonIsMemFileCineon(buf); + return logImageIsCineon(buf); } -ImBuf *imb_loadcineon(unsigned char *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE]) +ImBuf *imb_load_cineon(unsigned char *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE]) { if (imb_is_cineon(mem)) - return imb_load_dpx_cineon(mem, 1, size, flags, colorspace); - return NULL; + return imb_load_dpx_cineon(mem, size, 1, flags, colorspace); + return 0; } int imb_save_dpx(struct ImBuf *buf, const char *myfile, int flags) @@ -221,12 +195,12 @@ int imb_save_dpx(struct ImBuf *buf, const char *myfile, int flags) int imb_is_dpx(unsigned char *buf) { - return dpxIsMemFileCineon(buf); + return logImageIsDpx(buf); } -ImBuf *imb_loaddpx(unsigned char *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE]) +ImBuf *imb_load_dpx(unsigned char *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE]) { if (imb_is_dpx(mem)) - return imb_load_dpx_cineon(mem, 0, size, flags, colorspace); - return NULL; + return imb_load_dpx_cineon(mem, size, 0, flags, colorspace); + return 0; } |