mirror of
https://github.com/python-pillow/Pillow.git
synced 2024-12-25 17:36:18 +03:00
Merge from 12-bit-tiff
This commit is contained in:
commit
94e3c75179
|
@ -475,7 +475,7 @@ class Image:
|
|||
new.mode = im.mode
|
||||
new.size = im.size
|
||||
new.palette = self.palette
|
||||
if im.mode == "P":
|
||||
if im.mode == "P" and not new.palette:
|
||||
from PIL import ImagePalette
|
||||
new.palette = ImagePalette.ImagePalette()
|
||||
try:
|
||||
|
|
|
@ -54,6 +54,10 @@ import collections
|
|||
import itertools
|
||||
import os
|
||||
|
||||
# Set these to true to force use of libtiff for reading or writing.
|
||||
READ_LIBTIFF = False
|
||||
WRITE_LIBTIFF= False
|
||||
|
||||
II = b"II" # little-endian (intel-style)
|
||||
MM = b"MM" # big-endian (motorola-style)
|
||||
|
||||
|
@ -147,6 +151,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"),
|
||||
|
@ -617,8 +622,8 @@ class TiffImageFile(ImageFile.ImageFile):
|
|||
return args
|
||||
|
||||
def _load_libtiff(self):
|
||||
""" Overload method triggered when we detect a g3/g4 tiff
|
||||
Calls out to lib tiff """
|
||||
""" Overload method triggered when we detect a compressed tiff
|
||||
Calls out to libtiff """
|
||||
|
||||
pixel = Image.Image.load(self)
|
||||
|
||||
|
@ -633,7 +638,7 @@ class TiffImageFile(ImageFile.ImageFile):
|
|||
raise IOError("Not exactly one tile")
|
||||
|
||||
d, e, o, a = self.tile[0]
|
||||
d = Image._getdecoder(self.mode, d, a, self.decoderconfig)
|
||||
d = Image._getdecoder(self.mode, 'libtiff', a, self.decoderconfig)
|
||||
try:
|
||||
d.setimage(self.im, e)
|
||||
except ValueError:
|
||||
|
@ -759,11 +764,11 @@ class TiffImageFile(ImageFile.ImageFile):
|
|||
offsets = self.tag[STRIPOFFSETS]
|
||||
h = getscalar(ROWSPERSTRIP, ysize)
|
||||
w = self.size[0]
|
||||
if self._compression in ["tiff_ccitt", "group3", "group4",
|
||||
"tiff_jpeg", "tiff_adobe_deflate",
|
||||
"tiff_thunderscan", "tiff_deflate",
|
||||
"tiff_sgilog", "tiff_sgilog24",
|
||||
"tiff_raw_16"]:
|
||||
if READ_LIBTIFF or self._compression in ["tiff_ccitt", "group3", "group4",
|
||||
"tiff_jpeg", "tiff_adobe_deflate",
|
||||
"tiff_thunderscan", "tiff_deflate",
|
||||
"tiff_sgilog", "tiff_sgilog24",
|
||||
"tiff_raw_16"]:
|
||||
## if Image.DEBUG:
|
||||
## print "Activating g4 compression for whole file"
|
||||
|
||||
|
@ -810,7 +815,7 @@ class TiffImageFile(ImageFile.ImageFile):
|
|||
# we're expecting image byte order. So, if the rawmode
|
||||
# contains I;16, we need to convert from native to image
|
||||
# byte order.
|
||||
if self.mode in ('I;16B', 'I;16'):
|
||||
if self.mode in ('I;16B', 'I;16') and 'I;16' in rawmode:
|
||||
rawmode = 'I;16N'
|
||||
|
||||
# Offset in the tile tuple is 0, we go from 0,0 to
|
||||
|
@ -917,11 +922,12 @@ def _save(im, fp, filename):
|
|||
ifd = ImageFileDirectory(prefix)
|
||||
|
||||
compression = im.encoderinfo.get('compression',im.info.get('compression','raw'))
|
||||
libtiff = compression in ["tiff_ccitt", "group3", "group4",
|
||||
"tiff_jpeg", "tiff_adobe_deflate",
|
||||
"tiff_thunderscan", "tiff_deflate",
|
||||
"tiff_sgilog", "tiff_sgilog24",
|
||||
"tiff_raw_16"]
|
||||
|
||||
libtiff = WRITE_LIBTIFF or compression in ["tiff_ccitt", "group3", "group4",
|
||||
"tiff_jpeg", "tiff_adobe_deflate",
|
||||
"tiff_thunderscan", "tiff_deflate",
|
||||
"tiff_sgilog", "tiff_sgilog24",
|
||||
"tiff_raw_16"]
|
||||
|
||||
# required for color libtiff images
|
||||
ifd[PLANAR_CONFIGURATION] = getattr(im, '_planar_configuration', 1)
|
||||
|
@ -1057,8 +1063,8 @@ def _save(im, fp, filename):
|
|||
if Image.DEBUG:
|
||||
print (atts)
|
||||
|
||||
# libtiff always returns the bytes in native order.
|
||||
# we're expecting image byte order. So, if the rawmode
|
||||
# libtiff always expects the bytes in native order.
|
||||
# we're storing image byte order. So, if the rawmode
|
||||
# contains I;16, we need to convert from native to image
|
||||
# byte order.
|
||||
if im.mode in ('I;16B', 'I;16'):
|
||||
|
@ -1066,7 +1072,7 @@ def _save(im, fp, filename):
|
|||
|
||||
a = (rawmode, compression, _fp, filename, atts)
|
||||
# print (im.mode, compression, a, im.encoderconfig)
|
||||
e = Image._getencoder(im.mode, compression, a, im.encoderconfig)
|
||||
e = Image._getencoder(im.mode, 'libtiff', a, im.encoderconfig)
|
||||
e.setimage(im.im, (0,0)+im.size)
|
||||
while 1:
|
||||
l, s, d = e.encode(16*1024) # undone, change to self.decodermaxblock
|
||||
|
|
Binary file not shown.
BIN
Tests/images/12in16bit.tif
Normal file
BIN
Tests/images/12in16bit.tif
Normal file
Binary file not shown.
BIN
Tests/images/16bit.cropped.tif
Normal file
BIN
Tests/images/16bit.cropped.tif
Normal file
Binary file not shown.
|
@ -27,3 +27,22 @@ def test_optimize():
|
|||
return len(file.getvalue())
|
||||
assert_equal(test(0), 800)
|
||||
assert_equal(test(1), 38)
|
||||
|
||||
def test_roundtrip():
|
||||
out = tempfile('temp.gif')
|
||||
im = lena()
|
||||
im.save(out)
|
||||
reread = Image.open(out)
|
||||
|
||||
assert_image_similar(reread.convert('RGB'), im, 50)
|
||||
|
||||
def test_roundtrip2():
|
||||
#see https://github.com/python-imaging/Pillow/issues/403
|
||||
out = 'temp.gif'#tempfile('temp.gif')
|
||||
im = Image.open('Images/lena.gif')
|
||||
im2 = im.copy()
|
||||
im2.save(out)
|
||||
reread = Image.open(out)
|
||||
|
||||
assert_image_similar(reread.convert('RGB'), lena(), 50)
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
from tester import *
|
||||
|
||||
from PIL import Image
|
||||
from PIL import Image, TiffImagePlugin
|
||||
|
||||
codecs = dir(Image.core)
|
||||
|
||||
if "group4_encoder" not in codecs or "group4_decoder" not in codecs:
|
||||
if "libtiff_encoder" not in codecs or "libtiff_decoder" not in codecs:
|
||||
skip("tiff support not available")
|
||||
|
||||
def _assert_noerr(im):
|
||||
|
@ -118,7 +118,7 @@ def test_g3_compression():
|
|||
assert_image_equal(reread, i)
|
||||
|
||||
def test_little_endian():
|
||||
im = Image.open('Tests/images/12bit.deflate.tif')
|
||||
im = Image.open('Tests/images/16bit.deflate.tif')
|
||||
assert_equal(im.getpixel((0,0)), 480)
|
||||
assert_equal(im.mode, 'I;16')
|
||||
|
||||
|
@ -143,7 +143,7 @@ def test_little_endian():
|
|||
# on big endian, we'll get back mode = 'I;16B' here.
|
||||
|
||||
def test_big_endian():
|
||||
im = Image.open('Tests/images/12bit.MM.deflate.tif')
|
||||
im = Image.open('Tests/images/16bit.MM.deflate.tif')
|
||||
|
||||
assert_equal(im.getpixel((0,0)), 480)
|
||||
assert_equal(im.mode, 'I;16B')
|
||||
|
@ -178,6 +178,31 @@ def test_g4_string_info():
|
|||
reread = Image.open(out)
|
||||
assert_equal('temp.tif', reread.tag[269])
|
||||
|
||||
def test_12bit_rawmode():
|
||||
""" Are we generating the same interpretation of the image as Imagemagick is? """
|
||||
TiffImagePlugin.READ_LIBTIFF = True
|
||||
#Image.DEBUG = True
|
||||
im = Image.open('Tests/images/12bit.cropped.tif')
|
||||
im.load()
|
||||
TiffImagePlugin.READ_LIBTIFF = False
|
||||
# to make the target --
|
||||
# convert 12bit.cropped.tif -depth 16 tmp.tif
|
||||
# convert tmp.tif -evaluate RightShift 4 12in16bit2.tif
|
||||
# imagemagick will auto scale so that a 12bit FFF is 16bit FFF0,
|
||||
# so we need to unshift so that the integer values are the same.
|
||||
|
||||
im2 = Image.open('Tests/images/12in16bit.tif')
|
||||
|
||||
if Image.DEBUG:
|
||||
print (im.getpixel((0,0)))
|
||||
print (im.getpixel((0,1)))
|
||||
print (im.getpixel((0,2)))
|
||||
|
||||
print (im2.getpixel((0,0)))
|
||||
print (im2.getpixel((0,1)))
|
||||
print (im2.getpixel((0,2)))
|
||||
|
||||
assert_image_equal(im, im2)
|
||||
|
||||
def test_blur():
|
||||
# test case from irc, how to do blur on b/w image and save to compressed tif.
|
||||
|
|
|
@ -6,7 +6,7 @@ from test_file_libtiff import _assert_noerr
|
|||
|
||||
codecs = dir(Image.core)
|
||||
|
||||
if "group4_encoder" not in codecs or "group4_decoder" not in codecs:
|
||||
if "libtiff_encoder" not in codecs or "libtiff_decoder" not in codecs:
|
||||
skip("tiff support not available")
|
||||
|
||||
""" The small lena image was failing on open in the libtiff
|
||||
|
|
|
@ -74,7 +74,7 @@ def test_xyres_tiff():
|
|||
|
||||
|
||||
def test_little_endian():
|
||||
im = Image.open('Tests/images/12bit.cropped.tif')
|
||||
im = Image.open('Tests/images/16bit.cropped.tif')
|
||||
assert_equal(im.getpixel((0,0)), 480)
|
||||
assert_equal(im.mode, 'I;16')
|
||||
|
||||
|
@ -89,7 +89,7 @@ def test_little_endian():
|
|||
|
||||
|
||||
def test_big_endian():
|
||||
im = Image.open('Tests/images/12bit.MM.cropped.tif')
|
||||
im = Image.open('Tests/images/16bit.MM.cropped.tif')
|
||||
assert_equal(im.getpixel((0,0)), 480)
|
||||
assert_equal(im.mode, 'I;16B')
|
||||
|
||||
|
@ -102,3 +102,29 @@ def test_big_endian():
|
|||
else:
|
||||
assert_equal(b[0], b'\x01')
|
||||
assert_equal(b[1], b'\xe0')
|
||||
|
||||
|
||||
def test_12bit_rawmode():
|
||||
""" Are we generating the same interpretation of the image as Imagemagick is? """
|
||||
|
||||
#Image.DEBUG = True
|
||||
im = Image.open('Tests/images/12bit.cropped.tif')
|
||||
|
||||
# to make the target --
|
||||
# convert 12bit.cropped.tif -depth 16 tmp.tif
|
||||
# convert tmp.tif -evaluate RightShift 4 12in16bit2.tif
|
||||
# imagemagick will auto scale so that a 12bit FFF is 16bit FFF0,
|
||||
# so we need to unshift so that the integer values are the same.
|
||||
|
||||
im2 = Image.open('Tests/images/12in16bit.tif')
|
||||
|
||||
if Image.DEBUG:
|
||||
print (im.getpixel((0,0)))
|
||||
print (im.getpixel((0,1)))
|
||||
print (im.getpixel((0,2)))
|
||||
|
||||
print (im2.getpixel((0,0)))
|
||||
print (im2.getpixel((0,1)))
|
||||
print (im2.getpixel((0,2)))
|
||||
|
||||
assert_image_equal(im, im2)
|
||||
|
|
|
@ -38,12 +38,12 @@ def test_8bit():
|
|||
im = Image.open('Images/lena.jpg')
|
||||
_test_float_conversion(im.convert('L'))
|
||||
|
||||
def test_12bit():
|
||||
im = Image.open('Tests/images/12bit.cropped.tif')
|
||||
def test_16bit():
|
||||
im = Image.open('Tests/images/16bit.cropped.tif')
|
||||
_test_float_conversion(im)
|
||||
|
||||
def test_12bit_workaround():
|
||||
im = Image.open('Tests/images/12bit.cropped.tif')
|
||||
def test_16bit_workaround():
|
||||
im = Image.open('Tests/images/16bit.cropped.tif')
|
||||
_test_float_conversion(im.convert('I'))
|
||||
|
||||
|
||||
|
|
|
@ -75,7 +75,7 @@ def _test_img_equals_nparray(img, np):
|
|||
|
||||
|
||||
def test_16bit():
|
||||
img = Image.open('Tests/images/12bit.cropped.tif')
|
||||
img = Image.open('Tests/images/16bit.cropped.tif')
|
||||
np_img = numpy.array(img)
|
||||
_test_img_equals_nparray(img, np_img)
|
||||
assert_equal(np_img.dtype, numpy.dtype('<u2'))
|
||||
|
|
23
_imaging.c
23
_imaging.c
|
@ -3316,27 +3316,8 @@ static PyMethodDef functions[] = {
|
|||
#endif
|
||||
{"tiff_lzw_decoder", (PyCFunction)PyImaging_TiffLzwDecoderNew, 1},
|
||||
#ifdef HAVE_LIBTIFF
|
||||
{"tiff_ccitt_decoder", (PyCFunction)PyImaging_LibTiffDecoderNew, 1},
|
||||
{"group3_decoder", (PyCFunction)PyImaging_LibTiffDecoderNew, 1},
|
||||
{"group4_decoder", (PyCFunction)PyImaging_LibTiffDecoderNew, 1},
|
||||
{"tiff_jpeg_decoder", (PyCFunction)PyImaging_LibTiffDecoderNew, 1},
|
||||
{"tiff_adobe_deflate_decoder", (PyCFunction)PyImaging_LibTiffDecoderNew, 1},
|
||||
{"tiff_thunderscan_decoder", (PyCFunction)PyImaging_LibTiffDecoderNew, 1},
|
||||
{"tiff_deflate_decoder", (PyCFunction)PyImaging_LibTiffDecoderNew, 1},
|
||||
{"tiff_sgilog_decoder", (PyCFunction)PyImaging_LibTiffDecoderNew, 1},
|
||||
{"tiff_sgilog24_decoder", (PyCFunction)PyImaging_LibTiffDecoderNew, 1},
|
||||
{"tiff_raw_16_decoder", (PyCFunction)PyImaging_LibTiffDecoderNew, 1},
|
||||
|
||||
{"tiff_ccitt_encoder", (PyCFunction)PyImaging_LibTiffEncoderNew, 1},
|
||||
{"group3_encoder", (PyCFunction)PyImaging_LibTiffEncoderNew, 1},
|
||||
{"group4_encoder", (PyCFunction)PyImaging_LibTiffEncoderNew, 1},
|
||||
{"tiff_jpeg_encoder", (PyCFunction)PyImaging_LibTiffEncoderNew, 1},
|
||||
{"tiff_adobe_deflate_encoder", (PyCFunction)PyImaging_LibTiffEncoderNew, 1},
|
||||
{"tiff_thunderscan_encoder", (PyCFunction)PyImaging_LibTiffEncoderNew, 1},
|
||||
{"tiff_deflate_encoder", (PyCFunction)PyImaging_LibTiffEncoderNew, 1},
|
||||
{"tiff_sgilog_encoder", (PyCFunction)PyImaging_LibTiffEncoderNew, 1},
|
||||
{"tiff_sgilog24_encoder", (PyCFunction)PyImaging_LibTiffEncoderNew, 1},
|
||||
{"tiff_raw_16_encoder", (PyCFunction)PyImaging_LibTiffEncoderNew, 1},
|
||||
{"libtiff_decoder", (PyCFunction)PyImaging_LibTiffDecoderNew, 1},
|
||||
{"libtiff_encoder", (PyCFunction)PyImaging_LibTiffEncoderNew, 1},
|
||||
#endif
|
||||
{"msp_decoder", (PyCFunction)PyImaging_MspDecoderNew, 1},
|
||||
{"packbits_decoder", (PyCFunction)PyImaging_PackbitsDecoderNew, 1},
|
||||
|
|
43
decode.c
43
decode.c
|
@ -427,7 +427,6 @@ PyImaging_LibTiffDecoderNew(PyObject* self, PyObject* args)
|
|||
char* mode;
|
||||
char* rawmode;
|
||||
char* compname;
|
||||
int compression;
|
||||
int fp;
|
||||
|
||||
if (! PyArg_ParseTuple(args, "sssi", &mode, &rawmode, &compname, &fp))
|
||||
|
@ -435,46 +434,6 @@ PyImaging_LibTiffDecoderNew(PyObject* self, PyObject* args)
|
|||
|
||||
TRACE(("new tiff decoder %s\n", compname));
|
||||
|
||||
/* UNDONE -- we can probably do almost any arbitrary compression here,
|
||||
* since we're effective passing in the whole file in one shot and
|
||||
* getting back the data row by row. V2 maybe
|
||||
*/
|
||||
|
||||
if (strcasecmp(compname, "tiff_ccitt") == 0) {
|
||||
compression = COMPRESSION_CCITTRLE;
|
||||
|
||||
} else if (strcasecmp(compname, "group3") == 0) {
|
||||
compression = COMPRESSION_CCITTFAX3;
|
||||
|
||||
} else if (strcasecmp(compname, "group4") == 0) {
|
||||
compression = COMPRESSION_CCITTFAX4;
|
||||
|
||||
} else if (strcasecmp(compname, "tiff_jpeg") == 0) {
|
||||
compression = COMPRESSION_OJPEG;
|
||||
|
||||
} else if (strcasecmp(compname, "tiff_adobe_deflate") == 0) {
|
||||
compression = COMPRESSION_ADOBE_DEFLATE;
|
||||
|
||||
} else if (strcasecmp(compname, "tiff_thunderscan") == 0) {
|
||||
compression = COMPRESSION_THUNDERSCAN;
|
||||
|
||||
} else if (strcasecmp(compname, "tiff_deflate") == 0) {
|
||||
compression = COMPRESSION_DEFLATE;
|
||||
|
||||
} else if (strcasecmp(compname, "tiff_sgilog") == 0) {
|
||||
compression = COMPRESSION_SGILOG;
|
||||
|
||||
} else if (strcasecmp(compname, "tiff_sgilog24") == 0) {
|
||||
compression = COMPRESSION_SGILOG24;
|
||||
|
||||
} else if (strcasecmp(compname, "tiff_raw_16") == 0) {
|
||||
compression = COMPRESSION_CCITTRLEW;
|
||||
|
||||
} else {
|
||||
PyErr_SetString(PyExc_ValueError, "unknown compession");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
decoder = PyImaging_DecoderNew(sizeof(TIFFSTATE));
|
||||
if (decoder == NULL)
|
||||
return NULL;
|
||||
|
@ -482,7 +441,7 @@ PyImaging_LibTiffDecoderNew(PyObject* self, PyObject* args)
|
|||
if (get_unpacker(decoder, mode, rawmode) < 0)
|
||||
return NULL;
|
||||
|
||||
if (! ImagingLibTiffInit(&decoder->state, compression, fp)) {
|
||||
if (! ImagingLibTiffInit(&decoder->state, fp)) {
|
||||
Py_DECREF(decoder);
|
||||
PyErr_SetString(PyExc_RuntimeError, "tiff codec initialization failed");
|
||||
return NULL;
|
||||
|
|
42
encode.c
42
encode.c
|
@ -673,7 +673,6 @@ PyImaging_LibTiffEncoderNew(PyObject* self, PyObject* args)
|
|||
char* rawmode;
|
||||
char* compname;
|
||||
char* filename;
|
||||
int compression;
|
||||
int fp;
|
||||
|
||||
PyObject *dir;
|
||||
|
@ -706,47 +705,6 @@ PyImaging_LibTiffEncoderNew(PyObject* self, PyObject* args)
|
|||
|
||||
TRACE(("new tiff encoder %s fp: %d, filename: %s \n", compname, fp, filename));
|
||||
|
||||
/* UNDONE -- we can probably do almost any arbitrary compression here,
|
||||
* so long as we're doing row/stripe based actions and not tiles.
|
||||
*/
|
||||
|
||||
if (strcasecmp(compname, "tiff_ccitt") == 0) {
|
||||
compression = COMPRESSION_CCITTRLE;
|
||||
|
||||
} else if (strcasecmp(compname, "group3") == 0) {
|
||||
compression = COMPRESSION_CCITTFAX3;
|
||||
|
||||
} else if (strcasecmp(compname, "group4") == 0) {
|
||||
compression = COMPRESSION_CCITTFAX4;
|
||||
|
||||
} else if (strcasecmp(compname, "tiff_jpeg") == 0) {
|
||||
compression = COMPRESSION_OJPEG;
|
||||
|
||||
} else if (strcasecmp(compname, "tiff_adobe_deflate") == 0) {
|
||||
compression = COMPRESSION_ADOBE_DEFLATE;
|
||||
|
||||
} else if (strcasecmp(compname, "tiff_thunderscan") == 0) {
|
||||
compression = COMPRESSION_THUNDERSCAN;
|
||||
|
||||
} else if (strcasecmp(compname, "tiff_deflate") == 0) {
|
||||
compression = COMPRESSION_DEFLATE;
|
||||
|
||||
} else if (strcasecmp(compname, "tiff_sgilog") == 0) {
|
||||
compression = COMPRESSION_SGILOG;
|
||||
|
||||
} else if (strcasecmp(compname, "tiff_sgilog24") == 0) {
|
||||
compression = COMPRESSION_SGILOG24;
|
||||
|
||||
} else if (strcasecmp(compname, "tiff_raw_16") == 0) {
|
||||
compression = COMPRESSION_CCITTRLEW;
|
||||
|
||||
} else {
|
||||
PyErr_SetString(PyExc_ValueError, "unknown compession");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
TRACE(("Found compression: %d\n", compression));
|
||||
|
||||
encoder = PyImaging_EncoderNew(sizeof(TIFFSTATE));
|
||||
if (encoder == NULL)
|
||||
return NULL;
|
||||
|
|
|
@ -142,11 +142,11 @@ void _tiffUnmapProc(thandle_t hdata, tdata_t base, toff_t size) {
|
|||
(void) hdata; (void) base; (void) size;
|
||||
}
|
||||
|
||||
int ImagingLibTiffInit(ImagingCodecState state, int compression, int fp) {
|
||||
int ImagingLibTiffInit(ImagingCodecState state, int fp) {
|
||||
TIFFSTATE *clientstate = (TIFFSTATE *)state->context;
|
||||
|
||||
TRACE(("initing libtiff\n"));
|
||||
TRACE(("Compression: %d, filepointer: %d \n", compression, fp));
|
||||
TRACE(("filepointer: %d \n", fp));
|
||||
TRACE(("State: count %d, state %d, x %d, y %d, ystep %d\n", state->count, state->state,
|
||||
state->x, state->y, state->ystep));
|
||||
TRACE(("State: xsize %d, ysize %d, xoff %d, yoff %d \n", state->xsize, state->ysize,
|
||||
|
|
|
@ -38,7 +38,7 @@ typedef struct {
|
|||
|
||||
|
||||
|
||||
extern int ImagingLibTiffInit(ImagingCodecState state, int compression, int fp);
|
||||
extern int ImagingLibTiffInit(ImagingCodecState state, int fp);
|
||||
extern int ImagingLibTiffEncodeInit(ImagingCodecState state, char *filename, int fp);
|
||||
extern int ImagingLibTiffSetField(ImagingCodecState state, ttag_t tag, ...);
|
||||
|
||||
|
|
|
@ -795,6 +795,60 @@ unpackI16N_I16(UINT8* out, const UINT8* in, int pixels){
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
unpackI12_I16(UINT8* out, const UINT8* in, int pixels){
|
||||
/* Fillorder 1/MSB -> LittleEndian, for 12bit integer greyscale tiffs.
|
||||
|
||||
According to the TIFF 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. We'll see how well people read the spec.
|
||||
We've got several fillorder=2 modes in TiffImagePlugin.py
|
||||
|
||||
There's no spec I can find. It appears that the in storage
|
||||
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 +1217,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}, // 12 bit Tiffs stored in 16bits.
|
||||
|
||||
{NULL} /* sentinel */
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user