Changeset View
Changeset View
Standalone View
Standalone View
source/blender/imbuf/intern/tiff.c
| Show First 20 Lines • Show All 44 Lines • ▼ Show 20 Lines | |||||
| #include "imbuf.h" | #include "imbuf.h" | ||||
| #include "BLI_math.h" | #include "BLI_math.h" | ||||
| #include "BLI_utildefines.h" | #include "BLI_utildefines.h" | ||||
| #include "BKE_global.h" | #include "BKE_global.h" | ||||
| #include "CLG_log.h" | |||||
| #include "IMB_imbuf_types.h" | #include "IMB_imbuf_types.h" | ||||
| #include "IMB_imbuf.h" | #include "IMB_imbuf.h" | ||||
| #include "IMB_filetype.h" | #include "IMB_filetype.h" | ||||
| #include "IMB_colormanagement.h" | #include "IMB_colormanagement.h" | ||||
| #include "IMB_colormanagement_intern.h" | #include "IMB_colormanagement_intern.h" | ||||
| #include "tiffio.h" | #include "tiffio.h" | ||||
| #ifdef WIN32 | #ifdef WIN32 | ||||
| #include "utfconv.h" | #include "utfconv.h" | ||||
| #endif | #endif | ||||
| /*********************** | /*********************** | ||||
| * Local declarations. * | * Local declarations. * | ||||
| ***********************/ | ***********************/ | ||||
| static CLG_LogRef LOG = {"imb.tiff"}; | |||||
| /* Reading and writing of an in-memory TIFF file. */ | /* Reading and writing of an in-memory TIFF file. */ | ||||
| static tsize_t imb_tiff_ReadProc(thandle_t handle, tdata_t data, tsize_t n); | static tsize_t imb_tiff_ReadProc(thandle_t handle, tdata_t data, tsize_t n); | ||||
| static tsize_t imb_tiff_WriteProc(thandle_t handle, tdata_t data, tsize_t n); | static tsize_t imb_tiff_WriteProc(thandle_t handle, tdata_t data, tsize_t n); | ||||
| static toff_t imb_tiff_SeekProc(thandle_t handle, toff_t ofs, int whence); | static toff_t imb_tiff_SeekProc(thandle_t handle, toff_t ofs, int whence); | ||||
| static int imb_tiff_CloseProc(thandle_t handle); | static int imb_tiff_CloseProc(thandle_t handle); | ||||
| static toff_t imb_tiff_SizeProc(thandle_t handle); | static toff_t imb_tiff_SizeProc(thandle_t handle); | ||||
| static int imb_tiff_DummyMapProc(thandle_t fd, tdata_t *pbase, toff_t *psize); | static int imb_tiff_DummyMapProc(thandle_t fd, tdata_t *pbase, toff_t *psize); | ||||
| static void imb_tiff_DummyUnmapProc(thandle_t fd, tdata_t base, toff_t size); | static void imb_tiff_DummyUnmapProc(thandle_t fd, tdata_t base, toff_t size); | ||||
| ▲ Show 20 Lines • Show All 43 Lines • ▼ Show 20 Lines | |||||
| { | { | ||||
| tsize_t nRemaining, nCopy; | tsize_t nRemaining, nCopy; | ||||
| ImbTIFFMemFile *mfile; | ImbTIFFMemFile *mfile; | ||||
| void *srcAddr; | void *srcAddr; | ||||
| /* get the pointer to the in-memory file */ | /* get the pointer to the in-memory file */ | ||||
| mfile = IMB_TIFF_GET_MEMFILE(handle); | mfile = IMB_TIFF_GET_MEMFILE(handle); | ||||
| if (!mfile || !mfile->mem) { | if (!mfile || !mfile->mem) { | ||||
| fprintf(stderr, "imb_tiff_ReadProc: !mfile || !mfile->mem!\n"); | CLOG_STR_ERROR(&LOG, "!mfile || !mfile->mem!"); | ||||
| return 0; | return 0; | ||||
| } | } | ||||
| /* find the actual number of bytes to read (copy) */ | /* find the actual number of bytes to read (copy) */ | ||||
| nCopy = n; | nCopy = n; | ||||
| if ((tsize_t)mfile->offset >= mfile->size) | if ((tsize_t)mfile->offset >= mfile->size) | ||||
| nRemaining = 0; | nRemaining = 0; | ||||
| else | else | ||||
| Show All 22 Lines | |||||
| * is simply a stub. | * is simply a stub. | ||||
| */ | */ | ||||
| static tsize_t imb_tiff_WriteProc(thandle_t handle, tdata_t data, tsize_t n) | static tsize_t imb_tiff_WriteProc(thandle_t handle, tdata_t data, tsize_t n) | ||||
| { | { | ||||
| (void)handle; | (void)handle; | ||||
| (void)data; | (void)data; | ||||
| (void)n; | (void)n; | ||||
| printf("imb_tiff_WriteProc: this function should not be called.\n"); | CLOG_ERROR(&LOG, "this function should not be called."); | ||||
sobakasu: this is my favourite error message | |||||
| return (-1); | return (-1); | ||||
| } | } | ||||
| /** | /** | ||||
| * Seeks to a new location in an in-memory TIFF file. | * Seeks to a new location in an in-memory TIFF file. | ||||
| * | * | ||||
| Show All 11 Lines | |||||
| static toff_t imb_tiff_SeekProc(thandle_t handle, toff_t ofs, int whence) | static toff_t imb_tiff_SeekProc(thandle_t handle, toff_t ofs, int whence) | ||||
| { | { | ||||
| ImbTIFFMemFile *mfile; | ImbTIFFMemFile *mfile; | ||||
| toff_t new_offset; | toff_t new_offset; | ||||
| /* get the pointer to the in-memory file */ | /* get the pointer to the in-memory file */ | ||||
| mfile = IMB_TIFF_GET_MEMFILE(handle); | mfile = IMB_TIFF_GET_MEMFILE(handle); | ||||
| if (!mfile || !mfile->mem) { | if (!mfile || !mfile->mem) { | ||||
| fprintf(stderr, "imb_tiff_SeekProc: !mfile || !mfile->mem!\n"); | CLOG_ERROR(&LOG, "!mfile || !mfile->mem!"); | ||||
| return (-1); | return (-1); | ||||
| } | } | ||||
| /* find the location we plan to seek to */ | /* find the location we plan to seek to */ | ||||
| switch (whence) { | switch (whence) { | ||||
| case SEEK_SET: | case SEEK_SET: | ||||
| new_offset = ofs; | new_offset = ofs; | ||||
| break; | break; | ||||
| case SEEK_CUR: | case SEEK_CUR: | ||||
| new_offset = mfile->offset + ofs; | new_offset = mfile->offset + ofs; | ||||
| break; | break; | ||||
| default: | default: | ||||
| /* no other types are supported - return an error */ | /* no other types are supported - return an error */ | ||||
| fprintf(stderr, | CLOG_ERROR(&LOG, "Unsupported TIFF SEEK type."); | ||||
| "imb_tiff_SeekProc: " | |||||
| "Unsupported TIFF SEEK type.\n"); | |||||
| return (-1); | return (-1); | ||||
| } | } | ||||
| /* set the new location */ | /* set the new location */ | ||||
| mfile->offset = new_offset; | mfile->offset = new_offset; | ||||
| return mfile->offset; | return mfile->offset; | ||||
| } | } | ||||
| Show All 13 Lines | |||||
| */ | */ | ||||
| static int imb_tiff_CloseProc(thandle_t handle) | static int imb_tiff_CloseProc(thandle_t handle) | ||||
| { | { | ||||
| ImbTIFFMemFile *mfile; | ImbTIFFMemFile *mfile; | ||||
| /* get the pointer to the in-memory file */ | /* get the pointer to the in-memory file */ | ||||
| mfile = IMB_TIFF_GET_MEMFILE(handle); | mfile = IMB_TIFF_GET_MEMFILE(handle); | ||||
| if (!mfile || !mfile->mem) { | if (!mfile || !mfile->mem) { | ||||
| fprintf(stderr, "imb_tiff_CloseProc: !mfile || !mfile->mem!\n"); | CLOG_ERROR(&LOG, "!mfile || !mfile->mem!"); | ||||
| return (0); | return (0); | ||||
| } | } | ||||
| /* virtually close the file */ | /* virtually close the file */ | ||||
| mfile->mem = NULL; | mfile->mem = NULL; | ||||
| mfile->offset = 0; | mfile->offset = 0; | ||||
| mfile->size = 0; | mfile->size = 0; | ||||
| Show All 9 Lines | |||||
| */ | */ | ||||
| static toff_t imb_tiff_SizeProc(thandle_t handle) | static toff_t imb_tiff_SizeProc(thandle_t handle) | ||||
| { | { | ||||
| ImbTIFFMemFile *mfile; | ImbTIFFMemFile *mfile; | ||||
| /* get the pointer to the in-memory file */ | /* get the pointer to the in-memory file */ | ||||
| mfile = IMB_TIFF_GET_MEMFILE(handle); | mfile = IMB_TIFF_GET_MEMFILE(handle); | ||||
| if (!mfile || !mfile->mem) { | if (!mfile || !mfile->mem) { | ||||
| fprintf(stderr, "imb_tiff_SizeProc: !mfile || !mfile->mem!\n"); | CLOG_ERROR(&LOG, "!mfile || !mfile->mem!"); | ||||
| return (0); | return (0); | ||||
| } | } | ||||
| /* return the size */ | /* return the size */ | ||||
| return (toff_t)(mfile->size); | return (toff_t)(mfile->size); | ||||
| } | } | ||||
| static TIFF *imb_tiff_client_open(ImbTIFFMemFile *memFile, const unsigned char *mem, size_t size) | static TIFF *imb_tiff_client_open(ImbTIFFMemFile *memFile, const unsigned char *mem, size_t size) | ||||
| ▲ Show 20 Lines • Show All 261 Lines • ▼ Show 20 Lines | ImBuf *imb_loadtiff(const unsigned char *mem, size_t size, int flags, char colorspace[IM_MAX_SPACE]) | ||||
| char *format = NULL; | char *format = NULL; | ||||
| int level; | int level; | ||||
| short spp; | short spp; | ||||
| int ib_depth; | int ib_depth; | ||||
| int found; | int found; | ||||
| /* check whether or not we have a TIFF file */ | /* 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"); | CLOG_ERROR(&LOG, "size < IMB_TIFF_NCB"); | ||||
| return NULL; | return NULL; | ||||
| } | } | ||||
| if (imb_is_a_tiff(mem) == 0) | if (imb_is_a_tiff(mem) == 0) | ||||
| return NULL; | return NULL; | ||||
| /* both 8 and 16 bit PNGs are default to standard byte colorspace */ | /* both 8 and 16 bit PNGs are default to standard byte colorspace */ | ||||
| colorspace_set_default_role(colorspace, IM_MAX_SPACE, COLOR_ROLE_DEFAULT_BYTE); | colorspace_set_default_role(colorspace, IM_MAX_SPACE, COLOR_ROLE_DEFAULT_BYTE); | ||||
| image = imb_tiff_client_open(&memFile, mem, size); | image = imb_tiff_client_open(&memFile, mem, size); | ||||
| if (image == NULL) { | if (image == NULL) { | ||||
| printf("imb_loadtiff: could not open TIFF IO layer.\n"); | CLOG_ERROR(&LOG, "could not open TIFF IO layer."); | ||||
| return NULL; | return NULL; | ||||
| } | } | ||||
| /* allocate the image buffer */ | /* allocate the image buffer */ | ||||
| TIFFGetField(image, TIFFTAG_IMAGEWIDTH, &width); | TIFFGetField(image, TIFFTAG_IMAGEWIDTH, &width); | ||||
| TIFFGetField(image, TIFFTAG_IMAGELENGTH, &height); | TIFFGetField(image, TIFFTAG_IMAGELENGTH, &height); | ||||
| TIFFGetField(image, TIFFTAG_SAMPLESPERPIXEL, &spp); | TIFFGetField(image, TIFFTAG_SAMPLESPERPIXEL, &spp); | ||||
| ib_depth = (spp == 3) ? 24 : 32; | ib_depth = (spp == 3) ? 24 : 32; | ||||
| ibuf = IMB_allocImBuf(width, height, ib_depth, 0); | ibuf = IMB_allocImBuf(width, height, ib_depth, 0); | ||||
| if (ibuf) { | if (ibuf) { | ||||
| ibuf->ftype = IMB_FTYPE_TIF; | ibuf->ftype = IMB_FTYPE_TIF; | ||||
| } | } | ||||
| else { | else { | ||||
| fprintf(stderr, | CLOG_ERROR(&LOG, "could not allocate memory for TIFF image."); | ||||
| "imb_loadtiff: could not allocate memory for TIFF " | |||||
| "image.\n"); | |||||
| TIFFClose(image); | TIFFClose(image); | ||||
| return NULL; | return NULL; | ||||
| } | } | ||||
| /* get alpha mode from file header */ | /* get alpha mode from file header */ | ||||
| if (flags & IB_alphamode_detect) { | if (flags & IB_alphamode_detect) { | ||||
| if (spp == 4) { | if (spp == 4) { | ||||
| unsigned short extra, *extraSampleTypes; | unsigned short extra, *extraSampleTypes; | ||||
| ▲ Show 20 Lines • Show All 50 Lines • ▼ Show 20 Lines | if (format && STREQ(format, "Plain Texture") && TIFFIsTiled(image)) { | ||||
| ibuf->miptot++; | ibuf->miptot++; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| /* read pixels */ | /* read pixels */ | ||||
| if (!(ibuf->flags & IB_tilecache) && !imb_read_tiff_pixels(ibuf, image)) { | if (!(ibuf->flags & IB_tilecache) && !imb_read_tiff_pixels(ibuf, image)) { | ||||
| fprintf(stderr, "imb_loadtiff: Failed to read tiff image.\n"); | CLOG_ERROR(&LOG, "Failed to read tiff image."); | ||||
| TIFFClose(image); | TIFFClose(image); | ||||
| return NULL; | return NULL; | ||||
| } | } | ||||
| /* close the client layer interface to the in-memory file */ | /* close the client layer interface to the in-memory file */ | ||||
| TIFFClose(image); | TIFFClose(image); | ||||
| /* return successfully */ | /* return successfully */ | ||||
| return ibuf; | return ibuf; | ||||
| } | } | ||||
| void imb_loadtiletiff(ImBuf *ibuf, const unsigned char *mem, size_t size, int tx, int ty, unsigned int *rect) | void imb_loadtiletiff(ImBuf *ibuf, const unsigned char *mem, size_t size, int tx, int ty, unsigned int *rect) | ||||
| { | { | ||||
| TIFF *image = NULL; | TIFF *image = NULL; | ||||
| uint32 width, height; | uint32 width, height; | ||||
| ImbTIFFMemFile memFile; | ImbTIFFMemFile memFile; | ||||
| image = imb_tiff_client_open(&memFile, mem, size); | image = imb_tiff_client_open(&memFile, mem, size); | ||||
| if (image == NULL) { | if (image == NULL) { | ||||
| printf("imb_loadtiff: could not open TIFF IO layer for loading mipmap level.\n"); | CLOG_ERROR(&LOG, "could not open TIFF IO layer for loading mipmap level."); | ||||
| return; | return; | ||||
| } | } | ||||
| if (TIFFSetDirectory(image, ibuf->miplevel)) { /* allocate the image buffer */ | if (TIFFSetDirectory(image, ibuf->miplevel)) { /* allocate the image buffer */ | ||||
| TIFFGetField(image, TIFFTAG_IMAGEWIDTH, &width); | TIFFGetField(image, TIFFTAG_IMAGEWIDTH, &width); | ||||
| TIFFGetField(image, TIFFTAG_IMAGELENGTH, &height); | TIFFGetField(image, TIFFTAG_IMAGELENGTH, &height); | ||||
| if (width == ibuf->x && height == ibuf->y) { | if (width == ibuf->x && height == ibuf->y) { | ||||
| if (rect) { | if (rect) { | ||||
| /* tiff pixels are bottom to top, tiles are top to bottom */ | /* tiff pixels are bottom to top, tiles are top to bottom */ | ||||
| if (TIFFReadRGBATile(image, tx * ibuf->tilex, (ibuf->ytiles - 1 - ty) * ibuf->tiley, rect) == 1) { | if (TIFFReadRGBATile(image, tx * ibuf->tilex, (ibuf->ytiles - 1 - ty) * ibuf->tiley, rect) == 1) { | ||||
| if (ibuf->tiley > ibuf->y) | if (ibuf->tiley > ibuf->y) | ||||
| memmove(rect, rect + ibuf->tilex * (ibuf->tiley - ibuf->y), sizeof(int) * ibuf->tilex * ibuf->y); | memmove(rect, rect + ibuf->tilex * (ibuf->tiley - ibuf->y), sizeof(int) * ibuf->tilex * ibuf->y); | ||||
| } | } | ||||
| else | else | ||||
| printf("imb_loadtiff: failed to read tiff tile at mipmap level %d\n", ibuf->miplevel); | CLOG_ERROR(&LOG, "failed to read tiff tile at mipmap level %d", ibuf->miplevel); | ||||
| } | } | ||||
| } | } | ||||
| else | else | ||||
| printf("imb_loadtiff: mipmap level %d has unexpected size %ux%u instead of %dx%d\n", ibuf->miplevel, width, height, ibuf->x, ibuf->y); | CLOG_ERROR(&LOG, "mipmap level %d has unexpected size %ux%u instead of %dx%d", ibuf->miplevel, width, height, ibuf->x, ibuf->y); | ||||
| } | } | ||||
| else | else | ||||
| printf("imb_loadtiff: could not find mipmap level %d\n", ibuf->miplevel); | CLOG_ERROR(&LOG, "could not find mipmap level %d", ibuf->miplevel); | ||||
| /* close the client layer interface to the in-memory file */ | /* close the client layer interface to the in-memory file */ | ||||
| TIFFClose(image); | TIFFClose(image); | ||||
| } | } | ||||
| /** | /** | ||||
| * Saves a TIFF file. | * Saves a TIFF file. | ||||
| * | * | ||||
| Show All 23 Lines | int imb_savetiff(ImBuf *ibuf, const char *name, int flags) | ||||
| int x, y, from_i, to_i, i; | int x, y, from_i, to_i, i; | ||||
| int compress_mode = COMPRESSION_NONE; | int compress_mode = COMPRESSION_NONE; | ||||
| /* check for a valid number of bytes per pixel. Like the PNG writer, | /* check for a valid number of bytes per pixel. Like the PNG writer, | ||||
| * the TIFF writer supports 1, 3 or 4 bytes per pixel, corresponding | * the TIFF writer supports 1, 3 or 4 bytes per pixel, corresponding | ||||
| * to gray, RGB, RGBA respectively. */ | * to gray, RGB, RGBA respectively. */ | ||||
| samplesperpixel = (uint16)((ibuf->planes + 7) >> 3); | samplesperpixel = (uint16)((ibuf->planes + 7) >> 3); | ||||
| if ((samplesperpixel > 4) || (samplesperpixel == 2)) { | if ((samplesperpixel > 4) || (samplesperpixel == 2)) { | ||||
| fprintf(stderr, | CLOG_ERROR(&LOG, "unsupported number of bytes per pixel: %d", samplesperpixel); | ||||
| "imb_savetiff: unsupported number of bytes per " | |||||
| "pixel: %d\n", samplesperpixel); | |||||
| return (0); | return (0); | ||||
| } | } | ||||
| if ((ibuf->foptions.flag & TIF_16BIT) && ibuf->rect_float) | if ((ibuf->foptions.flag & TIF_16BIT) && ibuf->rect_float) | ||||
| bitspersample = 16; | bitspersample = 16; | ||||
| else | else | ||||
| bitspersample = 8; | bitspersample = 8; | ||||
| if (ibuf->foptions.flag & TIF_COMPRESS_DEFLATE) | if (ibuf->foptions.flag & TIF_COMPRESS_DEFLATE) | ||||
| compress_mode = COMPRESSION_DEFLATE; | compress_mode = COMPRESSION_DEFLATE; | ||||
| else if (ibuf->foptions.flag & TIF_COMPRESS_LZW) | else if (ibuf->foptions.flag & TIF_COMPRESS_LZW) | ||||
| compress_mode = COMPRESSION_LZW; | compress_mode = COMPRESSION_LZW; | ||||
| else if (ibuf->foptions.flag & TIF_COMPRESS_PACKBITS) | else if (ibuf->foptions.flag & TIF_COMPRESS_PACKBITS) | ||||
| compress_mode = COMPRESSION_PACKBITS; | compress_mode = COMPRESSION_PACKBITS; | ||||
| /* open TIFF file for writing */ | /* open TIFF file for writing */ | ||||
| if (flags & IB_mem) { | if (flags & IB_mem) { | ||||
| /* bork at the creation of a TIFF in memory */ | /* bork at the creation of a TIFF in memory */ | ||||
| fprintf(stderr, | CLOG_ERROR(&LOG, "creation of in-memory TIFF files is not yet supported."); | ||||
| "imb_savetiff: creation of in-memory TIFF files is " | |||||
| "not yet supported.\n"); | |||||
| return (0); | return (0); | ||||
| } | } | ||||
| else { | else { | ||||
| /* create image as a file */ | /* create image as a file */ | ||||
| #ifdef WIN32 | #ifdef WIN32 | ||||
| wchar_t *wname = alloc_utf16_from_8(name, 0); | wchar_t *wname = alloc_utf16_from_8(name, 0); | ||||
| image = TIFFOpenW(wname, "w"); | image = TIFFOpenW(wname, "w"); | ||||
| free(wname); | free(wname); | ||||
| #else | #else | ||||
| image = TIFFOpen(name, "w"); | image = TIFFOpen(name, "w"); | ||||
| #endif | #endif | ||||
| } | } | ||||
| if (image == NULL) { | if (image == NULL) { | ||||
| fprintf(stderr, | CLOG_ERROR(&LOG, "could not open TIFF for writing."); | ||||
| "imb_savetiff: could not open TIFF for writing.\n"); | |||||
| return (0); | return (0); | ||||
| } | } | ||||
| /* allocate array for pixel data */ | /* allocate array for pixel data */ | ||||
| npixels = ibuf->x * ibuf->y; | npixels = ibuf->x * ibuf->y; | ||||
| if (bitspersample == 16) | if (bitspersample == 16) | ||||
| pixels16 = (unsigned short *)_TIFFmalloc(npixels * | pixels16 = (unsigned short *)_TIFFmalloc(npixels * | ||||
| samplesperpixel * sizeof(unsigned short)); | samplesperpixel * sizeof(unsigned short)); | ||||
| else | else | ||||
| pixels = (unsigned char *)_TIFFmalloc(npixels * | pixels = (unsigned char *)_TIFFmalloc(npixels * | ||||
| samplesperpixel * sizeof(unsigned char)); | samplesperpixel * sizeof(unsigned char)); | ||||
| if (pixels == NULL && pixels16 == NULL) { | if (pixels == NULL && pixels16 == NULL) { | ||||
| fprintf(stderr, | CLOG_ERROR(&LOG, "could not allocate pixels array."); | ||||
| "imb_savetiff: could not allocate pixels array.\n"); | |||||
| TIFFClose(image); | TIFFClose(image); | ||||
| return (0); | return (0); | ||||
| } | } | ||||
| /* setup pointers */ | /* setup pointers */ | ||||
| if (bitspersample == 16) { | if (bitspersample == 16) { | ||||
| fromf = ibuf->rect_float; | fromf = ibuf->rect_float; | ||||
| to16 = pixels16; | to16 = pixels16; | ||||
| ▲ Show 20 Lines • Show All 107 Lines • ▼ Show 20 Lines | #endif | ||||
| TIFFSetField(image, TIFFTAG_XRESOLUTION, xres); | TIFFSetField(image, TIFFTAG_XRESOLUTION, xres); | ||||
| TIFFSetField(image, TIFFTAG_YRESOLUTION, yres); | TIFFSetField(image, TIFFTAG_YRESOLUTION, yres); | ||||
| TIFFSetField(image, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH); | TIFFSetField(image, TIFFTAG_RESOLUTIONUNIT, RESUNIT_INCH); | ||||
| if (TIFFWriteEncodedStrip(image, 0, | if (TIFFWriteEncodedStrip(image, 0, | ||||
| (bitspersample == 16) ? (unsigned char *)pixels16 : pixels, | (bitspersample == 16) ? (unsigned char *)pixels16 : pixels, | ||||
| (size_t)ibuf->x * ibuf->y * samplesperpixel * bitspersample / 8) == -1) | (size_t)ibuf->x * ibuf->y * samplesperpixel * bitspersample / 8) == -1) | ||||
| { | { | ||||
| fprintf(stderr, | CLOG_ERROR(&LOG, "Could not write encoded TIFF."); | ||||
| "imb_savetiff: Could not write encoded TIFF.\n"); | |||||
| TIFFClose(image); | TIFFClose(image); | ||||
| if (pixels) _TIFFfree(pixels); | if (pixels) _TIFFfree(pixels); | ||||
| if (pixels16) _TIFFfree(pixels16); | if (pixels16) _TIFFfree(pixels16); | ||||
| return (1); | return (1); | ||||
| } | } | ||||
| /* close the TIFF file */ | /* close the TIFF file */ | ||||
| TIFFClose(image); | TIFFClose(image); | ||||
| if (pixels) _TIFFfree(pixels); | if (pixels) _TIFFfree(pixels); | ||||
| if (pixels16) _TIFFfree(pixels16); | if (pixels16) _TIFFfree(pixels16); | ||||
| return (1); | return (1); | ||||
| } | } | ||||
this is my favourite error message