Read only implementation of 12bit tiffs

This commit is contained in:
wiredfool 2013-11-20 16:56:23 -08:00
parent b73ae9c27a
commit e4fe6ae7a3
2 changed files with 56 additions and 0 deletions

View File

@ -147,6 +147,7 @@ OPEN_INFO = {
(II, 1, 1, 1, (8,), ()): ("L", "L"),
(II, 1, 1, 1, (8,8), (2,)): ("LA", "LA"),
(II, 1, 1, 2, (8,), ()): ("L", "L;R"),
(II, 1, 1, 1, (12,), ()): ("I;16", "I;12"),
(II, 1, 1, 1, (16,), ()): ("I;16", "I;16"),
(II, 1, 2, 1, (16,), ()): ("I;16S", "I;16S"),
(II, 1, 1, 1, (32,), ()): ("I", "I;32N"),

View File

@ -795,6 +795,59 @@ unpackI16N_I16(UINT8* out, const UINT8* in, int pixels){
}
}
static void
unpackI12_I16(UINT8* out, const UINT8* in, int pixels){
/* Fillorder 1/MSB -> LittleEndian
According to the spec:
FillOrder = 2 should be used only when BitsPerSample = 1 and
the data is either uncompressed or compressed using CCITT 1D
or 2D compression, to avoid potentially ambigous situations.
Yeah. I thought so. See how well people read the spec.
So, it appears that the layout is: 00 80 00 ... -> (128 , 0
...). The samples are stored in a single big bitian 12bit
block, but need to be pulled out to little endian format to be
stored in a 2 byte int.
*/
int i;
UINT16 pixel;
#ifdef WORDS_BIGENDIAN
UINT8* tmp = (UINT8 *)&pixel;
#endif
UINT16* out16 = (UINT16 *)out;
for (i = 0; i < pixels-1; i+=2) {
pixel = (((UINT16) in[0]) << 4 ) + (in[1] >>4);
#ifdef WORDS_BIGENDIAN
out[0] = tmp[1]; out[1] = tmp[0];
#else
out16[0] = pixel;
#endif
pixel = (((UINT16) (in[1] & 0x0F)) << 8) + in[2];
#ifdef WORDS_BIGENDIAN
out[2] = tmp[1]; out[3] = tmp[0];
#else
out16[1] = pixel;
#endif
in += 3; out16 += 2; out+=4;
}
if (i == pixels-1) {
pixel = (((UINT16) in[0]) << 4 ) + (in[1] >>4);
#ifdef WORDS_BIGENDIAN
out[0] = tmp[1]; out[1] = tmp[0];
#else
out16[0] = pixel;
#endif
}
}
static void
copy1(UINT8* out, const UINT8* in, int pixels)
{
@ -1163,6 +1216,8 @@ static struct {
{"I;16L", "I;16N", 16, unpackI16N_I16}, // LibTiff native->image endian.
{"I;16B", "I;16N", 16, unpackI16N_I16B},
{"I;16", "I;12", 12, unpackI12_I16}, //
{NULL} /* sentinel */
};