Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Sharybin <sergey.vfx@gmail.com>2012-10-22 16:49:00 +0400
committerSergey Sharybin <sergey.vfx@gmail.com>2012-10-22 16:49:00 +0400
commit4e11fe6c5aec1d609e3ecc2218138b838d253ebf (patch)
treed57b4f18280c04e50ecb562135fed058cf11b82d /source/blender/imbuf/intern/cineon/cineon_dpx.c
parent655e24979bb37c97a34b328238233591cfd5c924 (diff)
Patch #27397: Improved DPX/Cineon code
Patch by Julien Enche, thanks! From the patch comment: It allows Blender to load: - 1, 8, 10, 12 and 16 bits files. For 10 and 12 bits files, packed or filled type A/B are supported. - RGB, Log, Luma and YCbCr colorspaces. - Big and little endian storage. - Multi-elements (planar) storage. It allows Blender to save : - 8, 10, 12 and 16 bits file. For 10 and 12 bits files, the most used type A padding is used. - RGB and Log colorspaces (Cineon can only be saved in Log colorspace). For Log colorspace, the common default values are used for gamma, reference black and reference white (respectively 1.7, 95 and 685 for 10 bits files). - Saved DPX/Cineon files now match the viewer. Some files won't load (mostly because I haven't seen any of them): - Compressed files - 32 and 64 bits files - Image orientation information are not taken in account. Here too, I haven't seen any file that was not top-bottom/left-right oriented.
Diffstat (limited to 'source/blender/imbuf/intern/cineon/cineon_dpx.c')
-rw-r--r--source/blender/imbuf/intern/cineon/cineon_dpx.c229
1 files changed, 101 insertions, 128 deletions
diff --git a/source/blender/imbuf/intern/cineon/cineon_dpx.c b/source/blender/imbuf/intern/cineon/cineon_dpx.c
index 7705af13b1e..21f68e79135 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,141 @@
#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;
-
- (void)flags; /* unused */
-
- // cineon_conversion_parameters(&conversion);
- logImageGetByteConversionDefaults(&conversion);
-
- /*
- * Get the drawable for the current image...
- */
+ float *fbuf_ptr;
+ unsigned char *rect_ptr;
+ int x, y, depth, bitspersample, rvalue;
- fbuf= IMB_float_profile_ensure(ibuf, conversion.doLogarithm ? IB_PROFILE_LINEAR_RGB : IB_PROFILE_NONE, &is_alloc);
-
- if (fbuf == NULL) { /* in the unlikely event that converting to a float buffer fails */
+ if (flags & IB_mem) {
+ printf("DPX/Cineon: saving in memory is not supported.\n");
return 0;
}
- logImageSetVerbose((G.debug & G_DEBUG) ? 1:0);
- logImage = logImageCreate(filename, use_cineon, width, height, depth);
+ logImageSetVerbose((G.f & G_DEBUG) ? 1:0);
- if (!logImage) return 0;
-
- if (logImageSetByteConversion(logImage, &conversion)==0) {
- printf("error setting args\n");
+ depth = (ibuf->planes + 7) >> 3;
+ if (depth > 4 || depth < 3) {
+ printf("DPX/Cineon: unsupported depth: %d for file: '%s'\n", depth, filename);
+ return 0;
}
- 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);
- }
- logImageSetRowBytes(logImage, (const unsigned short*)line, height-1-j);
+ 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;
+
+ logImage = logImageCreate(filename, use_cineon, ibuf->x, ibuf->y, bitspersample, (depth == 4),
+ (ibuf->ftype & CINEON_LOG), -1, -1, -1, "Blender");
+
+ if (logImage == 0) {
+ printf("DPX/Cineon: error creating file.\n");
+ return 0;
}
- logImageClose(logImage);
- MEM_freeN(line);
-
- if (is_alloc) {
+ 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);
+ } 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;
+ }
+ 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 +194,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;
}