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:
@@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user