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:
Diffstat (limited to 'source/blender/imbuf/intern/tiff.c')
-rw-r--r--source/blender/imbuf/intern/tiff.c134
1 files changed, 73 insertions, 61 deletions
diff --git a/source/blender/imbuf/intern/tiff.c b/source/blender/imbuf/intern/tiff.c
index 34d486fff11..194082d3e19 100644
--- a/source/blender/imbuf/intern/tiff.c
+++ b/source/blender/imbuf/intern/tiff.c
@@ -309,7 +309,7 @@ struct ImBuf *imb_loadtiff(unsigned char *mem, int size, int flags)
struct ImBuf *ibuf = NULL;
struct ImbTIFFMemFile memFile;
uint32 width, height;
- int bytesperpixel;
+ int bytesperpixel, bitspersample;
int success;
unsigned int pixel_i, byte_i;
uint32 *raster = NULL;
@@ -321,7 +321,7 @@ struct ImBuf *imb_loadtiff(unsigned char *mem, int size, int flags)
memFile.size = size;
/* check whether or not we have a TIFF file */
- if (size < IMB_TIFF_NCB) {
+ if (size < IMB_TIFF_NCB) {
fprintf(stderr, "imb_loadtiff: size < IMB_TIFF_NCB\n");
return NULL;
}
@@ -343,6 +343,7 @@ struct ImBuf *imb_loadtiff(unsigned char *mem, int size, int flags)
bytesperpixel = 4; /* 1 byte per channel, 4 channels */
libtiff_TIFFGetField(image, TIFFTAG_IMAGEWIDTH, &width);
libtiff_TIFFGetField(image, TIFFTAG_IMAGELENGTH, &height);
+ libtiff_TIFFGetField(image, TIFFTAG_BITSPERSAMPLE, &bitspersample);
ibuf = IMB_allocImBuf(width, height, 8*bytesperpixel, 0, 0);
if (ibuf) {
ibuf->ftype = TIF;
@@ -415,8 +416,6 @@ struct ImBuf *imb_loadtiff(unsigned char *mem, int size, int flags)
return (ibuf);
}
-
-
/**
* Saves a TIFF file.
*
@@ -432,14 +431,19 @@ struct ImBuf *imb_loadtiff(unsigned char *mem, int size, int flags)
*
* @return: 1 if the function is successful, 0 on failure.
*/
+
+#define FTOUSHORT(val) ((val >= 1.0f-0.5f/65535)? 65535: (val <= 0.0f)? 0: (unsigned short)(val*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,
@@ -453,6 +457,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 */
@@ -472,67 +481,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(bitspersample == 16)
+ 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(bitspersample == 16) {
+ 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 */
@@ -545,18 +554,21 @@ 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);
- libtiff__TIFFfree(pixels);
+ if(pixels) libtiff__TIFFfree(pixels);
+ if(pixels16) libtiff__TIFFfree(pixels16);
return (1);
}
/* close the TIFF file */
libtiff_TIFFClose(image);
- libtiff__TIFFfree(pixels);
+ if(pixels) libtiff__TIFFfree(pixels);
+ if(pixels16) libtiff__TIFFfree(pixels16);
return (1);
}