~ubuntu-branches/ubuntu/utopic/tifffile/utopic

« back to all changes in this revision

Viewing changes to tifffile.c

  • Committer: Package Import Robot
  • Author(s): Mathieu Malaterre
  • Date: 2011-11-13 19:41:37 UTC
  • Revision ID: package-import@ubuntu.com-20111113194137-7k23ioso3edjz2du
Tags: upstream-20111112
ImportĀ upstreamĀ versionĀ 20111112

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* tifffile.c
 
2
 
 
3
A Python C extension module for decoding PackBits and LZW encoded TIFF data.
 
4
 
 
5
Refer to the tifffile.py module for documentation and tests.
 
6
 
 
7
Tested on Python 2.7 and 3.2, 32-bit and 64-bit.
 
8
 
 
9
Authors:
 
10
  Christoph Gohlke <http://www.lfd.uci.edu/~gohlke/>,
 
11
  Laboratory for Fluorescence Dynamics. University of California, Irvine.
 
12
 
 
13
Copyright (c) 2008-2011, The Regents of the University of California
 
14
Produced by the Laboratory for Fluorescence Dynamics.
 
15
All rights reserved.
 
16
 
 
17
Redistribution and use in source and binary forms, with or without
 
18
modification, are permitted provided that the following conditions are met:
 
19
 
 
20
* Redistributions of source code must retain the above copyright
 
21
  notice, this list of conditions and the following disclaimer.
 
22
* Redistributions in binary form must reproduce the above copyright
 
23
  notice, this list of conditions and the following disclaimer in the
 
24
  documentation and/or other materials provided with the distribution.
 
25
* Neither the name of the copyright holders nor the names of any
 
26
  contributors may be used to endorse or promote products derived
 
27
  from this software without specific prior written permission.
 
28
 
 
29
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 
30
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 
31
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 
32
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 
33
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 
34
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 
35
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 
36
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 
37
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 
38
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 
39
POSSIBILITY OF SUCH DAMAGE.
 
40
*/
 
41
 
 
42
/*****************************************************************************/
 
43
/* setup.py
 
44
 
 
45
"""A Python script to build the _tifffile extension module.
 
46
 
 
47
Usage:: ``python setup.py build_ext --inplace``
 
48
 
 
49
"""
 
50
 
 
51
from distutils.core import setup, Extension
 
52
import numpy
 
53
 
 
54
setup(name='_tifffile', ext_modules=[Extension('_tifffile', ['tifffile.c'],
 
55
    include_dirs=[numpy.get_include()], extra_compile_args=[])],)
 
56
 
 
57
 
 
58
******************************************************************************/
 
59
 
 
60
#define _VERSION_ "2011.07.07"
 
61
 
 
62
#define WIN32_LEAN_AND_MEAN
 
63
 
 
64
#include "Python.h"
 
65
#include "string.h"
 
66
#include "numpy/arrayobject.h"
 
67
 
 
68
#define SWAP2BYTES(x) ((((x)>>8)&0xff) | (((x)&0xff)<<8))
 
69
#define SWAP4BYTES(x) ((((x)>>24)&0xff) | (((x)&0xff)<<24) | \
 
70
                       (((x)>>8)&0xff00) | (((x)&0xff00)<<8))
 
71
 
 
72
struct BYTE_STRING {
 
73
    unsigned int ref; /* reference count */
 
74
    unsigned int len; /* length of string */
 
75
    char *str;        /* pointer to bytes */
 
76
};
 
77
 
 
78
/*****************************************************************************/
 
79
/* C functions */
 
80
 
 
81
/*****************************************************************************/
 
82
/* Python functions */
 
83
 
 
84
/*
 
85
Decode TIFF PackBits encoded string.
 
86
*/
 
87
char py_decodepackbits_doc[] = "Return TIFF PackBits decoded string.";
 
88
 
 
89
static PyObject *
 
