diff options
author | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2010-07-30 17:31:22 +0400 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2010-07-30 17:31:22 +0400 |
commit | 2f4a78ec21ab7e350b3a77178982dffddce8d509 (patch) | |
tree | 1571c1a3afc0387d6dacdf01e874b6959e25130a /source/blender/imbuf | |
parent | ae662b823552c7962e5f3dbf9dbf298b319d2d26 (diff) |
Fix #23086: crash reading 1bit tiff files.
Diffstat (limited to 'source/blender/imbuf')
-rw-r--r-- | source/blender/imbuf/intern/tiff.c | 125 |
1 files changed, 32 insertions, 93 deletions
diff --git a/source/blender/imbuf/intern/tiff.c b/source/blender/imbuf/intern/tiff.c index 99f74fea640..6b94583f17d 100644 --- a/source/blender/imbuf/intern/tiff.c +++ b/source/blender/imbuf/intern/tiff.c @@ -301,17 +301,6 @@ int imb_is_a_tiff(unsigned char *mem) (memcmp(lil_endian, mem, IMB_TIFF_NCB) == 0) ); } -static void scanline_contig_8bit(unsigned char *rect, unsigned char *cbuf, int scanline_w, int spp) -{ - int i; - for (i=0; i < scanline_w; i++) { - rect[i*4 + 0] = cbuf[i*spp + 0]; - rect[i*4 + 1] = cbuf[i*spp + 1]; - rect[i*4 + 2] = cbuf[i*spp + 2]; - rect[i*4 + 3] = (spp==4)?cbuf[i*spp + 3]:255; - } -} - static void scanline_contig_16bit(float *rectf, unsigned short *sbuf, int scanline_w, int spp) { int i; @@ -334,13 +323,6 @@ static void scanline_contig_32bit(float *rectf, float *fbuf, int scanline_w, int } } -static void scanline_separate_8bit(unsigned char *rect, unsigned char *cbuf, int scanline_w, int chan) -{ - int i; - for (i=0; i < scanline_w; i++) - rect[i*4 + chan] = cbuf[i]; -} - static void scanline_separate_16bit(float *rectf, unsigned short *sbuf, int scanline_w, int chan) { int i; @@ -356,40 +338,6 @@ static void scanline_separate_32bit(float *rectf, float *fbuf, int scanline_w, i } -#if 0 -/* - * Use the libTIFF RGBAImage API to read a TIFF image. - * This function uses the "RGBA Image" support from libtiff, which enables - * it to load most commonly-encountered TIFF formats. libtiff handles format - * conversion, color depth conversion, etc. - */ -static int imb_read_tiff_pixels_rgba(ImBuf *ibuf, TIFF *image, int premul) -{ - ImBuf *tmpibuf; - int success; - - tmpibuf= IMB_allocImBuf(ibuf->x, ibuf->y, 32, IB_rect, 0); - success= TIFFReadRGBAImage(image, ibuf->x, ibuf->y, tmpibuf->rect, 0); - - if(ENDIAN_ORDER == B_ENDIAN) - IMB_convert_rgba_to_abgr(tmpibuf); - if(premul) { - IMB_premultiply_alpha(tmpibuf); - ibuf->flags |= IB_premul; - } - - /* assign rect last */ - ibuf->rect= tmpibuf->rect; - ibuf->mall |= IB_rect; - ibuf->flags |= IB_rect; - - tmpibuf->mall &= ~IB_rect; - IMB_freeImBuf(tmpibuf); - - return success; -} -#endif - /* * Use the libTIFF scanline API to read a TIFF image. * This method is most flexible and can handle multiple different bit depths @@ -398,13 +346,12 @@ static int imb_read_tiff_pixels_rgba(ImBuf *ibuf, TIFF *image, int premul) static int imb_read_tiff_pixels(ImBuf *ibuf, TIFF *image, int premul) { ImBuf *tmpibuf; - int success; + int success= 0; short bitspersample, spp, config; size_t scanline; int ib_flag=0, row, chan; float *fbuf=NULL; unsigned short *sbuf=NULL; - unsigned char *cbuf=NULL; TIFFGetField(image, TIFFTAG_BITSPERSAMPLE, &bitspersample); TIFFGetField(image, TIFFTAG_SAMPLESPERPIXEL, &spp); /* number of 'channels' */ @@ -417,30 +364,28 @@ static int imb_read_tiff_pixels(ImBuf *ibuf, TIFF *image, int premul) } else if (bitspersample == 16) { ib_flag = IB_rectfloat; sbuf = (unsigned short *)_TIFFmalloc(scanline); - } else if (bitspersample == 8) { + } else { ib_flag = IB_rect; - cbuf = (unsigned char *)_TIFFmalloc(scanline); } tmpibuf= IMB_allocImBuf(ibuf->x, ibuf->y, ibuf->depth, ib_flag, 0); + /* simple RGBA image */ + if (!(bitspersample == 32 || bitspersample == 16)) { + success |= TIFFReadRGBAImage(image, ibuf->x, ibuf->y, tmpibuf->rect, 0); + } /* contiguous channels: RGBRGBRGB */ - if (config == PLANARCONFIG_CONTIG) { + else if (config == PLANARCONFIG_CONTIG) { for (row = 0; row < ibuf->y; row++) { int ib_offset = ibuf->x*ibuf->y*4 - ibuf->x*4 * (row+1); if (bitspersample == 32) { - success = TIFFReadScanline(image, fbuf, row, 0); + success |= TIFFReadScanline(image, fbuf, row, 0); scanline_contig_32bit(tmpibuf->rect_float+ib_offset, fbuf, ibuf->x, spp); } else if (bitspersample == 16) { - success = TIFFReadScanline(image, sbuf, row, 0); + success |= TIFFReadScanline(image, sbuf, row, 0); scanline_contig_16bit(tmpibuf->rect_float+ib_offset, sbuf, ibuf->x, spp); - - } else if (bitspersample == 8) { - unsigned char *crect = (unsigned char*)tmpibuf->rect; - success = TIFFReadScanline(image, cbuf, row, 0); - scanline_contig_8bit(crect+ib_offset, cbuf, ibuf->x, spp); } } /* separate channels: RRRGGGBBB */ @@ -456,53 +401,47 @@ static int imb_read_tiff_pixels(ImBuf *ibuf, TIFF *image, int premul) if (chan == 3 && spp == 3) /* fill alpha if only RGB TIFF */ memset(fbuf, 1.0, sizeof(fbuf)); else - success = TIFFReadScanline(image, fbuf, row, chan); + success |= TIFFReadScanline(image, fbuf, row, chan); scanline_separate_32bit(tmpibuf->rect_float+ib_offset, fbuf, ibuf->x, chan); } else if (bitspersample == 16) { if (chan == 3 && spp == 3) /* fill alpha if only RGB TIFF */ memset(sbuf, 65535, sizeof(sbuf)); else - success = TIFFReadScanline(image, sbuf, row, chan); + success |= TIFFReadScanline(image, sbuf, row, chan); scanline_separate_16bit(tmpibuf->rect_float+ib_offset, sbuf, ibuf->x, chan); - } else if (bitspersample == 8) { - unsigned char *crect = (unsigned char*)tmpibuf->rect; - if (chan == 3 && spp == 3) /* fill alpha if only RGB TIFF */ - memset(cbuf, 255, sizeof(cbuf)); - else - success = TIFFReadScanline(image, cbuf, row, chan); - scanline_separate_8bit(crect+ib_offset, cbuf, ibuf->x, chan); } } } } - ibuf->profile = (bitspersample==32)?IB_PROFILE_LINEAR_RGB:IB_PROFILE_SRGB; - if (bitspersample == 32) _TIFFfree(fbuf); else if (bitspersample == 16) _TIFFfree(sbuf); - else if (bitspersample == 8) - _TIFFfree(cbuf); + + if(success) { + ibuf->profile = (bitspersample==32)?IB_PROFILE_LINEAR_RGB:IB_PROFILE_SRGB; + + if(ENDIAN_ORDER == B_ENDIAN) + IMB_convert_rgba_to_abgr(tmpibuf); + if(premul) { + IMB_premultiply_alpha(tmpibuf); + ibuf->flags |= IB_premul; + } - if(ENDIAN_ORDER == B_ENDIAN) - IMB_convert_rgba_to_abgr(tmpibuf); - if(premul) { - IMB_premultiply_alpha(tmpibuf); - ibuf->flags |= IB_premul; + /* assign rect last */ + if (tmpibuf->rect_float) + ibuf->rect_float= tmpibuf->rect_float; + else + ibuf->rect= tmpibuf->rect; + ibuf->mall |= ib_flag; + ibuf->flags |= ib_flag; + + tmpibuf->mall &= ~ib_flag; } - - /* assign rect last */ - if (tmpibuf->rect_float) - ibuf->rect_float= tmpibuf->rect_float; - else - ibuf->rect= tmpibuf->rect; - ibuf->mall |= ib_flag; - ibuf->flags |= ib_flag; - - tmpibuf->mall &= ~ib_flag; + IMB_freeImBuf(tmpibuf); return success; @@ -847,4 +786,4 @@ int imb_savetiff(ImBuf *ibuf, char *name, int flags) return (1); } -#endif /* WITH_TIFF */
\ No newline at end of file +#endif /* WITH_TIFF */ |