diff --git a/bento.info b/bento.info
index 564f1f5a..7518abbc 100644
--- a/bento.info
+++ b/bento.info
@@ -157,6 +157,9 @@ Library:
Extension: skimage.graph._ncut_cy
Sources:
skimage/graph/_ncut_cy.pyx
+ Extension: skimage.external.tifffile._tifffile
+ Sources:
+ skimage/external/tifffile/_tifffile.c
Executable: skivi
Module: skimage.scripts.skivi
diff --git a/skimage/external/setup.py b/skimage/external/setup.py
new file mode 100644
index 00000000..c046cd62
--- /dev/null
+++ b/skimage/external/setup.py
@@ -0,0 +1,26 @@
+#!/usr/bin/env python
+
+import os.path
+
+base_path = os.path.abspath(os.path.dirname(__file__))
+
+
+def configuration(parent_package='', top_path=None):
+ from numpy.distutils.misc_util import Configuration, get_numpy_include_dirs
+
+ config = Configuration('external', parent_package, top_path)
+
+ config.add_extension('tifffile._tifffile',
+ sources=['tifffile/_tifffile.c'],
+ include_dirs=[get_numpy_include_dirs()])
+ return config
+
+if __name__ == '__main__':
+ from numpy.distutils.core import setup
+ setup(maintainer='scikit-image Developers',
+ maintainer_email='scikit-image@googlegroups.com',
+ description='External Libaries',
+ url='https://github.com/scikit-image/scikit-image',
+ license='Modified BSD',
+ **(configuration(top_path='').todict())
+ )
diff --git a/skimage/external/tifffile/tifffile.c b/skimage/external/tifffile/tifffile.c
new file mode 100644
index 00000000..6aa0eaa1
--- /dev/null
+++ b/skimage/external/tifffile/tifffile.c
@@ -0,0 +1,962 @@
+
+
+/* tifffile.c
+
+A Python C extension module for decoding PackBits and LZW encoded TIFF data.
+
+Refer to the tifffile.py module for documentation and tests.
+
+:Author:
+ `Christoph Gohlke `_
+
+:Organization:
+ Laboratory for Fluorescence Dynamics, University of California, Irvine
+
+:Version: 2013.11.05
+
+Install
+-------
+Use this Python distutils setup script to build the extension module::
+
+ # setup.py
+ # Usage: ``python setup.py build_ext --inplace``
+ from distutils.core import setup, Extension
+ import numpy
+ setup(name='_tifffile',
+ ext_modules=[Extension('_tifffile', ['tifffile.c'],
+ include_dirs=[numpy.get_include()])])
+
+License
+-------
+Copyright (c) 2008-2014, Christoph Gohlke
+Copyright (c) 2008-2014, The Regents of the University of California
+Produced at the Laboratory for Fluorescence Dynamics
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+* Neither the name of the copyright holders nor the names of any
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#define _VERSION_ "2013.11.05"
+
+#define WIN32_LEAN_AND_MEAN
+#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
+
+#include "Python.h"
+#include "string.h"
+#include "numpy/arrayobject.h"
+
+/* little endian by default */
+#ifndef MSB
+#define MSB 1
+#endif
+
+#if MSB
+#define LSB 0
+#define BOC '<'
+#else
+#define LSB 1
+#define BOC '>'
+#endif
+
+#define NO_ERROR 0
+#define VALUE_ERROR -1
+
+#ifdef _MSC_VER
+typedef unsigned __int8 uint8_t;
+typedef unsigned __int16 uint16_t;
+typedef unsigned __int32 uint32_t;
+typedef unsigned __int64 uint64_t;
+#ifdef _WIN64
+typedef __int64 ssize_t;
+typedef signed __int64 intptr_t;
+typedef unsigned __int64 uintptr_t;
+#define SSIZE_MAX (9223372036854775808)
+#else
+typedef int ssize_t;
+typedef _W64 signed int intptr_t;
+typedef _W64 unsigned int uintptr_t;
+#define SSIZE_MAX (2147483648)
+#endif
+#else
+/* non MS compilers */
+#include
+#include
+#endif
+
+#define SWAP2BYTES(x) \
+ ((((x) >> 8) & 0x00FF) | (((x) & 0x00FF) << 8))
+
+#define SWAP4BYTES(x) \
+ ((((x) >> 24) & 0x00FF) | (((x)&0x00FF) << 24) | \
+ (((x) >> 8 ) & 0xFF00) | (((x)&0xFF00) << 8))
+
+#define SWAP8BYTES(x) \
+ ((((x) >> 56) & 0x00000000000000FF) | (((x) >> 40) & 0x000000000000FF00) | \
+ (((x) >> 24) & 0x0000000000FF0000) | (((x) >> 8) & 0x00000000FF000000) | \
+ (((x) << 8) & 0x000000FF00000000) | (((x) << 24) & 0x0000FF0000000000) | \
+ (((x) << 40) & 0x00FF000000000000) | (((x) << 56) & 0xFF00000000000000))
+
+struct BYTE_STRING {
+ unsigned int ref; /* reference count */
+ unsigned int len; /* length of string */
+ char *str; /* pointer to bytes */
+};
+
+typedef union {
+ uint8_t b[2];
+ uint16_t i;
+} u_uint16;
+
+typedef union {
+ uint8_t b[4];
+ uint32_t i;
+} u_uint32;
+
+typedef union {
+ uint8_t b[8];
+ uint64_t i;
+} u_uint64;
+
+/*****************************************************************************/
+/* C functions */
+
+/* Return mask for itemsize bits */
+unsigned char bitmask(const int itemsize) {
+ unsigned char result = 0;
+ unsigned char power = 1;
+ int i;
+ for (i = 0; i < itemsize; i++) {
+ result += power;
+ power *= 2;
+ }
+ return result << (8 - itemsize);
+}
+
+/** Unpack sequence of tigthly packed 1-32 bit integers.
+
+Native byte order will be returned.
+
+Input data array should be padded to the next 16, 32 or 64-bit boundary
+if itemsize not in (1, 2, 4, 8, 16, 24, 32, 64).
+
+*/
+int unpackbits(
+ unsigned char *data,
+ const ssize_t size, /** size of data in bytes */
+ const int itemsize, /** number of bits in integer */
+ ssize_t numitems, /** number of items to unpack */
+ unsigned char *result /** buffer to store unpacked items */
+ )
+{
+ ssize_t i, j, k, storagesize;
+ unsigned char value;
+ /* Input validation is done in wrapper function */
+ storagesize = (ssize_t)(ceil(itemsize / 8.0));
+ storagesize = storagesize < 3 ? storagesize : storagesize > 4 ? 8 : 4;
+ switch (itemsize) {
+ case 8:
+ case 16:
+ case 32:
+ case 64:
+ memcpy(result, data, numitems*storagesize);
+ return NO_ERROR;
+ case 1:
+ for (i = 0, j = 0; i < numitems/8; i++) {
+ value = data[i];
+ result[j++] = (value & (unsigned char)(128)) >> 7;
+ result[j++] = (value & (unsigned char)(64)) >> 6;
+ result[j++] = (value & (unsigned char)(32)) >> 5;
+ result[j++] = (value & (unsigned char)(16)) >> 4;
+ result[j++] = (value & (unsigned char)(8)) >> 3;
+ result[j++] = (value & (unsigned char)(4)) >> 2;
+ result[j++] = (value & (unsigned char)(2)) >> 1;
+ result[j++] = (value & (unsigned char)(1));
+ }
+ if (numitems % 8) {
+ value = data[i];
+ switch (numitems % 8) {
+ case 7: result[j+6] = (value & (unsigned char)(2)) >> 1;
+ case 6: result[j+5] = (value & (unsigned char)(4)) >> 2;
+ case 5: result[j+4] = (value & (unsigned char)(8)) >> 3;
+ case 4: result[j+3] = (value & (unsigned char)(16)) >> 4;
+ case 3: result[j+2] = (value & (unsigned char)(32)) >> 5;
+ case 2: result[j+1] = (value & (unsigned char)(64)) >> 6;
+ case 1: result[j] = (value & (unsigned char)(128)) >> 7;
+ }
+ }
+ return NO_ERROR;
+ case 2:
+ for (i = 0, j = 0; i < numitems/4; i++) {
+ value = data[i];
+ result[j++] = (value & (unsigned char)(192)) >> 6;
+ result[j++] = (value & (unsigned char)(48)) >> 4;
+ result[j++] = (value & (unsigned char)(12)) >> 2;
+ result[j++] = (value & (unsigned char)(3));
+ }
+ if (numitems % 4) {
+ value = data[i];
+ switch (numitems % 4) {
+ case 3: result[j+2] = (value & (unsigned char)(12)) >> 2;
+ case 2: result[j+1] = (value & (unsigned char)(48)) >> 4;
+ case 1: result[j] = (value & (unsigned char)(192)) >> 6;
+ }
+ }
+ return NO_ERROR;
+ case 4:
+ for (i = 0, j = 0; i < numitems/2; i++) {
+ value = data[i];
+ result[j++] = (value & (unsigned char)(240)) >> 4;
+ result[j++] = (value & (unsigned char)(15));
+ }
+ if (numitems % 2) {
+ value = data[i];
+ result[j] = (value & (unsigned char)(240)) >> 4;
+ }
+ return NO_ERROR;
+ case 24:
+ j = k = 0;
+ for (i = 0; i < numitems; i++) {
+ result[j++] = 0;
+ result[j++] = data[k++];
+ result[j++] = data[k++];
+ result[j++] = data[k++];
+ }
+ return NO_ERROR;
+ }
+ /* 3, 5, 6, 7 */
+ if (itemsize < 8) {
+ int shr = 16;
+ u_uint16 value, mask, tmp;
+ j = k = 0;
+ value.b[MSB] = data[j++];
+ value.b[LSB] = data[j++];
+ mask.b[MSB] = bitmask(itemsize);
+ mask.b[LSB] = 0;
+ for (i = 0; i < numitems; i++) {
+ shr -= itemsize;
+ tmp.i = (value.i & mask.i) >> shr;
+ result[k++] = tmp.b[LSB];
+ if (shr < itemsize) {
+ value.b[MSB] = value.b[LSB];
+ value.b[LSB] = data[j++];
+ mask.i <<= 8 - itemsize;
+ shr += 8;
+ } else {
+ mask.i >>= itemsize;
+ }
+ }
+ return NO_ERROR;
+ }
+ /* 9, 10, 11, 12, 13, 14, 15 */
+ if (itemsize < 16) {
+ int shr = 32;
+ u_uint32 value, mask, tmp;
+ mask.i = 0;
+ j = k = 0;
+#if MSB
+ for (i = 3; i >= 0; i--) {
+ value.b[i] = data[j++];
+ }
+ mask.b[3] = 0xFF;
+ mask.b[2] = bitmask(itemsize-8);
+ for (i = 0; i < numitems; i++) {
+ shr -= itemsize;
+ tmp.i = (value.i & mask.i) >> shr;
+ result[k++] = tmp.b[0]; /* swap bytes */
+ result[k++] = tmp.b[1];
+ if (shr < itemsize) {
+ value.b[3] = value.b[1];
+ value.b[2] = value.b[0];
+ value.b[1] = data[j++];
+ value.b[0] = data[j++];
+ mask.i <<= 16 - itemsize;
+ shr += 16;
+ } else {
+ mask.i >>= itemsize;
+ }
+ }
+#else
+ /* not implemented */
+#endif
+ return NO_ERROR;
+ }
+ /* 17, 18, 19, 20, 21, 22, 23, 25, 26, 27, 28, 29, 30, 31 */
+ if (itemsize < 32) {
+ int shr = 64;
+ u_uint64 value, mask, tmp;
+ mask.i = 0;
+ j = k = 0;
+#if MSB
+ for (i = 7; i >= 0; i--) {
+ value.b[i] = data[j++];
+ }
+ mask.b[7] = 0xFF;
+ mask.b[6] = 0xFF;
+ mask.b[5] = itemsize > 23 ? 0xFF : bitmask(itemsize-16);
+ mask.b[4] = itemsize < 24 ? 0x00 : bitmask(itemsize-24);
+ for (i = 0; i < numitems; i++) {
+ shr -= itemsize;
+ tmp.i = (value.i & mask.i) >> shr;
+ result[k++] = tmp.b[0]; /* swap bytes */
+ result[k++] = tmp.b[1];
+ result[k++] = tmp.b[2];
+ result[k++] = tmp.b[3];
+ if (shr < itemsize) {
+ value.b[7] = value.b[3];
+ value.b[6] = value.b[2];
+ value.b[5] = value.b[1];
+ value.b[4] = value.b[0];
+ value.b[3] = data[j++];
+ value.b[2] = data[j++];
+ value.b[1] = data[j++];
+ value.b[0] = data[j++];
+ mask.i <<= 32 - itemsize;
+ shr += 32;
+ } else {
+ mask.i >>= itemsize;
+ }
+ }
+#else
+ /* Not implemented */
+#endif
+ return NO_ERROR;
+ }
+ return VALUE_ERROR;
+}
+
+/*****************************************************************************/
+/* Python functions */
+
+/** Unpack tightly packed integers. */
+char py_unpackints_doc[] = "Unpack groups of bits into numpy array.";
+
+static PyObject*
+py_unpackints(PyObject *obj, PyObject *args, PyObject *kwds)
+{
+ PyObject *byteobj = NULL;
+ PyArrayObject *result = NULL;
+ PyArray_Descr *dtype = NULL;
+ char *encoded = NULL;
+ char *decoded = NULL;
+ Py_ssize_t encoded_len = 0;
+ Py_ssize_t decoded_len = 0;
+ Py_ssize_t runlen = 0;
+ Py_ssize_t i;
+ int storagesize, bytesize;
+ int itemsize = 0;
+ int skipbits = 0;
+ static char *kwlist[] = {"data", "dtype", "itemsize", "runlen", NULL};
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO&i|i", kwlist,
+ &byteobj, PyArray_DescrConverter, &dtype, &itemsize, &runlen))
+ return NULL;
+
+ Py_INCREF(byteobj);
+
+ if (((itemsize < 1) || (itemsize > 32)) && (itemsize != 64)) {
+ PyErr_Format(PyExc_ValueError, "itemsize out of range");
+ goto _fail;
+ }
+
+ if (!PyBytes_Check(byteobj)) {
+ PyErr_Format(PyExc_TypeError, "expected byte string as input");
+ goto _fail;
+ }
+
+ encoded = PyBytes_AS_STRING(byteobj);
+ encoded_len = PyBytes_GET_SIZE(byteobj);
+ bytesize = (int)ceil(itemsize / 8.0);
+ storagesize = bytesize < 3 ? bytesize : bytesize > 4 ? 8 : 4;
+ if ((encoded_len < bytesize) || (encoded_len > SSIZE_MAX / storagesize)) {
+ PyErr_Format(PyExc_ValueError, "data size out of range");
+ goto _fail;
+ }
+ if (dtype->elsize != storagesize) {
+ PyErr_Format(PyExc_TypeError, "dtype.elsize doesn't fit itemsize");
+ goto _fail;
+ }
+
+ if (runlen == 0) {
+ runlen = (Py_ssize_t)(((uint64_t)encoded_len*8) / (uint64_t)itemsize);
+ }
+ skipbits = (Py_ssize_t)(((uint64_t)runlen * (uint64_t)itemsize) % 8);
+ if (skipbits > 0) {
+ skipbits = 8 - skipbits;
+ }
+ decoded_len = (Py_ssize_t)((uint64_t)runlen * (((uint64_t)encoded_len*8) /
+ ((uint64_t)runlen*(uint64_t)itemsize + (uint64_t)skipbits)));
+
+ result = (PyArrayObject *)PyArray_SimpleNew(1, &decoded_len,
+ dtype->type_num);
+ if (result == NULL) {
+ PyErr_Format(PyExc_MemoryError, "unable to allocate output array");
+ goto _fail;
+ }
+ decoded = (char *)PyArray_DATA(result);
+
+ for (i = 0; i < decoded_len; i+=runlen) {
+ if (NO_ERROR !=
+ unpackbits((unsigned char *) encoded,
+ (ssize_t) encoded_len,
+ (int) itemsize,
+ (ssize_t) runlen,
+ (unsigned char *) decoded)) {
+ PyErr_Format(PyExc_ValueError, "unpackbits() failed");
+ goto _fail;
+ }
+ encoded += (Py_ssize_t)(((uint64_t)runlen * (uint64_t)itemsize +
+ (uint64_t)skipbits) / 8);
+ decoded += runlen * storagesize;
+ }
+
+ if ((dtype->byteorder != BOC) && (itemsize % 8 == 0)) {
+ switch (dtype->elsize) {
+ case 2: {
+ uint16_t *d = (uint16_t *)PyArray_DATA(result);
+ for (i = 0; i < PyArray_SIZE(result); i++) {
+ *d = SWAP2BYTES(*d); d++;
+ }
+ break; }
+ case 4: {
+ uint32_t *d = (uint32_t *)PyArray_DATA(result);
+ for (i = 0; i < PyArray_SIZE(result); i++) {
+ *d = SWAP4BYTES(*d); d++;
+ }
+ break; }
+ case 8: {
+ uint64_t *d = (uint64_t *)PyArray_DATA(result);
+ for (i = 0; i < PyArray_SIZE(result); i++) {
+ *d = SWAP8BYTES(*d); d++;
+ }
+ break; }
+ }
+ }
+ Py_DECREF(byteobj);
+ Py_DECREF(dtype);
+ return PyArray_Return(result);
+
+ _fail:
+ Py_XDECREF(byteobj);
+ Py_XDECREF(result);
+ Py_XDECREF(dtype);
+ return NULL;
+}
+
+
+/** Decode TIFF PackBits encoded string. */
+char py_decodepackbits_doc[] = "Return TIFF PackBits decoded string.";
+
+static PyObject *
+py_decodepackbits(PyObject *obj, PyObject *args)
+{
+ int n;
+ char e;
+ char *decoded = NULL;
+ char *encoded = NULL;
+ char *encoded_end = NULL;
+ char *encoded_pos = NULL;
+ unsigned int encoded_len;
+ unsigned int decoded_len;
+ PyObject *byteobj = NULL;
+ PyObject *result = NULL;
+
+ if (!PyArg_ParseTuple(args, "O", &byteobj))
+ return NULL;
+
+ if (!PyBytes_Check(byteobj)) {
+ PyErr_Format(PyExc_TypeError, "expected byte string as input");
+ goto _fail;
+ }
+
+ Py_INCREF(byteobj);
+ encoded = PyBytes_AS_STRING(byteobj);
+ encoded_len = (unsigned int)PyBytes_GET_SIZE(byteobj);
+
+ /* release GIL: byte/string objects are immutable */
+ Py_BEGIN_ALLOW_THREADS
+
+ /* determine size of decoded string */
+ encoded_pos = encoded;
+ encoded_end = encoded + encoded_len;
+ decoded_len = 0;
+ while (encoded_pos < encoded_end) {
+ n = (int)*encoded_pos++;
+ if (n >= 0) {
+ n++;
+ if (encoded_pos+n > encoded_end)
+ n = (int)(encoded_end - encoded_pos);
+ encoded_pos += n;
+ decoded_len += n;
+ } else if (n > -128) {
+ encoded_pos++;
+ decoded_len += 1-n;
+ }
+ }
+ Py_END_ALLOW_THREADS
+
+ result = PyBytes_FromStringAndSize(0, decoded_len);
+ if (result == NULL) {
+ PyErr_Format(PyExc_MemoryError, "failed to allocate decoded string");
+ goto _fail;
+ }
+ decoded = PyBytes_AS_STRING(result);
+
+ Py_BEGIN_ALLOW_THREADS
+
+ /* decode string */
+ encoded_end = encoded + encoded_len;
+ while (encoded < encoded_end) {
+ n = (int)*encoded++;
+ if (n >= 0) {
+ n++;
+ if (encoded+n > encoded_end)
+ n = (int)(encoded_end - encoded);
+ /* memmove(decoded, encoded, n); decoded += n; encoded += n; */
+ while (n--)
+ *decoded++ = *encoded++;
+ } else if (n > -128) {
+ n = 1 - n;
+ e = *encoded++;
+ /* memset(decoded, e, n); decoded += n; */
+ while (n--)
+ *decoded++ = e;
+ }
+ }
+ Py_END_ALLOW_THREADS
+
+ Py_DECREF(byteobj);
+ return result;
+
+ _fail:
+ Py_XDECREF(byteobj);
+ Py_XDECREF(result);
+ return NULL;
+}
+
+
+/** Decode TIFF LZW encoded string. */
+char py_decodelzw_doc[] = "Return TIFF LZW decoded string.";
+
+static PyObject *
+py_decodelzw(PyObject *obj, PyObject *args)
+{
+ PyThreadState *_save = NULL;
+ PyObject *byteobj = NULL;
+ PyObject *result = NULL;
+ int i, j;
+ unsigned int encoded_len = 0;
+ unsigned int decoded_len = 0;
+ unsigned int result_len = 0;
+ unsigned int table_len = 0;
+ unsigned int len;
+ unsigned int code, c, oldcode, mask, shr;
+ uint64_t bitcount, bitw;
+ char *encoded = NULL;
+ char *result_ptr = NULL;
+ char *table2 = NULL;
+ char *cptr;
+ struct BYTE_STRING *decoded = NULL;
+ struct BYTE_STRING *decoded_ptr = NULL;
+ struct BYTE_STRING *table[4096];
+ struct BYTE_STRING *newentry, *newresult, *t;
+ int little_endian = 0;
+
+ if (!PyArg_ParseTuple(args, "O", &byteobj))
+ return NULL;
+
+ if (!PyBytes_Check(byteobj)) {
+ PyErr_Format(PyExc_TypeError, "expected byte string as input");
+ goto _fail;
+ }
+
+ Py_INCREF(byteobj);
+ encoded = PyBytes_AS_STRING(byteobj);
+ encoded_len = (unsigned int)PyBytes_GET_SIZE(byteobj);
+ /*
+ if (encoded_len >= 512 * 1024 * 1024) {
+ PyErr_Format(PyExc_ValueError, "encoded data > 512 MB not supported");
+ goto _fail;
+ }
+ */
+ /* release GIL: byte/string objects are immutable */
+ _save = PyEval_SaveThread();
+
+ if ((*encoded != -128) || ((*(encoded+1) & 128))) {
+ PyEval_RestoreThread(_save);
+ PyErr_Format(PyExc_ValueError,
+ "strip must begin with CLEAR code");
+ goto _fail;
+ }
+ little_endian = (*(unsigned short *)encoded) & 128;
+
+ /* allocate buffer for codes and pointers */
+ decoded_len = 0;
+ len = (encoded_len + encoded_len/9) * sizeof(decoded);
+ decoded = PyMem_Malloc(len * sizeof(void *));
+ if (decoded == NULL) {
+ PyEval_RestoreThread(_save);
+ PyErr_Format(PyExc_MemoryError, "failed to allocate decoded");
+ goto _fail;
+ }
+ memset((void *)decoded, 0, len * sizeof(void *));
+ decoded_ptr = decoded;
+
+ /* cache strings of length 2 */
+ cptr = table2 = PyMem_Malloc(256*256*2 * sizeof(char));
+ if (table2 == NULL) {
+ PyEval_RestoreThread(_save);
+ PyErr_Format(PyExc_MemoryError, "failed to allocate table2");
+ goto _fail;
+ }
+ for (i = 0; i < 256; i++) {
+ for (j = 0; j < 256; j++) {
+ *cptr++ = (char)i;
+ *cptr++ = (char)j;
+ }
+ }
+
+ memset(table, 0, sizeof(table));
+ table_len = 258;
+ bitw = 9;
+ shr = 23;
+ mask = 4286578688;
+ bitcount = 0;
+ result_len = 0;
+ code = 0;
+ oldcode = 0;
+
+ while ((unsigned int)((bitcount + bitw) / 8) <= encoded_len) {
+ /* read next code */
+ code = *((unsigned int *)((void *)(encoded + (bitcount / 8))));
+ if (little_endian)
+ code = SWAP4BYTES(code);
+ code <<= (unsigned int)(bitcount % 8);
+ code &= mask;
+ code >>= shr;
+ bitcount += bitw;
+
+ if (code == 257) /* end of information */
+ break;
+
+ if (code == 256) { /* clearcode */
+ /* initialize table and switch to 9 bit */
+ while (table_len > 258) {
+ t = table[--table_len];
+ t->ref--;
+ if (t->ref == 0) {
+ if (t->len > 2)
+ PyMem_Free(t->str);
+ PyMem_Free(t);
+ }
+ }
+ bitw = 9;
+ shr = 23;
+ mask = 4286578688;
+
+ /* read next code */
+ code = *((unsigned int *)((void *)(encoded + (bitcount / 8))));
+ if (little_endian)
+ code = SWAP4BYTES(code);
+ code <<= bitcount % 8;
+ code &= mask;
+ code >>= shr;
+ bitcount += bitw;
+
+ if (code == 257) /* end of information */
+ break;
+
+ /* decoded.append(table[code]) */
+ if (code < 256) {
+ result_len++;
+ *((int *)decoded_ptr++) = code;
+ } else {
+ newresult = table[code];
+ newresult->ref++;
+ result_len += newresult->len;
+ *(struct BYTE_STRING **)decoded_ptr++ = newresult;
+ }
+ } else {
+ if (code < table_len) {
+ /* code is in table */
+ /* newresult = table[code]; */
+ /* newentry = table[oldcode] + table[code][0] */
+ /* decoded.append(newresult); table.append(newentry) */
+ if (code < 256) {
+ c = code;
+ *((unsigned int *)decoded_ptr++) = code;
+ result_len++;
+ } else {
+ newresult = table[code];
+ newresult->ref++;
+ c = (unsigned int) *newresult->str;
+ *(struct BYTE_STRING **)decoded_ptr++ = newresult;
+ result_len += newresult->len;
+ }
+ newentry = PyMem_Malloc(sizeof(struct BYTE_STRING));
+ newentry->ref = 1;
+ if (oldcode < 256) {
+ newentry->len = 2;
+ newentry->str = table2 + (oldcode << 9) +
+ ((unsigned char)c << 1);
+ } else {
+ len = table[oldcode]->len;
+ newentry->len = len + 1;
+ newentry->str = PyMem_Malloc(newentry->len);
+ if (newentry->str == NULL)
+ break;
+ memmove(newentry->str, table[oldcode]->str, len);
+ newentry->str[len] = c;
+ }
+ table[table_len++] = newentry;
+ } else {
+ /* code is not in table */
+ /* newentry = newresult = table[oldcode] + table[oldcode][0] */
+ /* decoded.append(newresult); table.append(newentry) */
+ newresult = PyMem_Malloc(sizeof(struct BYTE_STRING));
+ newentry = newresult;
+ newentry->ref = 2;
+ if (oldcode < 256) {
+ newentry->len = 2;
+ newentry->str = table2 + 514*oldcode;
+ } else {
+ len = table[oldcode]->len;
+ newentry->len = len + 1;
+ newentry->str = PyMem_Malloc(newentry->len);
+ if (newentry->str == NULL)
+ break;
+ memmove(newentry->str, table[oldcode]->str, len);
+ newentry->str[len] = *table[oldcode]->str;
+ }
+ table[table_len++] = newentry;
+ *(struct BYTE_STRING **)decoded_ptr++ = newresult;
+ result_len += newresult->len;
+ }
+ }
+ oldcode = code;
+ /* increase bit-width if necessary */
+ switch (table_len) {
+ case 511:
+ bitw = 10;
+ shr = 22;
+ mask = 4290772992;
+ break;
+ case 1023:
+ bitw = 11;
+ shr = 21;
+ mask = 4292870144;
+ break;
+ case 2047:
+ bitw = 12;
+ shr = 20;
+ mask = 4293918720;
+ }
+ }
+
+ PyEval_RestoreThread(_save);
+
+ if (code != 257) {
+ PyErr_WarnEx(NULL,
+ "py_decodelzw encountered unexpected end of stream", 1);
+ }
+
+ /* result = ''.join(decoded) */
+ decoded_len = (unsigned int)(decoded_ptr - decoded);
+ decoded_ptr = decoded;
+ result = PyBytes_FromStringAndSize(0, result_len);
+ if (result == NULL) {
+ PyErr_Format(PyExc_MemoryError, "failed to allocate decoded string");
+ goto _fail;
+ }
+ result_ptr = PyBytes_AS_STRING(result);
+
+ _save = PyEval_SaveThread();
+
+ while (decoded_len--) {
+ code = *((unsigned int *)decoded_ptr);
+ if (code < 256) {
+ *result_ptr++ = (char)code;
+ } else {
+ t = *((struct BYTE_STRING **)decoded_ptr);
+ memmove(result_ptr, t->str, t->len);
+ result_ptr += t->len;
+ if (--t->ref == 0) {
+ if (t->len > 2)
+ PyMem_Free(t->str);
+ PyMem_Free(t);
+ }
+ }
+ decoded_ptr++;
+ }
+ PyMem_Free(decoded);
+
+ while (table_len-- > 258) {
+ t = table[table_len];
+ if (t->len > 2)
+ PyMem_Free(t->str);
+ PyMem_Free(t);
+ }
+ PyMem_Free(table2);
+
+ PyEval_RestoreThread(_save);
+
+ Py_DECREF(byteobj);
+ return result;
+
+ _fail:
+ if (table2 != NULL)
+ PyMem_Free(table2);
+ if (decoded != NULL) {
+ /* Bug? are decoded_ptr and decoded_len correct? */
+ while (decoded_len--) {
+ code = *((unsigned int *) decoded_ptr);
+ if (code > 258) {
+ t = *((struct BYTE_STRING **) decoded_ptr);
+ if (--t->ref == 0) {
+ if (t->len > 2)
+ PyMem_Free(t->str);
+ PyMem_Free(t);
+ }
+ }
+ }
+ PyMem_Free(decoded);
+ }
+ while (table_len-- > 258) {
+ t = table[table_len];
+ if (t->len > 2)
+ PyMem_Free(t->str);
+ PyMem_Free(t);
+ }
+
+ Py_XDECREF(byteobj);
+ Py_XDECREF(result);
+
+ return NULL;
+}
+
+/*****************************************************************************/
+/* Create Python module */
+
+char module_doc[] =
+ "A Python C extension module for decoding PackBits and LZW encoded "
+ "TIFF data.\n\n"
+ "Refer to the tifffile.py module for documentation and tests.\n\n"
+ "Authors:\n Christoph Gohlke \n"
+ " Laboratory for Fluorescence Dynamics, University of California, Irvine."
+ "\n\nVersion: %s\n";
+
+static PyMethodDef module_methods[] = {
+#if MSB
+ {"unpackints", (PyCFunction)py_unpackints, METH_VARARGS|METH_KEYWORDS,
+ py_unpackints_doc},
+#endif
+ {"decodelzw", (PyCFunction)py_decodelzw, METH_VARARGS,
+ py_decodelzw_doc},
+ {"decodepackbits", (PyCFunction)py_decodepackbits, METH_VARARGS,
+ py_decodepackbits_doc},
+ {NULL, NULL, 0, NULL} /* Sentinel */
+};
+
+#if PY_MAJOR_VERSION >= 3
+
+struct module_state {
+ PyObject *error;
+};
+
+#define GETSTATE(m) ((struct module_state*)PyModule_GetState(m))
+
+static int module_traverse(PyObject *m, visitproc visit, void *arg) {
+ Py_VISIT(GETSTATE(m)->error);
+ return 0;
+}
+
+static int module_clear(PyObject *m) {
+ Py_CLEAR(GETSTATE(m)->error);
+ return 0;
+}
+
+static struct PyModuleDef moduledef = {
+ PyModuleDef_HEAD_INIT,
+ "_tifffile",
+ NULL,
+ sizeof(struct module_state),
+ module_methods,
+ NULL,
+ module_traverse,
+ module_clear,
+ NULL
+};
+
+#define INITERROR return NULL
+
+PyMODINIT_FUNC
+PyInit__tifffile(void)
+
+#else
+
+#define INITERROR return
+
+PyMODINIT_FUNC
+init_tifffile(void)
+
+#endif
+{
+ PyObject *module;
+
+ char *doc = (char *)PyMem_Malloc(sizeof(module_doc) + sizeof(_VERSION_));
+ PyOS_snprintf(doc, sizeof(doc), module_doc, _VERSION_);
+
+#if PY_MAJOR_VERSION >= 3
+ moduledef.m_doc = doc;
+ module = PyModule_Create(&moduledef);
+#else
+ module = Py_InitModule3("_tifffile", module_methods, doc);
+#endif
+
+ PyMem_Free(doc);
+
+ if (module == NULL)
+ INITERROR;
+
+ if (_import_array() < 0) {
+ Py_DECREF(module);
+ INITERROR;
+ }
+
+ {
+#if PY_MAJOR_VERSION < 3
+ PyObject *s = PyString_FromString(_VERSION_);
+#else
+ PyObject *s = PyUnicode_FromString(_VERSION_);
+#endif
+ PyObject *dict = PyModule_GetDict(module);
+ PyDict_SetItemString(dict, "__version__", s);
+ Py_DECREF(s);
+ }
+
+#if PY_MAJOR_VERSION >= 3
+ return module;
+#endif
+}
+
diff --git a/skimage/external/tifffile/_tifffile.py b/skimage/external/tifffile/tiffile_.py
similarity index 99%
rename from skimage/external/tifffile/_tifffile.py
rename to skimage/external/tifffile/tiffile_.py
index 83ae4f0e..b2d3303a 100644
--- a/skimage/external/tifffile/_tifffile.py
+++ b/skimage/external/tifffile/tiffile_.py
@@ -151,6 +151,8 @@ from xml.etree import cElementTree as etree
import numpy
+from . import _tifffile
+
__version__ = '0.3.1'
__docformat__ = 'restructuredtext en'
__all__ = ('imsave', 'imread', 'imshow', 'TiffFile', 'TiffWriter',
diff --git a/skimage/setup.py b/skimage/setup.py
index 962adb97..9a8c8ac2 100644
--- a/skimage/setup.py
+++ b/skimage/setup.py
@@ -21,6 +21,7 @@ def configuration(parent_package='', top_path=None):
config.add_subpackage('transform')
config.add_subpackage('util')
config.add_subpackage('segmentation')
+ config.add_subpackage('external')
def add_test_directories(arg, dirname, fnames):
if dirname.split(os.path.sep)[-1] == 'tests':