90
py_decodepackbits(PyObject *obj, PyObject *args)
 
91
{
 
92
    int n;
 
93
    char e;
 
94
    char *decoded = NULL;
 
95
    char *encoded = NULL;
 
96
    char *encoded_end = NULL;
 
97
    char *encoded_pos = NULL;
 
98
    unsigned int encoded_len;
 
99
    unsigned int decoded_len;
 
100
    PyObject *byteobj = NULL;
 
101
    PyObject *result = NULL;
 
102
 
 
103
    if (!PyArg_ParseTuple(args, "O", &byteobj))
 
104
        return NULL;
 
105
 
 
106
    if (!PyBytes_Check(byteobj)) {
 
107
        PyErr_Format(PyExc_TypeError, "expected byte string as input");
 
108
        goto _fail;
 
109
    }
 
110
 
 
111
    Py_INCREF(byteobj);
 
112
    encoded = PyBytes_AS_STRING(byteobj);
 
113
    encoded_len = (unsigned int)PyBytes_GET_SIZE(byteobj);
 
114
 
 
115
    /* release GIL: byte/string objects are immutable */
 
116
    Py_BEGIN_ALLOW_THREADS
 
117
 
 
118
    /* determine size of decoded string */
 
119
    encoded_pos = encoded;
 
120
    encoded_end = encoded + encoded_len;
 
121
    decoded_len = 0;
 
122
    while (encoded_pos < encoded_end) {
 
123
        n = (int)*encoded_pos++;
 
124
        if (n >= 0) {
 
125
            n++;
 
126
            if (encoded_pos+n > encoded_end)
 
127
                n = (int)(encoded_end - encoded_pos);
 
128
            encoded_pos += n;
 
129
            decoded_len += n;
 
130
        } else if (n > -128) {
 
131
            encoded_pos++;
 
132
            decoded_len += 1-n;
 
133
        }
 
134
    }
 
135
    Py_END_ALLOW_THREADS
 
136
 
 
137
    result = PyBytes_FromStringAndSize(0, decoded_len);
 
138
    if (result == NULL) {
 
139
        PyErr_Format(PyExc_MemoryError, "failed to allocate decoded string");
 
140
        goto _fail;
 
141
    }
 
142
    decoded = PyBytes_AS_STRING(result);
 
143
 
 
144
    Py_BEGIN_ALLOW_THREADS
 
145
 
 
146
    /* decode string */
 
147
    encoded_end = encoded + encoded_len;
 
148
    while (encoded < encoded_end) {
 
149
        n = (int)*encoded++;
 
150
        if (n >= 0) {
 
151
            n++;
 
152
            if (encoded+n > encoded_end)
 
153
                n = (int)(encoded_end - encoded);
 
154
            /* memmove(decoded, encoded, n); decoded += n; encoded += n; */
 
155
            while (n--)
 
156
                *decoded++ = *encoded++;
 
157
        } else if (n > -128) {
 
158
            n = 1 - n;
 
159
            e = *encoded++;
 
160
            /* memset(decoded, e, n); decoded += n; */
 
161
            while (n--)
 
162
                *decoded++ = e;
 
163
        }
 
164
    }
 
165
    Py_END_ALLOW_THREADS
 
166
 
 
167
    Py_DECREF(byteobj);
 
168
    return result;
 
169
 
 
170
  _fail:
 
171
    Py_XDECREF(byteobj);
 
172
    Py_XDECREF(result);
 
173
    return NULL;
 
174
}
 
175
 
 
176
/*
 
177
Decode TIFF LZW encoded string.
 
178
*/
 
179
char py_decodelzw_doc[] = "Return TIFF LZW decoded string.";
 
180
 
 
181
static PyObject *
 
182
py_decodelzw(PyObject *obj, PyObject *args)
 
183
{
 
184
    PyThreadState *_save = NULL;
 
185
    PyObject *byteobj = NULL;
 
186
    PyObject *result = NULL;
 
187
    int i, j;
 
188
    unsigned int encoded_len = 0;
 
189
    unsigned int decoded_len = 0;
 
190
    unsigned int result_len = 0;
 
191
    unsigned int table_len = 0;
 
192
    unsigned int len;
 
193
    unsigned int code, c, oldcode, mask, bitw, shr, bitcount;
 
194
    char *encoded = NULL;
 
195
    char *result_ptr = NULL;
 
196
    char *table2 = NULL;
 
197
    char *cptr;
 
198
    struct BYTE_STRING *decoded = NULL;
 
199
    struct BYTE_STRING *table[4096];
 
200
    struct BYTE_STRING *decoded_ptr, *newentry, *newresult, *t;
 
201
    int little_endian = 0;
 
202
 
 
203
    if (!PyArg_ParseTuple(args, "O", &byteobj))
 
204
        return NULL;
 
205
 
 
206
    if (!PyBytes_Check(byteobj)) {
 
207
        PyErr_Format(PyExc_TypeError, "expected byte string as input");
 
208
        goto _fail;
 
209
    }
 
210
 
 
211
    Py_INCREF(byteobj);
 
212
    encoded = PyBytes_AS_STRING(byteobj);
 
213
    encoded_len = (unsigned int)PyBytes_GET_SIZE(byteobj);
 
214
 
 
215
    /* release GIL: byte/string objects are immutable */
 
216
    _save = PyEval_SaveThread();
 
217
 
 
218
    if ((*encoded != -128) || ((*(encoded+1) & 128))) {
 
219
        PyEval_RestoreThread(_save);
 
220
        PyErr_Format(PyExc_ValueError,
 
221
            "strip must begin with CLEAR code");
 
222
        goto _fail;
 
223
    }
 
224
    little_endian = (*(unsigned short *)encoded) & 128;
 
225
 
 
226
    /* allocate buffer for codes and pointers */
 
227
    decoded_len = 0;
 
228
    len = (encoded_len + encoded_len/9) * sizeof(decoded);
 
229
    decoded = PyMem_Malloc(len * sizeof(void *));
 
230
    if (decoded == NULL) {
 
231
        PyEval_RestoreThread(_save);
 
232
        PyErr_Format(PyExc_MemoryError, "failed to allocate decoded");
 
233
        goto _fail;
 
234
    }
 
235
    memset((void *)decoded, 0, len * sizeof(void *));
 
236
    decoded_ptr = decoded;
 
237
 
 
238
    /* cache strings of length 2 */
 
239
    cptr = table2 = PyMem_Malloc(256*256*2 * sizeof(char));
 
240
    if (table2 == NULL) {
 
241
        PyEval_RestoreThread(_save);
 
242
        PyErr_Format(PyExc_MemoryError, "failed to allocate table2");
 
243
        goto _fail;
 
244
    }
 
245
    for (i = 0; i < 256; i++) {
 
246
        for (j = 0; j < 256; j++) {
 
247
            *cptr++ = (char)i;
 
248
            *cptr++ = (char)j;
 
249
        }
 
250
    }
 
251
 
 
252
    memset(table, 0, sizeof(table));
 
253
    table_len = 258;
 
254
    bitw = 9;
 
255
    shr = 23;
 
256
    mask = 4286578688;
 
257
    bitcount = 0;
 
258
    result_len = 0;
 
259
    code = 0;
 
260
    oldcode = 0;
 
261
 
 
262
    while ((unsigned int)((bitcount + bitw) >> 3) <= encoded_len) {
 
263
        /* read next code */
 
264
        code = *((unsigned int *)((void *)(encoded + (bitcount / 8))));
 
265
        if (little_endian)
 
266
            code = SWAP4BYTES(code);
 
267
        code <<= bitcount % 8;
 
268
        code &= mask;
 
269
        code >>= shr;
 
270
        bitcount += bitw;
 
271
 
 
272
        if (code == 257) /* end of information */
 
273
            break;
 
274
 
 
275
        if (code == 256) {  /* clearcode */
 
276
            /* initialize table and switch to 9 bit */
 
277
            while (table_len > 258) {
 
278
                t = table[--table_len];
 
279
                t->ref--;
 
280
                if (t->ref == 0) {
 
281
                    if (t->len > 2)
 
282
                        PyMem_Free(t->str);
 
283
                    PyMem_Free(t);
 
284
                }
 
285
            }
 
286
            bitw = 9;
 
287
            shr = 23;
 
288
            mask = 4286578688;
 
289
 
 
290
            /* read next code */
 
291
            code = *((unsigned int *)((void *)(encoded + (bitcount / 8))));
 
292
            if (little_endian)
 
293
                code = SWAP4BYTES(code);
 
294
            code <<= bitcount % 8;
 
295
            code &= mask;
 
296
            code >>= shr;
 
297
            bitcount += bitw;
 
298
 
 
299
            if (code == 257) /* end of information */
 
300
                break;
 
301
 
 
302
            /* decoded.append(table[code]) */
 
303
            if (code < 256) {
 
304
                result_len++;
 
305
                *((int *)decoded_ptr++) = code;
 
306
            } else {
 
307
                newresult = table[code];
 
308
                newresult->ref++;
 
309
                result_len += newresult->len;
 
310
                 *(struct BYTE_STRING **)decoded_ptr++ = newresult;
 
311
            }
 
312
        } else {
 
313
            if (code < table_len) {
 
314
                /* code is in table */
 
315
                /* newresult = table[code]; */
 
316
                /* newentry = table[oldcode] + table[code][0] */
 
317
                /* decoded.append(newresult); table.append(newentry) */
 
318
                if (code < 256) {
 
319
                    c = code;
 
320
                    *((unsigned int *)decoded_ptr++) = code;
 
321
                    result_len++;
 
322
                } else {
 
323
                    newresult = table[code];
 
324
                    newresult->ref++;
 
325
                    c = (unsigned int) *newresult->str;
 
326
                    *(struct BYTE_STRING **)decoded_ptr++ = newresult;
 
327
                    result_len += newresult->len;
 
328
                }
 
329
                newentry = PyMem_Malloc(sizeof(struct BYTE_STRING));
 
330
                newentry->ref = 1;
 
331
                if (oldcode < 256) {
 
332
                    newentry->len = 2;
 
333
                    newentry->str = table2 + (oldcode << 9) +
 
334
                                    ((unsigned char)c << 1);
 
335
                } else {
 
336
                    len = table[oldcode]->len;
 
337
                    newentry->len = len + 1;
 
338
                    newentry->str = PyMem_Malloc(newentry->len);
 
339
                    if (newentry->str == NULL)
 
340
                        break;
 
341
                    memmove(newentry->str, table[oldcode]->str, len);
 
342
                    newentry->str[len] = c;
 
343
                }
 
344
                table[table_len++] = newentry;
 
345
            } else {
 
346
                /* code is not in table */
 
347
                /* newentry = newresult = table[oldcode] + table[oldcode][0] */
 
348
                /* decoded.append(newresult); table.append(newentry) */
 
349
                newresult = PyMem_Malloc(sizeof(struct BYTE_STRING));
 
350
                newentry = newresult;
 
351
                newentry->ref = 2;
 
352
                if (oldcode < 256) {
 
353
                    newentry->len = 2;
 
354
                    newentry->str = table2 + 514*oldcode;
 
355
                } else {
 
356
                    len = table[oldcode]->len;
 
357
                    newentry->len = len + 1;
 
358
                    newentry->str = PyMem_Malloc(newentry->len);
 
359
                    if (newentry->str == NULL)
 
360
                        break;
 
361
                    memmove(newentry->str, table[oldcode]->str, len);
 
362
                    newentry->str[len] = *table[oldcode]->str;
 
363
                }
 
364
                table[table_len++] = newentry;
 
365
                *(struct BYTE_STRING **)decoded_ptr++ = newresult;
 
366
                result_len += newresult->len;
 
367
            }
 
368
        }
 
369
        oldcode = code;
 
370
        /* increase bit-width if necessary */
 
371
        switch (table_len) {
 
372
            case 511:
 
373
                bitw = 10;
 
374
                shr = 22;
 
375
                mask = 4290772992;
 
376
                break;
 
377
            case 1023:
 
378
                bitw = 11;
 
379
                shr = 21;
 
380
                mask = 4292870144;
 
381
                break;
 
382
            case 2047:
 
383
                bitw = 12;
 
384
                shr = 20;
 
385
                mask = 4293918720;
 
386
        }
 
387
    }
 
388
 
 
389
    PyEval_RestoreThread(_save);
 
390
 
 
391
    if (code != 257) {
 
392
        PyErr_Format(PyExc_TypeError, "unexpected end of stream");
 
393
        goto _fail;
 
394
    }
 
395
 
 
396
    /* result = ''.join(decoded) */
 
397
    decoded_len = (unsigned int)(decoded_ptr - decoded);
 
398
    decoded_ptr = decoded;
 
399
    result = PyBytes_FromStringAndSize(0, result_len);
 
400
    if (result == NULL) {
 
401
        PyErr_Format(PyExc_MemoryError, "failed to allocate decoded string");
 
402
        goto _fail;
 
403
    }
 
404
    result_ptr = PyBytes_AS_STRING(result);
 
405
 
 
406
    _save = PyEval_SaveThread();
 
407
 
 
408
    while (decoded_len--) {
 
409
        code = *((unsigned int *)decoded_ptr);
 
410
        if (code < 256) {
 
411
            *result_ptr++ = (char)code;
 
412
        } else {
 
413
            t = *((struct BYTE_STRING **)decoded_ptr);
 
414
            memmove(result_ptr, t->str, t->len);
 
415
            result_ptr +=  t->len;
 
416
            if (--t->ref == 0) {
 
417
                if (t->len > 2)
 
418
                    PyMem_Free(t->str);
 
419
                PyMem_Free(t);
 
420
            }
 
421
        }
 
422
        decoded_ptr++;
 
423
    }
 
424
    PyMem_Free(decoded);
 
425
 
 
426
    while (table_len-- > 258) {
 
427
        t = table[table_len];
 
428
        if (t->len > 2)
 
429
            PyMem_Free(t->str);
 
430
        PyMem_Free(t);
 
431
    }
 
432
    PyMem_Free(table2);
 
433
 
 
434
    PyEval_RestoreThread(_save);
 
435
 
 
436
    Py_DECREF(byteobj);
 
437
    return result;
 
438
 
 
439
  _fail:
 
440
    if (table2 != NULL)
 
441
        PyMem_Free(table2);
 
442
    if (decoded != NULL) {
 
443
        while (decoded_len--) {
 
444
            code = *((unsigned int *) decoded_ptr);
 
445
            if (code > 258) {
 
446
                t = *((struct BYTE_STRING **) decoded_ptr);
 
447
                if (--t->ref == 0) {
 
448
                    if (t->len > 2)
 
449
                        PyMem_Free(t->str);
 
450
                    PyMem_Free(t);
 
451
                }
 
452
            }
 
453
        }
 
454
        PyMem_Free(decoded);
 
455
    }
 
456
    while (table_len-- > 258) {
 
457
        t = table[table_len];
 
458
        if (t->len > 2)
 
459
            PyMem_Free(t->str);
 
460
        PyMem_Free(t);
 
461
    }
 
462
 
 
463
    Py_XDECREF(byteobj);
 
464
    Py_XDECREF(result);
 
465
 
 
466
    return NULL;
 
467
}
 
