Add an option for saving/loading DPX with in log color space with
reference black, reference white and gamma. Added 16 bit TIFF saving. This needs more work to cleanup code and add 16 bit TIFF reading, but committing it now so it can be tested.
This commit is contained in:
parent
397ece0008
commit
0ec0f2a02f
|
@ -1182,6 +1182,9 @@ int BKE_write_ibuf(ImBuf *ibuf, char *name, int imtype, int subimtype, int quali
|
|||
}
|
||||
else if ((G.have_libtiff) && (imtype==R_TIFF)) {
|
||||
ibuf->ftype= TIF;
|
||||
|
||||
if(subimtype & R_TIFF_16BIT)
|
||||
ibuf->ftype |= TIF_16BIT;
|
||||
}
|
||||
#ifdef WITH_OPENEXR
|
||||
else if (imtype==R_OPENEXR || imtype==R_MULTILAYER) {
|
||||
|
|
|
@ -225,6 +225,10 @@ Scene *add_scene(char *name)
|
|||
sce->r.simplify_shadowsamples= 16;
|
||||
sce->r.simplify_aosss= 1.0f;
|
||||
|
||||
sce->r.cineonblack= 95;
|
||||
sce->r.cineonwhite= 685;
|
||||
sce->r.cineongamma= 1.7f;
|
||||
|
||||
sce->toolsettings = MEM_callocN(sizeof(struct ToolSettings),"Tool Settings Struct");
|
||||
sce->toolsettings->cornertype=1;
|
||||
sce->toolsettings->degr = 90;
|
||||
|
@ -267,7 +271,7 @@ Scene *add_scene(char *name)
|
|||
sce->r.osa= 8;
|
||||
|
||||
sculptdata_init(sce);
|
||||
|
||||
|
||||
/* note; in header_info.c the scene copy happens..., if you add more to renderdata it has to be checked there */
|
||||
scene_add_render_layer(sce);
|
||||
|
||||
|
|
|
@ -7095,6 +7095,12 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
|
|||
sce->r.simplify_shadowsamples= 16;
|
||||
sce->r.simplify_aosss= 1.0f;
|
||||
}
|
||||
|
||||
if(sce->r.cineongamma == 0) {
|
||||
sce->r.cineonblack= 95;
|
||||
sce->r.cineonwhite= 685;
|
||||
sce->r.cineongamma= 1.7f;
|
||||
}
|
||||
}
|
||||
|
||||
for(ntree=main->nodetree.first; ntree; ntree= ntree->id.next)
|
||||
|
|
|
@ -170,6 +170,7 @@ typedef enum {
|
|||
|
||||
#define RADHDR (1 << 24)
|
||||
#define TIF (1 << 23)
|
||||
#define TIF_16BIT (1 << 8 )
|
||||
|
||||
#define OPENEXR (1 << 22)
|
||||
#define OPENEXR_HALF (1 << 8 )
|
||||
|
|
|
@ -42,14 +42,29 @@
|
|||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
/* ugly bad level, should be fixed */
|
||||
#include "DNA_scene_types.h"
|
||||
#include "BKE_global.h"
|
||||
|
||||
static void cineon_conversion_parameters(LogImageByteConversionParameters *params)
|
||||
{
|
||||
params->blackPoint = G.scene->r.cineonblack;
|
||||
params->whitePoint = G.scene->r.cineonwhite;
|
||||
params->gamma = G.scene->r.cineongamma;
|
||||
params->doLogarithm = G.scene->r.subimtype & R_CINEON_LOG;
|
||||
}
|
||||
|
||||
static struct ImBuf *imb_load_dpx_cineon(unsigned char *mem, int use_cineon, int size, int flags)
|
||||
{
|
||||
LogImageByteConversionParameters conversion;
|
||||
ImBuf *ibuf;
|
||||
LogImageFile *image;
|
||||
int x, y;
|
||||
unsigned short *row, *upix;
|
||||
int width, height, depth;
|
||||
float *frow;
|
||||
|
||||
cineon_conversion_parameters(&conversion);
|
||||
|
||||
image = logImageOpenFromMem(mem, size, use_cineon);
|
||||
|
||||
|
@ -70,6 +85,8 @@ static struct ImBuf *imb_load_dpx_cineon(unsigned char *mem, int use_cineon, int
|
|||
return NULL;
|
||||
}
|
||||
|
||||
logImageSetByteConversion(image, &conversion);
|
||||
|
||||
ibuf = IMB_allocImBuf(width, height, 32, IB_rectfloat | flags, 0);
|
||||
|
||||
row = MEM_mallocN(sizeof(unsigned short)*width*depth, "row in cineon_dpx.c");
|
||||
|
@ -107,10 +124,9 @@ static int imb_save_dpx_cineon(ImBuf *buf, char *filename, int use_cineon, int f
|
|||
int i, j;
|
||||
int index;
|
||||
float *fline;
|
||||
|
||||
conversion.blackPoint = 95;
|
||||
conversion.whitePoint = 685;
|
||||
conversion.gamma = 1;
|
||||
|
||||
cineon_conversion_parameters(&conversion);
|
||||
|
||||
/*
|
||||
* Get the drawable for the current image...
|
||||
*/
|
||||
|
|
|
@ -350,8 +350,10 @@ cineonGetRowBytes(CineonFile* cineon, unsigned short* row, int y) {
|
|||
|
||||
/* extract required pixels */
|
||||
for (pixelIndex = 0; pixelIndex < numPixels; ++pixelIndex) {
|
||||
/* row[pixelIndex] = cineon->lut10[cineon->pixelBuffer[pixelIndex]]; */
|
||||
row[pixelIndex] = cineon->pixelBuffer[pixelIndex] << 6;
|
||||
if(cineon->params.doLogarithm)
|
||||
row[pixelIndex] = cineon->lut10_16[cineon->pixelBuffer[pixelIndex]];
|
||||
else
|
||||
row[pixelIndex] = cineon->pixelBuffer[pixelIndex] << 6;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -367,8 +369,10 @@ cineonSetRowBytes(CineonFile* cineon, const unsigned short* row, int y) {
|
|||
|
||||
/* put new pixels into pixelBuffer */
|
||||
for (pixelIndex = 0; pixelIndex < numPixels; ++pixelIndex) {
|
||||
/* cineon->pixelBuffer[pixelIndex] = cineon->lut8[row[pixelIndex]]; */
|
||||
cineon->pixelBuffer[pixelIndex] = row[pixelIndex] >> 6;
|
||||
if(cineon->params.doLogarithm)
|
||||
cineon->pixelBuffer[pixelIndex] = cineon->lut16_16[row[pixelIndex]];
|
||||
else
|
||||
cineon->pixelBuffer[pixelIndex] = row[pixelIndex] >> 6;
|
||||
}
|
||||
|
||||
/* pack into longwords */
|
||||
|
|
|
@ -199,7 +199,7 @@ dumpDpxMainHeader(DpxMainHeader* header) {
|
|||
#endif
|
||||
}
|
||||
|
||||
static int verbose = 0;
|
||||
static int verbose = 1;
|
||||
void
|
||||
dpxSetVerbose(int verbosity) {
|
||||
verbose = verbosity;
|
||||
|
@ -275,8 +275,10 @@ dpxGetRowBytes(DpxFile* dpx, unsigned short* row, int y) {
|
|||
|
||||
/* extract required pixels */
|
||||
for (pixelIndex = 0; pixelIndex < numPixels; ++pixelIndex) {
|
||||
/* row[pixelIndex] = dpx->lut10[dpx->pixelBuffer[pixelIndex]]; */
|
||||
row[pixelIndex] = dpx->pixelBuffer[pixelIndex] << 6;
|
||||
if(dpx->params.doLogarithm)
|
||||
row[pixelIndex] = dpx->lut10_16[dpx->pixelBuffer[pixelIndex]];
|
||||
else
|
||||
row[pixelIndex] = dpx->pixelBuffer[pixelIndex] << 6;
|
||||
}
|
||||
|
||||
/* save remaining pixels */
|
||||
|
@ -316,8 +318,10 @@ dpxSetRowBytes(DpxFile* dpx, const unsigned short* row, int y) {
|
|||
|
||||
/* put new pixels into pixelBuffer */
|
||||
for (pixelIndex = 0; pixelIndex < numPixels; ++pixelIndex) {
|
||||
/* dpx->pixelBuffer[dpx->pixelBufferUsed + pixelIndex] = dpx->lut8[row[pixelIndex]]; */
|
||||
dpx->pixelBuffer[dpx->pixelBufferUsed + pixelIndex] = row[pixelIndex] >> 6;
|
||||
if(dpx->params.doLogarithm)
|
||||
dpx->pixelBuffer[dpx->pixelBufferUsed + pixelIndex] = dpx->lut16_16[row[pixelIndex]];
|
||||
else
|
||||
dpx->pixelBuffer[dpx->pixelBufferUsed + pixelIndex] = row[pixelIndex] >> 6;
|
||||
}
|
||||
dpx->pixelBufferUsed += numPixels;
|
||||
|
||||
|
|
|
@ -93,6 +93,35 @@ setupLut(LogImageFile *logImage) {
|
|||
}
|
||||
}
|
||||
|
||||
/* set up the 10 bit to 16 bit and 16 bit to 10 bit tables */
|
||||
void
|
||||
setupLut16(LogImageFile *logImage) {
|
||||
|
||||
int i;
|
||||
double f_black;
|
||||
double scale;
|
||||
|
||||
f_black = convertTo(logImage->params.blackPoint, logImage->params.whitePoint, logImage->params.gamma);
|
||||
scale = 65535.0 / (1.0 - f_black);
|
||||
|
||||
for (i = 0; i <= logImage->params.blackPoint; ++i) {
|
||||
logImage->lut10_16[i] = 0;
|
||||
}
|
||||
for (; i < logImage->params.whitePoint; ++i) {
|
||||
double f_i;
|
||||
f_i = convertTo(i, logImage->params.whitePoint, logImage->params.gamma);
|
||||
logImage->lut10_16[i] = (int)rint(scale * (f_i - f_black));
|
||||
}
|
||||
for (; i < 1024; ++i) {
|
||||
logImage->lut10_16[i] = 65535;
|
||||
}
|
||||
|
||||
for (i = 0; i < 65536; ++i) {
|
||||
double f_i = f_black + (i / 65535.0) * (1.0 - f_black);
|
||||
logImage->lut16_16[i] = convertFrom(f_i, logImage->params.whitePoint, logImage->params.gamma);
|
||||
}
|
||||
}
|
||||
|
||||
/* how many longwords to hold this many pixels? */
|
||||
int
|
||||
pixelsToLongs(int numPixels) {
|
||||
|
|
|
@ -71,6 +71,9 @@ struct _Log_Image_File_t_
|
|||
unsigned char lut10[1024];
|
||||
unsigned short lut8[256];
|
||||
|
||||
unsigned short lut10_16[1024];
|
||||
unsigned short lut16_16[65536];
|
||||
|
||||
/* pixel access functions */
|
||||
GetRowFn* getRow;
|
||||
SetRowFn* setRow;
|
||||
|
@ -82,6 +85,7 @@ struct _Log_Image_File_t_
|
|||
};
|
||||
|
||||
void setupLut(LogImageFile*);
|
||||
void setupLut16(LogImageFile*);
|
||||
|
||||
int pixelsToLongs(int numPixels);
|
||||
|
||||
|
|
|
@ -89,6 +89,7 @@ logImageGetByteConversionDefaults(LogImageByteConversionParameters* params) {
|
|||
params->gamma = DEFAULT_GAMMA;
|
||||
params->blackPoint = DEFAULT_BLACK_POINT;
|
||||
params->whitePoint = DEFAULT_WHITE_POINT;
|
||||
params->doLogarithm = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -97,6 +98,7 @@ logImageGetByteConversion(const LogImageFile* logImage, LogImageByteConversionPa
|
|||
params->gamma = logImage->params.gamma;
|
||||
params->blackPoint = logImage->params.blackPoint;
|
||||
params->whitePoint = logImage->params.whitePoint;
|
||||
params->doLogarithm = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -110,7 +112,8 @@ logImageSetByteConversion(LogImageFile* logImage, const LogImageByteConversionPa
|
|||
logImage->params.gamma = params->gamma;
|
||||
logImage->params.blackPoint = params->blackPoint;
|
||||
logImage->params.whitePoint = params->whitePoint;
|
||||
setupLut(logImage);
|
||||
logImage->params.doLogarithm = params->doLogarithm;
|
||||
setupLut16(logImage);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
|
|
|
@ -47,6 +47,7 @@ typedef struct {
|
|||
float gamma;
|
||||
int blackPoint;
|
||||
int whitePoint;
|
||||
int doLogarithm;
|
||||
} LogImageByteConversionParameters;
|
||||
|
||||
/* int functions return 0 for OK */
|
||||
|
|
|
@ -418,8 +418,6 @@ struct ImBuf *imb_loadtiff(unsigned char *mem, int size, int flags)
|
|||
return (ibuf);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Saves a TIFF file.
|
||||
*
|
||||
|
@ -435,14 +433,19 @@ struct ImBuf *imb_loadtiff(unsigned char *mem, int size, int flags)
|
|||
*
|
||||
* @return: 1 if the function is successful, 0 on failure.
|
||||
*/
|
||||
|
||||
#define FTOUSHORT(f) ((f >= 1.0f-0.5f/65535)? 65535: (f <= 0.0f)? 0: (unsigned short)(f*65535.0f + 0.5f))
|
||||
|
||||
short imb_savetiff(struct ImBuf *ibuf, char *name, int flags)
|
||||
{
|
||||
TIFF *image = NULL;
|
||||
uint16 samplesperpixel;
|
||||
uint16 samplesperpixel, bitspersample;
|
||||
size_t npixels;
|
||||
unsigned char *pixels = NULL;
|
||||
unsigned char *from = NULL, *to = NULL;
|
||||
int x, y, from_i, to_i;
|
||||
unsigned short *pixels16 = NULL, *to16 = NULL;
|
||||
float *fromf = NULL;
|
||||
int x, y, from_i, to_i, i;
|
||||
int extraSampleTypes[1] = { EXTRASAMPLE_ASSOCALPHA };
|
||||
|
||||
/* check for a valid number of bytes per pixel. Like the PNG writer,
|
||||
|
@ -456,6 +459,11 @@ short imb_savetiff(struct ImBuf *ibuf, char *name, int flags)
|
|||
return (0);
|
||||
}
|
||||
|
||||
if((ibuf->ftype & TIF_16BIT) && ibuf->rect_float)
|
||||
bitspersample = 16;
|
||||
else
|
||||
bitspersample = 8;
|
||||
|
||||
/* open TIFF file for writing */
|
||||
if (flags & IB_mem) {
|
||||
/* bork at the creation of a TIFF in memory */
|
||||
|
@ -475,67 +483,67 @@ short imb_savetiff(struct ImBuf *ibuf, char *name, int flags)
|
|||
|
||||
/* allocate array for pixel data */
|
||||
npixels = ibuf->x * ibuf->y;
|
||||
pixels = (unsigned char*)libtiff__TIFFmalloc(npixels *
|
||||
samplesperpixel * sizeof(unsigned char));
|
||||
if (pixels == NULL) {
|
||||
if(ibuf->ftype & TIF_16BIT)
|
||||
pixels16 = (unsigned short*)libtiff__TIFFmalloc(npixels *
|
||||
samplesperpixel * sizeof(unsigned short));
|
||||
else
|
||||
pixels = (unsigned char*)libtiff__TIFFmalloc(npixels *
|
||||
samplesperpixel * sizeof(unsigned char));
|
||||
|
||||
if (pixels == NULL && pixels16 == NULL) {
|
||||
fprintf(stderr,
|
||||
"imb_savetiff: could not allocate pixels array.\n");
|
||||
libtiff_TIFFClose(image);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* copy pixel data. While copying, we flip the image
|
||||
* vertically. */
|
||||
from = (unsigned char*)ibuf->rect;
|
||||
to = pixels;
|
||||
/* setup pointers */
|
||||
if(ibuf->ftype & TIF_16BIT) {
|
||||
fromf = ibuf->rect_float;
|
||||
to16 = pixels16;
|
||||
}
|
||||
else {
|
||||
from = (unsigned char*)ibuf->rect;
|
||||
to = pixels;
|
||||
}
|
||||
|
||||
/* setup samples per pixel */
|
||||
libtiff_TIFFSetField(image, TIFFTAG_BITSPERSAMPLE, bitspersample);
|
||||
libtiff_TIFFSetField(image, TIFFTAG_SAMPLESPERPIXEL, samplesperpixel);
|
||||
switch (samplesperpixel) {
|
||||
case 4: /* RGBA images, 8 bits per channel */
|
||||
libtiff_TIFFSetField(image, TIFFTAG_EXTRASAMPLES, 1,
|
||||
extraSampleTypes);
|
||||
libtiff_TIFFSetField(image, TIFFTAG_BITSPERSAMPLE, 8);
|
||||
libtiff_TIFFSetField(image, TIFFTAG_PHOTOMETRIC,
|
||||
PHOTOMETRIC_RGB);
|
||||
for (x = 0; x < ibuf->x; x++) {
|
||||
for (y = 0; y < ibuf->y; y++) {
|
||||
from_i = 4*(y*ibuf->x+x);
|
||||
to_i = 4*((ibuf->y-y-1)*ibuf->x+x);
|
||||
|
||||
to[to_i++] = from[from_i++];
|
||||
to[to_i++] = from[from_i++];
|
||||
to[to_i++] = from[from_i++];
|
||||
to[to_i] = from[from_i];
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 3: /* RGB images, 8 bits per channel */
|
||||
libtiff_TIFFSetField(image, TIFFTAG_BITSPERSAMPLE, 8);
|
||||
libtiff_TIFFSetField(image, TIFFTAG_PHOTOMETRIC,
|
||||
PHOTOMETRIC_RGB);
|
||||
for (x = 0; x < ibuf->x; x++) {
|
||||
for (y = 0; y < ibuf->y; y++) {
|
||||
from_i = 4*(y*ibuf->x+x);
|
||||
to_i = 3*((ibuf->y-y-1)*ibuf->x+x);
|
||||
|
||||
to[to_i++] = from[from_i++];
|
||||
to[to_i++] = from[from_i++];
|
||||
to[to_i] = from[from_i];
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 1: /* greyscale images, 1 channel with 8 bits */
|
||||
libtiff_TIFFSetField(image, TIFFTAG_BITSPERSAMPLE, 8);
|
||||
libtiff_TIFFSetField(image, TIFFTAG_PHOTOMETRIC,
|
||||
PHOTOMETRIC_MINISBLACK);
|
||||
for (x = 0; x < ibuf->x; x++) {
|
||||
for (y = 0; y < ibuf->y; y++) {
|
||||
from_i = 4*(y*ibuf->x+x);
|
||||
to_i = 1*((ibuf->y-y-1)*ibuf->x+x);
|
||||
if(samplesperpixel == 4) {
|
||||
/* RGBA images */
|
||||
libtiff_TIFFSetField(image, TIFFTAG_EXTRASAMPLES, 1,
|
||||
extraSampleTypes);
|
||||
libtiff_TIFFSetField(image, TIFFTAG_PHOTOMETRIC,
|
||||
PHOTOMETRIC_RGB);
|
||||
}
|
||||
else if(samplesperpixel == 3) {
|
||||
/* RGB images */
|
||||
libtiff_TIFFSetField(image, TIFFTAG_PHOTOMETRIC,
|
||||
PHOTOMETRIC_RGB);
|
||||
}
|
||||
else if(samplesperpixel == 1) {
|
||||
/* greyscale images, 1 channel */
|
||||
libtiff_TIFFSetField(image, TIFFTAG_PHOTOMETRIC,
|
||||
PHOTOMETRIC_MINISBLACK);
|
||||
}
|
||||
|
||||
/* copy pixel data. While copying, we flip the image vertically. */
|
||||
for (x = 0; x < ibuf->x; x++) {
|
||||
for (y = 0; y < ibuf->y; y++) {
|
||||
from_i = 4*(y*ibuf->x+x);
|
||||
to_i = samplesperpixel*((ibuf->y-y-1)*ibuf->x+x);
|
||||
|
||||
if(pixels16) {
|
||||
for (i = 0; i < samplesperpixel; i++, to_i++, from_i++)
|
||||
to16[to_i] = FTOUSHORT(fromf[from_i]);
|
||||
}
|
||||
else {
|
||||
for (i = 0; i < samplesperpixel; i++, to_i++, from_i++)
|
||||
to[to_i] = from[from_i];
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* write the actual TIFF file */
|
||||
|
@ -548,8 +556,9 @@ short imb_savetiff(struct ImBuf *ibuf, char *name, int flags)
|
|||
libtiff_TIFFSetField(image, TIFFTAG_XRESOLUTION, 150.0);
|
||||
libtiff_TIFFSetField(image, TIFFTAG_YRESOLUTION, 150.0);
|
||||
libtiff_TIFFSetField(image, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH);
|
||||
if (libtiff_TIFFWriteEncodedStrip(image, 0, pixels,
|
||||
ibuf->x*ibuf->y*samplesperpixel) == -1) {
|
||||
if (libtiff_TIFFWriteEncodedStrip(image, 0,
|
||||
(bitspersample == 16)? (unsigned char*)pixels16: pixels,
|
||||
ibuf->x*ibuf->y*samplesperpixel*bitspersample/8) == -1) {
|
||||
fprintf(stderr,
|
||||
"imb_savetiff: Could not write encoded TIFF.\n");
|
||||
libtiff_TIFFClose(image);
|
||||
|
|
|
@ -305,6 +305,10 @@ typedef struct RenderData {
|
|||
int simplify_shadowsamples;
|
||||
float simplify_particles;
|
||||
float simplify_aosss;
|
||||
|
||||
/* cineon */
|
||||
short cineonwhite, cineonblack;
|
||||
float cineongamma;
|
||||
} RenderData;
|
||||
|
||||
/* control render convert and shading engine */
|
||||
|
@ -670,6 +674,8 @@ typedef struct Scene {
|
|||
#define R_OPENEXR_HALF 1
|
||||
#define R_OPENEXR_ZBUF 2
|
||||
#define R_PREVIEW_JPG 4
|
||||
#define R_CINEON_LOG 8
|
||||
#define R_TIFF_16BIT 16
|
||||
|
||||
/* bake_mode: same as RE_BAKE_xxx defines */
|
||||
/* bake_flag: */
|
||||
|
|
|
@ -2552,6 +2552,18 @@ static void render_panel_format(void)
|
|||
892,yofs,74,20, &G.scene->r.quality, 0, 0, 0, 0, "Set codec settings for OpenEXR");
|
||||
|
||||
#endif
|
||||
} else if (G.scene->r.imtype == R_DPX || G.scene->r.imtype == R_CINEON) {
|
||||
uiDefButBitS(block, TOG, R_CINEON_LOG, B_REDR, "Log", 892,yofs,74,20, &G.scene->r.subimtype, 0, 0, 0, 0, "Convert to log color space");
|
||||
|
||||
if(G.scene->r.subimtype & R_CINEON_LOG) {
|
||||
uiBlockBeginAlign(block);
|
||||
uiDefButS(block, NUM, B_NOP, "B", 892,yofs+44,80,20, &G.scene->r.cineonblack, 0, 1024, 0, 0, "Log conversion reference black");
|
||||
uiDefButS(block, NUM, B_NOP, "W", 972,yofs+44,80,20, &G.scene->r.cineonwhite, 0, 1024, 0, 0, "Log conversion reference white");
|
||||
uiDefButF(block, NUM, B_NOP, "G", 1052,yofs+44,70,20, &G.scene->r.cineongamma, 0.0f, 10.0f, 1, 2, "Log conversion gamma");
|
||||
uiBlockEndAlign(block);
|
||||
}
|
||||
} else if (G.scene->r.imtype == R_TIFF) {
|
||||
uiDefButBitS(block, TOG, R_TIFF_16BIT, B_REDR, "16 Bit", 892,yofs,74,20, &G.scene->r.subimtype, 0, 0, 0, 0, "Save 16 bit per channel TIFF");
|
||||
} else {
|
||||
if(G.scene->r.quality < 5) G.scene->r.quality = 90; /* restore from openexr */
|
||||
|
||||
|
|
Loading…
Reference in New Issue