fixed issue with PHOTO_WHITEISZERO inverted grayscale images, added support for 1-D Group 3 Fax compressed images, added support for fill order 2 for monochrome images
git-svn-id: file:///srv/svn/repos/haiku/trunk/current@3176 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -31,15 +31,9 @@
|
|||||||
|
|
||||||
#include "BitReader.h"
|
#include "BitReader.h"
|
||||||
|
|
||||||
BitReader::BitReader(StreamBuffer *pstreambuf)
|
BitReader::BitReader(uint16 fillOrder, StreamBuffer *pstreambuf, bool binitialRead)
|
||||||
{
|
{
|
||||||
finitStatus = B_BAD_VALUE;
|
SetTo(fillOrder, pstreambuf, binitialRead);
|
||||||
fnbytesRead = 0;
|
|
||||||
fbitbuf = 0;
|
|
||||||
fcurrentbit = 0;
|
|
||||||
fpstreambuf = pstreambuf;
|
|
||||||
if (fpstreambuf)
|
|
||||||
finitStatus = ReadByte();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BitReader::~BitReader()
|
BitReader::~BitReader()
|
||||||
@@ -50,6 +44,25 @@ BitReader::~BitReader()
|
|||||||
fcurrentbit = 0;
|
fcurrentbit = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
status_t
|
||||||
|
BitReader::SetTo(uint16 fillOrder, StreamBuffer *pstreambuf, bool binitialRead)
|
||||||
|
{
|
||||||
|
finitStatus = B_OK;
|
||||||
|
fnbytesRead = 0;
|
||||||
|
fbitbuf = 0;
|
||||||
|
fcurrentbit = 0;
|
||||||
|
fpstreambuf = pstreambuf;
|
||||||
|
ffillOrder = fillOrder;
|
||||||
|
if (ffillOrder != 1 && ffillOrder != 2)
|
||||||
|
finitStatus = B_BAD_VALUE;
|
||||||
|
else if (!fpstreambuf)
|
||||||
|
finitStatus = B_BAD_VALUE;
|
||||||
|
else if (binitialRead)
|
||||||
|
finitStatus = ReadByte();
|
||||||
|
|
||||||
|
return finitStatus;
|
||||||
|
}
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
BitReader::NextBit()
|
BitReader::NextBit()
|
||||||
{
|
{
|
||||||
@@ -68,7 +81,10 @@ BitReader::PeekBit()
|
|||||||
if (!fcurrentbit && ReadByte() != B_OK)
|
if (!fcurrentbit && ReadByte() != B_OK)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
|
if (ffillOrder == 1)
|
||||||
return (fbitbuf >> (fcurrentbit - 1)) & 1;
|
return (fbitbuf >> (fcurrentbit - 1)) & 1;
|
||||||
|
else
|
||||||
|
return (fbitbuf >> (8 - fcurrentbit)) & 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
|
|||||||
@@ -37,9 +37,13 @@
|
|||||||
|
|
||||||
class BitReader {
|
class BitReader {
|
||||||
public:
|
public:
|
||||||
BitReader(StreamBuffer *pstreambuf);
|
// Setup the BitReader to read from the given stream with the given fill order
|
||||||
|
BitReader(uint16 fillOrder, StreamBuffer *pstreambuf, bool binitialRead = true);
|
||||||
~BitReader();
|
~BitReader();
|
||||||
|
|
||||||
|
// Change the BitReader to read from given stream with the given fill order
|
||||||
|
status_t SetTo(uint16 fillOrder, StreamBuffer *pstreambuf, bool binitialRead = true);
|
||||||
|
|
||||||
status_t InitCheck() const { return finitStatus; };
|
status_t InitCheck() const { return finitStatus; };
|
||||||
|
|
||||||
uint32 BytesRead() const { return fnbytesRead; };
|
uint32 BytesRead() const { return fnbytesRead; };
|
||||||
@@ -59,6 +63,7 @@ private:
|
|||||||
StreamBuffer *fpstreambuf;
|
StreamBuffer *fpstreambuf;
|
||||||
status_t finitStatus;
|
status_t finitStatus;
|
||||||
uint32 fnbytesRead;
|
uint32 fnbytesRead;
|
||||||
|
uint16 ffillOrder;
|
||||||
uint8 fbitbuf;
|
uint8 fbitbuf;
|
||||||
uint8 fcurrentbit;
|
uint8 fcurrentbit;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -396,9 +396,6 @@ check_tiff_fields(TiffIfd &ifd, TiffDetails *pdetails, bool bAllocArrays)
|
|||||||
// (If they are not present, that is fine, but if
|
// (If they are not present, that is fine, but if
|
||||||
// they are present and have a non-default value,
|
// they are present and have a non-default value,
|
||||||
// that is a problem)
|
// that is a problem)
|
||||||
if (ifd.HasField(TAG_FILL_ORDER) &&
|
|
||||||
ifd.GetUint(TAG_FILL_ORDER) != 1)
|
|
||||||
return B_NO_TRANSLATOR;
|
|
||||||
if (ifd.HasField(TAG_ORIENTATION) &&
|
if (ifd.HasField(TAG_ORIENTATION) &&
|
||||||
ifd.GetUint(TAG_ORIENTATION) != 1)
|
ifd.GetUint(TAG_ORIENTATION) != 1)
|
||||||
return B_NO_TRANSLATOR;
|
return B_NO_TRANSLATOR;
|
||||||
@@ -420,7 +417,7 @@ check_tiff_fields(TiffIfd &ifd, TiffDetails *pdetails, bool bAllocArrays)
|
|||||||
else
|
else
|
||||||
compression = ifd.GetUint(TAG_COMPRESSION);
|
compression = ifd.GetUint(TAG_COMPRESSION);
|
||||||
|
|
||||||
uint16 imageType = 0, bitsPerPixel = 0;
|
uint16 imageType = 0, bitsPerPixel = 0, fillOrder = 1;
|
||||||
switch (interpretation) {
|
switch (interpretation) {
|
||||||
// black and white or grayscale images
|
// black and white or grayscale images
|
||||||
case PHOTO_WHITEZERO:
|
case PHOTO_WHITEZERO:
|
||||||
@@ -430,6 +427,12 @@ check_tiff_fields(TiffIfd &ifd, TiffDetails *pdetails, bool bAllocArrays)
|
|||||||
ifd.GetUint(TAG_SAMPLES_PER_PIXEL) != 1)
|
ifd.GetUint(TAG_SAMPLES_PER_PIXEL) != 1)
|
||||||
return B_NO_TRANSLATOR;
|
return B_NO_TRANSLATOR;
|
||||||
|
|
||||||
|
// Only the default value for T4 Options
|
||||||
|
// is supported
|
||||||
|
if (ifd.HasField(TAG_T4_OPTIONS) &&
|
||||||
|
ifd.GetUint(TAG_T4_OPTIONS) != 0)
|
||||||
|
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) {
|
||||||
@@ -437,13 +440,23 @@ check_tiff_fields(TiffIfd &ifd, TiffDetails *pdetails, bool bAllocArrays)
|
|||||||
|
|
||||||
if (compression != COMPRESSION_NONE &&
|
if (compression != COMPRESSION_NONE &&
|
||||||
compression != COMPRESSION_HUFFMAN &&
|
compression != COMPRESSION_HUFFMAN &&
|
||||||
|
compression != COMPRESSION_T4 &&
|
||||||
compression != COMPRESSION_PACKBITS)
|
compression != COMPRESSION_PACKBITS)
|
||||||
return B_NO_TRANSLATOR;
|
return B_NO_TRANSLATOR;
|
||||||
|
|
||||||
|
if (ifd.HasField(TAG_FILL_ORDER)) {
|
||||||
|
fillOrder = ifd.GetUint(TAG_FILL_ORDER);
|
||||||
|
if (fillOrder != 1 && fillOrder != 2)
|
||||||
|
return B_NO_TRANSLATOR;
|
||||||
|
}
|
||||||
|
|
||||||
} else if (ifd.GetUint(TAG_BITS_PER_SAMPLE) == 4 ||
|
} else if (ifd.GetUint(TAG_BITS_PER_SAMPLE) == 4 ||
|
||||||
ifd.GetUint(TAG_BITS_PER_SAMPLE) == 8) {
|
ifd.GetUint(TAG_BITS_PER_SAMPLE) == 8) {
|
||||||
bitsPerPixel = ifd.GetUint(TAG_BITS_PER_SAMPLE);
|
bitsPerPixel = ifd.GetUint(TAG_BITS_PER_SAMPLE);
|
||||||
|
|
||||||
|
if (ifd.HasField(TAG_FILL_ORDER) &&
|
||||||
|
ifd.GetUint(TAG_FILL_ORDER) != 1)
|
||||||
|
return B_NO_TRANSLATOR;
|
||||||
if (compression != COMPRESSION_NONE &&
|
if (compression != COMPRESSION_NONE &&
|
||||||
compression != COMPRESSION_PACKBITS)
|
compression != COMPRESSION_PACKBITS)
|
||||||
return B_NO_TRANSLATOR;
|
return B_NO_TRANSLATOR;
|
||||||
@@ -456,6 +469,9 @@ check_tiff_fields(TiffIfd &ifd, TiffDetails *pdetails, bool bAllocArrays)
|
|||||||
|
|
||||||
// Palette color images
|
// Palette color images
|
||||||
case PHOTO_PALETTE:
|
case PHOTO_PALETTE:
|
||||||
|
if (ifd.HasField(TAG_FILL_ORDER) &&
|
||||||
|
ifd.GetUint(TAG_FILL_ORDER) != 1)
|
||||||
|
return B_NO_TRANSLATOR;
|
||||||
if (compression != COMPRESSION_NONE &&
|
if (compression != COMPRESSION_NONE &&
|
||||||
compression != COMPRESSION_PACKBITS)
|
compression != COMPRESSION_PACKBITS)
|
||||||
return B_NO_TRANSLATOR;
|
return B_NO_TRANSLATOR;
|
||||||
@@ -478,6 +494,9 @@ check_tiff_fields(TiffIfd &ifd, TiffDetails *pdetails, bool bAllocArrays)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case PHOTO_RGB:
|
case PHOTO_RGB:
|
||||||
|
if (ifd.HasField(TAG_FILL_ORDER) &&
|
||||||
|
ifd.GetUint(TAG_FILL_ORDER) != 1)
|
||||||
|
return B_NO_TRANSLATOR;
|
||||||
if (compression != COMPRESSION_NONE &&
|
if (compression != COMPRESSION_NONE &&
|
||||||
compression != COMPRESSION_PACKBITS)
|
compression != COMPRESSION_PACKBITS)
|
||||||
return B_NO_TRANSLATOR;
|
return B_NO_TRANSLATOR;
|
||||||
@@ -494,6 +513,9 @@ check_tiff_fields(TiffIfd &ifd, TiffDetails *pdetails, bool bAllocArrays)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case PHOTO_SEPARATED:
|
case PHOTO_SEPARATED:
|
||||||
|
if (ifd.HasField(TAG_FILL_ORDER) &&
|
||||||
|
ifd.GetUint(TAG_FILL_ORDER) != 1)
|
||||||
|
return B_NO_TRANSLATOR;
|
||||||
if (compression != COMPRESSION_NONE &&
|
if (compression != COMPRESSION_NONE &&
|
||||||
compression != COMPRESSION_PACKBITS)
|
compression != COMPRESSION_PACKBITS)
|
||||||
return B_NO_TRANSLATOR;
|
return B_NO_TRANSLATOR;
|
||||||
@@ -525,13 +547,16 @@ check_tiff_fields(TiffIfd &ifd, TiffDetails *pdetails, bool bAllocArrays)
|
|||||||
rowsPerStrip = DEFAULT_ROWS_PER_STRIP;
|
rowsPerStrip = DEFAULT_ROWS_PER_STRIP;
|
||||||
else
|
else
|
||||||
rowsPerStrip = ifd.GetUint(TAG_ROWS_PER_STRIP);
|
rowsPerStrip = ifd.GetUint(TAG_ROWS_PER_STRIP);
|
||||||
|
if (rowsPerStrip == DEFAULT_ROWS_PER_STRIP)
|
||||||
|
stripsPerImage = 1;
|
||||||
|
else
|
||||||
stripsPerImage = (height + rowsPerStrip - 1) / rowsPerStrip;
|
stripsPerImage = (height + rowsPerStrip - 1) / rowsPerStrip;
|
||||||
|
|
||||||
if (ifd.GetCount(TAG_STRIP_OFFSETS) != stripsPerImage ||
|
if (ifd.GetCount(TAG_STRIP_OFFSETS) != stripsPerImage ||
|
||||||
ifd.GetCount(TAG_STRIP_BYTE_COUNTS) != stripsPerImage)
|
ifd.GetCount(TAG_STRIP_BYTE_COUNTS) != stripsPerImage)
|
||||||
return B_NO_TRANSLATOR;
|
return B_NO_TRANSLATOR;
|
||||||
|
|
||||||
// return read in details if output pointer is supplied
|
// return read in details
|
||||||
pdetails->width = width;
|
pdetails->width = width;
|
||||||
pdetails->height = height;
|
pdetails->height = height;
|
||||||
pdetails->compression = compression;
|
pdetails->compression = compression;
|
||||||
@@ -540,6 +565,7 @@ check_tiff_fields(TiffIfd &ifd, TiffDetails *pdetails, bool bAllocArrays)
|
|||||||
pdetails->interpretation = interpretation;
|
pdetails->interpretation = interpretation;
|
||||||
pdetails->bitsPerPixel = bitsPerPixel;
|
pdetails->bitsPerPixel = bitsPerPixel;
|
||||||
pdetails->imageType = imageType;
|
pdetails->imageType = imageType;
|
||||||
|
pdetails->fillOrder = fillOrder;
|
||||||
|
|
||||||
if (bAllocArrays) {
|
if (bAllocArrays) {
|
||||||
ifd.GetUint32Array(TAG_STRIP_OFFSETS,
|
ifd.GetUint32Array(TAG_STRIP_OFFSETS,
|
||||||
@@ -823,23 +849,35 @@ tiff_to_bits(uint8 *ptiff, uint32 tifflen, uint8 *pbits, TiffDetails &details)
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// grayscale
|
// grayscale
|
||||||
uint8 invert = 0;
|
|
||||||
if (details.interpretation == PHOTO_WHITEZERO)
|
|
||||||
invert = 0xff;
|
|
||||||
|
|
||||||
if (details.bitsPerPixel == 8) {
|
if (details.bitsPerPixel == 8) {
|
||||||
|
if (details.interpretation == PHOTO_WHITEZERO) {
|
||||||
for (uint32 i = 0; i < details.width; i++) {
|
for (uint32 i = 0; i < details.width; i++) {
|
||||||
memset(pbits, invert + ptiff[i], 3);
|
memset(pbits, 255 - ptiff[i], 3);
|
||||||
pbits += 4;
|
pbits += 4;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
for (uint32 i = 0; i < details.width; i++) {
|
||||||
|
memset(pbits, ptiff[i], 3);
|
||||||
|
pbits += 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
} else if (details.bitsPerPixel == 4) {
|
} else if (details.bitsPerPixel == 4) {
|
||||||
const uint8 mask = 0x0f;
|
const uint8 mask = 0x0f;
|
||||||
|
if (details.interpretation == PHOTO_WHITEZERO) {
|
||||||
for (uint32 i = 0; i < details.width; i++) {
|
for (uint32 i = 0; i < details.width; i++) {
|
||||||
uint8 values = (ptiff + (i / 2))[0];
|
uint8 values = (ptiff + (i / 2))[0];
|
||||||
uint8 value = (values >> (4 * (1 - (i % 2)))) & mask;
|
uint8 value = (values >> (4 * (1 - (i % 2)))) & mask;
|
||||||
memset(pbits, invert + (value * 16), 3);
|
memset(pbits, 255 - (value * 16), 3);
|
||||||
pbits += 4;
|
pbits += 4;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
for (uint32 i = 0; i < details.width; i++) {
|
||||||
|
uint8 values = (ptiff + (i / 2))[0];
|
||||||
|
uint8 value = (values >> (4 * (1 - (i % 2)))) & mask;
|
||||||
|
memset(pbits, (value * 16), 3);
|
||||||
|
pbits += 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -958,11 +996,81 @@ unpack(StreamBuffer *pstreambuf, uint8 *tiffbuffer, uint32 tiffbufferlen)
|
|||||||
return read;
|
return read;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ssize_t
|
||||||
|
TIFFTranslator::decode_t4(BitReader &stream, TiffDetails &details,
|
||||||
|
uint8 *pbits, bool bfirstLine)
|
||||||
|
{
|
||||||
|
if (bfirstLine) {
|
||||||
|
// read in and verify end-of-line sequence
|
||||||
|
uint32 nzeros = 11;
|
||||||
|
while (nzeros--)
|
||||||
|
{
|
||||||
|
if (stream.NextBit() != 0) {
|
||||||
|
debugger("xxx");
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (stream.NextBit() != 1) {
|
||||||
|
debugger("xxx");
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint8 kblack = 0x00, kwhite = 0xff;
|
||||||
|
uint8 colors[2];
|
||||||
|
if (details.interpretation == PHOTO_WHITEZERO) {
|
||||||
|
colors[0] = kwhite;
|
||||||
|
colors[1] = kblack;
|
||||||
|
} else {
|
||||||
|
colors[0] = kblack;
|
||||||
|
colors[1] = kwhite;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 pixelswrit = 0;
|
||||||
|
DecodeTree *ptrees[2] = {fpwhiteTree, fpblackTree};
|
||||||
|
uint8 currentcolor = 0;
|
||||||
|
uint8 *pcurrentpixel = pbits;
|
||||||
|
status_t value = 0;
|
||||||
|
while (pixelswrit < details.width || value >= 64) {
|
||||||
|
value = ptrees[currentcolor]->GetValue(stream);
|
||||||
|
if (value < 0) {
|
||||||
|
debugger("value < 0");
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pixelswrit + value > details.width) {
|
||||||
|
debugger("gone past end of line");
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
pixelswrit += value;
|
||||||
|
|
||||||
|
// covert run length to B_RGB32 pixels
|
||||||
|
uint32 pixelsleft = value;
|
||||||
|
while (pixelsleft--) {
|
||||||
|
memset(pcurrentpixel, colors[currentcolor], 3);
|
||||||
|
pcurrentpixel += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value < 64)
|
||||||
|
currentcolor = 1 - currentcolor;
|
||||||
|
}
|
||||||
|
|
||||||
|
// read in end-of-line sequence
|
||||||
|
uint32 nzeros = 11;
|
||||||
|
while (nzeros--)
|
||||||
|
{
|
||||||
|
stream.NextBit();
|
||||||
|
}
|
||||||
|
stream.NextBit();
|
||||||
|
|
||||||
|
return stream.BytesRead();
|
||||||
|
}
|
||||||
|
|
||||||
ssize_t
|
ssize_t
|
||||||
TIFFTranslator::decode_huffman(StreamBuffer *pstreambuf, TiffDetails &details,
|
TIFFTranslator::decode_huffman(StreamBuffer *pstreambuf, TiffDetails &details,
|
||||||
uint8 *pbits)
|
uint8 *pbits)
|
||||||
{
|
{
|
||||||
BitReader stream(pstreambuf);
|
BitReader stream(details.fillOrder, pstreambuf);
|
||||||
if (stream.InitCheck() != B_OK) {
|
if (stream.InitCheck() != B_OK) {
|
||||||
debugger("stream init error");
|
debugger("stream init error");
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
@@ -1028,7 +1136,8 @@ TIFFTranslator::translate_from_tiff(BPositionIO *inSource, ssize_t amtread,
|
|||||||
|
|
||||||
// If TIFF uses Huffman compression, load
|
// If TIFF uses Huffman compression, load
|
||||||
// trees for decoding Huffman compression
|
// trees for decoding Huffman compression
|
||||||
if (details.compression == COMPRESSION_HUFFMAN) {
|
if (details.compression == COMPRESSION_HUFFMAN ||
|
||||||
|
details.compression == COMPRESSION_T4) {
|
||||||
result = LoadHuffmanTrees();
|
result = LoadHuffmanTrees();
|
||||||
if (result != B_OK)
|
if (result != B_OK)
|
||||||
return result;
|
return result;
|
||||||
@@ -1085,12 +1194,16 @@ TIFFTranslator::translate_from_tiff(BPositionIO *inSource, ssize_t amtread,
|
|||||||
// buffer for making reading compressed data
|
// buffer for making reading compressed data
|
||||||
// fast and convenient
|
// fast and convenient
|
||||||
StreamBuffer *pstreambuf = NULL;
|
StreamBuffer *pstreambuf = NULL;
|
||||||
|
BitReader bitreader(details.fillOrder, pstreambuf, false);
|
||||||
|
// this creates an invalid bitreader, but it is
|
||||||
|
// initialized properly with the SetTo() call
|
||||||
if (details.compression != COMPRESSION_NONE) {
|
if (details.compression != COMPRESSION_NONE) {
|
||||||
pstreambuf = new StreamBuffer(inSource, 2048, false);
|
pstreambuf = new StreamBuffer(inSource, 2048, false);
|
||||||
if (pstreambuf->InitCheck() != B_OK)
|
if (pstreambuf->InitCheck() != B_OK)
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool bfirstLine = true;
|
||||||
for (uint32 i = 0; i < details.stripsPerImage; i++) {
|
for (uint32 i = 0; i < details.stripsPerImage; i++) {
|
||||||
uint32 read = 0;
|
uint32 read = 0;
|
||||||
|
|
||||||
@@ -1100,6 +1213,10 @@ TIFFTranslator::translate_from_tiff(BPositionIO *inSource, ssize_t amtread,
|
|||||||
!pstreambuf->Seek(details.pstripOffsets[i]))
|
!pstreambuf->Seek(details.pstripOffsets[i]))
|
||||||
return B_NO_TRANSLATOR;
|
return B_NO_TRANSLATOR;
|
||||||
|
|
||||||
|
if (details.compression == COMPRESSION_T4 &&
|
||||||
|
bitreader.SetTo(details.fillOrder, pstreambuf) != B_OK)
|
||||||
|
return B_NO_TRANSLATOR;
|
||||||
|
|
||||||
// Read / Write one line at a time for each
|
// Read / Write one line at a time for each
|
||||||
// line in the strip
|
// line in the strip
|
||||||
while (read < details.pstripByteCounts[i]) {
|
while (read < details.pstripByteCounts[i]) {
|
||||||
@@ -1121,6 +1238,19 @@ TIFFTranslator::translate_from_tiff(BPositionIO *inSource, ssize_t amtread,
|
|||||||
ret = -1;
|
ret = -1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case COMPRESSION_T4:
|
||||||
|
ret = decode_t4(bitreader, details, outbuffer,
|
||||||
|
bfirstLine);
|
||||||
|
if (ret < 1)
|
||||||
|
// break out of while loop
|
||||||
|
ret = -1;
|
||||||
|
else
|
||||||
|
ret -= read;
|
||||||
|
// unlike other decoders, decode_t4 retruns
|
||||||
|
// the total bytes read from the current
|
||||||
|
// strip
|
||||||
|
break;
|
||||||
|
|
||||||
case COMPRESSION_PACKBITS:
|
case COMPRESSION_PACKBITS:
|
||||||
ret = unpack(pstreambuf, inbuffer, inbufferlen);
|
ret = unpack(pstreambuf, inbuffer, inbufferlen);
|
||||||
if (ret < 1)
|
if (ret < 1)
|
||||||
@@ -1132,9 +1262,11 @@ TIFFTranslator::translate_from_tiff(BPositionIO *inSource, ssize_t amtread,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
read += ret;
|
read += ret;
|
||||||
if (details.compression != COMPRESSION_HUFFMAN)
|
if (details.compression != COMPRESSION_HUFFMAN &&
|
||||||
|
details.compression != COMPRESSION_T4)
|
||||||
tiff_to_bits(inbuffer, inbufferlen, outbuffer, details);
|
tiff_to_bits(inbuffer, inbufferlen, outbuffer, details);
|
||||||
outDestination->Write(outbuffer, outbufferlen);
|
outDestination->Write(outbuffer, outbufferlen);
|
||||||
|
bfirstLine = false;
|
||||||
}
|
}
|
||||||
// If while loop was broken...
|
// If while loop was broken...
|
||||||
if (read < details.pstripByteCounts[i]) {
|
if (read < details.pstripByteCounts[i]) {
|
||||||
|
|||||||
@@ -83,6 +83,7 @@ public:
|
|||||||
uint16 interpretation;
|
uint16 interpretation;
|
||||||
uint16 bitsPerPixel;
|
uint16 bitsPerPixel;
|
||||||
uint16 imageType;
|
uint16 imageType;
|
||||||
|
uint16 fillOrder;
|
||||||
};
|
};
|
||||||
|
|
||||||
class TIFFTranslator : public BTranslator {
|
class TIFFTranslator : public BTranslator {
|
||||||
@@ -137,6 +138,8 @@ private:
|
|||||||
|
|
||||||
ssize_t decode_huffman(StreamBuffer *pstreambuf, TiffDetails &details,
|
ssize_t decode_huffman(StreamBuffer *pstreambuf, TiffDetails &details,
|
||||||
uint8 *pbits);
|
uint8 *pbits);
|
||||||
|
ssize_t decode_t4(BitReader &stream, TiffDetails &details,
|
||||||
|
uint8 *pbits, bool bfirstLine);
|
||||||
|
|
||||||
status_t translate_from_tiff(BPositionIO *inSource, ssize_t amtread,
|
status_t translate_from_tiff(BPositionIO *inSource, ssize_t amtread,
|
||||||
uint8 *read, swap_action swp, uint32 outType,
|
uint8 *read, swap_action swp, uint32 outType,
|
||||||
|
|||||||
@@ -53,6 +53,7 @@
|
|||||||
#define COMPRESSION_T4 3
|
#define COMPRESSION_T4 3
|
||||||
#define COMPRESSION_T6 4
|
#define COMPRESSION_T6 4
|
||||||
#define COMPRESSION_LZW 5
|
#define COMPRESSION_LZW 5
|
||||||
|
#define COMPRESSION_JPEG 6
|
||||||
#define COMPRESSION_PACKBITS 32773
|
#define COMPRESSION_PACKBITS 32773
|
||||||
#define TAG_PHOTO_INTERPRETATION 262
|
#define TAG_PHOTO_INTERPRETATION 262
|
||||||
#define PHOTO_WHITEZERO 0
|
#define PHOTO_WHITEZERO 0
|
||||||
@@ -69,6 +70,13 @@
|
|||||||
#define DEFAULT_ROWS_PER_STRIP 4294967295UL
|
#define DEFAULT_ROWS_PER_STRIP 4294967295UL
|
||||||
#define TAG_STRIP_BYTE_COUNTS 279
|
#define TAG_STRIP_BYTE_COUNTS 279
|
||||||
#define TAG_PLANAR_CONFIGURATION 284
|
#define TAG_PLANAR_CONFIGURATION 284
|
||||||
|
#define TAG_T4_OPTIONS 292
|
||||||
|
// (Also called Group3Options)
|
||||||
|
#define T4_2D 1
|
||||||
|
#define T4_UNCOMPRESSED 2
|
||||||
|
#define T4_FILL_BYTE_BOUNDARY 4
|
||||||
|
#define TAG_T6_OPTIONS 293
|
||||||
|
// (Also called Group4Options)
|
||||||
#define TAG_RESOLUTION_UNIT 296
|
#define TAG_RESOLUTION_UNIT 296
|
||||||
#define TAG_COLOR_MAP 320
|
#define TAG_COLOR_MAP 320
|
||||||
#define TAG_INK_SET 332
|
#define TAG_INK_SET 332
|
||||||
|
|||||||
Reference in New Issue
Block a user