468
 
 
469
/*****************************************************************************/
 
470
/* Create Python module */
 
471
 
 
472
char module_doc[] =
 
473
    "A Python C extension module for decoding PackBits and LZW encoded "
 
474
    "TIFF data.\n\n"
 
475
    "Refer to the tifffile.py module for documentation and tests.\n\n"
 
476
    "Authors:\n  Christoph Gohlke <http://www.lfd.uci.edu/~gohlke/>\n"
 
477
    "  Laboratory for Fluorescence Dynamics, University of California, Irvine."
 
478
    "\n\nVersion: %s\n";
 
479
 
 
480
static PyMethodDef module_methods[] = {
 
481
    {"decodelzw", (PyCFunction)py_decodelzw, METH_VARARGS,
 
482
        py_decodelzw_doc},
 
483
    {"decodepackbits", (PyCFunction)py_decodepackbits, METH_VARARGS,
 
484
        py_decodepackbits_doc},
 
485
    {NULL, NULL, 0, NULL} /* Sentinel */
 
486
};
 
487
 
 
488
#if PY_MAJOR_VERSION >= 3
 
489
 
 
490
struct module_state {
 
491
    PyObject *error;
 
492
};
 
493
 
 
494
#define GETSTATE(m) ((struct module_state*)PyModule_GetState(m))
 
