Merge branch 'issue104' of https://github.com/quintusdias/glymur into issue104
Conflicts: glymur/_uuid_io/Exif.py glymur/_uuid_io/__init__.py glymur/jp2box.py glymur/test/test_jp2box_uuid.py glymur/test/test_jp2k.py
This commit is contained in:
commit
84c50c8499
11 changed files with 219 additions and 193 deletions
|
|
@ -3,6 +3,7 @@
|
||||||
Handlers for Exif UUIDs. Be nice if we would find a standard for this.
|
Handlers for Exif UUIDs. Be nice if we would find a standard for this.
|
||||||
"""
|
"""
|
||||||
import pprint
|
import pprint
|
||||||
|
import re
|
||||||
import struct
|
import struct
|
||||||
import sys
|
import sys
|
||||||
import warnings
|
import warnings
|
||||||
|
|
|
||||||
|
|
@ -663,7 +663,7 @@ class Codestream(object):
|
||||||
|
|
||||||
bitdepth = tuple(((x & 0x7f) + 1) for x in data[0::3])
|
bitdepth = tuple(((x & 0x7f) + 1) for x in data[0::3])
|
||||||
signed = tuple(((x & 0xb0) > 0) for x in data[0::3])
|
signed = tuple(((x & 0xb0) > 0) for x in data[0::3])
|
||||||
|
|
||||||
xrsiz = data[1::3]
|
xrsiz = data[1::3]
|
||||||
yrsiz = data[2::3]
|
yrsiz = data[2::3]
|
||||||
|
|
||||||
|
|
@ -1529,7 +1529,7 @@ class SIZsegment(Segment):
|
||||||
signed=self.signed,
|
signed=self.signed,
|
||||||
xyrsiz=(self.xrsiz, self.yrsiz))
|
xyrsiz=(self.xrsiz, self.yrsiz))
|
||||||
return msg
|
return msg
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
msg = Segment.__str__(self)
|
msg = Segment.__str__(self)
|
||||||
msg += '\n '
|
msg += '\n '
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,6 @@ import os
|
||||||
import pprint
|
import pprint
|
||||||
import struct
|
import struct
|
||||||
import sys
|
import sys
|
||||||
import traceback
|
|
||||||
import uuid
|
import uuid
|
||||||
import warnings
|
import warnings
|
||||||
import xml.etree.cElementTree as ET
|
import xml.etree.cElementTree as ET
|
||||||
|
|
@ -563,11 +562,11 @@ class CodestreamHeaderBox(Jp2kBox):
|
||||||
box : list
|
box : list
|
||||||
List of boxes contained in this superbox.
|
List of boxes contained in this superbox.
|
||||||
"""
|
"""
|
||||||
def __init__(self, box=[], length=0, offset=-1):
|
def __init__(self, box=None, length=0, offset=-1):
|
||||||
Jp2kBox.__init__(self, box_id='jpch', longname='Codestream Header')
|
Jp2kBox.__init__(self, box_id='jpch', longname='Codestream Header')
|
||||||
self.length = length
|
self.length = length
|
||||||
self.offset = offset
|
self.offset = offset
|
||||||
self.box = box
|
self.box = box if box is not None else []
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
msg = "glymur.jp2box.CodestreamHeaderBox(box={0})".format(self.box)
|
msg = "glymur.jp2box.CodestreamHeaderBox(box={0})".format(self.box)
|
||||||
|
|
@ -625,12 +624,12 @@ class CompositingLayerHeaderBox(Jp2kBox):
|
||||||
box : list
|
box : list
|
||||||
List of boxes contained in this superbox.
|
List of boxes contained in this superbox.
|
||||||
"""
|
"""
|
||||||
def __init__(self, box=[], length=0, offset=-1):
|
def __init__(self, box=None, length=0, offset=-1):
|
||||||
Jp2kBox.__init__(self, box_id='jplh',
|
Jp2kBox.__init__(self, box_id='jplh',
|
||||||
longname='Compositing Layer Header')
|
longname='Compositing Layer Header')
|
||||||
self.length = length
|
self.length = length
|
||||||
self.offset = offset
|
self.offset = offset
|
||||||
self.box = []
|
self.box = box if box is not None else []
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
msg = "glymur.jp2box.CompositingLayerHeaderBox(box={0})"
|
msg = "glymur.jp2box.CompositingLayerHeaderBox(box={0})"
|
||||||
|
|
@ -1073,11 +1072,11 @@ class AssociationBox(Jp2kBox):
|
||||||
box : list
|
box : list
|
||||||
List of boxes contained in this superbox.
|
List of boxes contained in this superbox.
|
||||||
"""
|
"""
|
||||||
def __init__(self, box=[], length=0, offset=-1):
|
def __init__(self, box=None, length=0, offset=-1):
|
||||||
Jp2kBox.__init__(self, box_id='asoc', longname='Association')
|
Jp2kBox.__init__(self, box_id='asoc', longname='Association')
|
||||||
self.length = length
|
self.length = length
|
||||||
self.offset = offset
|
self.offset = offset
|
||||||
self.box = box
|
self.box = box if box is not None else []
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
msg = "glymur.jp2box.AssociationBox(box={0})".format(self.box)
|
msg = "glymur.jp2box.AssociationBox(box={0})".format(self.box)
|
||||||
|
|
@ -1135,11 +1134,11 @@ class JP2HeaderBox(Jp2kBox):
|
||||||
box : list
|
box : list
|
||||||
List of boxes contained in this superbox.
|
List of boxes contained in this superbox.
|
||||||
"""
|
"""
|
||||||
def __init__(self, box=[], length=0, offset=-1):
|
def __init__(self, box=None, length=0, offset=-1):
|
||||||
Jp2kBox.__init__(self, box_id='jp2h', longname='JP2 Header')
|
Jp2kBox.__init__(self, box_id='jp2h', longname='JP2 Header')
|
||||||
self.length = length
|
self.length = length
|
||||||
self.offset = offset
|
self.offset = offset
|
||||||
self.box = box
|
self.box = box if box is not None else []
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
msg = "glymur.jp2box.JP2HeaderBox(box={0})".format(self.box)
|
msg = "glymur.jp2box.JP2HeaderBox(box={0})".format(self.box)
|
||||||
|
|
@ -1621,11 +1620,11 @@ class ResolutionBox(Jp2kBox):
|
||||||
box : list
|
box : list
|
||||||
List of boxes contained in this superbox.
|
List of boxes contained in this superbox.
|
||||||
"""
|
"""
|
||||||
def __init__(self, box=[], length=0, offset=-1):
|
def __init__(self, box=None, length=0, offset=-1):
|
||||||
Jp2kBox.__init__(self, box_id='res ', longname='Resolution')
|
Jp2kBox.__init__(self, box_id='res ', longname='Resolution')
|
||||||
self.length = length
|
self.length = length
|
||||||
self.offset = offset
|
self.offset = offset
|
||||||
self.box = box
|
self.box = box if box is not None else []
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
msg = "glymur.jp2box.ResolutionBox(box={0})"
|
msg = "glymur.jp2box.ResolutionBox(box={0})"
|
||||||
|
|
@ -2040,11 +2039,11 @@ class UUIDInfoBox(Jp2kBox):
|
||||||
box : list
|
box : list
|
||||||
List of boxes contained in this superbox.
|
List of boxes contained in this superbox.
|
||||||
"""
|
"""
|
||||||
def __init__(self, box=[], length=0, offset=-1):
|
def __init__(self, box=None, length=0, offset=-1):
|
||||||
Jp2kBox.__init__(self, box_id='uinf', longname='UUIDInfo')
|
Jp2kBox.__init__(self, box_id='uinf', longname='UUIDInfo')
|
||||||
self.length = length
|
self.length = length
|
||||||
self.offset = offset
|
self.offset = offset
|
||||||
self.box = box
|
self.box = box if box is not None else []
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
msg = "glymur.jp2box.UUIDInfoBox(box={0})".format(self.box)
|
msg = "glymur.jp2box.UUIDInfoBox(box={0})".format(self.box)
|
||||||
|
|
|
||||||
|
|
@ -484,17 +484,17 @@ class Jp2k(Jp2kBox):
|
||||||
stack.callback(opj2.image_destroy, image)
|
stack.callback(opj2.image_destroy, image)
|
||||||
|
|
||||||
_populate_image_struct(cparams, image, img_array)
|
_populate_image_struct(cparams, image, img_array)
|
||||||
|
|
||||||
codec = opj2.create_compress(cparams.codec_fmt)
|
codec = opj2.create_compress(cparams.codec_fmt)
|
||||||
stack.callback(opj2.destroy_codec, codec)
|
stack.callback(opj2.destroy_codec, codec)
|
||||||
|
|
||||||
info_handler = _INFO_CALLBACK if verbose else None
|
info_handler = _INFO_CALLBACK if verbose else None
|
||||||
opj2.set_info_handler(codec, info_handler)
|
opj2.set_info_handler(codec, info_handler)
|
||||||
opj2.set_warning_handler(codec, _WARNING_CALLBACK)
|
opj2.set_warning_handler(codec, _WARNING_CALLBACK)
|
||||||
opj2.set_error_handler(codec, _ERROR_CALLBACK)
|
opj2.set_error_handler(codec, _ERROR_CALLBACK)
|
||||||
|
|
||||||
opj2.setup_encoder(codec, cparams, image)
|
opj2.setup_encoder(codec, cparams, image)
|
||||||
|
|
||||||
if _OPENJP2_IS_OFFICIAL_V2:
|
if _OPENJP2_IS_OFFICIAL_V2:
|
||||||
fptr = libc.fopen(self.filename, 'wb')
|
fptr = libc.fopen(self.filename, 'wb')
|
||||||
strm = opj2.stream_create_default_file_stream(fptr, False)
|
strm = opj2.stream_create_default_file_stream(fptr, False)
|
||||||
|
|
@ -505,11 +505,11 @@ class Jp2k(Jp2kBox):
|
||||||
strm = opj2.stream_create_default_file_stream_v3(self.filename,
|
strm = opj2.stream_create_default_file_stream_v3(self.filename,
|
||||||
False)
|
False)
|
||||||
stack.callback(opj2.stream_destroy_v3, strm)
|
stack.callback(opj2.stream_destroy_v3, strm)
|
||||||
|
|
||||||
opj2.start_compress(codec, image, strm)
|
opj2.start_compress(codec, image, strm)
|
||||||
opj2.encode(codec, strm)
|
opj2.encode(codec, strm)
|
||||||
opj2.end_compress(codec, strm)
|
opj2.end_compress(codec, strm)
|
||||||
|
|
||||||
# Refresh the metadata.
|
# Refresh the metadata.
|
||||||
self.parse()
|
self.parse()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,8 +11,8 @@ import numpy as np
|
||||||
from .config import glymur_config
|
from .config import glymur_config
|
||||||
_, OPENJPEG = glymur_config()
|
_, OPENJPEG = glymur_config()
|
||||||
|
|
||||||
# Maximum number of tile parts expected by JPWL: increase at your will
|
# Maximum number of tile parts expected by JPWL: increase at your will
|
||||||
JPWL_MAX_NO_TILESPECS = 16
|
JPWL_MAX_NO_TILESPECS = 16
|
||||||
|
|
||||||
J2K_MAXRLVLS = 33 # Number of maximum resolution level authorized
|
J2K_MAXRLVLS = 33 # Number of maximum resolution level authorized
|
||||||
PATH_LEN = 4096 # maximum allowed size for filenames
|
PATH_LEN = 4096 # maximum allowed size for filenames
|
||||||
|
|
@ -58,7 +58,7 @@ class CommonStructType(ctypes.Structure):
|
||||||
("mj2_handle", ctypes.c_void_p)]
|
("mj2_handle", ctypes.c_void_p)]
|
||||||
|
|
||||||
|
|
||||||
STREAM_READ = 0x0001 # The stream was opened for reading.
|
STREAM_READ = 0x0001 # The stream was opened for reading.
|
||||||
STREAM_WRITE = 0x0002 # The stream was opened for writing.
|
STREAM_WRITE = 0x0002 # The stream was opened for writing.
|
||||||
class CioType(ctypes.Structure):
|
class CioType(ctypes.Structure):
|
||||||
"""Byte input-output stream (CIO)
|
"""Byte input-output stream (CIO)
|
||||||
|
|
@ -81,7 +81,7 @@ class CioType(ctypes.Structure):
|
||||||
|
|
||||||
|
|
||||||
class CompressionInfoType(CommonStructType):
|
class CompressionInfoType(CommonStructType):
|
||||||
"""Common fields between JPEG-2000 compression and decompression contexts.
|
"""Common fields between JPEG-2000 compression and decompression contexts.
|
||||||
This is for compression contexts. Corresponds to common_struct_t.
|
This is for compression contexts. Corresponds to common_struct_t.
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
@ -91,68 +91,68 @@ class PocType(ctypes.Structure):
|
||||||
"""Progression order changes."""
|
"""Progression order changes."""
|
||||||
_fields_ = [("resno", ctypes.c_int),
|
_fields_ = [("resno", ctypes.c_int),
|
||||||
# Resolution num start, Component num start, given by POC
|
# Resolution num start, Component num start, given by POC
|
||||||
("compno0", ctypes.c_int),
|
("compno0", ctypes.c_int),
|
||||||
|
|
||||||
# Layer num end,Resolution num end, Component num end, given by POC
|
# Layer num end,Resolution num end, Component num end, given by POC
|
||||||
("layno1", ctypes.c_int),
|
("layno1", ctypes.c_int),
|
||||||
("resno1", ctypes.c_int),
|
("resno1", ctypes.c_int),
|
||||||
("compno1", ctypes.c_int),
|
("compno1", ctypes.c_int),
|
||||||
|
|
||||||
# Layer num start,Precinct num start, Precinct num end
|
# Layer num start,Precinct num start, Precinct num end
|
||||||
("layno0", ctypes.c_int),
|
("layno0", ctypes.c_int),
|
||||||
("precno0", ctypes.c_int),
|
("precno0", ctypes.c_int),
|
||||||
("precno1", ctypes.c_int),
|
("precno1", ctypes.c_int),
|
||||||
|
|
||||||
# Progression order enum
|
# Progression order enum
|
||||||
# OPJ_PROG_ORDER prg1,prg;
|
# OPJ_PROG_ORDER prg1,prg;
|
||||||
("prg1", ctypes.c_int),
|
("prg1", ctypes.c_int),
|
||||||
("prg", ctypes.c_int),
|
("prg", ctypes.c_int),
|
||||||
|
|
||||||
# Progression order string
|
# Progression order string
|
||||||
# char progorder[5];
|
# char progorder[5];
|
||||||
("progorder", ctypes.c_char * 5),
|
("progorder", ctypes.c_char * 5),
|
||||||
|
|
||||||
# Tile number
|
# Tile number
|
||||||
# int tile;
|
# int tile;
|
||||||
("tile", ctypes.c_int),
|
("tile", ctypes.c_int),
|
||||||
|
|
||||||
# /** Start and end values for Tile width and height*/
|
# /** Start and end values for Tile width and height*/
|
||||||
# int tx0,tx1,ty0,ty1;
|
# int tx0,tx1,ty0,ty1;
|
||||||
("tx0", ctypes.c_int),
|
("tx0", ctypes.c_int),
|
||||||
("tx1", ctypes.c_int),
|
("tx1", ctypes.c_int),
|
||||||
("ty0", ctypes.c_int),
|
("ty0", ctypes.c_int),
|
||||||
("ty1", ctypes.c_int),
|
("ty1", ctypes.c_int),
|
||||||
|
|
||||||
# /** Start value, initialised in pi_initialise_encode*/
|
# /** Start value, initialised in pi_initialise_encode*/
|
||||||
# int layS, resS, compS, prcS;
|
# int layS, resS, compS, prcS;
|
||||||
("layS", ctypes.c_int),
|
("layS", ctypes.c_int),
|
||||||
("resS", ctypes.c_int),
|
("resS", ctypes.c_int),
|
||||||
("compS", ctypes.c_int),
|
("compS", ctypes.c_int),
|
||||||
("prcS", ctypes.c_int),
|
("prcS", ctypes.c_int),
|
||||||
|
|
||||||
# /** End value, initialised in pi_initialise_encode */
|
# /** End value, initialised in pi_initialise_encode */
|
||||||
# int layE, resE, compE, prcE;
|
# int layE, resE, compE, prcE;
|
||||||
("layE", ctypes.c_int),
|
("layE", ctypes.c_int),
|
||||||
("resE", ctypes.c_int),
|
("resE", ctypes.c_int),
|
||||||
("compE", ctypes.c_int),
|
("compE", ctypes.c_int),
|
||||||
("prcE", ctypes.c_int),
|
("prcE", ctypes.c_int),
|
||||||
|
|
||||||
# Start and end values of Tile width and height, initialised in
|
# Start and end values of Tile width and height, initialised in
|
||||||
# pi_initialise_encode int txS,txE,tyS,tyE,dx,dy;
|
# pi_initialise_encode int txS,txE,tyS,tyE,dx,dy;
|
||||||
("txS", ctypes.c_int),
|
("txS", ctypes.c_int),
|
||||||
("txE", ctypes.c_int),
|
("txE", ctypes.c_int),
|
||||||
("tyS", ctypes.c_int),
|
("tyS", ctypes.c_int),
|
||||||
("tyE", ctypes.c_int),
|
("tyE", ctypes.c_int),
|
||||||
("dx", ctypes.c_int),
|
("dx", ctypes.c_int),
|
||||||
("dy", ctypes.c_int),
|
("dy", ctypes.c_int),
|
||||||
|
|
||||||
# Temporary values for Tile parts, initialised in pi_create_encode
|
# Temporary values for Tile parts, initialised in pi_create_encode
|
||||||
# int lay_t, res_t, comp_t, prc_t,tx0_t,ty0_t;
|
# int lay_t, res_t, comp_t, prc_t,tx0_t,ty0_t;
|
||||||
("lay_t", ctypes.c_int),
|
("lay_t", ctypes.c_int),
|
||||||
("res_t", ctypes.c_int),
|
("res_t", ctypes.c_int),
|
||||||
("comp_t", ctypes.c_int),
|
("comp_t", ctypes.c_int),
|
||||||
("prc_t", ctypes.c_int),
|
("prc_t", ctypes.c_int),
|
||||||
("tx0_t", ctypes.c_int),
|
("tx0_t", ctypes.c_int),
|
||||||
("ty0_t", ctypes.c_int)]
|
("ty0_t", ctypes.c_int)]
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -374,23 +374,23 @@ class DecompressionParametersType(ctypes.Structure):
|
||||||
class ImageComptParmType(ctypes.Structure):
|
class ImageComptParmType(ctypes.Structure):
|
||||||
"""Component parameters structure used by the opj_image_create function.
|
"""Component parameters structure used by the opj_image_create function.
|
||||||
"""
|
"""
|
||||||
_fields_ = [
|
_fields_ = [
|
||||||
# XRsiz: horizontal separation of a sample of ith component with
|
# XRsiz: horizontal separation of a sample of ith component with
|
||||||
# respect to the reference grid
|
# respect to the reference grid
|
||||||
("dx", ctypes.c_int),
|
("dx", ctypes.c_int),
|
||||||
|
|
||||||
# YRsiz: vertical separation of a sample of ith component with
|
# YRsiz: vertical separation of a sample of ith component with
|
||||||
# respect to the reference grid */
|
# respect to the reference grid */
|
||||||
("dy", ctypes.c_int),
|
("dy", ctypes.c_int),
|
||||||
|
|
||||||
# data width, height
|
|
||||||
("w", ctypes.c_int),
|
|
||||||
("h", ctypes.c_int),
|
|
||||||
|
|
||||||
# x component offset compared to the whole image
|
# data width, height
|
||||||
# y component offset compared to the whole image
|
("w", ctypes.c_int),
|
||||||
("x0", ctypes.c_int),
|
("h", ctypes.c_int),
|
||||||
("y0", ctypes.c_int),
|
|
||||||
|
# x component offset compared to the whole image
|
||||||
|
# y component offset compared to the whole image
|
||||||
|
("x0", ctypes.c_int),
|
||||||
|
("y0", ctypes.c_int),
|
||||||
|
|
||||||
# precision
|
# precision
|
||||||
('prec', ctypes.c_int),
|
('prec', ctypes.c_int),
|
||||||
|
|
@ -398,7 +398,7 @@ class ImageComptParmType(ctypes.Structure):
|
||||||
# image depth in bits
|
# image depth in bits
|
||||||
('bpp', ctypes.c_int),
|
('bpp', ctypes.c_int),
|
||||||
|
|
||||||
# signed (1) / unsigned (0)
|
# signed (1) / unsigned (0)
|
||||||
('sgnd', ctypes.c_int)]
|
('sgnd', ctypes.c_int)]
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -511,7 +511,7 @@ def destroy_compress(cinfo):
|
||||||
def encode(cinfo, cio, image):
|
def encode(cinfo, cio, image):
|
||||||
"""Wrapper for openjpeg library function opj_encode.
|
"""Wrapper for openjpeg library function opj_encode.
|
||||||
|
|
||||||
Encodes an image into a JPEG-2000 codestream.
|
Encodes an image into a JPEG-2000 codestream.
|
||||||
|
|
||||||
Parameters
|
Parameters
|
||||||
----------
|
----------
|
||||||
|
|
@ -540,7 +540,7 @@ def destroy_decompress(dinfo):
|
||||||
def image_cmptparm_t_from_np(np_image):
|
def image_cmptparm_t_from_np(np_image):
|
||||||
"""Return appropriate image_cmptparm_t based on given numpy array.
|
"""Return appropriate image_cmptparm_t based on given numpy array.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
num_comps = np_image.shape[2]
|
num_comps = np_image.shape[2]
|
||||||
except IndexError:
|
except IndexError:
|
||||||
num_comps = 1
|
num_comps = 1
|
||||||
|
|
@ -557,17 +557,17 @@ def image_cmptparm_t_from_np(np_image):
|
||||||
bpp = 8
|
bpp = 8
|
||||||
sgnd = 1
|
sgnd = 1
|
||||||
elif np_image.dtype == np.uint16:
|
elif np_image.dtype == np.uint16:
|
||||||
prec = 16
|
prec = 16
|
||||||
bpp = 16
|
bpp = 16
|
||||||
sgnd = 0
|
sgnd = 0
|
||||||
elif np_image.dtype == np.int16:
|
elif np_image.dtype == np.int16:
|
||||||
prec = 16
|
prec = 16
|
||||||
bpp = 16
|
bpp = 16
|
||||||
sgnd = 1
|
sgnd = 1
|
||||||
else:
|
else:
|
||||||
raise(TypeError("unhandled"))
|
raise(TypeError("unhandled"))
|
||||||
|
|
||||||
for j in range(0, num_comps):
|
for j in range(0, num_comps):
|
||||||
tarr[j].dx = 1
|
tarr[j].dx = 1
|
||||||
tarr[j].dy = 1
|
tarr[j].dy = 1
|
||||||
tarr[j].w = np_image.shape[1]
|
tarr[j].w = np_image.shape[1]
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
"""
|
"""
|
||||||
Tests for libopenjp2 wrapping functions.
|
Tests for libopenjp2 wrapping functions.
|
||||||
"""
|
"""
|
||||||
# R0904: Seems like pylint is fooled in this situation
|
# R0904: Seems like pylint is fooled in this situation
|
||||||
# W0142: using kwargs is ok in this context
|
# W0142: using kwargs is ok in this context
|
||||||
|
|
@ -212,7 +212,7 @@ class TestOpenJP2(unittest.TestCase):
|
||||||
"""Runs test designated tte3 in OpenJPEG test suite."""
|
"""Runs test designated tte3 in OpenJPEG test suite."""
|
||||||
with tempfile.NamedTemporaryFile(suffix=".j2k") as tfile:
|
with tempfile.NamedTemporaryFile(suffix=".j2k") as tfile:
|
||||||
xtx3_setup(tfile.name)
|
xtx3_setup(tfile.name)
|
||||||
self.assertTrue(True)
|
self.assertTrue(True)
|
||||||
|
|
||||||
def test_rta3(self):
|
def test_rta3(self):
|
||||||
"""Runs test designated rta3 in OpenJPEG test suite."""
|
"""Runs test designated rta3 in OpenJPEG test suite."""
|
||||||
|
|
@ -221,13 +221,13 @@ class TestOpenJP2(unittest.TestCase):
|
||||||
|
|
||||||
codec_format = openjp2.CODEC_J2K
|
codec_format = openjp2.CODEC_J2K
|
||||||
self.j2k_random_tile_access(tfile.name, codec_format)
|
self.j2k_random_tile_access(tfile.name, codec_format)
|
||||||
self.assertTrue(True)
|
self.assertTrue(True)
|
||||||
|
|
||||||
def test_tte4(self):
|
def test_tte4(self):
|
||||||
"""Runs test designated tte4 in OpenJPEG test suite."""
|
"""Runs test designated tte4 in OpenJPEG test suite."""
|
||||||
with tempfile.NamedTemporaryFile(suffix=".j2k") as tfile:
|
with tempfile.NamedTemporaryFile(suffix=".j2k") as tfile:
|
||||||
xtx4_setup(tfile.name)
|
xtx4_setup(tfile.name)
|
||||||
self.assertTrue(True)
|
self.assertTrue(True)
|
||||||
|
|
||||||
def test_rta4(self):
|
def test_rta4(self):
|
||||||
"""Runs test designated rta4 in OpenJPEG test suite."""
|
"""Runs test designated rta4 in OpenJPEG test suite."""
|
||||||
|
|
@ -241,7 +241,7 @@ class TestOpenJP2(unittest.TestCase):
|
||||||
"""Runs test designated tte5 in OpenJPEG test suite."""
|
"""Runs test designated tte5 in OpenJPEG test suite."""
|
||||||
with tempfile.NamedTemporaryFile(suffix=".j2k") as tfile:
|
with tempfile.NamedTemporaryFile(suffix=".j2k") as tfile:
|
||||||
xtx5_setup(tfile.name)
|
xtx5_setup(tfile.name)
|
||||||
self.assertTrue(True)
|
self.assertTrue(True)
|
||||||
|
|
||||||
def test_rta5(self):
|
def test_rta5(self):
|
||||||
"""Runs test designated rta5 in OpenJPEG test suite."""
|
"""Runs test designated rta5 in OpenJPEG test suite."""
|
||||||
|
|
@ -332,8 +332,8 @@ def tile_encoder(**kwargs):
|
||||||
|
|
||||||
def tile_decoder(**kwargs):
|
def tile_decoder(**kwargs):
|
||||||
"""Fixture called with various configurations by many tests.
|
"""Fixture called with various configurations by many tests.
|
||||||
|
|
||||||
Reads a tile. That's all it does.
|
Reads a tile. That's all it does.
|
||||||
"""
|
"""
|
||||||
stream = openjp2.stream_create_default_file_stream_v3(kwargs['filename'],
|
stream = openjp2.stream_create_default_file_stream_v3(kwargs['filename'],
|
||||||
True)
|
True)
|
||||||
|
|
@ -355,7 +355,7 @@ def tile_decoder(**kwargs):
|
||||||
|
|
||||||
openjp2.setup_decoder(codec, dparam)
|
openjp2.setup_decoder(codec, dparam)
|
||||||
image = openjp2.read_header(stream, codec)
|
image = openjp2.read_header(stream, codec)
|
||||||
openjp2.set_decode_area(codec, image,
|
openjp2.set_decode_area(codec, image,
|
||||||
kwargs['x0'], kwargs['y0'],
|
kwargs['x0'], kwargs['y0'],
|
||||||
kwargs['x1'], kwargs['y1'])
|
kwargs['x1'], kwargs['y1'])
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,19 @@ import numpy as np
|
||||||
import glymur
|
import glymur
|
||||||
|
|
||||||
|
|
||||||
|
# The Python XMP Toolkit may be used for XMP UUIDs, but only if available and
|
||||||
|
# if the version is at least 2.0.0.
|
||||||
|
try:
|
||||||
|
import libxmp
|
||||||
|
if hasattr(libxmp, 'version') and re.match(r'''[2-9].\d*.\d*''',
|
||||||
|
libxmp.version.VERSION):
|
||||||
|
from libxmp import XMPMeta
|
||||||
|
HAS_PYTHON_XMP_TOOLKIT = True
|
||||||
|
else:
|
||||||
|
HAS_PYTHON_XMP_TOOLKIT = False
|
||||||
|
except ImportError:
|
||||||
|
HAS_PYTHON_XMP_TOOLKIT = False
|
||||||
|
|
||||||
# Need to know of the libopenjp2 version is the official 2.0.0 release and NOT
|
# Need to know of the libopenjp2 version is the official 2.0.0 release and NOT
|
||||||
# the 2.0+ development version.
|
# the 2.0+ development version.
|
||||||
OPENJP2_IS_V2_OFFICIAL = False
|
OPENJP2_IS_V2_OFFICIAL = False
|
||||||
|
|
@ -170,90 +183,96 @@ def read_pgx_header(pgx_file):
|
||||||
|
|
||||||
nemo_xmp_box = """UUID Box (uuid) @ (77, 3146)
|
nemo_xmp_box = """UUID Box (uuid) @ (77, 3146)
|
||||||
UUID: be7acfcb-97a9-42e8-9c71-999491e3afac (XMP)
|
UUID: be7acfcb-97a9-42e8-9c71-999491e3afac (XMP)
|
||||||
UUID Data:
|
UUID Data: <?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?>
|
||||||
<ns0:xmpmeta xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:ns0="adobe:ns:meta/" xmlns:ns2="http://ns.adobe.com/xap/1.0/" xmlns:ns3="http://ns.adobe.com/tiff/1.0/" xmlns:ns4="http://ns.adobe.com/exif/1.0/" xmlns:ns5="http://ns.adobe.com/photoshop/1.0/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" ns0:xmptk="Exempi + XMP Core 5.1.2">
|
<x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="Exempi + XMP Core 4.4.0">
|
||||||
<rdf:RDF>
|
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
|
||||||
<rdf:Description rdf:about="">
|
<rdf:Description rdf:about=""
|
||||||
<ns2:CreatorTool>Google</ns2:CreatorTool>
|
xmlns:xmp="http://ns.adobe.com/xap/1.0/">
|
||||||
<ns2:CreateDate>2013-02-09T14:47:53</ns2:CreateDate>
|
<xmp:CreatorTool>Google</xmp:CreatorTool>
|
||||||
</rdf:Description>
|
<xmp:CreateDate>2013-02-09T14:47:53</xmp:CreateDate>
|
||||||
<rdf:Description rdf:about="">
|
</rdf:Description>
|
||||||
<ns3:YCbCrPositioning>1</ns3:YCbCrPositioning>
|
<rdf:Description rdf:about=""
|
||||||
<ns3:XResolution>72/1</ns3:XResolution>
|
xmlns:tiff="http://ns.adobe.com/tiff/1.0/">
|
||||||
<ns3:YResolution>72/1</ns3:YResolution>
|
<tiff:YCbCrPositioning>1</tiff:YCbCrPositioning>
|
||||||
<ns3:ResolutionUnit>2</ns3:ResolutionUnit>
|
<tiff:XResolution>72/1</tiff:XResolution>
|
||||||
<ns3:Make>HTC</ns3:Make>
|
<tiff:YResolution>72/1</tiff:YResolution>
|
||||||
<ns3:Model>HTC Glacier</ns3:Model>
|
<tiff:ResolutionUnit>2</tiff:ResolutionUnit>
|
||||||
<ns3:ImageWidth>2592</ns3:ImageWidth>
|
<tiff:Make>HTC</tiff:Make>
|
||||||
<ns3:ImageLength>1456</ns3:ImageLength>
|
<tiff:Model>HTC Glacier</tiff:Model>
|
||||||
<ns3:BitsPerSample>
|
<tiff:ImageWidth>2592</tiff:ImageWidth>
|
||||||
<rdf:Seq>
|
<tiff:ImageLength>1456</tiff:ImageLength>
|
||||||
<rdf:li>8</rdf:li>
|
<tiff:BitsPerSample>
|
||||||
<rdf:li>8</rdf:li>
|
<rdf:Seq>
|
||||||
<rdf:li>8</rdf:li>
|
<rdf:li>8</rdf:li>
|
||||||
</rdf:Seq>
|
<rdf:li>8</rdf:li>
|
||||||
</ns3:BitsPerSample>
|
<rdf:li>8</rdf:li>
|
||||||
<ns3:PhotometricInterpretation>2</ns3:PhotometricInterpretation>
|
</rdf:Seq>
|
||||||
<ns3:SamplesPerPixel>3</ns3:SamplesPerPixel>
|
</tiff:BitsPerSample>
|
||||||
<ns3:WhitePoint>
|
<tiff:PhotometricInterpretation>2</tiff:PhotometricInterpretation>
|
||||||
<rdf:Seq>
|
<tiff:SamplesPerPixel>3</tiff:SamplesPerPixel>
|
||||||
<rdf:li>1343036288/4294967295</rdf:li>
|
<tiff:WhitePoint>
|
||||||
<rdf:li>1413044224/4294967295</rdf:li>
|
<rdf:Seq>
|
||||||
</rdf:Seq>
|
<rdf:li>1343036288/4294967295</rdf:li>
|
||||||
</ns3:WhitePoint>
|
<rdf:li>1413044224/4294967295</rdf:li>
|
||||||
<ns3:PrimaryChromaticities>
|
</rdf:Seq>
|
||||||
<rdf:Seq>
|
</tiff:WhitePoint>
|
||||||
<rdf:li>2748779008/4294967295</rdf:li>
|
<tiff:PrimaryChromaticities>
|
||||||
<rdf:li>1417339264/4294967295</rdf:li>
|
<rdf:Seq>
|
||||||
<rdf:li>1288490240/4294967295</rdf:li>
|
<rdf:li>2748779008/4294967295</rdf:li>
|
||||||
<rdf:li>2576980480/4294967295</rdf:li>
|
<rdf:li>1417339264/4294967295</rdf:li>
|
||||||
<rdf:li>644245120/4294967295</rdf:li>
|
<rdf:li>1288490240/4294967295</rdf:li>
|
||||||
<rdf:li>257698032/4294967295</rdf:li>
|
<rdf:li>2576980480/4294967295</rdf:li>
|
||||||
</rdf:Seq>
|
<rdf:li>644245120/4294967295</rdf:li>
|
||||||
</ns3:PrimaryChromaticities>
|
<rdf:li>257698032/4294967295</rdf:li>
|
||||||
</rdf:Description>
|
</rdf:Seq>
|
||||||
<rdf:Description rdf:about="">
|
</tiff:PrimaryChromaticities>
|
||||||
<ns4:ColorSpace>1</ns4:ColorSpace>
|
</rdf:Description>
|
||||||
<ns4:PixelXDimension>2528</ns4:PixelXDimension>
|
<rdf:Description rdf:about=""
|
||||||
<ns4:PixelYDimension>1424</ns4:PixelYDimension>
|
xmlns:exif="http://ns.adobe.com/exif/1.0/">
|
||||||
<ns4:FocalLength>353/100</ns4:FocalLength>
|
<exif:ColorSpace>1</exif:ColorSpace>
|
||||||
<ns4:GPSAltitudeRef>0</ns4:GPSAltitudeRef>
|
<exif:PixelXDimension>2528</exif:PixelXDimension>
|
||||||
<ns4:GPSAltitude>0/1</ns4:GPSAltitude>
|
<exif:PixelYDimension>1424</exif:PixelYDimension>
|
||||||
<ns4:GPSMapDatum>WGS-84</ns4:GPSMapDatum>
|
<exif:FocalLength>353/100</exif:FocalLength>
|
||||||
<ns4:DateTimeOriginal>2013-02-09T14:47:53</ns4:DateTimeOriginal>
|
<exif:GPSAltitudeRef>0</exif:GPSAltitudeRef>
|
||||||
<ns4:ISOSpeedRatings>
|
<exif:GPSAltitude>0/1</exif:GPSAltitude>
|
||||||
<rdf:Seq>
|
<exif:GPSMapDatum>WGS-84</exif:GPSMapDatum>
|
||||||
<rdf:li>76</rdf:li>
|
<exif:DateTimeOriginal>2013-02-09T14:47:53</exif:DateTimeOriginal>
|
||||||
</rdf:Seq>
|
<exif:ISOSpeedRatings>
|
||||||
</ns4:ISOSpeedRatings>
|
<rdf:Seq>
|
||||||
<ns4:ExifVersion>0220</ns4:ExifVersion>
|
<rdf:li>76</rdf:li>
|
||||||
<ns4:FlashpixVersion>0100</ns4:FlashpixVersion>
|
</rdf:Seq>
|
||||||
<ns4:ComponentsConfiguration>
|
</exif:ISOSpeedRatings>
|
||||||
<rdf:Seq>
|
<exif:ExifVersion>0220</exif:ExifVersion>
|
||||||
<rdf:li>1</rdf:li>
|
<exif:FlashpixVersion>0100</exif:FlashpixVersion>
|
||||||
<rdf:li>2</rdf:li>
|
<exif:ComponentsConfiguration>
|
||||||
<rdf:li>3</rdf:li>
|
<rdf:Seq>
|
||||||
<rdf:li>0</rdf:li>
|
<rdf:li>1</rdf:li>
|
||||||
</rdf:Seq>
|
<rdf:li>2</rdf:li>
|
||||||
</ns4:ComponentsConfiguration>
|
<rdf:li>3</rdf:li>
|
||||||
<ns4:GPSLatitude>42,20.56N</ns4:GPSLatitude>
|
<rdf:li>0</rdf:li>
|
||||||
<ns4:GPSLongitude>71,5.29W</ns4:GPSLongitude>
|
</rdf:Seq>
|
||||||
<ns4:GPSTimeStamp>2013-02-09T19:47:53Z</ns4:GPSTimeStamp>
|
</exif:ComponentsConfiguration>
|
||||||
<ns4:GPSProcessingMethod>NETWORK</ns4:GPSProcessingMethod>
|
<exif:GPSLatitude>42,20.56N</exif:GPSLatitude>
|
||||||
</rdf:Description>
|
<exif:GPSLongitude>71,5.29W</exif:GPSLongitude>
|
||||||
<rdf:Description rdf:about="">
|
<exif:GPSTimeStamp>2013-02-09T19:47:53Z</exif:GPSTimeStamp>
|
||||||
<ns5:DateCreated>2013-02-09T14:47:53</ns5:DateCreated>
|
<exif:GPSProcessingMethod>NETWORK</exif:GPSProcessingMethod>
|
||||||
</rdf:Description>
|
</rdf:Description>
|
||||||
<rdf:Description rdf:about="">
|
<rdf:Description rdf:about=""
|
||||||
<dc:Creator>
|
xmlns:photoshop="http://ns.adobe.com/photoshop/1.0/">
|
||||||
<rdf:Seq>
|
<photoshop:DateCreated>2013-02-09T14:47:53</photoshop:DateCreated>
|
||||||
<rdf:li>Glymur</rdf:li>
|
</rdf:Description>
|
||||||
<rdf:li>Python XMP Toolkit</rdf:li>
|
<rdf:Description rdf:about=""
|
||||||
</rdf:Seq>
|
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||||
</dc:Creator>
|
<dc:Creator>
|
||||||
</rdf:Description>
|
<rdf:Seq>
|
||||||
</rdf:RDF>
|
<rdf:li>Glymur</rdf:li>
|
||||||
</ns0:xmpmeta>"""
|
<rdf:li>Python XMP Toolkit</rdf:li>
|
||||||
|
</rdf:Seq>
|
||||||
|
</dc:Creator>
|
||||||
|
</rdf:Description>
|
||||||
|
</rdf:RDF>
|
||||||
|
</x:xmpmeta>
|
||||||
|
<?xpacket end="w"?>"""
|
||||||
|
|
||||||
SimpleRDF = """<rdf:RDF xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'>
|
SimpleRDF = """<rdf:RDF xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'>
|
||||||
<rdf:Description rdf:about='Test:XMPCoreCoverage/kSimpleRDF'
|
<rdf:Description rdf:about='Test:XMPCoreCoverage/kSimpleRDF'
|
||||||
|
|
|
||||||
|
|
@ -894,9 +894,9 @@ class TestRepr(unittest.TestCase):
|
||||||
tree = ET.ElementTree(elt)
|
tree = ET.ElementTree(elt)
|
||||||
box = glymur.jp2box.XMLBox(xml=tree)
|
box = glymur.jp2box.XMLBox(xml=tree)
|
||||||
|
|
||||||
regexp = "glymur.jp2box.XMLBox"
|
regexp = r"""glymur.jp2box.XMLBox"""
|
||||||
regexp += "\(xml=<(xml.etree.ElementTree.){0,1}ElementTree object "
|
regexp += r"""\(xml=<(xml.etree.ElementTree.){0,1}ElementTree object """
|
||||||
regexp += "at 0x([a-f0-9]*)>\)"
|
regexp += """at 0x([a-f0-9]*)>\)"""
|
||||||
|
|
||||||
if sys.hexversion < 0x03000000:
|
if sys.hexversion < 0x03000000:
|
||||||
self.assertRegexpMatches(repr(box), regexp)
|
self.assertRegexpMatches(repr(box), regexp)
|
||||||
|
|
@ -927,9 +927,9 @@ class TestRepr(unittest.TestCase):
|
||||||
|
|
||||||
# Since the raw_data parameter is a sequence of bytes which could be
|
# Since the raw_data parameter is a sequence of bytes which could be
|
||||||
# quite long, don't bother trying to make it conform to eval(repr()).
|
# quite long, don't bother trying to make it conform to eval(repr()).
|
||||||
regexp = "glymur.jp2box.UUIDBox\("
|
regexp = r"""glymur.jp2box.UUIDBox\("""
|
||||||
regexp += "the_uuid=UUID\('00000000-0000-0000-0000-000000000000'\),\s"
|
regexp += """the_uuid=UUID\('00000000-0000-0000-0000-000000000000'\),\s"""
|
||||||
regexp += "raw_data=<byte\sarray\s10\selements>\)"
|
regexp += """raw_data=<byte\sarray\s10\selements>\)"""
|
||||||
|
|
||||||
if sys.hexversion < 0x03000000:
|
if sys.hexversion < 0x03000000:
|
||||||
self.assertRegexpMatches(repr(box), regexp)
|
self.assertRegexpMatches(repr(box), regexp)
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,9 @@ if sys.hexversion <= 0x03030000:
|
||||||
else:
|
else:
|
||||||
from unittest.mock import patch
|
from unittest.mock import patch
|
||||||
|
|
||||||
from libxmp import XMPMeta
|
from .fixtures import HAS_PYTHON_XMP_TOOLKIT, OPJ_DATA_ROOT
|
||||||
|
if HAS_PYTHON_XMP_TOOLKIT:
|
||||||
|
from libxmp import XMPMeta
|
||||||
|
|
||||||
import glymur
|
import glymur
|
||||||
from glymur import Jp2k
|
from glymur import Jp2k
|
||||||
|
|
|
||||||
|
|
@ -30,13 +30,14 @@ import warnings
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import pkg_resources
|
import pkg_resources
|
||||||
|
|
||||||
import libxmp
|
|
||||||
from libxmp import XMPMeta
|
|
||||||
|
|
||||||
import glymur
|
import glymur
|
||||||
from glymur import Jp2k
|
from glymur import Jp2k
|
||||||
|
|
||||||
from .fixtures import OPENJP2_IS_V2_OFFICIAL
|
from .fixtures import HAS_PYTHON_XMP_TOOLKIT, OPENJP2_IS_V2_OFFICIAL
|
||||||
|
if HAS_PYTHON_XMP_TOOLKIT:
|
||||||
|
import libxmp
|
||||||
|
from libxmp import XMPMeta
|
||||||
|
|
||||||
from .fixtures import OPJ_DATA_ROOT, opj_data_file
|
from .fixtures import OPJ_DATA_ROOT, opj_data_file
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -362,6 +363,8 @@ class TestJp2k(unittest.TestCase):
|
||||||
self.assertEqual(ET.tostring(jp2k.box[3].xml.getroot()),
|
self.assertEqual(ET.tostring(jp2k.box[3].xml.getroot()),
|
||||||
b'<test>this is a test</test>')
|
b'<test>this is a test</test>')
|
||||||
|
|
||||||
|
@unittest.skipIf(not HAS_PYTHON_XMP_TOOLKIT,
|
||||||
|
"Requires Python XMP Toolkit >= 2.0")
|
||||||
def test_xmp_attribute(self):
|
def test_xmp_attribute(self):
|
||||||
"""Verify the XMP packet in the shipping example file can be read."""
|
"""Verify the XMP packet in the shipping example file can be read."""
|
||||||
j = Jp2k(self.jp2file)
|
j = Jp2k(self.jp2file)
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,12 @@
|
||||||
# This file is part of glymur, a Python interface for accessing JPEG 2000.
|
"""
|
||||||
#
|
This file is part of glymur, a Python interface for accessing JPEG 2000.
|
||||||
# http://glymur.readthedocs.org
|
|
||||||
#
|
http://glymur.readthedocs.org
|
||||||
# Copyright 2013 John Evans
|
|
||||||
#
|
Copyright 2013 John Evans
|
||||||
# License: MIT
|
|
||||||
|
License: MIT
|
||||||
|
"""
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue