diff --git a/src/tiffio.c b/src/tiffio.c index 80e1b76..95a811a 100644 --- a/src/tiffio.c +++ b/src/tiffio.c @@ -188,7 +188,8 @@ TIFF *tif; static PIX * pixReadFromTiffStream(TIFF *tif) { -l_uint8 *linebuf, *data; +void *linebuf; +l_uint8 *data; l_uint16 spp, bps, bpp, tiffbpl, photometry, orientation; l_uint16 *redmap, *greenmap, *bluemap; l_int32 d, wpl, bpl, i, j, k, ncolors; @@ -220,8 +221,15 @@ PIXCMAP *cmap; TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &h); tiffbpl = TIFFScanlineSize(tif); - if ((linebuf = (l_uint8 *)CALLOC(tiffbpl + 1, sizeof(l_uint8))) == NULL) - return (PIX *)ERROR_PTR("calloc fail for linebuf", procName, NULL); + if (spp > 1) { + if ((linebuf = (l_uint8 *)CALLOC(w * h + 1, sizeof(l_uint32))) == NULL) { + return (PIX *)ERROR_PTR("calloc fail for linebuf", procName, NULL); + } + } else { + if ((linebuf = (l_uint8 *)CALLOC(tiffbpl + 1, sizeof(l_uint8))) == NULL) { + return (PIX *)ERROR_PTR("calloc fail for linebuf", procName, NULL); + } + } if ((pix = pixCreate(w, h, d)) == NULL) { FREE(linebuf); @@ -235,7 +243,7 @@ PIXCMAP *cmap; /* Read the data */ if (spp == 1) { for (i = 0 ; i < h ; i++) { - if (TIFFReadScanline(tif, linebuf, i, 0) < 0) { + if (TIFFReadScanline(tif, (l_uint8 *)linebuf, i, 0) < 0) { FREE(linebuf); pixDestroy(&pix); return (PIX *)ERROR_PTR("line read fail", procName, NULL); @@ -249,18 +257,24 @@ PIXCMAP *cmap; pixEndianTwoByteSwap(pix); } else { /* rgb */ + if (TIFFReadRGBAImageOriented(tif, w, h, (uint32 *)linebuf, ORIENTATION_TOPLEFT, 0) == 0) { + FREE(linebuf); + pixDestroy(&pix); + return (PIX *)ERROR_PTR("line read fail", procName, NULL); + } + + if (TIFFIsByteSwapped(tif)) { + TIFFSwabArrayOfLong((uint32 *)linebuf, w * h); + } + line = pixGetData(pix); for (i = 0 ; i < h ; i++, line += wpl) { - if (TIFFReadScanline(tif, linebuf, i, 0) < 0) { - FREE(linebuf); - pixDestroy(&pix); - return (PIX *)ERROR_PTR("line read fail", procName, NULL); - } + l_uint32 *dataline = (l_uint32 *)linebuf + i*wpl; for (j = 0, k = 0, ppixel = line; j < w; j++) { - SET_DATA_BYTE(ppixel, COLOR_RED, linebuf[k++]); - SET_DATA_BYTE(ppixel, COLOR_GREEN, linebuf[k++]); - SET_DATA_BYTE(ppixel, COLOR_BLUE, linebuf[k++]); + SET_DATA_BYTE(ppixel, COLOR_RED, dataline[k++]); + SET_DATA_BYTE(ppixel, COLOR_GREEN, dataline[k++]); + SET_DATA_BYTE(ppixel, COLOR_BLUE, dataline[k++]); ppixel++; } }