495
 
 
496
static int module_traverse(PyObject *m, visitproc visit, void *arg) {
 
497
    Py_VISIT(GETSTATE(m)->error);
 
498
    return 0;
 
499
}
 
500
 
 
501
static int module_clear(PyObject *m) {
 
502
    Py_CLEAR(GETSTATE(m)->error);
 
503
    return 0;
 
504
}
 
505
 
 
506
static struct PyModuleDef moduledef = {
 
507
        PyModuleDef_HEAD_INIT,
 
508
        "_tifffile",
 
509
        NULL,
 
510
        sizeof(struct module_state),
 
511
        module_methods,
 
512
        NULL,
 
513
        module_traverse,
 
514
        module_clear,
 
515
        NULL
 
516
};
 
517
 
 
518
#define INITERROR return NULL
 
519
 
 
520
PyMODINIT_FUNC
 
521
PyInit__tifffile(void)
 
522
 
 
523
#else
 
524
 
 
525
#define INITERROR return
 
526
 
 
527
PyMODINIT_FUNC
 
528
init_tifffile(void)
 
529
 
 
530
#endif
 
531
{
 
532
    PyObject *module;
 
533
 
 
534
    char *doc = (char *)PyMem_Malloc(sizeof(module_doc) + sizeof(_VERSION_));
 
535
    sprintf(doc, module_doc, _VERSION_);
 
536
 
 
537
#if PY_MAJOR_VERSION >= 3
 
538
    moduledef.m_doc = doc;
 
539
    module = PyModule_Create(&moduledef);
 
540
#else
 
541
    module = Py_InitModule3("_tifffile", module_methods, doc);
 
542
#endif
 
543
 
 
544
    PyMem_Free(doc);
 
545
 
 
546
    if (module == NULL)
 
547
        INITERROR;
 
548
 
 
549
    if (_import_array() < 0) {
 
550
        Py_DECREF(module);
 
551
        INITERROR;
 
552
    }
 
553
 
 
554
    {   
 
555
#if PY_MAJOR_VERSION < 3
 
556
    PyObject *s = PyString_FromString(_VERSION_);
 
557
#else
 
558
    PyObject *s = PyUnicode_FromString(_VERSION_);
 
559
#endif
 
560
    PyObject *dict = PyModule_GetDict(module);
 
561
    PyDict_SetItemString(dict, "__version__", s);
 
562
    Py_DECREF(s);
 
563
    }
 
564
 
 
565
#if PY_MAJOR_VERSION >= 3
 
566
    return module;
 
567
#endif
 
568
}