diff options
-rw-r--r-- | source/blender/blenkernel/intern/image.c | 3 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/scene.c | 6 | ||||
-rw-r--r-- | source/blender/blenloader/intern/readfile.c | 6 | ||||
-rw-r--r-- | source/blender/imbuf/IMB_imbuf_types.h | 1 | ||||
-rw-r--r-- | source/blender/imbuf/intern/cineon/cineon_dpx.c | 24 | ||||
-rw-r--r-- | source/blender/imbuf/intern/cineon/cineonlib.c | 12 | ||||
-rw-r--r-- | source/blender/imbuf/intern/cineon/dpxlib.c | 14 | ||||
-rw-r--r-- | source/blender/imbuf/intern/cineon/logImageCore.c | 29 | ||||
-rw-r--r-- | source/blender/imbuf/intern/cineon/logImageCore.h | 4 | ||||
-rw-r--r-- | source/blender/imbuf/intern/cineon/logImageLib.c | 5 | ||||
-rw-r--r-- | source/blender/imbuf/intern/cineon/logImageLib.h | 1 | ||||
-rw-r--r-- | source/blender/imbuf/intern/tiff.c | 123 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_scene_types.h | 6 | ||||
-rw-r--r-- | source/blender/src/buttons_scene.c | 12 |
14 files changed, 174 insertions, 72 deletions
diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index 094e35d6c8b..195f4aa4bbf 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -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) { diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index 150fb2b5020..216ad101569 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -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); diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index ef3d5cd0680..3c42cf3ae51 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -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) diff --git a/source/blender/imbuf/IMB_imbuf_types.h b/source/blender/imbuf/IMB_imbuf_types.h index 8a642a79889..a46fdf4af2d 100644 --- a/source/blender/imbuf/IMB_imbuf_types.h +++ b/source/blender/imbuf/IMB_imbuf_types.h @@ -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 ) diff --git a/source/blender/imbuf/intern/cineon/cineon_dpx.c b/source/blender/imbuf/intern/cineon/cineon_dpx.c index 691b81745e0..f00f6bc38c5 100644 --- a/source/blender/imbuf/intern/cineon/cineon_dpx.c +++ b/source/blender/imbuf/intern/cineon/cineon_dpx.c @@ -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... */ diff --git a/source/blender/imbuf/intern/cineon/cineonlib.c b/source/blender/imbuf/intern/cineon/cineonlib.c index 20f4e0d4de4..3b45a9de822 100644 --- a/source/blender/imbuf/intern/cineon/cineonlib.c +++ b/source/blender/imbuf/intern/cineon/cineonlib.c @@ -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 */ diff --git a/source/blender/imbuf/intern/cineon/dpxlib.c b/source/blender/imbuf/intern/cineon/dpxlib.c index b769d1e6132..a81e632a797 100644 --- a/source/blender/imbuf/intern/cineon/dpxlib.c +++ b/source/blender/imbuf/intern/cineon/dpxlib.c @@ -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; diff --git a/source/blender/imbuf/intern/cineon/logImageCore.c b/source/blender/imbuf/intern/cineon/logImageCore.c index e88e9241443..6032f342ed8 100644 --- a/source/blender/imbuf/intern/cineon/logImageCore.c +++ b/source/blender/imbuf/intern/cineon/logImageCore.c @@ -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) { diff --git a/source/blender/imbuf/intern/cineon/logImageCore.h b/source/blender/imbuf/intern/cineon/logImageCore.h index 1af18d5e3b8..01eff8d570d 100644 --- a/source/blender/imbuf/intern/cineon/logImageCore.h +++ b/source/blender/imbuf/intern/cineon/logImageCore.h @@ -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); diff --git a/source/blender/imbuf/intern/cineon/logImageLib.c b/source/blender/imbuf/intern/cineon/logImageLib.c index ff209d5ebd0..2fc52959ff6 100644 --- a/source/blender/imbuf/intern/cineon/logImageLib.c +++ b/source/blender/imbuf/intern/cineon/logImageLib.c @@ -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; diff --git a/source/blender/imbuf/intern/cineon/logImageLib.h b/source/blender/imbuf/intern/cineon/logImageLib.h index ea45c675fe2..617da1d0d92 100644 --- a/source/blender/imbuf/intern/cineon/logImageLib.h +++ b/source/blender/imbuf/intern/cineon/logImageLib.h @@ -47,6 +47,7 @@ typedef struct { float gamma; int blackPoint; int whitePoint; + int doLogarithm; } LogImageByteConversionParameters; /* int functions return 0 for OK */ diff --git a/source/blender/imbuf/intern/tiff.c b/source/blender/imbuf/intern/tiff.c index 42c8ddb7d38..a14bad42203 100644 --- a/source/blender/imbuf/intern/tiff.c +++ b/source/blender/imbuf/intern/tiff.c @@ -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); diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index d42c3a48713..869f1cb426d 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -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: */ diff --git a/source/blender/src/buttons_scene.c b/source/blender/src/buttons_scene.c index c0dcf7945f5..302c76f4edf 100644 --- a/source/blender/src/buttons_scene.c +++ b/source/blender/src/buttons_scene.c @@ -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 */ |