Glymur 0.13.6__py3-none-any.whl → 0.13.8__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-0.13.6.dist-info → Glymur-0.13.8.dist-info}/METADATA +5 -3
- Glymur-0.13.8.dist-info/RECORD +25 -0
- {Glymur-0.13.6.dist-info → Glymur-0.13.8.dist-info}/WHEEL +1 -1
- glymur/_iccprofile.py +73 -72
- glymur/codestream.py +385 -308
- glymur/config.py +15 -14
- glymur/core.py +18 -22
- glymur/jp2box.py +736 -577
- glymur/jp2k.py +185 -149
- glymur/jp2kr.py +62 -48
- glymur/lib/openjp2.py +198 -285
- glymur/lib/tiff.py +1152 -1156
- glymur/options.py +33 -28
- glymur/tiff.py +105 -103
- glymur/version.py +1 -1
- Glymur-0.13.6.dist-info/RECORD +0 -25
- {Glymur-0.13.6.dist-info → Glymur-0.13.8.dist-info}/LICENSE.txt +0 -0
- {Glymur-0.13.6.dist-info → Glymur-0.13.8.dist-info}/entry_points.txt +0 -0
- {Glymur-0.13.6.dist-info → Glymur-0.13.8.dist-info}/top_level.txt +0 -0
glymur/tiff.py
CHANGED
|
@@ -21,7 +21,7 @@ from .lib.tiff import DATATYPE2FMT
|
|
|
21
21
|
from . import jp2box
|
|
22
22
|
|
|
23
23
|
# we need a lower case mapping from the tag name to the tag number
|
|
24
|
-
TAGNAME2NUM = {k.lower(): v[
|
|
24
|
+
TAGNAME2NUM = {k.lower(): v["number"] for k, v in libtiff.TAGS.items()}
|
|
25
25
|
|
|
26
26
|
|
|
27
27
|
# Mnemonics for the two TIFF format version numbers.
|
|
@@ -78,7 +78,7 @@ class Tiff2Jp2k(object):
|
|
|
78
78
|
tilesize: Tuple[int, int] | None = None,
|
|
79
79
|
include_icc_profile: bool = False,
|
|
80
80
|
verbosity: int = logging.CRITICAL,
|
|
81
|
-
**kwargs
|
|
81
|
+
**kwargs,
|
|
82
82
|
):
|
|
83
83
|
"""
|
|
84
84
|
Construct the object.
|
|
@@ -108,7 +108,7 @@ class Tiff2Jp2k(object):
|
|
|
108
108
|
|
|
109
109
|
self.tiff_filename = tiff_filename
|
|
110
110
|
if not self.tiff_filename.exists():
|
|
111
|
-
raise FileNotFoundError(f
|
|
111
|
+
raise FileNotFoundError(f"{tiff_filename} does not exist")
|
|
112
112
|
|
|
113
113
|
self.jp2_filename = jp2_filename
|
|
114
114
|
self.tilesize = tilesize
|
|
@@ -135,7 +135,7 @@ class Tiff2Jp2k(object):
|
|
|
135
135
|
self.setup_logging(verbosity)
|
|
136
136
|
|
|
137
137
|
if num_threads > 1:
|
|
138
|
-
set_option(
|
|
138
|
+
set_option("lib.num_threads", num_threads)
|
|
139
139
|
|
|
140
140
|
def _process_exclude_tags(self, exclude_tags):
|
|
141
141
|
"""The list of tags to exclude may be mixed type (str or integer).
|
|
@@ -189,7 +189,7 @@ class Tiff2Jp2k(object):
|
|
|
189
189
|
return lst
|
|
190
190
|
|
|
191
191
|
def setup_logging(self, verbosity):
|
|
192
|
-
self.logger = logging.getLogger(
|
|
192
|
+
self.logger = logging.getLogger("tiff2jp2")
|
|
193
193
|
self.logger.setLevel(verbosity)
|
|
194
194
|
ch = logging.StreamHandler()
|
|
195
195
|
ch.setLevel(verbosity)
|
|
@@ -226,7 +226,7 @@ class Tiff2Jp2k(object):
|
|
|
226
226
|
if photo != libtiff.Photometric.PALETTE:
|
|
227
227
|
return
|
|
228
228
|
|
|
229
|
-
jp2h = [box for box in self.jp2.box if box.box_id ==
|
|
229
|
+
jp2h = [box for box in self.jp2.box if box.box_id == "jp2h"][0]
|
|
230
230
|
|
|
231
231
|
bps = (8, 8, 8)
|
|
232
232
|
pclr = jp2box.PaletteBox(
|
|
@@ -246,10 +246,10 @@ class Tiff2Jp2k(object):
|
|
|
246
246
|
|
|
247
247
|
# fix the colr box. the colorspace needs to be changed from greyscale
|
|
248
248
|
# to rgb
|
|
249
|
-
colr = [box for box in jp2h.box if box.box_id ==
|
|
249
|
+
colr = [box for box in jp2h.box if box.box_id == "colr"][0]
|
|
250
250
|
colr.colorspace = SRGB
|
|
251
251
|
|
|
252
|
-
temp_filename = str(self.jp2_filename) +
|
|
252
|
+
temp_filename = str(self.jp2_filename) + ".tmp"
|
|
253
253
|
self.jp2.wrap(temp_filename, boxes=self.jp2.box)
|
|
254
254
|
shutil.move(temp_filename, self.jp2_filename)
|
|
255
255
|
self.jp2.parse()
|
|
@@ -263,7 +263,7 @@ class Tiff2Jp2k(object):
|
|
|
263
263
|
return
|
|
264
264
|
|
|
265
265
|
self.logger.info(
|
|
266
|
-
|
|
266
|
+
"Consuming an ICC profile into JP2 color specification box."
|
|
267
267
|
)
|
|
268
268
|
|
|
269
269
|
colr = jp2box.ColourSpecificationBox(
|
|
@@ -279,9 +279,9 @@ class Tiff2Jp2k(object):
|
|
|
279
279
|
boxes[2].box = [boxes[2].box[0], colr]
|
|
280
280
|
|
|
281
281
|
# re-wrap the codestream, involves a file copy
|
|
282
|
-
tmp_filename = str(self.jp2_filename) +
|
|
282
|
+
tmp_filename = str(self.jp2_filename) + ".tmp"
|
|
283
283
|
|
|
284
|
-
with open(tmp_filename, mode=
|
|
284
|
+
with open(tmp_filename, mode="wb") as tfile:
|
|
285
285
|
jp2.wrap(tfile.name, boxes=boxes)
|
|
286
286
|
|
|
287
287
|
shutil.move(tmp_filename, self.jp2_filename)
|
|
@@ -305,7 +305,7 @@ class Tiff2Jp2k(object):
|
|
|
305
305
|
|
|
306
306
|
# write this 32-bit header into the UUID, no matter if we had bigtiff
|
|
307
307
|
# or regular tiff or big endian
|
|
308
|
-
data = struct.pack(
|
|
308
|
+
data = struct.pack("<BBHI", 73, 73, 42, 8)
|
|
309
309
|
b.write(data)
|
|
310
310
|
|
|
311
311
|
self._write_ifd(b, self.tags)
|
|
@@ -313,19 +313,19 @@ class Tiff2Jp2k(object):
|
|
|
313
313
|
# create the Exif UUID
|
|
314
314
|
if self.found_geotiff_tags:
|
|
315
315
|
# geotiff UUID
|
|
316
|
-
the_uuid = UUID(
|
|
316
|
+
the_uuid = UUID("b14bf8bd-083d-4b43-a5ae-8cd7d5a6ce03")
|
|
317
317
|
payload = b.getvalue()
|
|
318
318
|
else:
|
|
319
319
|
# Make it an exif UUID.
|
|
320
|
-
the_uuid = UUID(bytes=b
|
|
321
|
-
payload = b
|
|
320
|
+
the_uuid = UUID(bytes=b"JpgTiffExif->JP2")
|
|
321
|
+
payload = b"EXIF\0\0" + b.getvalue()
|
|
322
322
|
|
|
323
323
|
# the length of the box is the length of the payload plus 8 bytes
|
|
324
324
|
# to store the length of the box and the box ID
|
|
325
325
|
box_length = len(payload) + 8
|
|
326
326
|
|
|
327
327
|
uuid_box = jp2box.UUIDBox(the_uuid, payload, box_length)
|
|
328
|
-
with open(self.jp2_filename, mode=
|
|
328
|
+
with open(self.jp2_filename, mode="ab") as f:
|
|
329
329
|
uuid_box.write(f)
|
|
330
330
|
|
|
331
331
|
self.jp2.finalize(force_parse=True)
|
|
@@ -342,11 +342,11 @@ class Tiff2Jp2k(object):
|
|
|
342
342
|
return
|
|
343
343
|
|
|
344
344
|
# create the XMP UUID
|
|
345
|
-
the_uuid = jp2box.UUID(
|
|
345
|
+
the_uuid = jp2box.UUID("be7acfcb-97a9-42e8-9c71-999491e3afac")
|
|
346
346
|
payload = bytes(self.xmp_data)
|
|
347
347
|
box_length = len(payload) + 8
|
|
348
348
|
uuid_box = jp2box.UUIDBox(the_uuid, payload, box_length)
|
|
349
|
-
with open(self.jp2_filename, mode=
|
|
349
|
+
with open(self.jp2_filename, mode="ab") as f:
|
|
350
350
|
uuid_box.write(f)
|
|
351
351
|
|
|
352
352
|
def get_main_ifd(self):
|
|
@@ -355,7 +355,7 @@ class Tiff2Jp2k(object):
|
|
|
355
355
|
can differ.
|
|
356
356
|
"""
|
|
357
357
|
|
|
358
|
-
with open(self.tiff_filename,
|
|
358
|
+
with open(self.tiff_filename, "rb") as tfp:
|
|
359
359
|
|
|
360
360
|
self.read_tiff_header(tfp)
|
|
361
361
|
|
|
@@ -364,7 +364,7 @@ class Tiff2Jp2k(object):
|
|
|
364
364
|
if 320 in self.tags:
|
|
365
365
|
|
|
366
366
|
# the TIFF must have PALETTE photometric interpretation
|
|
367
|
-
data = np.array(self.tags[320][
|
|
367
|
+
data = np.array(self.tags[320]["payload"])
|
|
368
368
|
self._colormap = data.reshape(len(data) // 3, 3)
|
|
369
369
|
self._colormap = self._colormap / 65535
|
|
370
370
|
self._colormap = (self._colormap * 255).astype(np.uint8)
|
|
@@ -372,22 +372,22 @@ class Tiff2Jp2k(object):
|
|
|
372
372
|
if 700 in self.tags:
|
|
373
373
|
|
|
374
374
|
# XMLPacket
|
|
375
|
-
self.xmp_data = self.tags[700][
|
|
375
|
+
self.xmp_data = self.tags[700]["payload"]
|
|
376
376
|
|
|
377
377
|
else:
|
|
378
378
|
self.xmp_data = None
|
|
379
379
|
|
|
380
380
|
if 34665 in self.tags:
|
|
381
381
|
# we have an EXIF IFD
|
|
382
|
-
offset = self.tags[34665][
|
|
382
|
+
offset = self.tags[34665]["payload"][0]
|
|
383
383
|
tfp.seek(offset)
|
|
384
384
|
exif_ifd = self.read_ifd(tfp)
|
|
385
385
|
|
|
386
|
-
self.tags[34665][
|
|
386
|
+
self.tags[34665]["payload"] = exif_ifd
|
|
387
387
|
|
|
388
388
|
if 34675 in self.tags:
|
|
389
389
|
# ICC profile
|
|
390
|
-
self.icc_profile = bytes(self.tags[34675][
|
|
390
|
+
self.icc_profile = bytes(self.tags[34675]["payload"])
|
|
391
391
|
|
|
392
392
|
else:
|
|
393
393
|
self.icc_profile = None
|
|
@@ -412,10 +412,10 @@ class Tiff2Jp2k(object):
|
|
|
412
412
|
# how many tags?
|
|
413
413
|
if self.version == _BIGTIFF:
|
|
414
414
|
buffer = tfp.read(8)
|
|
415
|
-
num_tags, = struct.unpack(self.endian +
|
|
415
|
+
(num_tags,) = struct.unpack(self.endian + "Q", buffer)
|
|
416
416
|
else:
|
|
417
417
|
buffer = tfp.read(2)
|
|
418
|
-
num_tags, = struct.unpack(self.endian +
|
|
418
|
+
(num_tags,) = struct.unpack(self.endian + "H", buffer)
|
|
419
419
|
|
|
420
420
|
# Ok, so now we have the IFD main body, but following that we have
|
|
421
421
|
# the tag payloads that cannot fit into 4 bytes.
|
|
@@ -425,11 +425,11 @@ class Tiff2Jp2k(object):
|
|
|
425
425
|
buffer = tfp.read(num_tags * tag_length)
|
|
426
426
|
|
|
427
427
|
if self.version == _BIGTIFF:
|
|
428
|
-
tag_format_str = self.endian +
|
|
428
|
+
tag_format_str = self.endian + "HHQQ"
|
|
429
429
|
tag_payload_offset = 12
|
|
430
430
|
max_tag_payload_length = 8
|
|
431
431
|
else:
|
|
432
|
-
tag_format_str = self.endian +
|
|
432
|
+
tag_format_str = self.endian + "HHII"
|
|
433
433
|
tag_payload_offset = 8
|
|
434
434
|
max_tag_payload_length = 4
|
|
435
435
|
|
|
@@ -437,16 +437,18 @@ class Tiff2Jp2k(object):
|
|
|
437
437
|
|
|
438
438
|
for idx in range(num_tags):
|
|
439
439
|
|
|
440
|
-
self.logger.debug(f
|
|
440
|
+
self.logger.debug(f"tag #: {idx}")
|
|
441
441
|
|
|
442
442
|
tag_data = buffer[idx * tag_length:(idx + 1) * tag_length]
|
|
443
443
|
|
|
444
|
-
tag, dtype, nvalues, offset = struct.unpack(
|
|
444
|
+
tag, dtype, nvalues, offset = struct.unpack(
|
|
445
|
+
tag_format_str, tag_data
|
|
446
|
+
) # noqa : E501
|
|
445
447
|
|
|
446
448
|
if tag == 34735:
|
|
447
449
|
self.found_geotiff_tags = True
|
|
448
450
|
|
|
449
|
-
payload_length = DATATYPE2FMT[dtype][
|
|
451
|
+
payload_length = DATATYPE2FMT[dtype]["nbytes"] * nvalues
|
|
450
452
|
|
|
451
453
|
if payload_length > max_tag_payload_length:
|
|
452
454
|
# the payload does not fit into the tag entry, so use the
|
|
@@ -457,9 +459,10 @@ class Tiff2Jp2k(object):
|
|
|
457
459
|
tfp.seek(current_position)
|
|
458
460
|
|
|
459
461
|
# read the payload from the TIFF
|
|
460
|
-
payload_format = DATATYPE2FMT[dtype][
|
|
462
|
+
payload_format = DATATYPE2FMT[dtype]["format"] * nvalues
|
|
461
463
|
payload = struct.unpack(
|
|
462
|
-
self.endian + payload_format,
|
|
464
|
+
self.endian + payload_format,
|
|
465
|
+
payload_buffer
|
|
463
466
|
)
|
|
464
467
|
|
|
465
468
|
else:
|
|
@@ -467,10 +470,9 @@ class Tiff2Jp2k(object):
|
|
|
467
470
|
payload_buffer = tag_data[tag_payload_offset:]
|
|
468
471
|
|
|
469
472
|
# read ALL of the payload buffer
|
|
470
|
-
fmt = DATATYPE2FMT[dtype][
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
)
|
|
473
|
+
fmt = DATATYPE2FMT[dtype]["format"]
|
|
474
|
+
nelts = max_tag_payload_length / DATATYPE2FMT[dtype]["nbytes"]
|
|
475
|
+
num_items = int(nelts)
|
|
474
476
|
payload_format = self.endian + fmt * num_items
|
|
475
477
|
payload = struct.unpack(payload_format, payload_buffer)
|
|
476
478
|
|
|
@@ -483,15 +485,11 @@ class Tiff2Jp2k(object):
|
|
|
483
485
|
# unsigned rational datatypes effectively have twice
|
|
484
486
|
# the number of values so we need to account for that.
|
|
485
487
|
if dtype in [5, 10]:
|
|
486
|
-
payload = payload[:2 * nvalues]
|
|
488
|
+
payload = payload[: 2 * nvalues]
|
|
487
489
|
else:
|
|
488
490
|
payload = payload[:nvalues]
|
|
489
491
|
|
|
490
|
-
tags[tag] = {
|
|
491
|
-
'dtype': dtype,
|
|
492
|
-
'nvalues': nvalues,
|
|
493
|
-
'payload': payload
|
|
494
|
-
}
|
|
492
|
+
tags[tag] = {"dtype": dtype, "nvalues": nvalues, "payload": payload}
|
|
495
493
|
|
|
496
494
|
return tags
|
|
497
495
|
|
|
@@ -511,7 +509,7 @@ class Tiff2Jp2k(object):
|
|
|
511
509
|
tags.pop(tag)
|
|
512
510
|
|
|
513
511
|
num_tags = len(tags)
|
|
514
|
-
write_buffer = struct.pack(
|
|
512
|
+
write_buffer = struct.pack("<H", num_tags)
|
|
515
513
|
b.write(write_buffer)
|
|
516
514
|
|
|
517
515
|
# Ok, so now we have the IFD main body, but following that we have
|
|
@@ -523,28 +521,26 @@ class Tiff2Jp2k(object):
|
|
|
523
521
|
for idx, tag in enumerate(tags):
|
|
524
522
|
|
|
525
523
|
tag_offset = ifd_start_loc + idx * little_tiff_tag_length
|
|
526
|
-
self.logger.debug(f
|
|
527
|
-
self.logger.debug(f
|
|
524
|
+
self.logger.debug(f"tag #: {tag}, writing to {tag_offset}")
|
|
525
|
+
self.logger.debug(f"tag #: {tag}, after IFD {after_ifd_position}")
|
|
528
526
|
|
|
529
527
|
b.seek(tag_offset)
|
|
530
528
|
|
|
531
|
-
dtype = tags[tag][
|
|
532
|
-
nvalues = tags[tag][
|
|
533
|
-
payload = tags[tag][
|
|
529
|
+
dtype = tags[tag]["dtype"]
|
|
530
|
+
nvalues = tags[tag]["nvalues"]
|
|
531
|
+
payload = tags[tag]["payload"]
|
|
534
532
|
|
|
535
|
-
payload_length = DATATYPE2FMT[dtype][
|
|
533
|
+
payload_length = DATATYPE2FMT[dtype]["nbytes"] * nvalues
|
|
536
534
|
|
|
537
535
|
if payload_length > max_tag_payload_length:
|
|
538
536
|
# the payload does not fit into the tag entry
|
|
539
537
|
|
|
540
538
|
# read the payload from the TIFF
|
|
541
|
-
payload_format = DATATYPE2FMT[dtype][
|
|
539
|
+
payload_format = DATATYPE2FMT[dtype]["format"] * nvalues
|
|
542
540
|
|
|
543
541
|
# write the tag entry to the UUID
|
|
544
542
|
new_offset = after_ifd_position
|
|
545
|
-
buffer = struct.pack(
|
|
546
|
-
'<HHII', tag, dtype, nvalues, new_offset
|
|
547
|
-
)
|
|
543
|
+
buffer = struct.pack("<HHII", tag, dtype, nvalues, new_offset)
|
|
548
544
|
b.write(buffer)
|
|
549
545
|
|
|
550
546
|
# now write the payload at the outlying position and then come
|
|
@@ -552,7 +548,7 @@ class Tiff2Jp2k(object):
|
|
|
552
548
|
cpos = b.tell()
|
|
553
549
|
b.seek(new_offset)
|
|
554
550
|
|
|
555
|
-
format =
|
|
551
|
+
format = "<" + DATATYPE2FMT[dtype]["format"] * nvalues
|
|
556
552
|
buffer = struct.pack(format, *payload)
|
|
557
553
|
b.write(buffer)
|
|
558
554
|
|
|
@@ -564,26 +560,26 @@ class Tiff2Jp2k(object):
|
|
|
564
560
|
|
|
565
561
|
# the payload DOES fit into the TIFF tag entry
|
|
566
562
|
# write the tag metadata
|
|
567
|
-
buffer = struct.pack(
|
|
563
|
+
buffer = struct.pack("<HHI", tag, dtype, nvalues)
|
|
568
564
|
b.write(buffer)
|
|
569
565
|
|
|
570
|
-
payload_format = DATATYPE2FMT[dtype][
|
|
566
|
+
payload_format = DATATYPE2FMT[dtype]["format"] * nvalues
|
|
571
567
|
|
|
572
568
|
# we may need to alter the output format
|
|
573
|
-
if payload_format in [
|
|
569
|
+
if payload_format in ["H", "B", "I"]:
|
|
574
570
|
# just write it as an integer
|
|
575
|
-
payload_format =
|
|
571
|
+
payload_format = "I"
|
|
576
572
|
|
|
577
573
|
if tag == 34665:
|
|
578
574
|
# special case for an EXIF IFD
|
|
579
|
-
buffer = struct.pack(
|
|
575
|
+
buffer = struct.pack("<I", after_ifd_position)
|
|
580
576
|
b.write(buffer)
|
|
581
577
|
b.seek(after_ifd_position)
|
|
582
578
|
after_ifd_position = self._write_ifd(b, payload)
|
|
583
579
|
|
|
584
580
|
else:
|
|
585
581
|
# write a normal tag
|
|
586
|
-
buffer = struct.pack(
|
|
582
|
+
buffer = struct.pack("<" + payload_format, *payload)
|
|
587
583
|
b.write(buffer)
|
|
588
584
|
|
|
589
585
|
return after_ifd_position
|
|
@@ -592,15 +588,15 @@ class Tiff2Jp2k(object):
|
|
|
592
588
|
"""Get the endian-ness of the TIFF, seek to the main IFD"""
|
|
593
589
|
|
|
594
590
|
buffer = tfp.read(4)
|
|
595
|
-
data = struct.unpack(
|
|
591
|
+
data = struct.unpack("BB", buffer[:2])
|
|
596
592
|
|
|
597
593
|
# big endian or little endian?
|
|
598
594
|
if data[0] == 73 and data[1] == 73:
|
|
599
595
|
# little endian
|
|
600
|
-
self.endian =
|
|
596
|
+
self.endian = "<"
|
|
601
597
|
elif data[0] == 77 and data[1] == 77:
|
|
602
598
|
# big endian
|
|
603
|
-
self.endian =
|
|
599
|
+
self.endian = ">"
|
|
604
600
|
# no other option is possible, libtiff.open would have errored out
|
|
605
601
|
# else:
|
|
606
602
|
# msg = (
|
|
@@ -611,15 +607,15 @@ class Tiff2Jp2k(object):
|
|
|
611
607
|
# raise RuntimeError(msg)
|
|
612
608
|
|
|
613
609
|
# version number and offset to the first IFD
|
|
614
|
-
version, = struct.unpack(self.endian +
|
|
610
|
+
(version,) = struct.unpack(self.endian + "H", buffer[2:4])
|
|
615
611
|
self.version = _TIFF if version == 42 else _BIGTIFF
|
|
616
612
|
|
|
617
613
|
if self.version == _BIGTIFF:
|
|
618
614
|
buffer = tfp.read(12)
|
|
619
|
-
_, _, offset = struct.unpack(self.endian +
|
|
615
|
+
_, _, offset = struct.unpack(self.endian + "HHQ", buffer)
|
|
620
616
|
else:
|
|
621
617
|
buffer = tfp.read(4)
|
|
622
|
-
offset, = struct.unpack(self.endian +
|
|
618
|
+
(offset,) = struct.unpack(self.endian + "I", buffer)
|
|
623
619
|
tfp.seek(offset)
|
|
624
620
|
|
|
625
621
|
def get_tag_value(self, tagnum):
|
|
@@ -640,11 +636,10 @@ class Tiff2Jp2k(object):
|
|
|
640
636
|
return 1
|
|
641
637
|
|
|
642
638
|
# The tag value is always stored as a tuple with at least one member.
|
|
643
|
-
return self.tags[tagnum][
|
|
639
|
+
return self.tags[tagnum]["payload"][0]
|
|
644
640
|
|
|
645
641
|
def copy_image(self):
|
|
646
|
-
"""Transfer the image data from the TIFF to the JPEG 2000 file.
|
|
647
|
-
"""
|
|
642
|
+
"""Transfer the image data from the TIFF to the JPEG 2000 file."""
|
|
648
643
|
|
|
649
644
|
if libtiff.isTiled(self.tiff_fp):
|
|
650
645
|
isTiled = True
|
|
@@ -695,7 +690,12 @@ class Tiff2Jp2k(object):
|
|
|
695
690
|
self.th = self.get_tag_value(323)
|
|
696
691
|
else:
|
|
697
692
|
self.tw = self.imagewidth
|
|
698
|
-
|
|
693
|
+
try:
|
|
694
|
+
self.rps = self.get_tag_value(278)
|
|
695
|
+
except KeyError:
|
|
696
|
+
# stripped but no RowsPerStrip tag? default to the image
|
|
697
|
+
# height
|
|
698
|
+
self.rps = self.imageheight
|
|
699
699
|
|
|
700
700
|
if self.spp == 1:
|
|
701
701
|
shape = (self.imageheight, self.imagewidth)
|
|
@@ -759,7 +759,7 @@ class Tiff2Jp2k(object):
|
|
|
759
759
|
)
|
|
760
760
|
|
|
761
761
|
# must reorder image planes on big-endian
|
|
762
|
-
if sys.byteorder ==
|
|
762
|
+
if sys.byteorder == "big":
|
|
763
763
|
image = np.flip(image, axis=2)
|
|
764
764
|
|
|
765
765
|
# potentially get rid of the alpha plane
|
|
@@ -777,7 +777,9 @@ class Tiff2Jp2k(object):
|
|
|
777
777
|
# This might be a bit bigger than the actual image because of a
|
|
778
778
|
# possibly partial last strip.
|
|
779
779
|
stripped_shape = (
|
|
780
|
-
num_tiff_strip_rows * self.rps,
|
|
780
|
+
num_tiff_strip_rows * self.rps,
|
|
781
|
+
self.imagewidth,
|
|
782
|
+
self.spp
|
|
781
783
|
)
|
|
782
784
|
image = np.zeros(stripped_shape, dtype=self.dtype)
|
|
783
785
|
|
|
@@ -793,7 +795,7 @@ class Tiff2Jp2k(object):
|
|
|
793
795
|
|
|
794
796
|
if self.imageheight != stripped_shape[0]:
|
|
795
797
|
# cut the image down due to a partial last strip
|
|
796
|
-
image = image[:self.imageheight, :, :]
|
|
798
|
+
image = image[: self.imageheight, :, :]
|
|
797
799
|
|
|
798
800
|
self.jp2[:] = image
|
|
799
801
|
|
|
@@ -810,7 +812,7 @@ class Tiff2Jp2k(object):
|
|
|
810
812
|
tiled_shape = (
|
|
811
813
|
num_tiff_tile_rows * self.th,
|
|
812
814
|
num_tiff_tile_cols * self.tw,
|
|
813
|
-
self.spp
|
|
815
|
+
self.spp,
|
|
814
816
|
)
|
|
815
817
|
|
|
816
818
|
image = np.zeros(tiled_shape, dtype=self.dtype)
|
|
@@ -830,7 +832,7 @@ class Tiff2Jp2k(object):
|
|
|
830
832
|
image[rows, cols, :] = tiff_tile
|
|
831
833
|
|
|
832
834
|
if final_shape != tiled_shape:
|
|
833
|
-
image = image[:final_shape[0], :final_shape[1], :]
|
|
835
|
+
image = image[: final_shape[0], : final_shape[1], :]
|
|
834
836
|
|
|
835
837
|
self.jp2[:] = image
|
|
836
838
|
|
|
@@ -841,7 +843,7 @@ class Tiff2Jp2k(object):
|
|
|
841
843
|
for jp2k_tilenum, tilewriter in enumerate(self.jp2.get_tilewriters()):
|
|
842
844
|
tiff_tiles = self._get_covering_tiles(jp2k_tilenum)
|
|
843
845
|
jp2k_tile = self._cover_tile(jp2k_tilenum, tiff_tiles)
|
|
844
|
-
self.logger.info(f
|
|
846
|
+
self.logger.info(f"Writing tile {jp2k_tilenum}")
|
|
845
847
|
tilewriter[:] = jp2k_tile
|
|
846
848
|
|
|
847
849
|
def _cover_tile(self, jp2k_tile_num, tiff_tile_nums):
|
|
@@ -859,8 +861,12 @@ class Tiff2Jp2k(object):
|
|
|
859
861
|
|
|
860
862
|
# Does the JP2K have partial tiles on the far right and bottom of the
|
|
861
863
|
# image.
|
|
862
|
-
partial_jp2_tile_rows = (self.imageheight / jth) != (
|
|
863
|
-
|
|
864
|
+
partial_jp2_tile_rows = (self.imageheight / jth) != (
|
|
865
|
+
self.imageheight // jth
|
|
866
|
+
) # noqa : E501
|
|
867
|
+
partial_jp2_tile_cols = (self.imagewidth / jtw) != (
|
|
868
|
+
self.imagewidth // jtw
|
|
869
|
+
) # noqa : E501
|
|
864
870
|
|
|
865
871
|
num_jp2k_tile_rows = int(np.ceil(self.imageheight / jth))
|
|
866
872
|
num_jp2k_tile_cols = int(np.ceil(self.imagewidth / jtw))
|
|
@@ -896,7 +902,7 @@ class Tiff2Jp2k(object):
|
|
|
896
902
|
libtiff.readRGBATile(self.tiff_fp, x, y, rgba_tile)
|
|
897
903
|
|
|
898
904
|
# The RGBA interface requires some reordering.
|
|
899
|
-
if sys.byteorder ==
|
|
905
|
+
if sys.byteorder == "little":
|
|
900
906
|
# image is upside down
|
|
901
907
|
dims = [0]
|
|
902
908
|
else:
|
|
@@ -911,7 +917,8 @@ class Tiff2Jp2k(object):
|
|
|
911
917
|
else:
|
|
912
918
|
|
|
913
919
|
tiff_tile = np.zeros(
|
|
914
|
-
(self.th, self.tw, self.spp),
|
|
920
|
+
(self.th, self.tw, self.spp),
|
|
921
|
+
dtype=self.dtype
|
|
915
922
|
)
|
|
916
923
|
libtiff.readEncodedTile(self.tiff_fp, ttile_num, tiff_tile)
|
|
917
924
|
|
|
@@ -936,17 +943,11 @@ class Tiff2Jp2k(object):
|
|
|
936
943
|
jp2k_tile[jrows, jcols, :] = tiff_tile[trows, tcols, :]
|
|
937
944
|
|
|
938
945
|
# last tile column? last tile row? If so, we may have a partial tile.
|
|
939
|
-
if
|
|
940
|
-
partial_jp2_tile_cols
|
|
941
|
-
and jp2k_tile_col == num_jp2k_tile_cols - 1
|
|
942
|
-
):
|
|
946
|
+
if partial_jp2_tile_cols and jp2k_tile_col == num_jp2k_tile_cols - 1:
|
|
943
947
|
last_j2k_cols = slice(0, self.imagewidth - jp2k_ulx)
|
|
944
948
|
jp2k_tile = jp2k_tile[:, last_j2k_cols, :].copy()
|
|
945
949
|
|
|
946
|
-
if
|
|
947
|
-
partial_jp2_tile_rows
|
|
948
|
-
and jp2k_tile_row == num_jp2k_tile_rows - 1
|
|
949
|
-
):
|
|
950
|
+
if partial_jp2_tile_rows and jp2k_tile_row == num_jp2k_tile_rows - 1:
|
|
950
951
|
last_j2k_rows = slice(0, self.imageheight - jp2k_uly)
|
|
951
952
|
jp2k_tile = jp2k_tile[last_j2k_rows, :, :].copy()
|
|
952
953
|
|
|
@@ -979,8 +980,6 @@ class Tiff2Jp2k(object):
|
|
|
979
980
|
# lower left corner
|
|
980
981
|
llx = ulx
|
|
981
982
|
lly = min(uly + jth - 1, self.imageheight - 1)
|
|
982
|
-
ll_tiff_tilenum = libtiff.computeTile(self.tiff_fp, llx, lly, 0, 0)
|
|
983
|
-
lower_tiff_tile_row = int(np.ceil(ll_tiff_tilenum // num_tiff_tile_cols)) # noqa : E501
|
|
984
983
|
|
|
985
984
|
# lower right corner
|
|
986
985
|
lrx = min(llx + jtw - 1, self.imagewidth - 1)
|
|
@@ -1014,8 +1013,8 @@ class Tiff2Jp2k(object):
|
|
|
1014
1013
|
|
|
1015
1014
|
jth, jtw = self.tilesize
|
|
1016
1015
|
|
|
1017
|
-
self.logger.debug(f
|
|
1018
|
-
self.logger.debug(f
|
|
1016
|
+
self.logger.debug(f"image: {self.imageheight} x {self.imagewidth}")
|
|
1017
|
+
self.logger.debug(f"jptile: {jth} x {jtw}")
|
|
1019
1018
|
num_strips = libtiff.numberOfStrips(self.tiff_fp)
|
|
1020
1019
|
|
|
1021
1020
|
num_jp2k_tile_cols = int(np.ceil(self.imagewidth / jtw))
|
|
@@ -1025,7 +1024,7 @@ class Tiff2Jp2k(object):
|
|
|
1025
1024
|
jp2k_tile_row = idx // num_jp2k_tile_cols
|
|
1026
1025
|
jp2k_tile_col = idx % num_jp2k_tile_cols
|
|
1027
1026
|
|
|
1028
|
-
msg = f
|
|
1027
|
+
msg = f"Tile: #{idx} row #{jp2k_tile_row} col #{jp2k_tile_col}"
|
|
1029
1028
|
self.logger.info(msg)
|
|
1030
1029
|
|
|
1031
1030
|
# the coordinates of the upper left pixel of the jp2k tile
|
|
@@ -1037,7 +1036,9 @@ class Tiff2Jp2k(object):
|
|
|
1037
1036
|
# jp2k tiles from this same TIFF multi-strip.
|
|
1038
1037
|
if jp2k_tile_col == 0:
|
|
1039
1038
|
tiff_multi_strip = self._construct_multi_strip(
|
|
1040
|
-
july,
|
|
1039
|
+
july,
|
|
1040
|
+
num_strips,
|
|
1041
|
+
jth,
|
|
1041
1042
|
)
|
|
1042
1043
|
|
|
1043
1044
|
# construct the TIFF row and column slices from the multi-strip,
|
|
@@ -1102,7 +1103,8 @@ class Tiff2Jp2k(object):
|
|
|
1102
1103
|
# This may result in a multi-strip that has more rows than the jp2k
|
|
1103
1104
|
# tile
|
|
1104
1105
|
tiff_multi_strip = np.zeros(
|
|
1105
|
-
(num_rows, self.imagewidth, spp),
|
|
1106
|
+
(num_rows, self.imagewidth, spp),
|
|
1107
|
+
dtype=dtype
|
|
1106
1108
|
)
|
|
1107
1109
|
|
|
1108
1110
|
# Fill the multi-strip
|
|
@@ -1111,7 +1113,8 @@ class Tiff2Jp2k(object):
|
|
|
1111
1113
|
if self.photo == libtiff.Photometric.YCBCR:
|
|
1112
1114
|
|
|
1113
1115
|
tiff_rgba_strip = np.zeros(
|
|
1114
|
-
(self.rps, self.imagewidth, 4),
|
|
1116
|
+
(self.rps, self.imagewidth, 4),
|
|
1117
|
+
dtype=dtype
|
|
1115
1118
|
)
|
|
1116
1119
|
|
|
1117
1120
|
libtiff.readRGBAStrip(
|
|
@@ -1138,24 +1141,23 @@ class Tiff2Jp2k(object):
|
|
|
1138
1141
|
|
|
1139
1142
|
# The rgba interface requires at least flipping the image
|
|
1140
1143
|
# upside down, and also reordering the planes on big endian
|
|
1141
|
-
if sys.byteorder ==
|
|
1144
|
+
if sys.byteorder == "little":
|
|
1142
1145
|
dims = [0]
|
|
1143
1146
|
else:
|
|
1144
1147
|
dims = [0, 2]
|
|
1145
1148
|
tiff_rgba_strip = np.flip(tiff_rgba_strip, axis=dims)
|
|
1146
1149
|
|
|
1147
1150
|
# potentially get rid of alpha plane
|
|
1148
|
-
tiff_strip = tiff_rgba_strip[:, :, :self.spp]
|
|
1151
|
+
tiff_strip = tiff_rgba_strip[:, :, : self.spp]
|
|
1149
1152
|
|
|
1150
1153
|
else:
|
|
1151
1154
|
|
|
1152
1155
|
tiff_strip = np.zeros(
|
|
1153
|
-
|
|
1156
|
+
(self.rps, self.imagewidth, spp),
|
|
1157
|
+
dtype=dtype
|
|
1154
1158
|
)
|
|
1155
1159
|
|
|
1156
|
-
libtiff.readEncodedStrip(
|
|
1157
|
-
self.tiff_fp, stripnum, tiff_strip
|
|
1158
|
-
)
|
|
1160
|
+
libtiff.readEncodedStrip(self.tiff_fp, stripnum, tiff_strip)
|
|
1159
1161
|
|
|
1160
1162
|
# push the strip into the multi-strip
|
|
1161
1163
|
top_row = (stripnum - top_strip_num) * self.rps
|
glymur/version.py
CHANGED
Glymur-0.13.6.dist-info/RECORD
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
glymur/__init__.py,sha256=k14IfdaYuTWXSpAIDR3LVDtXt9XKjr-ZSNXCyu8pQko,586
|
|
2
|
-
glymur/_iccprofile.py,sha256=_WfQsT-BqEWQzQVTtuY7tSXqPjOtwvWGW36rKxlLv1s,4148
|
|
3
|
-
glymur/codestream.py,sha256=nctHzG_bQKhln_gGAmoaxDhH3ndEbsiVVKy3dPqh4JM,62290
|
|
4
|
-
glymur/command_line.py,sha256=jm-6dD2jcU_G7mJAJ0U5sanfG9kRy-j0-G3eSN_Ieek,7476
|
|
5
|
-
glymur/config.py,sha256=ceGulS8TN2OYiTPtq3mAdhXrCCRlxjuLmvN_UG0009Y,4139
|
|
6
|
-
glymur/core.py,sha256=IDkk8FESyukQTB10LHBZ4VQM36NwKE4CXCcuJ407Kzg,3638
|
|
7
|
-
glymur/jp2box.py,sha256=qh1xUGKoGgVrUHq48yRcJAk7miJ__Udua8QHPTxpfQY,112434
|
|
8
|
-
glymur/jp2k.py,sha256=PYrjzhNPsmG2H_tyRUlIheQ-Gx7sXzH7igNAWdVyMXA,53489
|
|
9
|
-
glymur/jp2kr.py,sha256=Qf7ZsSoMkPDvOb0SCP60MARH4ZmkukFiS8oP4T1iYK8,32991
|
|
10
|
-
glymur/options.py,sha256=Y777g4wpxPqRAF8s963goeAIogfLqIe_Dyd9f77MfmU,4428
|
|
11
|
-
glymur/tiff.py,sha256=h4zFc3hq72kFqcuNqwr2CUKYtBj0o50H6YjiQl6OvP4,41116
|
|
12
|
-
glymur/version.py,sha256=WslVB8kmzZSuaZ_RLqTqs6bBB8qRb4ntrX40HtVasvM,981
|
|
13
|
-
glymur/data/__init__.py,sha256=n2KZrHV15it7Wu4YCaBLXui1ZleQ30dnZ92dyP6q05k,955
|
|
14
|
-
glymur/data/goodstuff.j2k,sha256=xKQG68KMu33gYjRUDTQvam1Cue2tdio85rNp5J-rYZE,115220
|
|
15
|
-
glymur/data/heliov.jpx,sha256=KXnYdBZgl25jcGLu-m-QfhuP9pqUXV0Hp9HHEdJqr34,1399071
|
|
16
|
-
glymur/data/nemo.jp2,sha256=yJ1NkTEwU0B_gBtAiA1c5hxtGYSJtJgq6cHC2IHpj70,1132373
|
|
17
|
-
glymur/lib/__init__.py,sha256=JnM9oPfcZhBDLKo7_yLS-lIRQ1wXb1N9hKKQ-G7vYVk,127
|
|
18
|
-
glymur/lib/openjp2.py,sha256=VHCy_TnBSDqQ8YlIQHkyFqUXOQ2E5C3jxJoziG73s0I,45052
|
|
19
|
-
glymur/lib/tiff.py,sha256=2o29IzYTsprVR_C6VDNHOzqk_U7aUdCoLQ2fjiyyoaI,50777
|
|
20
|
-
Glymur-0.13.6.dist-info/LICENSE.txt,sha256=G9pvBgkJdPTtZqQmoRyIgAydtic1ZwWtOWBea9VMW7I,1077
|
|
21
|
-
Glymur-0.13.6.dist-info/METADATA,sha256=TWLv_q2k_R7keyBdDDUzlGBGWD4VIleohi-QK8-Ya4c,1018
|
|
22
|
-
Glymur-0.13.6.dist-info/WHEEL,sha256=nCVcAvsfA9TDtwGwhYaRrlPhTLV9m-Ga6mdyDtuwK18,91
|
|
23
|
-
Glymur-0.13.6.dist-info/entry_points.txt,sha256=inzxpDbDDfIxtdXpCncAHdAdwJfjtXt3xKvIOsuZsG8,93
|
|
24
|
-
Glymur-0.13.6.dist-info/top_level.txt,sha256=D0SvtBUoPxOs40OTRW3l-kjGFHM6VrXS8yZPK5Fx2wY,7
|
|
25
|
-
Glymur-0.13.6.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|