forked from bartvdbraak/blender
bugfix [#23406] DPX Images load darker then saved, UI broken.
- a linear float buffer was being created and saved into a non-linear DPX/Cineon file. - removed the UI since the settings are not used at the moment. added a utility function IMB_float_profile_ensure(), which returns a float buffer in the requested profile, using the existing if needed or returning an allocated buffer if the profile is different to that of the ImBuf. - Useful this case where the save function has its own linear setting.
This commit is contained in:
parent
ad0dd98f26
commit
f801b2bcba
@ -336,7 +336,10 @@ class RENDER_PT_output(RenderButtonsPanel, bpy.types.Panel):
|
||||
col.prop(rd, "jpeg2k_ycc")
|
||||
|
||||
elif file_format in ('CINEON', 'DPX'):
|
||||
|
||||
split = layout.split()
|
||||
split.label("FIXME: hard coded Non-Linear, Gamma:1.0")
|
||||
'''
|
||||
col = split.column()
|
||||
col.prop(rd, "use_cineon_log", text="Convert to Log")
|
||||
|
||||
@ -345,6 +348,7 @@ class RENDER_PT_output(RenderButtonsPanel, bpy.types.Panel):
|
||||
col.prop(rd, "cineon_black", text="Black")
|
||||
col.prop(rd, "cineon_white", text="White")
|
||||
col.prop(rd, "cineon_gamma", text="Gamma")
|
||||
'''
|
||||
|
||||
elif file_format == 'TIFF':
|
||||
split = layout.split()
|
||||
|
@ -321,6 +321,7 @@ void IMB_float_from_rect(struct ImBuf *ibuf);
|
||||
void IMB_float_from_rect_simple(struct ImBuf *ibuf); /* no profile conversion */
|
||||
/* note, check that the conversion exists, only some are supported */
|
||||
void IMB_convert_profile(struct ImBuf *ibuf, int profile);
|
||||
float *IMB_float_profile_ensure(struct ImBuf *ibuf, int profile, int *alloc);
|
||||
|
||||
/**
|
||||
* Change the ordering of the color bytes pointed to by rect from
|
||||
|
@ -44,6 +44,7 @@
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#if 0
|
||||
static void cineon_conversion_parameters(LogImageByteConversionParameters *params)
|
||||
{
|
||||
// params->blackPoint = scene?scene->r.cineonblack:95;
|
||||
@ -55,8 +56,8 @@ static void cineon_conversion_parameters(LogImageByteConversionParameters *param
|
||||
params->whitePoint = 685;
|
||||
params->gamma = 1.0f;
|
||||
params->doLogarithm = 0;
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
static struct ImBuf *imb_load_dpx_cineon(unsigned char *mem, int use_cineon, int size, int flags)
|
||||
{
|
||||
@ -116,49 +117,50 @@ static struct ImBuf *imb_load_dpx_cineon(unsigned char *mem, int use_cineon, int
|
||||
return ibuf;
|
||||
}
|
||||
|
||||
static int imb_save_dpx_cineon(ImBuf *buf, const char *filename, int use_cineon, int flags)
|
||||
static int imb_save_dpx_cineon(ImBuf *ibuf, const char *filename, int use_cineon, int flags)
|
||||
{
|
||||
LogImageByteConversionParameters conversion;
|
||||
int width, height, depth;
|
||||
const int width= ibuf->x;
|
||||
const int height= ibuf->y;
|
||||
const int depth= 3;
|
||||
LogImageFile* logImage;
|
||||
unsigned short* line, *pixel;
|
||||
int i, j;
|
||||
int index;
|
||||
float *fline;
|
||||
float *fbuf;
|
||||
int is_alloc= 0;
|
||||
|
||||
(void)flags; /* unused */
|
||||
|
||||
cineon_conversion_parameters(&conversion);
|
||||
// cineon_conversion_parameters(&conversion);
|
||||
logImageGetByteConversionDefaults(&conversion);
|
||||
|
||||
/*
|
||||
* Get the drawable for the current image...
|
||||
*/
|
||||
|
||||
width = buf->x;
|
||||
height = buf->y;
|
||||
depth = 3;
|
||||
fbuf= IMB_float_profile_ensure(ibuf, conversion.doLogarithm ? IB_PROFILE_LINEAR_RGB : IB_PROFILE_NONE, &is_alloc);
|
||||
|
||||
|
||||
if (!buf->rect_float) {
|
||||
IMB_float_from_rect(buf);
|
||||
if (!buf->rect_float) { /* in the unlikely event that converting to a float buffer fails */
|
||||
if (fbuf == NULL) { /* in the unlikely event that converting to a float buffer fails */
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
logImageSetVerbose((G.f & G_DEBUG) ? 1:0);
|
||||
logImage = logImageCreate(filename, use_cineon, width, height, depth);
|
||||
|
||||
if (!logImage) return 0;
|
||||
|
||||
logImageSetByteConversion(logImage, &conversion);
|
||||
if(logImageSetByteConversion(logImage, &conversion)==0) {
|
||||
printf("error setting args\n");
|
||||
}
|
||||
|
||||
index = 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 = &buf->rect_float[width*j*4];
|
||||
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*/
|
||||
@ -179,6 +181,11 @@ static int imb_save_dpx_cineon(ImBuf *buf, const char *filename, int use_cineon,
|
||||
logImageClose(logImage);
|
||||
|
||||
MEM_freeN(line);
|
||||
|
||||
if(is_alloc) {
|
||||
MEM_freeN(fbuf);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -40,6 +40,8 @@
|
||||
#include "BKE_utildefines.h"
|
||||
#include "BKE_colortools.h"
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
void IMB_de_interlace(struct ImBuf *ibuf)
|
||||
{
|
||||
struct ImBuf * tbuf1, * tbuf2;
|
||||
@ -187,13 +189,47 @@ void IMB_rect_from_float(struct ImBuf *ibuf)
|
||||
}
|
||||
}
|
||||
|
||||
static void imb_float_from_rect_nonlinear(struct ImBuf *ibuf, float *fbuf)
|
||||
{
|
||||
float *tof = fbuf;
|
||||
int i;
|
||||
unsigned char *to = (unsigned char *) ibuf->rect;
|
||||
|
||||
for (i = ibuf->x * ibuf->y; i > 0; i--)
|
||||
{
|
||||
tof[0] = ((float)to[0])*(1.0f/255.0f);
|
||||
tof[1] = ((float)to[1])*(1.0f/255.0f);
|
||||
tof[2] = ((float)to[2])*(1.0f/255.0f);
|
||||
tof[3] = ((float)to[3])*(1.0f/255.0f);
|
||||
to += 4;
|
||||
tof += 4;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void imb_float_from_rect_linear(struct ImBuf *ibuf, float *fbuf)
|
||||
{
|
||||
float *tof = fbuf;
|
||||
int i;
|
||||
unsigned char *to = (unsigned char *) ibuf->rect;
|
||||
|
||||
for (i = ibuf->x * ibuf->y; i > 0; i--)
|
||||
{
|
||||
tof[0] = srgb_to_linearrgb(((float)to[0])*(1.0f/255.0f));
|
||||
tof[1] = srgb_to_linearrgb(((float)to[1])*(1.0f/255.0f));
|
||||
tof[2] = srgb_to_linearrgb(((float)to[2])*(1.0f/255.0f));
|
||||
tof[3] = ((float)to[3])*(1.0f/255.0f);
|
||||
to += 4;
|
||||
tof += 4;
|
||||
}
|
||||
}
|
||||
|
||||
void IMB_float_from_rect(struct ImBuf *ibuf)
|
||||
{
|
||||
/* quick method to convert byte to floatbuf */
|
||||
float *tof = ibuf->rect_float;
|
||||
int i;
|
||||
unsigned char *to = (unsigned char *) ibuf->rect;
|
||||
|
||||
unsigned char *to = (unsigned char *) ibuf->rect;
|
||||
if(to==NULL) return;
|
||||
if(tof==NULL) {
|
||||
if (imb_addrectfloatImBuf(ibuf) == 0) return;
|
||||
@ -205,41 +241,16 @@ void IMB_float_from_rect(struct ImBuf *ibuf)
|
||||
if (ibuf->profile != IB_PROFILE_NONE) {
|
||||
/* if the image has been given a profile then we're working
|
||||
* with color management in mind, so convert it to linear space */
|
||||
|
||||
for (i = ibuf->x * ibuf->y; i > 0; i--)
|
||||
{
|
||||
tof[0] = srgb_to_linearrgb(((float)to[0])*(1.0f/255.0f));
|
||||
tof[1] = srgb_to_linearrgb(((float)to[1])*(1.0f/255.0f));
|
||||
tof[2] = srgb_to_linearrgb(((float)to[2])*(1.0f/255.0f));
|
||||
tof[3] = ((float)to[3])*(1.0f/255.0f);
|
||||
to += 4;
|
||||
tof += 4;
|
||||
}
|
||||
imb_float_from_rect_linear(ibuf, ibuf->rect_float);
|
||||
} else {
|
||||
for (i = ibuf->x * ibuf->y; i > 0; i--)
|
||||
{
|
||||
tof[0] = ((float)to[0])*(1.0f/255.0f);
|
||||
tof[1] = ((float)to[1])*(1.0f/255.0f);
|
||||
tof[2] = ((float)to[2])*(1.0f/255.0f);
|
||||
tof[3] = ((float)to[3])*(1.0f/255.0f);
|
||||
to += 4;
|
||||
tof += 4;
|
||||
}
|
||||
imb_float_from_rect_nonlinear(ibuf, ibuf->rect_float);
|
||||
}
|
||||
}
|
||||
|
||||
/* no profile conversion */
|
||||
void IMB_float_from_rect_simple(struct ImBuf *ibuf)
|
||||
{
|
||||
int profile = IB_PROFILE_NONE;
|
||||
|
||||
/* no color management:
|
||||
* don't disturb the existing profiles */
|
||||
SWAP(int, ibuf->profile, profile);
|
||||
|
||||
IMB_float_from_rect(ibuf);
|
||||
|
||||
SWAP(int, ibuf->profile, profile);
|
||||
imb_float_from_rect_nonlinear(ibuf, ibuf->rect_float);
|
||||
}
|
||||
|
||||
void IMB_convert_profile(struct ImBuf *ibuf, int profile)
|
||||
@ -299,3 +310,48 @@ void IMB_convert_profile(struct ImBuf *ibuf, int profile)
|
||||
|
||||
ibuf->profile= profile;
|
||||
}
|
||||
|
||||
/* use when you need to get a buffer with a certain profile
|
||||
* if the return */
|
||||
float *IMB_float_profile_ensure(struct ImBuf *ibuf, int profile, int *alloc)
|
||||
{
|
||||
/* stupid but it works like this everywhere now */
|
||||
const short is_lin_from= (ibuf->profile != IB_PROFILE_NONE);
|
||||
const short is_lin_to= (profile != IB_PROFILE_NONE);
|
||||
|
||||
|
||||
if(is_lin_from == is_lin_to) {
|
||||
*alloc= 0;
|
||||
|
||||
/* simple case, just allocate the buffer and return */
|
||||
if(ibuf->rect_float == NULL) {
|
||||
IMB_float_from_rect(ibuf);
|
||||
}
|
||||
|
||||
return ibuf->rect_float;
|
||||
}
|
||||
else {
|
||||
/* conversion is needed, first check */
|
||||
float *fbuf= MEM_mallocN(ibuf->x * ibuf->y * sizeof(float) * 4, "IMB_float_profile_ensure");
|
||||
*alloc= 1;
|
||||
|
||||
if(ibuf->rect_float == NULL) {
|
||||
if(is_lin_to) {
|
||||
imb_float_from_rect_linear(ibuf, fbuf);
|
||||
}
|
||||
else {
|
||||
imb_float_from_rect_nonlinear(ibuf, fbuf);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(is_lin_to) { /* lin -> nonlin */
|
||||
linearrgb_to_srgb_rgba_rgba_buf(fbuf, ibuf->rect_float, ibuf->x * ibuf->y);
|
||||
}
|
||||
else { /* nonlin -> lin */
|
||||
srgb_to_linearrgb_rgba_rgba_buf(fbuf, ibuf->rect_float, ibuf->x * ibuf->y);
|
||||
}
|
||||
}
|
||||
|
||||
return fbuf;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user