Glymur 0.14.1__py3-none-any.whl → 0.14.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
glymur/lib/_tiff.py ADDED
@@ -0,0 +1,2142 @@
1
+ # standard library imports
2
+ from collections import OrderedDict
3
+ import ctypes
4
+ from enum import IntEnum
5
+ import os
6
+ import queue
7
+ import re
8
+ import struct
9
+ import warnings
10
+
11
+ # 3rd party library imports
12
+ import numpy as np
13
+
14
+ # Local imports
15
+ from ..config import glymur_config
16
+
17
+ # The error messages queue
18
+ EQ = queue.Queue()
19
+
20
+ loader = ctypes.windll.LoadLibrary if os.name == "nt" else ctypes.CDLL
21
+ _LIBTIFF = glymur_config("tiff")
22
+ _LIBC = glymur_config("c")
23
+
24
+
25
+ class LibTIFFError(RuntimeError):
26
+ """Raise this exception if we detect a generic error from libtiff."""
27
+
28
+ pass
29
+
30
+
31
+ class Compression(IntEnum):
32
+ """Compression scheme used on the image data.
33
+
34
+ See Also
35
+ --------
36
+ Photometric : The color space of the image data.
37
+ """
38
+
39
+ NONE = 1
40
+ CCITTRLE = 2 # CCITT modified Huffman RLE
41
+ CCITTFAX3 = 3 # CCITT Group 3 fax encoding
42
+ CCITT_T4 = 3 # CCITT T.4 (TIFF 6 name)
43
+ CCITTFAX4 = 4 # CCITT Group 4 fax encoding
44
+ CCITT_T6 = 4 # CCITT T.6 (TIFF 6 name)
45
+ LZW = 5 # Lempel-Ziv & Welch
46
+ OJPEG = 6 # 6.0 JPEG
47
+ JPEG = 7 # JPEG DCT compression
48
+ T85 = 9 # TIFF/FX T.85 JBIG compression
49
+ T43 = 10 # TIFF/FX T.43 colour by layered JBIG compression
50
+ NEXT = 32766 # NeXT 2-bit RLE
51
+ CCITTRLEW = 32771 # #1 w/ word alignment
52
+ PACKBITS = 32773 # Macintosh RLE
53
+ THUNDERSCAN = 32809 # ThunderScan RLE
54
+ PIXARFILM = 32908 # companded 10bit LZW
55
+ PIXARLOG = 32909 # companded 11bit ZIP
56
+ DEFLATE = 32946 # compression
57
+ ADOBE_DEFLATE = 8 # compression, as recognized by Adobe
58
+ DCS = 32947 # DCS encoding
59
+ JBIG = 34661 # JBIG
60
+ SGILOG = 34676 # Log Luminance RLE
61
+ SGILOG24 = 34677 # Log 24-bit packed
62
+ JP2000 = 34712 # JPEG2000
63
+ LZMA = 34925 # LZMA2
64
+
65
+
66
+ class InkSet(IntEnum):
67
+ """
68
+ The set of inks used in a separated (PhotometricInterpretation=5) image.
69
+ """
70
+
71
+ CMYK = 1
72
+ MULTIINK = 2
73
+
74
+
75
+ class JPEGColorMode(IntEnum):
76
+ """When writing images with photometric interpretation equal to YCbCr and
77
+ compression equal to JPEG, the pseudo tag JPEGColorMode should usually be
78
+ set to RGB, unless the image values truly are in YCbCr.
79
+
80
+ See Also
81
+ --------
82
+ Photometric : The color space of the image data.
83
+ """
84
+
85
+ RAW = 0
86
+ RGB = 1
87
+
88
+
89
+ class PlanarConfig(IntEnum):
90
+ """How the components of each pixel are stored.
91
+
92
+ Writing images with a PlanarConfig value of PlanarConfig.SEPARATE is not
93
+ currently supported.
94
+ """
95
+
96
+ CONTIG = 1 # single image plane
97
+ SEPARATE = 2 # separate planes of data
98
+
99
+
100
+ class Orientation(IntEnum):
101
+ """The orientation of the image with respect to the rows and columns."""
102
+
103
+ TOPLEFT = 1 # row 0 top, col 0 lhs */
104
+ TOPRIGHT = 2 # row 0 top, col 0 rhs */
105
+ BOTRIGHT = 3 # row 0 bottom, col 0 rhs */
106
+ BOTLEFT = 4 # row 0 bottom, col 0 lhs */
107
+ LEFTTOP = 5 # row 0 lhs, col 0 top */
108
+ RIGHTTOP = 6 # row 0 rhs, col 0 top */
109
+ RIGHTBOT = 7 # row 0 rhs, col 0 bottom */
110
+ LEFTBOT = 8 # row 0 lhs, col 0 bottom */
111
+
112
+
113
+ class Photometric(IntEnum):
114
+ """The color space of the image data."""
115
+
116
+ MINISWHITE = 0 # value is white
117
+ MINISBLACK = 1 # value is black
118
+ RGB = 2 # color model
119
+ PALETTE = 3 # map indexed
120
+ MASK = 4 # holdout mask
121
+ SEPARATED = 5 # color separations
122
+ YCBCR = 6 # CCIR 601
123
+ CIELAB = 8 # 1976 CIE L*a*b*
124
+ ICCLAB = 9 # L*a*b* [Adobe TIFF Technote 4]
125
+ ITULAB = 10 # L*a*b*
126
+ CFA = 32803 # filter array
127
+ LOGL = 32844 # Log2(L)
128
+ LOGLUV = 32845 # Log2(L) (u',v')
129
+
130
+
131
+ class SampleFormat(IntEnum):
132
+ """Specifies how to interpret each data sample in a pixel."""
133
+
134
+ UINT = 1
135
+ INT = 2
136
+ IEEEFP = 3
137
+ VOID = 4
138
+ COMPLEXINT = 5
139
+ COMPLEXIEEEP = 6
140
+
141
+
142
+ def _handle_error(module, fmt, ap):
143
+ # Use VSPRINTF in the C library to put together the error message.
144
+ # int vsprintf(char * buffer, const char * restrict format, va_list ap);
145
+ buffer = ctypes.create_string_buffer(1000)
146
+
147
+ argtypes = [ctypes.c_char_p, ctypes.c_char_p, ctypes.c_void_p]
148
+ _LIBC.vsprintf.argtypes = argtypes
149
+ _LIBC.vsprintf.restype = ctypes.c_int32
150
+ _LIBC.vsprintf(buffer, fmt, ap)
151
+
152
+ module = module.decode("utf-8")
153
+ error_str = buffer.value.decode("utf-8")
154
+
155
+ message = f"{module}: {error_str}"
156
+ EQ.put(message)
157
+ return None
158
+
159
+
160
+ def _handle_warning(module, fmt, ap):
161
+ # Use VSPRINTF in the C library to put together the warning message.
162
+ # int vsprintf(char * buffer, const char * restrict format, va_list ap);
163
+ buffer = ctypes.create_string_buffer(1000)
164
+
165
+ argtypes = [ctypes.c_char_p, ctypes.c_char_p, ctypes.c_void_p]
166
+ _LIBC.vsprintf.argtypes = argtypes
167
+ _LIBC.vsprintf.restype = ctypes.c_int32
168
+ _LIBC.vsprintf(buffer, fmt, ap)
169
+
170
+ module = module.decode("utf-8")
171
+ warning_str = buffer.value.decode("utf-8")
172
+
173
+ message = f"{module}: {warning_str}"
174
+ warnings.warn(message)
175
+
176
+
177
+ # Set the function types for the warning handler.
178
+ _WFUNCTYPE = ctypes.CFUNCTYPE(
179
+ ctypes.c_void_p, # return type of warning handler, void *
180
+ ctypes.c_char_p, # module
181
+ ctypes.c_char_p, # fmt
182
+ ctypes.c_void_p, # va_list
183
+ )
184
+
185
+ _ERROR_HANDLER = _WFUNCTYPE(_handle_error)
186
+ _WARNING_HANDLER = _WFUNCTYPE(_handle_warning)
187
+
188
+
189
+ def _set_error_warning_handlers():
190
+ """Setup default python error and warning handlers."""
191
+ old_warning_handler = setWarningHandler()
192
+ old_error_handler = setErrorHandler()
193
+
194
+ return old_error_handler, old_warning_handler
195
+
196
+
197
+ def _reset_error_warning_handlers(old_error_handler, old_warning_handler):
198
+ """Restore previous error and warning handlers."""
199
+ setWarningHandler(old_warning_handler)
200
+ setErrorHandler(old_error_handler)
201
+
202
+
203
+ def close(fp):
204
+ """Corresponds to TIFFClose"""
205
+ err_handler, warn_handler = _set_error_warning_handlers()
206
+
207
+ ARGTYPES = [ctypes.c_void_p]
208
+ _LIBTIFF.TIFFClose.argtypes = ARGTYPES
209
+ _LIBTIFF.TIFFClose.restype = None
210
+ _LIBTIFF.TIFFClose(fp)
211
+
212
+ _reset_error_warning_handlers(err_handler, warn_handler)
213
+
214
+
215
+ def computeStrip(fp, row, sample):
216
+ """Corresponds to TIFFComputeStrip"""
217
+ err_handler, warn_handler = _set_error_warning_handlers()
218
+
219
+ ARGTYPES = [ctypes.c_void_p, ctypes.c_uint32, ctypes.c_uint16]
220
+ _LIBTIFF.TIFFComputeStrip.argtypes = ARGTYPES
221
+ _LIBTIFF.TIFFComputeStrip.restype = ctypes.c_uint32
222
+ stripnum = _LIBTIFF.TIFFComputeStrip(fp, row, sample)
223
+
224
+ _reset_error_warning_handlers(err_handler, warn_handler)
225
+
226
+ return stripnum
227
+
228
+
229
+ def computeTile(fp, x, y, z, sample):
230
+ """Corresponds to TIFFComputeTile"""
231
+ err_handler, warn_handler = _set_error_warning_handlers()
232
+
233
+ ARGTYPES = [
234
+ ctypes.c_void_p,
235
+ ctypes.c_uint32,
236
+ ctypes.c_uint32,
237
+ ctypes.c_uint32,
238
+ ctypes.c_uint16,
239
+ ]
240
+ _LIBTIFF.TIFFComputeTile.argtypes = ARGTYPES
241
+ _LIBTIFF.TIFFComputeTile.restype = ctypes.c_uint32
242
+ tilenum = _LIBTIFF.TIFFComputeTile(fp, x, y, z, sample)
243
+
244
+ _reset_error_warning_handlers(err_handler, warn_handler)
245
+
246
+ return tilenum
247
+
248
+
249
+ def isTiled(fp):
250
+ """Corresponds to TIFFIsTiled"""
251
+ err_handler, warn_handler = _set_error_warning_handlers()
252
+
253
+ ARGTYPES = [ctypes.c_void_p]
254
+
255
+ _LIBTIFF.TIFFIsTiled.argtypes = ARGTYPES
256
+ _LIBTIFF.TIFFIsTiled.restype = ctypes.c_int
257
+
258
+ status = _LIBTIFF.TIFFIsTiled(fp)
259
+
260
+ _reset_error_warning_handlers(err_handler, warn_handler)
261
+
262
+ return status
263
+
264
+
265
+ def numberOfStrips(fp):
266
+ """Corresponds to TIFFNumberOfStrips."""
267
+ err_handler, warn_handler = _set_error_warning_handlers()
268
+
269
+ ARGTYPES = [ctypes.c_void_p]
270
+ _LIBTIFF.TIFFNumberOfStrips.argtypes = ARGTYPES
271
+ _LIBTIFF.TIFFNumberOfStrips.restype = ctypes.c_uint32
272
+
273
+ numstrips = _LIBTIFF.TIFFNumberOfStrips(fp)
274
+
275
+ _reset_error_warning_handlers(err_handler, warn_handler)
276
+
277
+ return numstrips
278
+
279
+
280
+ def numberOfTiles(fp):
281
+ """Corresponds to TIFFNumberOfTiles."""
282
+ err_handler, warn_handler = _set_error_warning_handlers()
283
+
284
+ ARGTYPES = [ctypes.c_void_p]
285
+ _LIBTIFF.TIFFNumberOfTiles.argtypes = ARGTYPES
286
+ _LIBTIFF.TIFFNumberOfTiles.restype = ctypes.c_uint32
287
+
288
+ numtiles = _LIBTIFF.TIFFNumberOfTiles(fp)
289
+
290
+ _reset_error_warning_handlers(err_handler, warn_handler)
291
+
292
+ return numtiles
293
+
294
+
295
+ def readEncodedStrip(fp, stripnum, strip, size=-1):
296
+ """Corresponds to TIFFReadEncodedStrip"""
297
+ err_handler, warn_handler = _set_error_warning_handlers()
298
+
299
+ if size == -1:
300
+ size = strip.nbytes
301
+
302
+ ARGTYPES = [
303
+ ctypes.c_void_p,
304
+ ctypes.c_uint32,
305
+ ctypes.c_void_p,
306
+ ctypes.c_int32
307
+ ]
308
+ _LIBTIFF.TIFFReadEncodedStrip.argtypes = ARGTYPES
309
+ _LIBTIFF.TIFFReadEncodedStrip.restype = check_error
310
+ _LIBTIFF.TIFFReadEncodedStrip(
311
+ fp, stripnum, strip.ctypes.data_as(ctypes.c_void_p), size
312
+ )
313
+
314
+ _reset_error_warning_handlers(err_handler, warn_handler)
315
+
316
+ return strip
317
+
318
+
319
+ def readEncodedTile(fp, tilenum, tile, size=-1):
320
+ """Corresponds to TIFFComputeTile"""
321
+ err_handler, warn_handler = _set_error_warning_handlers()
322
+
323
+ if size == -1:
324
+ size = tile.nbytes
325
+
326
+ ARGTYPES = [
327
+ ctypes.c_void_p,
328
+ ctypes.c_uint32,
329
+ ctypes.c_void_p,
330
+ ctypes.c_int32
331
+ ]
332
+ _LIBTIFF.TIFFReadEncodedTile.argtypes = ARGTYPES
333
+ _LIBTIFF.TIFFReadEncodedTile.restype = check_error
334
+ _LIBTIFF.TIFFReadEncodedTile(
335
+ fp,
336
+ tilenum,
337
+ tile.ctypes.data_as(ctypes.c_void_p),
338
+ -1
339
+ )
340
+
341
+ _reset_error_warning_handlers(err_handler, warn_handler)
342
+
343
+ return tile
344
+
345
+
346
+ def readRGBAStrip(fp, row, strip):
347
+ """Corresponds to TIFFReadRGBAStrip"""
348
+ err_handler, warn_handler = _set_error_warning_handlers()
349
+
350
+ ARGTYPES = [ctypes.c_void_p, ctypes.c_uint32, ctypes.c_void_p]
351
+ _LIBTIFF.TIFFReadRGBAStrip.argtypes = ARGTYPES
352
+ _LIBTIFF.TIFFReadRGBAStrip.restype = check_error
353
+ _LIBTIFF.TIFFReadRGBAStrip(fp, row, strip.ctypes.data_as(ctypes.c_void_p))
354
+
355
+ _reset_error_warning_handlers(err_handler, warn_handler)
356
+
357
+ return strip
358
+
359
+
360
+ def readRGBATile(fp, x, y, tile):
361
+ """Corresponds to TIFFReadRGBATile"""
362
+ err_handler, warn_handler = _set_error_warning_handlers()
363
+
364
+ ARGTYPES = [
365
+ ctypes.c_void_p,
366
+ ctypes.c_uint32,
367
+ ctypes.c_uint32,
368
+ ctypes.c_void_p
369
+ ]
370
+ _LIBTIFF.TIFFReadRGBATile.argtypes = ARGTYPES
371
+ _LIBTIFF.TIFFReadRGBATile.restype = check_error
372
+ _LIBTIFF.TIFFReadRGBATile(fp, x, y, tile.ctypes.data_as(ctypes.c_void_p))
373
+
374
+ _reset_error_warning_handlers(err_handler, warn_handler)
375
+
376
+ return tile
377
+
378
+
379
+ def readRGBAImageOriented(
380
+ fp,
381
+ width=None,
382
+ height=None,
383
+ orientation=Orientation.TOPLEFT
384
+ ):
385
+ """Read an image as if it were RGBA.
386
+
387
+ This function corresponds to the TIFFReadRGBAImageOriented function in the
388
+ libtiff library.
389
+
390
+ Parameters
391
+ ----------
392
+ fp : ctypes void pointer
393
+ File pointer returned by libtiff.
394
+ width, height : int
395
+ Width and height of the returned image.
396
+ orientation : int
397
+ The raster origin position.
398
+
399
+ See Also
400
+ --------
401
+ Orientation
402
+ """
403
+ err_handler, warn_handler = _set_error_warning_handlers()
404
+
405
+ ARGTYPES = [
406
+ ctypes.c_void_p,
407
+ ctypes.c_uint32,
408
+ ctypes.c_uint32,
409
+ ctypes.POINTER(ctypes.c_uint32),
410
+ ctypes.c_int32,
411
+ ctypes.c_int32,
412
+ ]
413
+
414
+ _LIBTIFF.TIFFReadRGBAImageOriented.argtypes = ARGTYPES
415
+ _LIBTIFF.TIFFReadRGBAImageOriented.restype = check_error
416
+
417
+ if width is None:
418
+ width = getFieldDefaulted(fp, "ImageWidth")
419
+ if height is None:
420
+ height = getFieldDefaulted(fp, "ImageLength")
421
+
422
+ img = np.zeros((height, width, 4), dtype=np.uint8)
423
+ raster = img.ctypes.data_as(ctypes.POINTER(ctypes.c_uint32))
424
+ _LIBTIFF.TIFFReadRGBAImageOriented(
425
+ fp,
426
+ width,
427
+ height,
428
+ raster,
429
+ orientation,
430
+ 0
431
+ )
432
+
433
+ _reset_error_warning_handlers(err_handler, warn_handler)
434
+
435
+ return img
436
+
437
+
438
+ def writeEncodedStrip(fp, stripnum, stripdata, size=-1):
439
+ """Corresponds to TIFFWriteEncodedStrip."""
440
+ err_handler, warn_handler = _set_error_warning_handlers()
441
+
442
+ ARGTYPES = [
443
+ ctypes.c_void_p,
444
+ ctypes.c_uint32,
445
+ ctypes.c_void_p,
446
+ ctypes.c_uint32
447
+ ]
448
+ _LIBTIFF.TIFFWriteEncodedStrip.argtypes = ARGTYPES
449
+ _LIBTIFF.TIFFWriteEncodedStrip.restype = check_error
450
+ raster = stripdata.ctypes.data_as(ctypes.c_void_p)
451
+
452
+ if size == -1:
453
+ size = stripdata.nbytes
454
+
455
+ _LIBTIFF.TIFFWriteEncodedStrip(fp, stripnum, raster, size)
456
+
457
+ _reset_error_warning_handlers(err_handler, warn_handler)
458
+
459
+
460
+ def writeEncodedTile(fp, tilenum, tiledata, size=-1):
461
+ """Corresponds to TIFFWriteEncodedTile."""
462
+ err_handler, warn_handler = _set_error_warning_handlers()
463
+
464
+ ARGTYPES = [
465
+ ctypes.c_void_p,
466
+ ctypes.c_uint32,
467
+ ctypes.c_void_p,
468
+ ctypes.c_uint32
469
+ ]
470
+ _LIBTIFF.TIFFWriteEncodedTile.argtypes = ARGTYPES
471
+ _LIBTIFF.TIFFWriteEncodedTile.restype = check_error
472
+ raster = tiledata.ctypes.data_as(ctypes.c_void_p)
473
+
474
+ if size == -1:
475
+ size = tiledata.nbytes
476
+
477
+ _LIBTIFF.TIFFWriteEncodedTile(fp, tilenum, raster, size)
478
+
479
+ _reset_error_warning_handlers(err_handler, warn_handler)
480
+
481
+
482
+ def RGBAImageOK(fp):
483
+ """Corresponds to TIFFRGBAImageOK."""
484
+ err_handler, warn_handler = _set_error_warning_handlers()
485
+
486
+ emsg = ctypes.create_string_buffer(1024)
487
+ ARGTYPES = [ctypes.c_void_p, ctypes.c_char_p]
488
+ _LIBTIFF.TIFFRGBAImageOK.argtypes = ARGTYPES
489
+ _LIBTIFF.TIFFRGBAImageOK.restype = ctypes.c_int
490
+ ok = _LIBTIFF.TIFFRGBAImageOK(fp, emsg)
491
+
492
+ _reset_error_warning_handlers(err_handler, warn_handler)
493
+
494
+ if ok:
495
+ return True
496
+ else:
497
+ return False
498
+
499
+
500
+ def getFieldDefaulted(fp, tag):
501
+ """Corresponds to the TIFFGetFieldDefaulted library routine."""
502
+ err_handler, warn_handler = _set_error_warning_handlers()
503
+
504
+ ARGTYPES = [ctypes.c_void_p, ctypes.c_int32]
505
+
506
+ tag_num = TAGS[tag]["number"]
507
+
508
+ # Append the proper return type for the tag.
509
+ tag_type = TAGS[tag]["type"]
510
+ ARGTYPES.append(ctypes.POINTER(TAGS[tag]["type"]))
511
+ _LIBTIFF.TIFFGetFieldDefaulted.argtypes = ARGTYPES
512
+
513
+ _LIBTIFF.TIFFGetFieldDefaulted.restype = check_error
514
+
515
+ # instantiate the tag value
516
+ item = tag_type()
517
+ _LIBTIFF.TIFFGetFieldDefaulted(fp, tag_num, ctypes.byref(item))
518
+
519
+ _reset_error_warning_handlers(err_handler, warn_handler)
520
+
521
+ return item.value
522
+
523
+
524
+ def getVersion():
525
+ """Corresponds to the TIFFGetVersion library routine."""
526
+ try:
527
+ _LIBTIFF.TIFFGetVersion.restype = ctypes.c_char_p
528
+ except AttributeError:
529
+ # libtiff not installed
530
+ return "0.0.0"
531
+
532
+ v = _LIBTIFF.TIFFGetVersion().decode("utf-8")
533
+
534
+ # v would be something like
535
+ #
536
+ # LIBTIFF, Version 4.3.0
537
+ # Copyright (c) 1988-1996 Sam Leffler
538
+ # Copyright (c) 1991-1996 Silicon Graphics, Inc.
539
+ #
540
+ # All we want is the '4.3.0'
541
+ m = re.search(r"(?P<version>\d+\.\d+\.\d+)", v)
542
+ return m.group("version")
543
+
544
+
545
+ def open(filename, mode="r"):
546
+ """Corresponds to TIFFOpen
547
+
548
+ Parameters
549
+ ----------
550
+ filename : path or str
551
+ Path to TIFF
552
+ """
553
+ err_handler, warn_handler = _set_error_warning_handlers()
554
+
555
+ filename = str(filename)
556
+
557
+ ARGTYPES = [ctypes.c_char_p, ctypes.c_char_p]
558
+ _LIBTIFF.TIFFOpen.argtypes = ARGTYPES
559
+ _LIBTIFF.TIFFOpen.restype = ctypes.c_void_p
560
+ file_argument = ctypes.c_char_p(filename.encode())
561
+ mode_argument = ctypes.c_char_p(mode.encode())
562
+ fp = _LIBTIFF.TIFFOpen(file_argument, mode_argument)
563
+ check_error(fp)
564
+
565
+ _reset_error_warning_handlers(err_handler, warn_handler)
566
+
567
+ return fp
568
+
569
+
570
+ def setErrorHandler(func=_ERROR_HANDLER):
571
+ # The signature of the error handler is
572
+ # const char *module, const char *fmt, va_list ap
573
+ #
574
+ # The return type is void *
575
+ _LIBTIFF.TIFFSetErrorHandler.argtypes = [_WFUNCTYPE]
576
+ _LIBTIFF.TIFFSetErrorHandler.restype = _WFUNCTYPE
577
+ old_error_handler = _LIBTIFF.TIFFSetErrorHandler(func)
578
+ return old_error_handler
579
+
580
+
581
+ def setField(fp, tag, *value):
582
+ """Corresponds to TIFFSetField"""
583
+ err_handler, warn_handler = _set_error_warning_handlers()
584
+
585
+ ARGTYPES = [ctypes.c_void_p, ctypes.c_int32]
586
+
587
+ # Append the proper return type for the tag.
588
+ tag_num = TAGS[tag]["number"]
589
+ tag_type = TAGS[tag]["type"]
590
+
591
+ try:
592
+ for ttype in tag_type:
593
+ ARGTYPES.append(ttype)
594
+ except TypeError:
595
+ ARGTYPES.append(tag_type)
596
+
597
+ _LIBTIFF.TIFFSetField.argtypes = ARGTYPES
598
+ _LIBTIFF.TIFFSetField.restype = check_error
599
+
600
+ if len(value) == 1 and tag_type == ctypes.c_char_p:
601
+ _LIBTIFF.TIFFSetField(fp, tag_num, ctypes.c_char_p(value[0].encode()))
602
+ elif len(value) == 1:
603
+ _LIBTIFF.TIFFSetField(fp, tag_num, value[0])
604
+ else:
605
+ _LIBTIFF.TIFFSetField(fp, tag_num, *value)
606
+
607
+ _reset_error_warning_handlers(err_handler, warn_handler)
608
+
609
+
610
+ def setWarningHandler(func=_WARNING_HANDLER):
611
+ # The signature of the warning handler is
612
+ # const char *module, const char *fmt, va_list ap
613
+ #
614
+ # The return type is void *
615
+ _LIBTIFF.TIFFSetWarningHandler.argtypes = [_WFUNCTYPE]
616
+ _LIBTIFF.TIFFSetWarningHandler.restype = _WFUNCTYPE
617
+ old_warning_handler = _LIBTIFF.TIFFSetWarningHandler(func)
618
+ return old_warning_handler
619
+
620
+
621
+ def check_error(status):
622
+ """Set a generic function as the restype attribute of all TIFF
623
+ functions that return a int value. This way we do not have to check
624
+ for error status in each wrapping function and an exception will always be
625
+ appropriately raised.
626
+ """
627
+ msg = ""
628
+ while not EQ.empty():
629
+ msg = EQ.get()
630
+ raise LibTIFFError(msg)
631
+
632
+ if status == 0:
633
+ raise RuntimeError("failed")
634
+
635
+
636
+ TAGS = {
637
+ "GPSVersionID": {
638
+ "number": 0,
639
+ "type": ctypes.c_char_p,
640
+ },
641
+ "GPSLatitudeRef": {
642
+ "number": 1,
643
+ "type": ctypes.c_char_p,
644
+ },
645
+ "GPSLatitude": {
646
+ "number": 2,
647
+ "type": ctypes.c_char_p,
648
+ },
649
+ "GPSLongitudeRef": {
650
+ "number": 3,
651
+ "type": ctypes.c_char_p,
652
+ },
653
+ "GPSLongitude": {
654
+ "number": 4,
655
+ "type": ctypes.c_char_p,
656
+ },
657
+ "GPSAltitudeRef": {
658
+ "number": 5,
659
+ "type": ctypes.c_char_p,
660
+ },
661
+ "GPSAltitude": {
662
+ "number": 6,
663
+ "type": ctypes.c_char_p,
664
+ },
665
+ "GPSTimestamp": {
666
+ "number": 7,
667
+ "type": ctypes.c_char_p,
668
+ },
669
+ "GPSSatellites": {
670
+ "number": 8,
671
+ "type": ctypes.c_char_p,
672
+ },
673
+ "GPSStatus": {
674
+ "number": 9,
675
+ "type": ctypes.c_char_p,
676
+ },
677
+ "GPSMeasureMode": {
678
+ "number": 10,
679
+ "type": ctypes.c_char_p,
680
+ },
681
+ "GPSDOP": {
682
+ "number": 11,
683
+ "type": ctypes.c_char_p,
684
+ },
685
+ "GPSSpeedRef": {
686
+ "number": 12,
687
+ "type": ctypes.c_char_p,
688
+ },
689
+ "GPSSpeed": {
690
+ "number": 13,
691
+ "type": ctypes.c_char_p,
692
+ },
693
+ "GPSTrackRef": {
694
+ "number": 14,
695
+ "type": ctypes.c_char_p,
696
+ },
697
+ "GPSTrack": {
698
+ "number": 15,
699
+ "type": ctypes.c_char_p,
700
+ },
701
+ "GPSImgDirectionRef": {
702
+ "number": 16,
703
+ "type": ctypes.c_char_p,
704
+ },
705
+ "GPSImgDirection": {
706
+ "number": 17,
707
+ "type": ctypes.c_char_p,
708
+ },
709
+ "GPSMapDatum": {
710
+ "number": 18,
711
+ "type": ctypes.c_char_p,
712
+ },
713
+ "GPSDestLatitudeRef": {
714
+ "number": 19,
715
+ "type": ctypes.c_char_p,
716
+ },
717
+ "GPSDestLatitude": {
718
+ "number": 20,
719
+ "type": ctypes.c_char_p,
720
+ },
721
+ "GPSDestLongitudeRef": {
722
+ "number": 21,
723
+ "type": ctypes.c_char_p,
724
+ },
725
+ "GPSDestLongitude": {
726
+ "number": 22,
727
+ "type": ctypes.c_char_p,
728
+ },
729
+ "GPSBearingRef": {
730
+ "number": 23,
731
+ "type": ctypes.c_char_p,
732
+ },
733
+ "GPSBearing": {
734
+ "number": 24,
735
+ "type": ctypes.c_char_p,
736
+ },
737
+ "GPSDestDistanceRef": {
738
+ "number": 25,
739
+ "type": ctypes.c_char_p,
740
+ },
741
+ "GPSDestDistance": {
742
+ "number": 26,
743
+ "type": ctypes.c_int16,
744
+ },
745
+ "GPSProcessingMethod": {
746
+ "number": 27,
747
+ "type": ctypes.c_char_p,
748
+ },
749
+ "GPSAreaInformation": {
750
+ "number": 28,
751
+ "type": ctypes.c_char_p,
752
+ },
753
+ "GPSDateStamp": {
754
+ "number": 29,
755
+ "type": ctypes.c_char_p,
756
+ },
757
+ "GPSDifferential": {
758
+ "number": 30,
759
+ "type": ctypes.c_char_p,
760
+ },
761
+ "GPSHPositioningError": {
762
+ "number": 31,
763
+ "type": ctypes.c_int16,
764
+ },
765
+ "SubFileType": {
766
+ "number": 254,
767
+ "type": ctypes.c_int16,
768
+ },
769
+ "OSubFileType": {
770
+ "number": 255,
771
+ "type": ctypes.c_int16,
772
+ },
773
+ "ImageWidth": {
774
+ "number": 256,
775
+ "type": ctypes.c_int32,
776
+ },
777
+ "ImageLength": {
778
+ "number": 257,
779
+ "type": ctypes.c_int32,
780
+ },
781
+ "BitsPerSample": {
782
+ "number": 258,
783
+ "type": ctypes.c_int16,
784
+ },
785
+ "Compression": {
786
+ "number": 259,
787
+ "type": ctypes.c_int16,
788
+ },
789
+ "Photometric": {
790
+ "number": 262,
791
+ "type": ctypes.c_int16,
792
+ },
793
+ "Threshholding": {
794
+ "number": 263,
795
+ "type": ctypes.c_int16,
796
+ },
797
+ "CellWidth": {
798
+ "number": 264,
799
+ "type": ctypes.c_int16,
800
+ },
801
+ "CellLength": {
802
+ "number": 265,
803
+ "type": ctypes.c_int16,
804
+ },
805
+ "FillOrder": {
806
+ "number": 266,
807
+ "type": ctypes.c_int16,
808
+ },
809
+ "DocumentName": {
810
+ "number": 269,
811
+ "type": ctypes.c_char_p,
812
+ },
813
+ "ImageDescription": {
814
+ "number": 270,
815
+ "type": ctypes.c_char_p,
816
+ },
817
+ "Make": {
818
+ "number": 271,
819
+ "type": ctypes.c_char_p,
820
+ },
821
+ "Model": {
822
+ "number": 272,
823
+ "type": ctypes.c_char_p,
824
+ },
825
+ "StripOffsets": {
826
+ "number": 273,
827
+ "type": (ctypes.c_int32, ctypes.c_int64),
828
+ },
829
+ "Orientation": {
830
+ "number": 274,
831
+ "type": ctypes.c_int16,
832
+ },
833
+ "SamplesPerPixel": {
834
+ "number": 277,
835
+ "type": ctypes.c_int16,
836
+ },
837
+ "RowsPerStrip": {
838
+ "number": 278,
839
+ "type": ctypes.c_int16,
840
+ },
841
+ "StripByteCounts": {
842
+ "number": 279,
843
+ "type": None,
844
+ },
845
+ "MinSampleValue": {
846
+ "number": 280,
847
+ "type": ctypes.c_int16,
848
+ },
849
+ "MaxSampleValue": {
850
+ "number": 281,
851
+ "type": ctypes.c_int16,
852
+ },
853
+ "XResolution": {
854
+ "number": 282,
855
+ "type": ctypes.c_double,
856
+ },
857
+ "YResolution": {
858
+ "number": 283,
859
+ "type": ctypes.c_double,
860
+ },
861
+ "PlanarConfig": {
862
+ "number": 284,
863
+ "type": ctypes.c_int16,
864
+ },
865
+ "PageName": {
866
+ "number": 285,
867
+ "type": ctypes.c_char_p,
868
+ },
869
+ "XPosition": {
870
+ "number": 286,
871
+ "type": ctypes.c_double,
872
+ },
873
+ "YPosition": {
874
+ "number": 287,
875
+ "type": ctypes.c_double,
876
+ },
877
+ "FreeOffsets": {
878
+ "number": 288,
879
+ "type": ctypes.c_int32,
880
+ },
881
+ "FreeByteCounts": {
882
+ "number": 289,
883
+ "type": ctypes.c_int32,
884
+ },
885
+ "GrayResponseUnit": {
886
+ "number": 290,
887
+ "type": ctypes.c_int16,
888
+ },
889
+ "GrayResponseCurve": {
890
+ "number": 291,
891
+ "type": None,
892
+ },
893
+ "T4Options": {
894
+ "number": 292,
895
+ "type": None,
896
+ },
897
+ "T6Options": {
898
+ "number": 293,
899
+ "type": None,
900
+ },
901
+ "ResolutionUnit": {
902
+ "number": 296,
903
+ "type": ctypes.c_int16,
904
+ },
905
+ "PageNumber": {
906
+ "number": 297,
907
+ "type": (ctypes.c_int16, ctypes.c_uint16),
908
+ },
909
+ "TransferFunction": {
910
+ "number": 301,
911
+ "type": None,
912
+ },
913
+ "Software": {
914
+ "number": 305,
915
+ "type": ctypes.c_char_p,
916
+ },
917
+ "Datetime": {
918
+ "number": 306,
919
+ "type": ctypes.c_char_p,
920
+ },
921
+ "Artist": {
922
+ "number": 315,
923
+ "type": ctypes.c_char_p,
924
+ },
925
+ "HostComputer": {
926
+ "number": 316,
927
+ "type": ctypes.c_char_p,
928
+ },
929
+ "Predictor": {
930
+ "number": 317,
931
+ "type": ctypes.c_int16,
932
+ },
933
+ "WhitePoint": {
934
+ "number": 318,
935
+ "type": ctypes.c_double,
936
+ },
937
+ "PrimaryChromaticities": {
938
+ "number": 319,
939
+ "type": None,
940
+ },
941
+ "ColorMap": {
942
+ "number": 320,
943
+ "type": (ctypes.c_int16, ctypes.c_uint16),
944
+ },
945
+ "HalfToneHints": {
946
+ "number": 321,
947
+ "type": ctypes.c_int16,
948
+ },
949
+ "TileWidth": {
950
+ "number": 322,
951
+ "type": ctypes.c_int32,
952
+ },
953
+ "TileLength": {
954
+ "number": 323,
955
+ "type": ctypes.c_int32,
956
+ },
957
+ "TileOffsets": {
958
+ "number": 324,
959
+ "type": None,
960
+ },
961
+ "TileByteCounts": {
962
+ "number": 325,
963
+ "type": None,
964
+ },
965
+ "BadFaxLines": {
966
+ "number": 326,
967
+ "type": None,
968
+ },
969
+ "CleanFaxData": {
970
+ "number": 327,
971
+ "type": None,
972
+ },
973
+ "ConsecutiveBadFaxLines": {
974
+ "number": 328,
975
+ "type": None,
976
+ },
977
+ "SubIFDs": {
978
+ "number": 330,
979
+ "type": None,
980
+ },
981
+ "InkSet": {
982
+ "number": 332,
983
+ "type": ctypes.c_uint16,
984
+ },
985
+ "InkNames": {
986
+ "number": 333,
987
+ "type": ctypes.c_char_p,
988
+ },
989
+ "NumberOfInks": {
990
+ "number": 334,
991
+ "type": ctypes.c_uint16,
992
+ },
993
+ "DotRange": {
994
+ "number": 336,
995
+ "type": None,
996
+ },
997
+ "TargetPrinter": {
998
+ "number": 337,
999
+ "type": ctypes.c_uint16,
1000
+ },
1001
+ "ExtraSamples": {
1002
+ "number": 338,
1003
+ "type": ctypes.c_uint16,
1004
+ },
1005
+ "SampleFormat": {
1006
+ "number": 339,
1007
+ "type": ctypes.c_uint16,
1008
+ },
1009
+ "SMinSampleValue": {
1010
+ "number": 340,
1011
+ "type": ctypes.c_double,
1012
+ },
1013
+ "SMaxSampleValue": {
1014
+ "number": 341,
1015
+ "type": ctypes.c_double,
1016
+ },
1017
+ "TransferRange": {
1018
+ "number": 342,
1019
+ "type": None,
1020
+ },
1021
+ "ClipPath": {
1022
+ "number": 343,
1023
+ "type": None,
1024
+ },
1025
+ "XClipPathUnits": {
1026
+ "number": 344,
1027
+ "type": None,
1028
+ },
1029
+ "YClipPathUnits": {
1030
+ "number": 345,
1031
+ "type": None,
1032
+ },
1033
+ "Indexed": {
1034
+ "number": 346,
1035
+ "type": None,
1036
+ },
1037
+ "JPEGTables": {
1038
+ "number": 347,
1039
+ "type": None,
1040
+ },
1041
+ "OPIProxy": {
1042
+ "number": 351,
1043
+ "type": None,
1044
+ },
1045
+ "GlobalParametersIFD": {
1046
+ "number": 400,
1047
+ "type": None,
1048
+ },
1049
+ "ProfileType": {
1050
+ "number": 401,
1051
+ "type": None,
1052
+ },
1053
+ "FaxProfile": {
1054
+ "number": 402,
1055
+ "type": ctypes.c_uint8,
1056
+ },
1057
+ "CodingMethods": {
1058
+ "number": 403,
1059
+ "type": None,
1060
+ },
1061
+ "VersionYear": {
1062
+ "number": 404,
1063
+ "type": None,
1064
+ },
1065
+ "ModeNumber": {
1066
+ "number": 405,
1067
+ "type": None,
1068
+ },
1069
+ "Decode": {
1070
+ "number": 433,
1071
+ "type": None,
1072
+ },
1073
+ "DefaultImageColor": {
1074
+ "number": 434,
1075
+ "type": None,
1076
+ },
1077
+ "JPEGProc": {
1078
+ "number": 512,
1079
+ "type": None,
1080
+ },
1081
+ "JPEGInterchangeFormat": {
1082
+ "number": 513,
1083
+ "type": None,
1084
+ },
1085
+ "JPEGInterchangeFormatLength": {
1086
+ "number": 514,
1087
+ "type": None,
1088
+ },
1089
+ "JPEGRestartInterval": {
1090
+ "number": 515,
1091
+ "type": None,
1092
+ },
1093
+ "JPEGLosslessPredictors": {
1094
+ "number": 517,
1095
+ "type": None,
1096
+ },
1097
+ "JPEGPointTransforms": {
1098
+ "number": 518,
1099
+ "type": None,
1100
+ },
1101
+ "JPEGQTables": {
1102
+ "number": 519,
1103
+ "type": None,
1104
+ },
1105
+ "JPEGDCTables": {
1106
+ "number": 520,
1107
+ "type": None,
1108
+ },
1109
+ "JPEGACTables": {
1110
+ "number": 521,
1111
+ "type": None,
1112
+ },
1113
+ "YCbCrCoefficients": {
1114
+ "number": 529,
1115
+ "type": (ctypes.c_float, ctypes.c_float, ctypes.c_float),
1116
+ },
1117
+ "YCbCrSubsampling": {
1118
+ "number": 530,
1119
+ "type": (ctypes.c_uint16, ctypes.c_uint16),
1120
+ },
1121
+ "YCbCrPositioning": {
1122
+ "number": 531,
1123
+ "type": ctypes.c_uint16,
1124
+ },
1125
+ "ReferenceBlackWhite": {
1126
+ "number": 532,
1127
+ "type": (
1128
+ ctypes.c_float,
1129
+ ctypes.c_float,
1130
+ ctypes.c_float,
1131
+ ctypes.c_float,
1132
+ ctypes.c_float,
1133
+ ctypes.c_float,
1134
+ ),
1135
+ },
1136
+ "StripRowCounts": {
1137
+ "number": 559,
1138
+ "type": None,
1139
+ },
1140
+ "XMLPacket": {
1141
+ "number": 700,
1142
+ "type": ctypes.c_uint8,
1143
+ },
1144
+ "ImageID": {
1145
+ "number": 32781,
1146
+ "type": None,
1147
+ },
1148
+ "Rating": {
1149
+ "number": 18246,
1150
+ "type": ctypes.c_uint16,
1151
+ },
1152
+ "RatingPercent": {
1153
+ "number": 18249,
1154
+ "type": ctypes.c_uint16,
1155
+ },
1156
+ "Datatype": {
1157
+ "number": 32996,
1158
+ "type": None,
1159
+ },
1160
+ "WANGAnnotation": {
1161
+ "number": 32932,
1162
+ "type": None,
1163
+ },
1164
+ "ImageDepth": {
1165
+ "number": 32997,
1166
+ "type": None,
1167
+ },
1168
+ "TileDepth": {
1169
+ "number": 32998,
1170
+ "type": None,
1171
+ },
1172
+ "CFARepeatPatternDim": {
1173
+ "number": 33421,
1174
+ "type": None,
1175
+ },
1176
+ "CFAPattern": {
1177
+ "number": 33422,
1178
+ "type": None,
1179
+ },
1180
+ "BatteryLevel": {
1181
+ "number": 33423,
1182
+ "type": None,
1183
+ },
1184
+ "Copyright": {
1185
+ "number": 33432,
1186
+ "type": ctypes.c_char_p,
1187
+ },
1188
+ "ExposureTime": {
1189
+ "number": 33434,
1190
+ "type": ctypes.c_double,
1191
+ },
1192
+ "FNumber": {
1193
+ "number": 33437,
1194
+ "type": ctypes.c_double,
1195
+ },
1196
+ "MDFile": {
1197
+ "number": 33445,
1198
+ "type": None,
1199
+ },
1200
+ "MDScalePixel": {
1201
+ "number": 33446,
1202
+ "type": None,
1203
+ },
1204
+ "MDColorTable": {
1205
+ "number": 33447,
1206
+ "type": None,
1207
+ },
1208
+ "MDLabName": {
1209
+ "number": 33448,
1210
+ "type": None,
1211
+ },
1212
+ "MDSampleInfo": {
1213
+ "number": 33449,
1214
+ "type": None,
1215
+ },
1216
+ "MdPrepDate": {
1217
+ "number": 33450,
1218
+ "type": None,
1219
+ },
1220
+ "MDPrepTime": {
1221
+ "number": 33451,
1222
+ "type": None,
1223
+ },
1224
+ "MDFileUnits": {
1225
+ "number": 33452,
1226
+ "type": None,
1227
+ },
1228
+ "ModelPixelScale": {
1229
+ "number": 33550,
1230
+ "type": None,
1231
+ },
1232
+ "IPTC": {
1233
+ "number": 33723,
1234
+ "type": None,
1235
+ },
1236
+ "INGRPacketData": {
1237
+ "number": 33918,
1238
+ "type": None,
1239
+ },
1240
+ "INGRFlagRegisters": {
1241
+ "number": 33919,
1242
+ "type": None,
1243
+ },
1244
+ "IRASbTransformationMatrix": {
1245
+ "number": 33920,
1246
+ "type": None,
1247
+ },
1248
+ "ModelTiePoint": {
1249
+ "number": 33922,
1250
+ "type": None,
1251
+ },
1252
+ "ModelTransformation": {
1253
+ "number": 34264,
1254
+ "type": None,
1255
+ },
1256
+ "Photoshop": {
1257
+ "number": 34377,
1258
+ "type": None,
1259
+ },
1260
+ "ExifTag": {
1261
+ "number": 34665,
1262
+ "type": ctypes.c_int32,
1263
+ },
1264
+ "ICCProfile": {
1265
+ "number": 34675,
1266
+ "type": None,
1267
+ },
1268
+ "ImageLayer": {
1269
+ "number": 34732,
1270
+ "type": None,
1271
+ },
1272
+ "GeoKeyDirectory": {
1273
+ "number": 34735,
1274
+ "type": None,
1275
+ },
1276
+ "GeoDoubleParams": {
1277
+ "number": 34736,
1278
+ "type": None,
1279
+ },
1280
+ "GeoAsciiParams": {
1281
+ "number": 34737,
1282
+ "type": None,
1283
+ },
1284
+ "ExposureProgram": {
1285
+ "number": 34850,
1286
+ "type": ctypes.c_uint16,
1287
+ },
1288
+ "SpectralSensitivity": {
1289
+ "number": 34852,
1290
+ "type": ctypes.c_char_p,
1291
+ },
1292
+ "GPSIFD": {
1293
+ "number": 34853,
1294
+ "type": None,
1295
+ },
1296
+ "ISOSpeedRatings": {
1297
+ "number": 34855,
1298
+ "type": ctypes.c_uint16,
1299
+ },
1300
+ "OECF": {
1301
+ "number": 34856,
1302
+ "type": None,
1303
+ },
1304
+ "Interlace": {
1305
+ "number": 34857,
1306
+ "type": None,
1307
+ },
1308
+ "TimeZoneOffset": {
1309
+ "number": 34858,
1310
+ "type": None,
1311
+ },
1312
+ "SelfTimerMode": {
1313
+ "number": 34859,
1314
+ "type": None,
1315
+ },
1316
+ "SensitivityType": {
1317
+ "number": 34864,
1318
+ "type": None,
1319
+ },
1320
+ "StandardOutputSensitivity": {
1321
+ "number": 34865,
1322
+ "type": None,
1323
+ },
1324
+ "RecommendedExposureIndex": {
1325
+ "number": 34866,
1326
+ "type": None,
1327
+ },
1328
+ "ISOSpeed": {
1329
+ "number": 34867,
1330
+ "type": None,
1331
+ },
1332
+ "ISOSpeedLatitudeYYY": {
1333
+ "number": 34868,
1334
+ "type": None,
1335
+ },
1336
+ "ISOSpeedLatitudeZZZ": {
1337
+ "number": 34869,
1338
+ "type": None,
1339
+ },
1340
+ "HYLAFAXRecvParams": {
1341
+ "number": 34908,
1342
+ "type": None,
1343
+ },
1344
+ "HYLAFAXSubAddress": {
1345
+ "number": 34909,
1346
+ "type": None,
1347
+ },
1348
+ "HYLAFAXRecvTime": {
1349
+ "number": 34910,
1350
+ "type": None,
1351
+ },
1352
+ "ExifVersion": {
1353
+ "number": 36864,
1354
+ "type": ctypes.c_uint8,
1355
+ },
1356
+ "DateTimeOriginal": {
1357
+ "number": 36867,
1358
+ "type": None,
1359
+ },
1360
+ "DateTimeDigitized": {
1361
+ "number": 36868,
1362
+ "type": None,
1363
+ },
1364
+ "OffsetTime": {
1365
+ "number": 36880,
1366
+ "type": None,
1367
+ },
1368
+ "OffsetTimeOriginal": {
1369
+ "number": 36881,
1370
+ "type": None,
1371
+ },
1372
+ "OffsetTimeDigitized": {
1373
+ "number": 36882,
1374
+ "type": None,
1375
+ },
1376
+ "ComponentsConfiguration": {"number": 37121, "type": None},
1377
+ "CompressedBitsPerPixel": {
1378
+ "number": 37122,
1379
+ "type": ctypes.c_uint8,
1380
+ },
1381
+ "ShutterSpeedValue": {
1382
+ "number": 37377,
1383
+ "type": ctypes.c_double,
1384
+ },
1385
+ "ApertureValue": {
1386
+ "number": 37378,
1387
+ "type": ctypes.c_double,
1388
+ },
1389
+ "BrightnessValue": {
1390
+ "number": 37379,
1391
+ "type": ctypes.c_double,
1392
+ },
1393
+ "ExposureBiasValue": {
1394
+ "number": 37380,
1395
+ "type": ctypes.c_double,
1396
+ },
1397
+ "MaxApertureValue": {
1398
+ "number": 37381,
1399
+ "type": ctypes.c_double,
1400
+ },
1401
+ "SubjectDistance": {
1402
+ "number": 37382,
1403
+ "type": ctypes.c_double,
1404
+ },
1405
+ "MeteringMode": {
1406
+ "number": 37383,
1407
+ "type": ctypes.c_uint16,
1408
+ },
1409
+ "LightSource": {
1410
+ "number": 37384,
1411
+ "type": ctypes.c_uint16,
1412
+ },
1413
+ "Flash": {
1414
+ "number": 37385,
1415
+ "type": ctypes.c_uint16,
1416
+ },
1417
+ "FocalLength": {
1418
+ "number": 37386,
1419
+ "type": ctypes.c_double,
1420
+ },
1421
+ "Noise": {
1422
+ "number": 37389,
1423
+ "type": None,
1424
+ },
1425
+ "ImageNumber": {
1426
+ "number": 37393,
1427
+ "type": None,
1428
+ },
1429
+ "SecurityClassification": {
1430
+ "number": 37394,
1431
+ "type": None,
1432
+ },
1433
+ "ImageHistory": {
1434
+ "number": 37395,
1435
+ "type": None,
1436
+ },
1437
+ "TIFFEPStandardID": {
1438
+ "number": 37398,
1439
+ "type": None,
1440
+ },
1441
+ "MakerNote": {
1442
+ "number": 37500,
1443
+ "type": ctypes.c_char_p,
1444
+ },
1445
+ "UserComment": {
1446
+ "number": 37510,
1447
+ "type": ctypes.c_char_p,
1448
+ },
1449
+ "SubSecTime": {
1450
+ "number": 37520,
1451
+ "type": ctypes.c_char_p,
1452
+ },
1453
+ "SubSecTimeOriginal": {
1454
+ "number": 37521,
1455
+ "type": ctypes.c_char_p,
1456
+ },
1457
+ "SubSecTimeDigitized": {
1458
+ "number": 37522,
1459
+ "type": ctypes.c_char_p,
1460
+ },
1461
+ "ImageSourceData": {
1462
+ "number": 37724,
1463
+ "type": None,
1464
+ },
1465
+ "Temperature": {
1466
+ "number": 37888,
1467
+ "type": None,
1468
+ },
1469
+ "Humidity": {
1470
+ "number": 37889,
1471
+ "type": None,
1472
+ },
1473
+ "Pressure": {
1474
+ "number": 37890,
1475
+ "type": None,
1476
+ },
1477
+ "WaterDepth": {
1478
+ "number": 37891,
1479
+ "type": None,
1480
+ },
1481
+ "Acceleration": {
1482
+ "number": 37892,
1483
+ "type": None,
1484
+ },
1485
+ "CameraElevationAngle": {
1486
+ "number": 37893,
1487
+ "type": None,
1488
+ },
1489
+ "XPTitle": {
1490
+ "number": 40091,
1491
+ "type": None,
1492
+ },
1493
+ "XPComment": {
1494
+ "number": 40092,
1495
+ "type": None,
1496
+ },
1497
+ "XPAuthor": {
1498
+ "number": 40093,
1499
+ "type": None,
1500
+ },
1501
+ "XPKeywords": {
1502
+ "number": 40094,
1503
+ "type": None,
1504
+ },
1505
+ "XPSubject": {
1506
+ "number": 40095,
1507
+ "type": None,
1508
+ },
1509
+ "FlashPixVersion": {
1510
+ "number": 40960,
1511
+ "type": None,
1512
+ },
1513
+ "ColorSpace": {
1514
+ "number": 40961,
1515
+ "type": ctypes.c_uint16,
1516
+ },
1517
+ "PixelXDimension": {
1518
+ "number": 40962,
1519
+ "type": ctypes.c_uint64,
1520
+ },
1521
+ "PixelYDimension": {
1522
+ "number": 40963,
1523
+ "type": ctypes.c_uint64,
1524
+ },
1525
+ "InteroperabilityIFD": {
1526
+ "number": 40965,
1527
+ "type": None,
1528
+ },
1529
+ "FocalPlaneXResolution": {
1530
+ "number": 41486,
1531
+ "type": ctypes.c_double,
1532
+ },
1533
+ "FocalPlaneYResolution": {
1534
+ "number": 41487,
1535
+ "type": ctypes.c_double,
1536
+ },
1537
+ "FocalPlaneResolutionUnit": {
1538
+ "number": 41488,
1539
+ "type": ctypes.c_uint16,
1540
+ },
1541
+ "ExposureIndex": {
1542
+ "number": 41493,
1543
+ "type": ctypes.c_double,
1544
+ },
1545
+ "SensingMethod": {
1546
+ "number": 41495,
1547
+ "type": ctypes.c_uint16,
1548
+ },
1549
+ "SceneType": {
1550
+ "number": 41729,
1551
+ "type": ctypes.c_uint8,
1552
+ },
1553
+ "FlashEnergy": {"number": 41483, "type": None},
1554
+ "SpatialFrequencyResponse": {"number": 41484, "type": None},
1555
+ "SubjectLocation": {"number": 41492, "type": None},
1556
+ "FileSource": {"number": 41728, "type": None},
1557
+ "ExifCFAPattern": {"number": 41730, "type": None},
1558
+ "CustomRendered": {"number": 41985, "type": None},
1559
+ "ExposureMode": {
1560
+ "number": 41986,
1561
+ "type": ctypes.c_uint16,
1562
+ },
1563
+ "WhiteBalance": {
1564
+ "number": 41987,
1565
+ "type": ctypes.c_uint16,
1566
+ },
1567
+ "DigitalZoomRatio": {
1568
+ "number": 41988,
1569
+ "type": ctypes.c_double,
1570
+ },
1571
+ "FocalLengthIn35mmFilm": {
1572
+ "number": 41989,
1573
+ "type": ctypes.c_uint16,
1574
+ },
1575
+ "SceneCaptureType": {
1576
+ "number": 41990,
1577
+ "type": ctypes.c_uint16,
1578
+ },
1579
+ "GainControl": {
1580
+ "number": 41991,
1581
+ "type": ctypes.c_uint16,
1582
+ },
1583
+ "Contrast": {
1584
+ "number": 41992,
1585
+ "type": ctypes.c_uint16,
1586
+ },
1587
+ "Saturation": {
1588
+ "number": 41993,
1589
+ "type": ctypes.c_uint16,
1590
+ },
1591
+ "Sharpness": {
1592
+ "number": 41994,
1593
+ "type": ctypes.c_uint16,
1594
+ },
1595
+ "DeviceSettingDescription": {
1596
+ "number": 41995,
1597
+ "type": ctypes.c_char_p,
1598
+ },
1599
+ "SubjectDistanceRange": {
1600
+ "number": 41996,
1601
+ "type": ctypes.c_uint16,
1602
+ },
1603
+ "ImageUniqueID": {"number": 42016, "type": None},
1604
+ "CameraOwnerName": {"number": 42032, "type": None},
1605
+ "BodySerialNumber": {"number": 42033, "type": None},
1606
+ "LensSpecification": {"number": 42034, "type": None},
1607
+ "LensMake": {"number": 42035, "type": None},
1608
+ "LensModel": {"number": 42036, "type": None},
1609
+ "LensSerialNumber": {"number": 42037, "type": None},
1610
+ "CompositeImage": {"number": 42080, "type": None},
1611
+ "SourceImageNumberOfCompositeImage": {"number": 42081, "type": None},
1612
+ "SourceExposureTimeOfCompositeImage": {"number": 42082, "type": None},
1613
+ "GDAL_Metadata": {
1614
+ "number": 42112,
1615
+ "type": None,
1616
+ },
1617
+ "GDAL_NoData": {
1618
+ "number": 42113,
1619
+ "type": None,
1620
+ },
1621
+ "Gamma": {
1622
+ "number": 42240,
1623
+ "type": None,
1624
+ },
1625
+ "OCEScanJobDescription": {
1626
+ "number": 50215,
1627
+ "type": None,
1628
+ },
1629
+ "OCEApplicationSelector": {
1630
+ "number": 50216,
1631
+ "type": None,
1632
+ },
1633
+ "OCEIdentificationNumber": {
1634
+ "number": 50217,
1635
+ "type": None,
1636
+ },
1637
+ "OCEImageLogicCharacteristics": {
1638
+ "number": 50218,
1639
+ "type": None,
1640
+ },
1641
+ "PrintImageMatching": {
1642
+ "number": 50341,
1643
+ "type": None,
1644
+ },
1645
+ "DNGVersion": {
1646
+ "number": 50706,
1647
+ "type": None,
1648
+ },
1649
+ "DNGBackwardVersion": {
1650
+ "number": 50707,
1651
+ "type": None,
1652
+ },
1653
+ "UniqueCameraModel": {
1654
+ "number": 50708,
1655
+ "type": None,
1656
+ },
1657
+ "LocalizedCameraModel": {
1658
+ "number": 50709,
1659
+ "type": None,
1660
+ },
1661
+ "CFAPlaneColor": {
1662
+ "number": 50710,
1663
+ "type": None,
1664
+ },
1665
+ "CFALayout": {
1666
+ "number": 50711,
1667
+ "type": None,
1668
+ },
1669
+ "LinearizationTable": {
1670
+ "number": 50712,
1671
+ "type": None,
1672
+ },
1673
+ "BlackLevelRepeatDim": {
1674
+ "number": 50713,
1675
+ "type": None,
1676
+ },
1677
+ "BlackLevel": {
1678
+ "number": 50714,
1679
+ "type": None,
1680
+ },
1681
+ "BlackLevelDeltaH": {
1682
+ "number": 50715,
1683
+ "type": None,
1684
+ },
1685
+ "BlackLevelDeltaV": {
1686
+ "number": 50716,
1687
+ "type": None,
1688
+ },
1689
+ "WhiteLevel": {
1690
+ "number": 50717,
1691
+ "type": None,
1692
+ },
1693
+ "DefaultScale": {
1694
+ "number": 50718,
1695
+ "type": None,
1696
+ },
1697
+ "DefaultCropOrigin": {
1698
+ "number": 50719,
1699
+ "type": None,
1700
+ },
1701
+ "DefaultCropSize": {
1702
+ "number": 50720,
1703
+ "type": None,
1704
+ },
1705
+ "ColorMatrix1": {
1706
+ "number": 50721,
1707
+ "type": None,
1708
+ },
1709
+ "ColorMatrix2": {
1710
+ "number": 50722,
1711
+ "type": None,
1712
+ },
1713
+ "CameraCalibration1": {
1714
+ "number": 50723,
1715
+ "type": None,
1716
+ },
1717
+ "CameraCalibration2": {
1718
+ "number": 50724,
1719
+ "type": None,
1720
+ },
1721
+ "ReductionMatrix1": {
1722
+ "number": 50725,
1723
+ "type": None,
1724
+ },
1725
+ "ReductionMatrix2": {
1726
+ "number": 50726,
1727
+ "type": None,
1728
+ },
1729
+ "AnalogBalance": {
1730
+ "number": 50727,
1731
+ "type": None,
1732
+ },
1733
+ "AsShotNeutral": {
1734
+ "number": 50728,
1735
+ "type": None,
1736
+ },
1737
+ "AsShotWhiteXY": {
1738
+ "number": 50729,
1739
+ "type": None,
1740
+ },
1741
+ "BaselineExposure": {
1742
+ "number": 50730,
1743
+ "type": None,
1744
+ },
1745
+ "BaselineNoise": {
1746
+ "number": 50731,
1747
+ "type": None,
1748
+ },
1749
+ "BaselineSharpness": {
1750
+ "number": 50732,
1751
+ "type": None,
1752
+ },
1753
+ "BayerGreenSplit": {
1754
+ "number": 50733,
1755
+ "type": None,
1756
+ },
1757
+ "LinearResponseLimit": {
1758
+ "number": 50734,
1759
+ "type": None,
1760
+ },
1761
+ "CameraSerialNumber": {
1762
+ "number": 50735,
1763
+ "type": None,
1764
+ },
1765
+ "LensInfo": {
1766
+ "number": 50736,
1767
+ "type": None,
1768
+ },
1769
+ "ChromaBlurRadius": {
1770
+ "number": 50737,
1771
+ "type": None,
1772
+ },
1773
+ "AntiAliasStrength": {
1774
+ "number": 50738,
1775
+ "type": None,
1776
+ },
1777
+ "ShadowScale": {
1778
+ "number": 50739,
1779
+ "type": None,
1780
+ },
1781
+ "DNGPrivateData": {
1782
+ "number": 50740,
1783
+ "type": None,
1784
+ },
1785
+ "MakerNoteSafety": {
1786
+ "number": 50741,
1787
+ "type": None,
1788
+ },
1789
+ "CalibrationIllumintant1": {
1790
+ "number": 50778,
1791
+ "type": None,
1792
+ },
1793
+ "CalibrationIllumintant2": {
1794
+ "number": 50779,
1795
+ "type": None,
1796
+ },
1797
+ "BestQualityScale": {
1798
+ "number": 50780,
1799
+ "type": None,
1800
+ },
1801
+ "RawDataUniqueID": {
1802
+ "number": 50781,
1803
+ "type": None,
1804
+ },
1805
+ "AliasLayerMetadata": {
1806
+ "number": 50784,
1807
+ "type": None,
1808
+ },
1809
+ "OriginalRawFileName": {
1810
+ "number": 50827,
1811
+ "type": None,
1812
+ },
1813
+ "OriginalRawFileData": {
1814
+ "number": 50828,
1815
+ "type": None,
1816
+ },
1817
+ "ActiveArea": {
1818
+ "number": 50829,
1819
+ "type": None,
1820
+ },
1821
+ "MaskedAreas": {
1822
+ "number": 50830,
1823
+ "type": None,
1824
+ },
1825
+ "AsShotICCProfile": {
1826
+ "number": 50831,
1827
+ "type": None,
1828
+ },
1829
+ "AsShotPreProfileMatrix": {
1830
+ "number": 50832,
1831
+ "type": None,
1832
+ },
1833
+ "CurrentICCProfile": {
1834
+ "number": 50833,
1835
+ "type": None,
1836
+ },
1837
+ "CurrentPreProfileMatrix": {
1838
+ "number": 50834,
1839
+ "type": None,
1840
+ },
1841
+ "ColorimetricReference": {
1842
+ "number": 50839,
1843
+ "type": None,
1844
+ },
1845
+ "TIFF_RSID": {
1846
+ "number": 50908,
1847
+ "type": None,
1848
+ },
1849
+ "GEO_Metadata": {
1850
+ "number": 50909,
1851
+ "type": None,
1852
+ },
1853
+ "CameraCalibrationSignature": {
1854
+ "number": 50931,
1855
+ "type": None,
1856
+ },
1857
+ "ProfileCalibrationSignature": {
1858
+ "number": 50932,
1859
+ "type": None,
1860
+ },
1861
+ "AsShotProfileName": {
1862
+ "number": 50934,
1863
+ "type": None,
1864
+ },
1865
+ "NoiseReductionApplied": {
1866
+ "number": 50935,
1867
+ "type": None,
1868
+ },
1869
+ "ProfileName": {
1870
+ "number": 50936,
1871
+ "type": None,
1872
+ },
1873
+ "ProfileHueSatMapDims": {
1874
+ "number": 50937,
1875
+ "type": None,
1876
+ },
1877
+ "ProfileHueSatMapData1": {
1878
+ "number": 50938,
1879
+ "type": None,
1880
+ },
1881
+ "ProfileHueSatMapData2": {
1882
+ "number": 50939,
1883
+ "type": None,
1884
+ },
1885
+ "ProfileToneCurve": {
1886
+ "number": 50940,
1887
+ "type": None,
1888
+ },
1889
+ "ProfileEmbedPolicy": {
1890
+ "number": 50941,
1891
+ "type": None,
1892
+ },
1893
+ "ProfileCopyright": {
1894
+ "number": 50942,
1895
+ "type": None,
1896
+ },
1897
+ "ForwardMatrix1": {
1898
+ "number": 50964,
1899
+ "type": None,
1900
+ },
1901
+ "ForwardMatrix2": {
1902
+ "number": 50965,
1903
+ "type": None,
1904
+ },
1905
+ "PreviewApplicationName": {
1906
+ "number": 50966,
1907
+ "type": None,
1908
+ },
1909
+ "PreviewApplicationVersion": {
1910
+ "number": 50967,
1911
+ "type": None,
1912
+ },
1913
+ "PreviewSettingsName": {
1914
+ "number": 50968,
1915
+ "type": None,
1916
+ },
1917
+ "PreviewSettingsDigest": {
1918
+ "number": 50969,
1919
+ "type": None,
1920
+ },
1921
+ "PreviewColorSpace": {
1922
+ "number": 50970,
1923
+ "type": None,
1924
+ },
1925
+ "PreviewDateTime": {
1926
+ "number": 50971,
1927
+ "type": None,
1928
+ },
1929
+ "RawImageDigest": {
1930
+ "number": 50972,
1931
+ "type": None,
1932
+ },
1933
+ "OriginalRawFileDigest": {
1934
+ "number": 50973,
1935
+ "type": None,
1936
+ },
1937
+ "SubTileBlockSize": {
1938
+ "number": 50974,
1939
+ "type": None,
1940
+ },
1941
+ "RowInterleaveFactor": {
1942
+ "number": 50975,
1943
+ "type": None,
1944
+ },
1945
+ "ProfileLookTableDims": {
1946
+ "number": 50981,
1947
+ "type": None,
1948
+ },
1949
+ "ProfileLookTableData": {
1950
+ "number": 50982,
1951
+ "type": None,
1952
+ },
1953
+ "OpcodeList1": {
1954
+ "number": 51008,
1955
+ "type": None,
1956
+ },
1957
+ "OpcodeList2": {
1958
+ "number": 51009,
1959
+ "type": None,
1960
+ },
1961
+ "OpcodeList3": {
1962
+ "number": 51022,
1963
+ "type": None,
1964
+ },
1965
+ "NoiseProfile": {
1966
+ "number": 51041,
1967
+ "type": None,
1968
+ },
1969
+ "JPEGQuality": {
1970
+ "number": 65537,
1971
+ "type": ctypes.c_int32,
1972
+ },
1973
+ "JPEGColorMode": {
1974
+ "number": 65538,
1975
+ "type": ctypes.c_int32,
1976
+ },
1977
+ }
1978
+
1979
+ # We need the reverse mapping as well.
1980
+ TAGNUM2NAME = {value["number"]: key for key, value in TAGS.items()}
1981
+
1982
+
1983
+ def tiff_header(read_buffer):
1984
+ """Interpret the uuid raw data as a tiff header."""
1985
+ # First 8 should be (73, 73, 42, 8) or (77, 77, 42, 8)
1986
+ data = struct.unpack("BB", read_buffer[0:2])
1987
+ if data[0] == 73 and data[1] == 73:
1988
+ # little endian
1989
+ endian = "<"
1990
+ elif data[0] == 77 and data[1] == 77:
1991
+ # big endian
1992
+ endian = ">"
1993
+ else:
1994
+ msg = (
1995
+ f"The byte order indication in the TIFF header "
1996
+ f"({read_buffer[0:2]}) is invalid. It should be either "
1997
+ f"{bytes([73, 73])} or {bytes([77, 77])}."
1998
+ )
1999
+ raise RuntimeError(msg)
2000
+
2001
+ _, offset = struct.unpack(endian + "HI", read_buffer[2:8])
2002
+
2003
+ # This is the 'Exif Image' portion.
2004
+ return _Ifd(endian, read_buffer, offset).processed_ifd
2005
+
2006
+
2007
+ class BadTiffTagDatatype(RuntimeError):
2008
+ """This exception exists soley to better communicate up the stack that the
2009
+ problem exists.
2010
+ """
2011
+
2012
+ pass
2013
+
2014
+
2015
+ class _Ifd(object):
2016
+ """Corresponds to TIFF IFD data structure on file.
2017
+
2018
+ Attributes
2019
+ ----------
2020
+ read_buffer : bytes
2021
+ Raw byte stream consisting of the UUID data.
2022
+ endian : str
2023
+ Either '<' for big-endian, or '>' for little-endian.
2024
+ num_tags : int
2025
+ Number of tags in the IFD.
2026
+ raw_ifd : dictionary
2027
+ Maps tag number to "mildly-interpreted" tag value.
2028
+ processed_ifd : dictionary
2029
+ Maps tag name to "mildly-interpreted" tag value.
2030
+ """
2031
+
2032
+ def __init__(self, endian, read_buffer, offset):
2033
+ self.endian = endian
2034
+ self.read_buffer = read_buffer
2035
+ self.processed_ifd = OrderedDict()
2036
+
2037
+ (self.num_tags,) = struct.unpack(
2038
+ endian + "H",
2039
+ read_buffer[offset:offset + 2]
2040
+ )
2041
+
2042
+ fmt = self.endian + "HHII" * self.num_tags
2043
+ ifd_buffer = read_buffer[offset + 2:offset + 2 + self.num_tags * 12]
2044
+ data = struct.unpack(fmt, ifd_buffer)
2045
+ self.raw_ifd = OrderedDict()
2046
+ for j, tag in enumerate(data[0::4]):
2047
+ # The offset to the tag offset/payload is the offset to the IFD
2048
+ # plus 2 bytes for the number of tags plus 12 bytes for each
2049
+ # tag entry plus 8 bytes to the offset/payload itself.
2050
+ toffp = read_buffer[offset + 10 + j * 12:offset + 10 + j * 12 + 4]
2051
+ self.raw_ifd[tag] = self.parse_tag(
2052
+ tag, data[j * 4 + 1], data[j * 4 + 2], toffp
2053
+ )
2054
+
2055
+ self.post_process()
2056
+
2057
+ def parse_tag(self, tag, dtype, count, offset_buf):
2058
+ """Interpret an Exif image tag data payload."""
2059
+
2060
+ try:
2061
+ fmt = DATATYPE2FMT[dtype]["format"] * count
2062
+ payload_size = DATATYPE2FMT[dtype]["nbytes"] * count
2063
+ except KeyError:
2064
+ msg = f"Invalid TIFF tag datatype ({dtype})."
2065
+ raise BadTiffTagDatatype(msg)
2066
+
2067
+ if payload_size <= 4:
2068
+ # Interpret the payload from the 4 bytes in the tag entry.
2069
+ target_buffer = offset_buf[:payload_size]
2070
+ else:
2071
+ # Interpret the payload at the offset specified by the 4 bytes in
2072
+ # the tag entry.
2073
+ (offset,) = struct.unpack(self.endian + "I", offset_buf)
2074
+ target_buffer = self.read_buffer[offset:offset + payload_size]
2075
+
2076
+ if dtype == 2:
2077
+ # ASCII
2078
+ payload = target_buffer.decode("utf-8").rstrip("\x00")
2079
+
2080
+ else:
2081
+ payload = struct.unpack(self.endian + fmt, target_buffer)
2082
+ if dtype == 5 or dtype == 10:
2083
+ # Rational or Signed Rational. Construct the list of values.
2084
+ rational_payload = []
2085
+ for j in range(count):
2086
+ try:
2087
+ value = float(payload[j * 2]) / float(payload[j * 2 + 1]) # noqa : E501
2088
+ except ZeroDivisionError:
2089
+ value = np.nan
2090
+ rational_payload.append(value)
2091
+ payload = np.array(rational_payload)
2092
+ if count == 1:
2093
+ # If just a single value, then return a scalar instead of a
2094
+ # tuple.
2095
+ payload = payload[0]
2096
+ else:
2097
+ payload = np.array(
2098
+ payload, dtype=DATATYPE2FMT[dtype]["nptype"]
2099
+ )
2100
+
2101
+ return payload
2102
+
2103
+ def post_process(self):
2104
+ """Map the tag name instead of tag number to the tag value."""
2105
+ for tag, value in self.raw_ifd.items():
2106
+ try:
2107
+ tag_name = TAGNUM2NAME[tag]
2108
+ except KeyError:
2109
+ # Ok, we don't recognize this tag. Just use the numeric id.
2110
+ msg = f"Unrecognized UUID box TIFF tag ({tag})."
2111
+ warnings.warn(msg, UserWarning)
2112
+ tag_name = tag
2113
+
2114
+ if tag_name in ("ExifTag", 'GPSIFD'):
2115
+ # There's an IFD at the offset specified here.
2116
+ ifd = _Ifd(self.endian, self.read_buffer, value)
2117
+ self.processed_ifd[tag_name] = ifd.processed_ifd
2118
+ else:
2119
+ # just a regular tag, treat it as a simple value
2120
+ self.processed_ifd[tag_name] = value
2121
+
2122
+
2123
+ # maps the TIFF enumerated datatype to the corresponding structs datatype code,
2124
+ # the data width, and the corresponding numpy datatype
2125
+ DATATYPE2FMT = {
2126
+ 1: {"format": "B", "nbytes": 1, "nptype": np.ubyte},
2127
+ 2: {"format": "B", "nbytes": 1, "nptype": str},
2128
+ 3: {"format": "H", "nbytes": 2, "nptype": np.uint16},
2129
+ 4: {"format": "I", "nbytes": 4, "nptype": np.uint32},
2130
+ 5: {"format": "II", "nbytes": 8, "nptype": np.double},
2131
+ 6: {"format": "b", "nbytes": 1, "nptype": np.int8},
2132
+ 7: {"format": "B", "nbytes": 1, "nptype": np.uint8},
2133
+ 8: {"format": "h", "nbytes": 2, "nptype": np.int16},
2134
+ 9: {"format": "i", "nbytes": 4, "nptype": np.int32},
2135
+ 10: {"format": "ii", "nbytes": 8, "nptype": np.double},
2136
+ 11: {"format": "f", "nbytes": 4, "nptype": np.double},
2137
+ 12: {"format": "d", "nbytes": 8, "nptype": np.double},
2138
+ 13: {"format": "I", "nbytes": 4, "nptype": np.uint32},
2139
+ 16: {"format": "Q", "nbytes": 8, "nptype": np.uint64},
2140
+ 17: {"format": "q", "nbytes": 8, "nptype": np.int64},
2141
+ 18: {"format": "Q", "nbytes": 8, "nptype": np.uint64},
2142
+ }