added support for reading 8, 4-bit uncompressed, packbits encoded grayscale TIFF images

git-svn-id: file:///srv/svn/repos/haiku/trunk/current@3092 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Matthew Wilber
2003-04-22 01:51:33 +00:00
parent d9e72f220a
commit 08c96d28c5
2 changed files with 61 additions and 26 deletions
@@ -420,21 +420,28 @@ check_tiff_fields(TiffIfd &ifd, TiffDetails *pdetails)
compression != COMPRESSION_PACKBITS) compression != COMPRESSION_PACKBITS)
return B_NO_TRANSLATOR; return B_NO_TRANSLATOR;
uint16 imageType; uint16 imageType = 0, bitsPerPixel = 0;
switch (interpretation) { switch (interpretation) {
// Bilevel images // black and white or grayscale images
case PHOTO_WHITEZERO: case PHOTO_WHITEZERO:
case PHOTO_BLACKZERO: case PHOTO_BLACKZERO:
// default value for samples per pixel is 1 // default value for samples per pixel is 1
if (ifd.HasField(TAG_SAMPLES_PER_PIXEL) && if (ifd.HasField(TAG_SAMPLES_PER_PIXEL) &&
ifd.GetUint(TAG_SAMPLES_PER_PIXEL) != 1) ifd.GetUint(TAG_SAMPLES_PER_PIXEL) != 1)
return B_NO_TRANSLATOR; return B_NO_TRANSLATOR;
// default value for bits per sample is 1 // default value for bits per sample is 1
if (ifd.HasField(TAG_BITS_PER_SAMPLE) && if (!ifd.HasField(TAG_BITS_PER_SAMPLE) ||
ifd.GetUint(TAG_BITS_PER_SAMPLE) != 1) ifd.GetUint(TAG_BITS_PER_SAMPLE) == 1)
bitsPerPixel = 1;
else if (ifd.GetUint(TAG_BITS_PER_SAMPLE) == 4 ||
ifd.GetUint(TAG_BITS_PER_SAMPLE) == 8)
bitsPerPixel = ifd.GetUint(TAG_BITS_PER_SAMPLE);
else
return B_NO_TRANSLATOR; return B_NO_TRANSLATOR;
imageType = TIFF_BILEVEL; imageType = TIFF_BILEVEL;
break; break;
// Palette color images // Palette color images
@@ -521,10 +528,13 @@ check_tiff_fields(TiffIfd &ifd, TiffDetails *pdetails)
pdetails->rowsPerStrip = rowsPerStrip; pdetails->rowsPerStrip = rowsPerStrip;
pdetails->stripsPerImage = stripsPerImage; pdetails->stripsPerImage = stripsPerImage;
pdetails->interpretation = interpretation; pdetails->interpretation = interpretation;
pdetails->bitsPerPixel = bitsPerPixel;
pdetails->imageType = imageType; pdetails->imageType = imageType;
ifd.GetUintArray(TAG_STRIP_OFFSETS, &pdetails->pstripOffsets); ifd.GetUintArray(TAG_STRIP_OFFSETS,
ifd.GetUintArray(TAG_STRIP_BYTE_COUNTS, &pdetails->pstripByteCounts); &pdetails->pstripOffsets);
ifd.GetUintArray(TAG_STRIP_BYTE_COUNTS,
&pdetails->pstripByteCounts);
} }
} catch (TiffIfdException) { } catch (TiffIfdException) {
@@ -704,28 +714,49 @@ tiff_to_bits(uint8 *ptiff, uint32 tifflen, uint8 *pbits, TiffDetails &details)
switch (details.imageType) { switch (details.imageType) {
case TIFF_BILEVEL: case TIFF_BILEVEL:
{ if (details.bitsPerPixel == 1) {
uint8 black[3] = { 0x00, 0x00, 0x00 }, // black and white
white[3] = { 0xFF, 0xFF, 0xFF }; uint8 black[3] = { 0x00, 0x00, 0x00 },
uint8 *colors[2]; white[3] = { 0xFF, 0xFF, 0xFF };
if (details.interpretation == PHOTO_WHITEZERO) { uint8 *colors[2];
colors[0] = white; if (details.interpretation == PHOTO_WHITEZERO) {
colors[1] = black; colors[0] = white;
colors[1] = black;
} else {
colors[0] = black;
colors[1] = white;
}
for (uint32 i = 0; i < details.width; i++) {
uint8 eightbits = (ptiff + (i / 8))[0];
uint8 abit;
abit = (eightbits >> (7 - (i % 8))) & 1;
memcpy(pbits + (i * 4), colors[abit], 3);
}
} else { } else {
colors[0] = black; // grayscale
colors[1] = white; uint8 invert = 0;
if (details.interpretation == PHOTO_WHITEZERO)
invert = 0xff;
if (details.bitsPerPixel == 8) {
for (uint32 i = 0; i < details.width; i++) {
memset(pbits, invert + ptiff[i], 3);
pbits += 4;
}
} else if (details.bitsPerPixel == 4) {
const uint8 mask = 0x0f;
for (uint32 i = 0; i < details.width; i++) {
uint8 values = (ptiff + (i / 2))[0];
uint8 value = (values >> (4 * (1 - (i % 2)))) & mask;
memset(pbits, invert + (value * 16), 3);
pbits += 4;
}
}
} }
for (uint32 i = 0; i < details.width; i++) {
uint8 eightbits = (ptiff + (i / 8))[0];
uint8 abit;
abit = (eightbits >> (7 - (i % 8))) & 1;
memcpy(pbits + (i * 4), colors[abit], 3);
}
break; break;
}
case TIFF_RGB: case TIFF_RGB:
while (ptiff < ptiffend) { while (ptiff < ptiffend) {
@@ -904,9 +935,12 @@ TIFFTranslator::translate_from_tiff(BPositionIO *inSource, ssize_t amtread,
outbufferlen = 4 * details.width; outbufferlen = 4 * details.width;
switch (details.imageType) { switch (details.imageType) {
case TIFF_BILEVEL: case TIFF_BILEVEL:
inbufferlen = (details.width / 8) + {
((details.width % 8) ? 1 : 0); uint32 pixelsPerByte = 8 / details.bitsPerPixel;
inbufferlen = (details.width / pixelsPerByte) +
((details.width % pixelsPerByte) ? 1 : 0);
break; break;
}
case TIFF_RGB: case TIFF_RGB:
inbufferlen = 3 * details.width; inbufferlen = 3 * details.width;
break; break;
@@ -80,6 +80,7 @@ public:
uint32 *pstripOffsets; uint32 *pstripOffsets;
uint32 *pstripByteCounts; uint32 *pstripByteCounts;
uint16 interpretation; uint16 interpretation;
uint16 bitsPerPixel;
uint16 imageType; uint16 imageType;
}; };