From 658b61672ccfc52be93162ee2a628686d81c9905 Mon Sep 17 00:00:00 2001 From: John Evans Date: Thu, 8 Aug 2013 17:37:02 -0400 Subject: [PATCH 01/20] pylint work --- glymur/jp2box.py | 202 +++++++++++++++++++++++++++++------------------ 1 file changed, 124 insertions(+), 78 deletions(-) diff --git a/glymur/jp2box.py b/glymur/jp2box.py index 5bbe733..e6e811c 100644 --- a/glymur/jp2box.py +++ b/glymur/jp2box.py @@ -24,6 +24,7 @@ import uuid import warnings import xml.etree.cElementTree as ET if sys.hexversion < 0x02070000: + # pylint: disable=F0401,E0611 from ordereddict import OrderedDict from xml.etree.cElementTree import XMLParserError as ParseError else: @@ -361,7 +362,8 @@ class _ICCProfile(object): header['Connection Space'] = data data = struct.unpack('>HHHHHH', self._raw_buffer[24:36]) - header['Datetime'] = datetime.datetime(*data) + header['Datetime'] = datetime.datetime(data[0], data[1], data[2], + data[3], data[4], data[5]) header['File Signature'] = read_buffer[36:40].decode('utf-8') if read_buffer[40:44] == b'\x00\x00\x00\x00': header['Platform'] = 'unrecognized' @@ -369,10 +371,9 @@ class _ICCProfile(object): header['Platform'] = read_buffer[40:44].decode('utf-8') fval, = struct.unpack('>I', read_buffer[44:48]) - flags = 'embedded, ' if fval & 0x01 else 'not embedded, ' - flags += 'cannot ' if fval & 0x02 else 'can ' - flags += 'be used independently' - header['Flags'] = flags + flags = "{0}embedded, {1} be used independently" + header['Flags'] = flags.format('' if fval & 0x01 else 'not ', + 'cannot' if fval & 0x02 else 'can') header['Device Manufacturer'] = read_buffer[48:52].decode('utf-8') if read_buffer[52:56] == b'\x00\x00\x00\x00': @@ -382,11 +383,11 @@ class _ICCProfile(object): header['Device Model'] = device_model val, = struct.unpack('>Q', read_buffer[56:64]) - attr = 'transparency, ' if val & 0x01 else 'reflective, ' - attr += 'matte, ' if val & 0x02 else 'glossy, ' - attr += 'negative ' if val & 0x04 else 'positive ' - attr += 'media polarity, ' - attr += 'black and white media' if val & 0x08 else 'color media' + attr = "{0}, {1}, {2} media polarity, {3} media" + attr = attr.format('transparency' if val & 0x01 else 'reflective', + 'matte' if val & 0x02 else 'glossy', + 'negative' if val & 0x04 else 'positive', + 'black and white' if val & 0x08 else 'color') header['Device Attributes'] = attr rval, = struct.unpack('>I', read_buffer[64:68]) @@ -1233,9 +1234,13 @@ class PaletteBox(Jp2kBox): # Need to determine bps and signed or not read_buffer = fptr.read(num_columns) - data = struct.unpack('>' + 'B' * num_columns, read_buffer) - bps = [((x & 0x07f) + 1) for x in data] - signed = [((x & 0x80) > 1) for x in data] + #data = struct.unpack('>' + 'B' * num_columns, read_buffer) + bps = [((x & 0x07f) + 1) for x in read_buffer] + signed = [((x & 0x80) > 1) for x in read_buffer] + + # Each palette component is padded out to the next largest byte. + # That means a list comprehension does this in one shot. + row_nbytes = sum([math.ceil(x/8) for x in bps]) # Form the format string so that we can intelligently unpack the # colormap. We have to do this because it is possible that the @@ -1243,37 +1248,45 @@ class PaletteBox(Jp2kBox): # # This means that we store the palette as a list of 1D arrays, # which reverses the usual indexing scheme. - palette = [] - fmt = '>' - row_nbytes = 0 - for j in range(num_columns): - if bps[j] <= 8: - fmt += 'B' - row_nbytes += 1 - palette.append(np.zeros(num_entries, dtype=np.uint8)) - elif bps[j] <= 16: - fmt += 'H' - row_nbytes += 2 - palette.append(np.zeros(num_entries, dtype=np.uint16)) - elif bps[j] <= 32: - fmt += 'I' - row_nbytes += 4 - palette.append(np.zeros(num_entries, dtype=np.uint32)) - else: - msg = 'Unsupported palette bitdepth (%d).'.format(bps[j]) - raise IOError(msg) read_buffer = fptr.read(num_entries * row_nbytes) - - for j in range(num_entries): - row_buffer = read_buffer[(row_nbytes * j):(row_nbytes * (j + 1))] - row = struct.unpack(fmt, row_buffer) - for k in range(num_columns): - palette[k][j] = row[k] + palette = buffer2palette(read_buffer, num_entries, num_columns, bps) box = PaletteBox(palette, bps, signed, length=length, offset=offset) return box +def buffer2palette(read_buffer, num_rows, num_cols, bps): + """Construct the palette from the buffer read from file. + """ + row_nbytes = 0 + palette = [] + fmt = '>' + for j in range(num_cols): + if bps[j] <= 8: + row_nbytes += 1 + fmt += 'B' + palette.append(np.zeros(num_rows, dtype=np.uint8)) + elif bps[j] <= 16: + row_nbytes += 2 + fmt += 'H' + palette.append(np.zeros(num_rows, dtype=np.uint16)) + elif bps[j] <= 32: + row_nbytes += 4 + fmt += 'I' + palette.append(np.zeros(num_rows, dtype=np.uint32)) + else: + msg = 'Unsupported palette bitdepth (%d).'.format(bps[j]) + raise IOError(msg) + + + for j in range(num_rows): + row_buffer = read_buffer[(row_nbytes * j):(row_nbytes * (j + 1))] + row = struct.unpack(fmt, row_buffer) + for k in range(num_cols): + palette[k][j] = row[k] + + return palette + # Map rreq codes to display text. _READER_REQUIREMENTS_DISPLAY = { 0: 'File not completely understood', @@ -1434,52 +1447,18 @@ class ReaderRequirementsBox(Jp2kBox): """ read_buffer = fptr.read(1) mask_length, = struct.unpack('>B', read_buffer) - if mask_length == 1: - mask_format = 'B' - elif mask_length == 2: - mask_format = 'H' - elif mask_length == 4: - mask_format = 'I' - else: - msg = 'Unhandled reader requirements box mask length (%d).' - msg %= mask_length - raise RuntimeError(msg) # Fully Understands Aspect Mask # Decodes Completely Mask read_buffer = fptr.read(2 * mask_length) - data = struct.unpack('>' + mask_format * 2, read_buffer) - fuam = data[0] - dcm = data[1] - read_buffer = fptr.read(2) - num_standard_flags, = struct.unpack('>H', read_buffer) + # The mask length tells us the format string to use when unpacking + # from the buffer read from file. + mask_format = {1: 'B', 2: 'H', 4: 'I'}[mask_length] + fuam, dcm = struct.unpack('>' + mask_format * 2, read_buffer) - # Read in standard flags and standard masks. Each standard flag should - # be two bytes, but the standard mask flag is as long as specified by - # the mask length. - read_buffer = fptr.read(num_standard_flags * (2 + mask_length)) - data = struct.unpack('>' + ('H' + mask_format) * num_standard_flags, - read_buffer) - standard_flag = data[0:num_standard_flags * 2:2] - standard_mask = data[1:num_standard_flags * 2:2] - - # Vendor features - read_buffer = fptr.read(2) - num_vendor_features, = struct.unpack('>H', read_buffer) - - # Each vendor feature consists of a 16-byte UUID plus a mask whose - # length is specified by, you guessed it, "mask_length". - entry_length = 16 + mask_length - read_buffer = fptr.read(num_vendor_features * entry_length) - vendor_feature = [] - vendor_mask = [] - for j in range(num_vendor_features): - ubuffer = read_buffer[j * entry_length:(j + 1) * entry_length] - vendor_feature.append(uuid.UUID(bytes=ubuffer[0:16])) - - vmask = struct.unpack('>' + mask_format, ubuffer[16:]) - vendor_mask.append(vmask) + standard_flag, standard_mask = _parse_standard_flag(fptr, mask_length) + vendor_feature, vendor_mask = _parse_vendor_features(fptr, mask_length) box = ReaderRequirementsBox(fuam, dcm, standard_flag, standard_mask, vendor_feature, vendor_mask, @@ -1487,6 +1466,73 @@ class ReaderRequirementsBox(Jp2kBox): return box +def _parse_standard_flag(fptr, mask_length): + """Construct standard flag, standard mask data from the file. + + Specifically working on Reader Requirements box. + + Parameters + ---------- + fptr : file object + File object for JP2K file. + mask_length : int + Length of standard mask flag + """ + # The mask length tells us the format string to use when unpacking + # from the buffer read from file. + mask_format = {1: 'B', 2: 'H', 4: 'I'}[mask_length] + + read_buffer = fptr.read(2) + num_standard_flags, = struct.unpack('>H', read_buffer) + + # Read in standard flags and standard masks. Each standard flag should + # be two bytes, but the standard mask flag is as long as specified by + # the mask length. + read_buffer = fptr.read(num_standard_flags * (2 + mask_length)) + + fmt = '>' + ('H' + mask_format) * num_standard_flags + data = struct.unpack(fmt, read_buffer) + + standard_flag = data[0:num_standard_flags * 2:2] + standard_mask = data[1:num_standard_flags * 2:2] + + return standard_flag, standard_mask + +def _parse_vendor_features(fptr, mask_length): + """Construct vendor features, vendor mask data from the file. + + Specifically working on Reader Requirements box. + + Parameters + ---------- + fptr : file object + File object for JP2K file. + mask_length : int + Length of vendor mask flag + """ + # The mask length tells us the format string to use when unpacking + # from the buffer read from file. + mask_format = {1: 'B', 2: 'H', 4: 'I'}[mask_length] + + read_buffer = fptr.read(2) + num_vendor_features, = struct.unpack('>H', read_buffer) + + # Each vendor feature consists of a 16-byte UUID plus a mask whose + # length is specified by, you guessed it, "mask_length". + entry_length = 16 + mask_length + read_buffer = fptr.read(num_vendor_features * entry_length) + vendor_feature = [] + vendor_mask = [] + for j in range(num_vendor_features): + ubuffer = read_buffer[j * entry_length:(j + 1) * entry_length] + vendor_feature.append(uuid.UUID(bytes=ubuffer[0:16])) + + vmask = struct.unpack('>' + mask_format, ubuffer[16:]) + vendor_mask.append(vmask) + + return vendor_feature, vendor_mask + + class ResolutionBox(Jp2kBox): """Container for Resolution superbox information. From 77a601b4deb520a37eaaebeb78cd804c3e3bde15 Mon Sep 17 00:00:00 2001 From: John Evans Date: Thu, 8 Aug 2013 18:23:31 -0400 Subject: [PATCH 02/20] pylint work, #99 --- glymur/jp2k.py | 265 +++++++++++++++++++++++++------------------------ 1 file changed, 135 insertions(+), 130 deletions(-) diff --git a/glymur/jp2k.py b/glymur/jp2k.py index ff3b92a..0d61ae1 100644 --- a/glymur/jp2k.py +++ b/glymur/jp2k.py @@ -582,72 +582,7 @@ class Jp2k(Jp2kBox): num_components=num_components), ColourSpecificationBox(colorspace=SRGB)] - # Check for a bad sequence of boxes. - # 1st two boxes must be 'jP ' and 'ftyp' - if boxes[0].box_id != 'jP ' or boxes[1].box_id != 'ftyp': - msg = "The first box must be the signature box and the second " - msg += "must be the file type box." - raise IOError(msg) - - # jp2c must be preceeded by jp2h - jp2h_lst = [idx for (idx, box) in enumerate(boxes) - if box.box_id == 'jp2h'] - jp2h_idx = jp2h_lst[0] - jp2c_lst = [idx for (idx, box) in enumerate(boxes) - if box.box_id == 'jp2c'] - if len(jp2c_lst) == 0: - msg = "A codestream box must be defined in the outermost " - msg += "list of boxes." - raise IOError(msg) - - jp2c_idx = jp2c_lst[0] - if jp2h_idx >= jp2c_idx: - msg = "The codestream box must be preceeded by a jp2 header box." - raise IOError(msg) - - # 1st jp2 header box must be ihdr - jp2h = boxes[jp2h_idx] - if jp2h.box[0].box_id != 'ihdr': - msg = "The first box in the jp2 header box must be the image " - msg += "header box." - raise IOError(msg) - - # colr must be present in jp2 header box. - colr_lst = [j for (j, box) in enumerate(jp2h.box) - if box.box_id == 'colr'] - if len(colr_lst) == 0: - msg = "The jp2 header box must contain a color definition box." - raise IOError(msg) - colr = jp2h.box[colr_lst[0]] - - # Any cdef box must be in the jp2 header following the image header. - cdef_lst = [j for (j, box) in enumerate(boxes) if box.box_id == 'cdef'] - if len(cdef_lst) != 0: - msg = "Any channel defintion box must be in the JP2 header " - msg += "following the image header." - raise IOError(msg) - - cdef_lst = [j for (j, box) in enumerate(jp2h.box) - if box.box_id == 'cdef'] - if len(cdef_lst) > 1: - msg = "Only one channel definition box is allowed in the " - msg += "JP2 header." - raise IOError(msg) - elif len(cdef_lst) == 1: - cdef = jp2h.box[cdef_lst[0]] - assn = cdef.association - typ = cdef.channel_type - if colr.colorspace == SRGB: - if any([chan + 1 not in assn or typ[chan] != 0 - for chan in [0, 1, 2]]): - msg = "All color channels must be defined in the " - msg += "channel definition box." - raise IOError(msg) - elif colr.colorspace == GREYSCALE: - if 0 not in typ: - msg = "All color channels must be defined in the " - msg += "channel definition box." - raise IOError(msg) + _validate_jp2_box_sequence(boxes) with open(filename, 'wb') as ofile: for box in boxes: @@ -740,6 +675,18 @@ class Jp2k(Jp2kBox): "using this functionality.") return img + def _subsampling_sanity_check(self): + """Check for differing subsample factors. + """ + codestream = self.get_codestream(header_only=True) + dxs = np.array(codestream.segment[1].xrsiz) + dys = np.array(codestream.segment[1].yrsiz) + if np.any(dxs - dxs[0]) or np.any(dys - dys[0]): + msg = "Components must all have the same subsampling factors " + msg += "to use this method. Please consider using OPENJP2 and " + msg += "the read_bands method instead." + raise RuntimeError(msg) + def _read_openjpeg(self, rlevel=0, verbose=False): """Read a JPEG 2000 image using libopenjpeg. @@ -761,15 +708,7 @@ class Jp2k(Jp2kBox): RuntimeError If the image has differing subsample factors. """ - # Check for differing subsample factors. - codestream = self.get_codestream(header_only=True) - dxs = np.array(codestream.segment[1].xrsiz) - dys = np.array(codestream.segment[1].yrsiz) - if np.any(dxs - dxs[0]) or np.any(dys - dys[0]): - msg = "Components must all have the same subsampling factors " - msg += "to use this method with OpenJPEG 1.5.1. Please consider " - msg += "using OPENJP2 instead." - raise RuntimeError(msg) + self._subsampling_sanity_check() with ExitStack() as stack: # Set decoding parameters. @@ -808,20 +747,7 @@ class Jp2k(Jp2kBox): ncomps = image.contents.numcomps component = image.contents.comps[0] - if component.sgnd: - if component.prec <= 8: - dtype = np.int8 - elif component.prec <= 16: - dtype = np.int16 - else: - raise RuntimeError("Unhandled precision, datatype") - else: - if component.prec <= 8: - dtype = np.uint8 - elif component.prec <= 16: - dtype = np.uint16 - else: - raise RuntimeError("Unhandled precision, datatype") + dtype = component2dtype(component) nrows = image.contents.comps[0].h ncols = image.contents.comps[0].w @@ -833,12 +759,7 @@ class Jp2k(Jp2kBox): nrows = component.h ncols = component.w - if nrows == 0 or ncols == 0: - # Letting this situation continue would segfault - # Python. - msg = "Component {0} has dimensions {1} x {2}" - msg = msg.format(k, nrows, ncols) - raise IOError(msg) + _validate_nonzero_image_size(nrows, ncols, k) addr = ctypes.addressof(component.data.contents) with warnings.catch_warnings(): @@ -884,13 +805,7 @@ class Jp2k(Jp2kBox): RuntimeError If the image has differing subsample factors. """ - # Check for differing subsample factors. - codestream = self.get_codestream(header_only=True) - dxs = np.array(codestream.segment[1].xrsiz) - dys = np.array(codestream.segment[1].yrsiz) - if np.any(dxs - dxs[0]) or np.any(dys - dys[0]): - msg = "Components must all have the same subsampling factors." - raise RuntimeError(msg) + self._subsampling_sanity_check() img_array = self._read_common(rlevel=rlevel, layer=layer, @@ -948,14 +863,10 @@ class Jp2k(Jp2kBox): dparam.cp_reduce = rlevel if area is not None: - if area[0] < 0 or area[1] < 0: - msg = "Upper left corner coordinates must be nonnegative: {0}" - msg = msg.format(area) - raise IOError(msg) - if area[2] <= 0 or area[3] <= 0: - msg = "Lower right corner coordinates must be positive: {0}" - msg = msg.format(area) - raise IOError(msg) + if area[0] < 0 or area[1] < 0 or area[2] <= 0 or area[3] <= 0: + msg = "Upper left corner coordinates must be nonnegative and " + msg += "lower right corner coordinates must be positive: {0}" + raise IOError(msg.format(area)) dparam.DA_y0 = area[0] dparam.DA_x0 = area[1] dparam.DA_y1 = area[2] @@ -1001,20 +912,7 @@ class Jp2k(Jp2kBox): _opj2.end_decompress(codec, stream) component = image.contents.comps[0] - if component.sgnd: - if component.prec <= 8: - dtype = np.int8 - elif component.prec <= 16: - dtype = np.int16 - else: - raise RuntimeError("Unhandled precision, datatype") - else: - if component.prec <= 8: - dtype = np.uint8 - elif component.prec <= 16: - dtype = np.uint16 - else: - raise RuntimeError("Unhandled precision, datatype") + dtype = component2dtype(component) if as_bands: data = [] @@ -1029,12 +927,7 @@ class Jp2k(Jp2kBox): nrows = component.h ncols = component.w - if nrows == 0 or ncols == 0: - # Letting this situation continue would segfault - # Python. - msg = "Component {0} has dimensions {1} x {2}" - msg = msg.format(k, nrows, ncols) - raise IOError(msg) + _validate_nonzero_image_size(nrows, ncols, k) addr = ctypes.addressof(component.data.contents) with warnings.catch_warnings(): @@ -1165,3 +1058,115 @@ class Jp2k(Jp2kBox): header_only=header_only) return codestream + +def component2dtype(component): + """Take an OpenJPEG component structure and determine the numpy datatype. + + Parameters + ---------- + component : ctypes pointer to ImageCompType (image_comp_t) + single image component structure. + + Returns + ------- + dtype : builtins.type + numpy datatype to be used to construct an image array. + """ + if component.sgnd: + if component.prec <= 8: + dtype = np.int8 + elif component.prec <= 16: + dtype = np.int16 + else: + raise RuntimeError("Unhandled precision, datatype") + else: + if component.prec <= 8: + dtype = np.uint8 + elif component.prec <= 16: + dtype = np.uint16 + else: + raise RuntimeError("Unhandled precision, datatype") + + return dtype + + +def _validate_nonzero_image_size(nrows, ncols, component_index): + """The image cannot have area of zero. + """ + if nrows == 0 or ncols == 0: + # Letting this situation continue would segfault Python. + msg = "Component {0} has dimensions {1} x {2}" + msg = msg.format(component_index, nrows, ncols) + raise IOError(msg) + +def _validate_jp2_box_sequence(boxes): + """Run through series of tests for JP2 box legality. + + This is non-exhaustive. + """ + # Check for a bad sequence of boxes. + # 1st two boxes must be 'jP ' and 'ftyp' + if boxes[0].box_id != 'jP ' or boxes[1].box_id != 'ftyp': + msg = "The first box must be the signature box and the second " + msg += "must be the file type box." + raise IOError(msg) + + # jp2c must be preceeded by jp2h + jp2h_lst = [idx for (idx, box) in enumerate(boxes) + if box.box_id == 'jp2h'] + jp2h_idx = jp2h_lst[0] + jp2c_lst = [idx for (idx, box) in enumerate(boxes) + if box.box_id == 'jp2c'] + if len(jp2c_lst) == 0: + msg = "A codestream box must be defined in the outermost " + msg += "list of boxes." + raise IOError(msg) + + jp2c_idx = jp2c_lst[0] + if jp2h_idx >= jp2c_idx: + msg = "The codestream box must be preceeded by a jp2 header box." + raise IOError(msg) + + # 1st jp2 header box must be ihdr + jp2h = boxes[jp2h_idx] + if jp2h.box[0].box_id != 'ihdr': + msg = "The first box in the jp2 header box must be the image " + msg += "header box." + raise IOError(msg) + + # colr must be present in jp2 header box. + colr_lst = [j for (j, box) in enumerate(jp2h.box) + if box.box_id == 'colr'] + if len(colr_lst) == 0: + msg = "The jp2 header box must contain a color definition box." + raise IOError(msg) + colr = jp2h.box[colr_lst[0]] + + # Any cdef box must be in the jp2 header following the image header. + cdef_lst = [j for (j, box) in enumerate(boxes) if box.box_id == 'cdef'] + if len(cdef_lst) != 0: + msg = "Any channel defintion box must be in the JP2 header " + msg += "following the image header." + raise IOError(msg) + + cdef_lst = [j for (j, box) in enumerate(jp2h.box) + if box.box_id == 'cdef'] + if len(cdef_lst) > 1: + msg = "Only one channel definition box is allowed in the " + msg += "JP2 header." + raise IOError(msg) + elif len(cdef_lst) == 1: + cdef = jp2h.box[cdef_lst[0]] + if colr.colorspace == SRGB: + if any([chan + 1 not in cdef.association + or cdef.channel_type[chan] != 0 + for chan in [0, 1, 2]]): + msg = "All color channels must be defined in the " + msg += "channel definition box." + raise IOError(msg) + elif colr.colorspace == GREYSCALE: + if 0 not in cdef.channel_type: + msg = "All color channels must be defined in the " + msg += "channel definition box." + raise IOError(msg) + From bf24e9b280b3b962ed845dd1e1b9439cdd7266fd Mon Sep 17 00:00:00 2001 From: jevans Date: Fri, 9 Aug 2013 23:11:03 -0400 Subject: [PATCH 03/20] pylint work, #99 --- glymur/jp2box.py | 8 +- glymur/jp2k.py | 689 ++++++++++++++++++++++++++++------------------- 2 files changed, 417 insertions(+), 280 deletions(-) diff --git a/glymur/jp2box.py b/glymur/jp2box.py index e6e811c..56021b9 100644 --- a/glymur/jp2box.py +++ b/glymur/jp2box.py @@ -1234,13 +1234,13 @@ class PaletteBox(Jp2kBox): # Need to determine bps and signed or not read_buffer = fptr.read(num_columns) - #data = struct.unpack('>' + 'B' * num_columns, read_buffer) - bps = [((x & 0x07f) + 1) for x in read_buffer] - signed = [((x & 0x80) > 1) for x in read_buffer] + data = struct.unpack('>' + 'B' * num_columns, read_buffer) + bps = [((x & 0x07f) + 1) for x in data] + signed = [((x & 0x80) > 1) for x in data] # Each palette component is padded out to the next largest byte. # That means a list comprehension does this in one shot. - row_nbytes = sum([math.ceil(x/8) for x in bps]) + row_nbytes = sum([int(math.ceil(x/8.0)) for x in bps]) # Form the format string so that we can intelligently unpack the # colormap. We have to do this because it is possible that the diff --git a/glymur/jp2k.py b/glymur/jp2k.py index 0d61ae1..0785178 100644 --- a/glymur/jp2k.py +++ b/glymur/jp2k.py @@ -187,36 +187,147 @@ class Jp2k(Jp2kBox): msg += "profile if the file type box brand is 'jp2 '." warnings.warn(msg) - def _validate_write_parameters(self, img_array, code_block_size, - precinct_sizes, cratios, psnr, colorspace, - codec_fmt): - """Check that the input parameters to the write function are valid. + #def _populate_cparams(self, cbsize, cratios, eph, grid_offset, modesw, + # numres, prog, psnr, psizes, sop, subsam, tilesize): + def _populate_cparams(self, **kwargs): + """Populate compression parameters structure from input arguments. + Parameters + ---------- + cbsize : tuple, optional + Code block size (DY, DX). + cratios : iterable + Compression ratios for successive layers. + eph : bool, optional + If true, write SOP marker after each header packet. + grid_offset : tuple, optional + Offset (DY, DX) of the origin of the image in the reference grid. + mct : bool, optional + Specifies usage of the multi component transform. If not + specified, defaults to True if the colorspace is RGB. + modesw : int, optional + Mode switch. + 1 = BYPASS(LAZY) + 2 = RESET + 4 = RESTART(TERMALL) + 8 = VSC + 16 = ERTERM(SEGTERM) + 32 = SEGMARK(SEGSYM) + numres : int, optional + Number of resolutions. + prog : str, optional + Progression order, one of "LRCP" "RLCP", "RPCL", "PCRL", "CPRL". + psnr : iterable, optional + Different PSNR for successive layers. + psizes : list, optional + List of precinct sizes. Each precinct size tuple is defined in + (height x width). + sop : bool, optional + If true, write SOP marker before each packet. + subsam : tuple, optional + Subsampling factors (dy, dx). + tilesize : tuple, optional + Numeric tuple specifying tile size in terms of (numrows, numcols), + not (X, Y). + + Returns + ------- + cparams : CompressionParametersType(ctypes.Structure) + Corresponds to cparameters_t type in openjp2 headers. + """ + + cparams = _opj2.set_default_encoder_parameters() + + outfile = self.filename.encode() + num_pad_bytes = _opj2.PATH_LEN - len(outfile) + outfile += b'0' * num_pad_bytes + cparams.outfile = outfile + + if self.filename[-4:].lower() == '.jp2': + cparams.codec_fmt = _opj2.CODEC_JP2 + else: + cparams.codec_fmt = _opj2.CODEC_J2K + + # Set defaults to lossless to begin. + cparams.tcp_rates[0] = 0 + cparams.tcp_numlayers = 1 + cparams.cp_disto_alloc = 1 + + if 'cbsize' in kwargs: + cparams.cblockw_init = kwargs['cbsize'][1] + cparams.cblockh_init = kwargs['cbsize'][0] + + if 'cratios' in kwargs: + cparams.tcp_numlayers = len(kwargs['cratios']) + for j, cratio in enumerate(kwargs['cratios']): + cparams.tcp_rates[j] = cratio + cparams.cp_disto_alloc = 1 + + if 'eph' in kwargs: + cparams.csty |= 0x04 + + if 'grid_offset' in kwargs: + cparams.image_offset_x0 = kwargs['grid_offset'][1] + cparams.image_offset_y0 = kwargs['grid_offset'][0] + + if 'modesw' in kwargs: + for shift in range(6): + power_of_two = 1 << shift + if kwargs['modesw'] & power_of_two: + cparams.mode |= power_of_two + + if 'numres' in kwargs: + cparams.numresolution = kwargs['numres'] + + if 'prog' in kwargs: + prog = kwargs['prog'].upper() + cparams.prog_order = PROGRESSION_ORDER[prog] + + if 'psnr' in kwargs: + cparams.tcp_numlayers = len(kwargs['psnr']) + for j, snr_layer in enumerate(kwargs['psnr']): + cparams.tcp_distoratio[j] = snr_layer + cparams.cp_fixed_quality = 1 + + if 'psizes' in kwargs: + for j, (prch, prcw) in enumerate(kwargs['psizes']): + cparams.prcw_init[j] = prcw + cparams.prch_init[j] = prch + cparams.csty |= 0x01 + cparams.res_spec = len(kwargs['psizes']) + + if 'sop' in kwargs: + cparams.csty |= 0x02 + + if 'subsam' in kwargs: + cparams.subsampling_dy = kwargs['subsam'][0] + cparams.subsampling_dx = kwargs['subsam'][1] + + if 'tilesize' in kwargs: + cparams.cp_tdx = kwargs['tilesize'][1] + cparams.cp_tdy = kwargs['tilesize'][0] + cparams.tile_size_on = _opj2.TRUE + + return cparams + + def _validate_compression_params(self, img_array, cparams): + """Check that the compression parameters are valid. + Parameters ---------- img_array : ndarray Image data to be written to file. - code_block_size : tuple - Code block size (DY, DX). - precinct_sizes : list - List of precinct sizes. Each precinct size tuple is defined in - (height x width). - cratios : iterable - Compression ratios for successive layers. - psnr : iterable - Different PSNR for successive layers. - mct : bool - Specifies usage of the multi component transform. If not - specified, defaults to True if the colorspace is RGB. - colorspace : str, optional - Either 'rgb' or 'gray'. - codec_fmt : int - Are we writing a JP2 file or a J2K file? + cparams : CompressionParametersType(ctypes.Structure) + Corresponds to cparameters_t type in openjp2 headers. """ - # Validate code block size and precinct sizes. - if code_block_size is not None: - width = code_block_size[1] - height = code_block_size[0] + + # Code block size + code_block_specified = False + if cparams.cblockw_init != 0 and cparams.cblockh_init != 0: + # These fields ARE zero if uninitialized. + width = cparams.cblockw_init + height = cparams.cblockh_init + code_block_specified = True if height * width > 4096 or height < 4 or width < 4: msg = "Code block area cannot exceed 4096. " msg += "Code block height and width must be larger than 4." @@ -226,12 +337,16 @@ class Jp2k(Jp2kBox): msg = "Bad code block size ({0}, {1}), " msg += "must be powers of 2." raise IOError(msg.format(height, width)) - - if precinct_sizes is not None: - for j, (prch, prcw) in enumerate(precinct_sizes): - if j == 0 and code_block_size is not None: - cblkh, cblkw = code_block_size - if cblkh * 2 > prch or cblkw * 2 > prcw: + + # Precinct size + if cparams.res_spec != 0: + # precinct size was not specified if this field is zero. + for j in range(cparams.res_spec): + prch = cparams.prch_init[j] + prcw = cparams.prcw_init[j] + if j == 0 and code_block_specified: + height, width = cparams.cblockh_init, cparams.cblockw_init + if height * 2 > prch or width * 2 > prcw: msg = "Highest Resolution precinct size must be at " msg += "least twice that of the code block dimensions." raise IOError(msg) @@ -240,16 +355,12 @@ class Jp2k(Jp2kBox): msg = "Bad precinct sizes ({0}, {1}), " msg += "must be powers of 2." raise IOError(msg.format(prch, prcw)) - - if cratios is not None and psnr is not None: - msg = "Cannot specify cratios and psnr together." - raise IOError(msg) - + # What would the point of 1D images be? if img_array.ndim == 1 or img_array.ndim > 3: msg = "{0}D imagery is not allowed.".format(img_array.ndim) raise IOError(msg) - + if _OPENJP2_IS_OFFICIAL_V2: if (((img_array.ndim != 2) and (img_array.shape[2] != 1 and img_array.shape[2] != 3))): @@ -258,28 +369,110 @@ class Jp2k(Jp2kBox): msg += "the OpenJPEG library version is the official 2.0.0 " msg += "release." raise IOError(msg) - - if colorspace is not None: - if codec_fmt == _opj2.CODEC_J2K: - msg = 'Do not specify a colorspace when writing a raw ' - msg += 'codestream.' - raise IOError(msg) - if colorspace.lower() not in ('rgb', 'grey', 'gray'): - msg = 'Invalid colorspace "{0}"'.format(colorspace) - raise IOError(msg) - elif colorspace.lower() == 'rgb' and img_array.shape[2] < 3: - msg = 'RGB colorspace requires at least 3 components.' - raise IOError(msg) - + if img_array.dtype != np.uint8 and img_array.dtype != np.uint16: msg = "Only uint8 and uint16 images are currently supported." raise RuntimeError(msg) + + def _set_multi_component_transform(self, colorspace, cparams, mct=None): + """Set multi component transform usage. - # pylint: disable-msg=W0221 - def write(self, img_array, cratios=None, eph=False, psnr=None, numres=None, - cbsize=None, psizes=None, grid_offset=None, sop=False, - subsam=None, tilesize=None, prog=None, modesw=None, - colorspace=None, verbose=False, mct=None): + Parameters + ---------- + colorspace : int + Either CLRSPC_SRGB or CLRSPC_GRAY + cparams : CompressionParametersType(ctypes.Structure) + Corresponds to cparameters_t type in openjp2 headers. + mct : bool, optional + Specifies usage of the multi component transform. If not + specified, defaults to True if the colorspace is RGB. + """ + if mct is None: + # If the multi component transform was not specified, we infer + # that it should be used if the color space is RGB. + if colorspace == _opj2.CLRSPC_SRGB: + cparams.tcp_mct = 1 + else: + cparams.tcp_mct = 0 + else: + # MCT was specified. Does it make sense? + if mct and colorspace == _opj2.CLRSPC_GRAY: + # Cannot check for this in the validate routine, as we need + # to know what the target colorspace has been determined to be. + msg = "Cannot specify usage of the multi component transform " + msg += "if the colorspace is gray." + raise IOError(msg) + cparams.tcp_mct = 1 if mct else 0 + + def _process_write_inputs(self, img_array, colorspace=None, **kwargs): + """Directs processing of write method arguments. + + It's somewhat awkward to process all the kwargs arguments at once. + The "colorspace" is not a parameter that gets processed into the + compression parameters structure, and it unfortunately must be handled + in the middle of the compression parameter processing. + + Parameters + ---------- + + Returns + ------- + cparams : CompressionParametersType(ctypes.Structure) + Corresponds to cparameters_t type in openjp2 headers. + colorspace : int + Either CLRSPC_SRGB or CLRSPC_GRAY + """ + + if 'cratios' in kwargs and 'psnr' in kwargs: + msg = "Cannot specify cratios and psnr together." + raise IOError(msg) + + cparams = self._populate_cparams(**kwargs) + self._validate_compression_params(img_array, cparams) + + colorspace = _unpack_colorspace(colorspace, img_array, cparams) + + try: + mct = kwargs['mct'] + except KeyError: + mct = None + self._set_multi_component_transform(colorspace, cparams, mct) + + return cparams, colorspace + + def _populate_image_struct(self, cparams, image, imgdata): + """Populates image struct needed for compression. + + Parameters + ---------- + cparams : CompressionParametersType(ctypes.Structure) + Corresponds to cparameters_t type in openjp2 headers. + image : ImageType(ctypes.Structure) + Corresponds to image_t type in openjp2 headers. + imgarray : ndarray + Image data to be written to file. + """ + + numrows, numcols, num_comps = imgdata.shape + + # set image offset and reference grid + image.contents.x0 = cparams.image_offset_x0 + image.contents.y0 = cparams.image_offset_y0 + image.contents.x1 = (image.contents.x0 + + (numcols - 1) * cparams.subsampling_dx + 1) + image.contents.y1 = (image.contents.y0 + + (numrows - 1) * cparams.subsampling_dy + 1) + + # Stage the image data to the openjpeg data structure. + for k in range(0, num_comps): + layer = np.ascontiguousarray(imgdata[:, :, k], dtype=np.int32) + dest = image.contents.comps[k].data + src = layer.ctypes.data + ctypes.memmove(dest, src, layer.nbytes) + + return image + + def write(self, img_array, verbose=False, **kwargs): """Write image data to a JP2/JPX/J2k file. Intended usage of the various parameters follows that of OpenJPEG's opj_compress utility. @@ -290,11 +483,6 @@ class Jp2k(Jp2kBox): ---------- img_array : ndarray Image data to be written to file. - callbacks : bool, optional - If true, enable default info handler such that INFO messages - produced by the OpenJPEG library are output to the console. By - default, OpenJPEG warning and error messages are captured by - Python's own warning and error mechanisms. cbsize : tuple, optional Code block size (DY, DX). colorspace : str, optional @@ -356,128 +544,17 @@ class Jp2k(Jp2kBox): "installed before using this " "functionality.") - if self.filename[-4:].lower() == '.jp2': - codec_fmt = _opj2.CODEC_JP2 - else: - codec_fmt = _opj2.CODEC_J2K - - self._validate_write_parameters(img_array, cbsize, psizes, cratios, - psnr, colorspace, codec_fmt) - - cparams = _opj2.set_default_encoder_parameters() - - outfile = self.filename.encode() - num_pad_bytes = _opj2.PATH_LEN - len(outfile) - outfile += b'0' * num_pad_bytes - cparams.outfile = outfile - - cparams.cod_format = codec_fmt - - # Set defaults to lossless to begin. - cparams.tcp_rates[0] = 0 - cparams.tcp_numlayers = 1 - cparams.cp_disto_alloc = 1 - - if cbsize is not None: - width = cbsize[1] - height = cbsize[0] - cparams.cblockw_init = width - cparams.cblockh_init = height - - if cratios is not None: - cparams.tcp_numlayers = len(cratios) - for j, cratio in enumerate(cratios): - cparams.tcp_rates[j] = cratio - cparams.cp_disto_alloc = 1 - - if eph: - cparams.csty |= 0x04 - - if grid_offset is not None: - cparams.image_offset_x0 = grid_offset[1] - cparams.image_offset_y0 = grid_offset[0] - - if modesw is not None: - for shift in range(6): - power_of_two = 1 << shift - if modesw & power_of_two: - cparams.mode |= power_of_two - - if numres is not None: - cparams.numresolution = numres - - if prog is not None: - prog = prog.upper() - cparams.prog_order = PROGRESSION_ORDER[prog] - - if psnr is not None: - cparams.tcp_numlayers = len(psnr) - for j, snr_layer in enumerate(psnr): - cparams.tcp_distoratio[j] = snr_layer - cparams.cp_fixed_quality = 1 - - if psizes is not None: - for j, (prch, prcw) in enumerate(psizes): - cparams.prcw_init[j] = prcw - cparams.prch_init[j] = prch - cparams.csty |= 0x01 - cparams.res_spec = len(psizes) - - if sop: - cparams.csty |= 0x02 - - if subsam is not None: - cparams.subsampling_dy = subsam[0] - cparams.subsampling_dx = subsam[1] - - if tilesize is not None: - cparams.cp_tdx = tilesize[1] - cparams.cp_tdy = tilesize[0] - cparams.tile_size_on = _opj2.TRUE + cparams, colorspace = self._process_write_inputs(img_array, **kwargs) if img_array.ndim == 2: - # Force it to be 3D. Just makes things easier later on. + # Force the image to be 3D. Just makes things easier later on. numrows, numcols = img_array.shape img_array = img_array.reshape(numrows, numcols, 1) + # Only two precisions are possible. + comp_prec = 8 if img_array.dtype == np.uint8 else 16 + numrows, numcols, num_comps = img_array.shape - - if colorspace is None: - # Must infer the colorspace from the image dimensions. - if img_array.shape[2] == 1 or img_array.shape[2] == 2: - # A single channel image or an image with two channels is going - # to be greyscale. - colorspace = _opj2.CLRSPC_GRAY - else: - # Anything else must be RGB, right? - colorspace = _opj2.CLRSPC_SRGB - else: - # Turn the colorspace from a string to the enumerated value that - # the library expects. - colorspace = _COLORSPACE_MAP[colorspace.lower()] - - if mct is None: - # If the multi component transform was not specified, we infer - # that it should be used if the color space is RGB. - if colorspace == _opj2.CLRSPC_SRGB: - cparams.tcp_mct = 1 - else: - cparams.tcp_mct = 0 - else: - if mct and colorspace == _opj2.CLRSPC_GRAY: - # Cannot check for this in the validate routine, as we need - # to know what the target colorspace has been determined to be. - msg = "Cannot specify usage of the multi component transform " - msg += "if the colorspace is gray." - raise IOError(msg) - cparams.tcp_mct = 1 if mct else 0 - - if img_array.dtype == np.uint8: - comp_prec = 8 - else: - # We already know it cannot be anything else than uint16. - comp_prec = 16 - comptparms = (_opj2.ImageComptParmType * num_comps)() for j in range(num_comps): comptparms[j].dx = cparams.subsampling_dx @@ -491,37 +568,22 @@ class Jp2k(Jp2kBox): comptparms[j].sgnd = 0 image = _opj2.image_create(comptparms, colorspace) + self._populate_image_struct(cparams, image, img_array) - # set image offset and reference grid - image.contents.x0 = cparams.image_offset_x0 - image.contents.y0 = cparams.image_offset_y0 - image.contents.x1 = (image.contents.x0 + - (numcols - 1) * cparams.subsampling_dx + 1) - image.contents.y1 = (image.contents.y0 + - (numrows - 1) * cparams.subsampling_dy + 1) - - # Stage the image data to the openjpeg data structure. - for k in range(0, num_comps): - layer = np.ascontiguousarray(img_array[:, :, k], dtype=np.int32) - dest = image.contents.comps[k].data - src = layer.ctypes.data - ctypes.memmove(dest, src, layer.nbytes) - - codec = _opj2.create_compress(codec_fmt) - - if verbose: - _opj2.set_info_handler(codec, _INFO_CALLBACK) - else: - _opj2.set_info_handler(codec, None) + codec = _opj2.create_compress(cparams.codec_fmt) + info_handler = _INFO_CALLBACK if verbose else None + _opj2.set_info_handler(codec, info_handler) _opj2.set_warning_handler(codec, _WARNING_CALLBACK) _opj2.set_error_handler(codec, _ERROR_CALLBACK) + _opj2.setup_encoder(codec, cparams, image) if _OPENJP2_IS_OFFICIAL_V2: fptr = _libc.fopen(self.filename, 'wb') strm = _opj2.stream_create_default_file_stream(fptr, False) else: + # This routine introduced in 2.0 devel series. strm = _opj2.stream_create_default_file_stream_v3(self.filename, False) @@ -534,6 +596,7 @@ class Jp2k(Jp2kBox): _opj2.stream_destroy(strm) _libc.fclose(fptr) else: + # This routine introduced in 2.0 devel series. _opj2.stream_destroy_v3(strm) _opj2.destroy_codec(codec) @@ -745,32 +808,11 @@ class Jp2k(Jp2kBox): stack.callback(_opj.destroy_decompress, dinfo) stack.callback(_opj.cio_close, cio) - ncomps = image.contents.numcomps - component = image.contents.comps[0] - dtype = component2dtype(component) - - nrows = image.contents.comps[0].h - ncols = image.contents.comps[0].w - ncomps = image.contents.numcomps - data = np.zeros((nrows, ncols, ncomps), dtype) - - for k in range(image.contents.numcomps): - component = image.contents.comps[k] - nrows = component.h - ncols = component.w - - _validate_nonzero_image_size(nrows, ncols, k) - - addr = ctypes.addressof(component.data.contents) - with warnings.catch_warnings(): - warnings.simplefilter("ignore") - nelts = nrows * ncols - band = np.ctypeslib.as_array( - (ctypes.c_int32 * nelts).from_address(addr)) - data[:, :, k] = np.reshape(band.astype(dtype), - (nrows, ncols)) + data = extract_image_cube(image) if data.shape[2] == 1: + # The third dimension has just a single layer. Make the image + # data 2D instead of 3D. data = data.view() data.shape = data.shape[0:2] @@ -820,6 +862,59 @@ class Jp2k(Jp2kBox): return img_array + def _populate_dparam(self, layer, rlevel, area, tile): + """Populate decompression structure with appropriate input parameters. + + Parameters + ---------- + layer : int, optional + Number of quality layer to decode. + rlevel : int, optional + Factor by which to rlevel output resolution. + area : tuple, optional + Specifies decoding image area, + (first_row, first_col, last_row, last_col) + tile : int, optional + Number of tile to decode. + + Returns + ------- + dparam : DecompressionParametersType (ctypes) + Corresponds to openjp2 decompression parameters structure. + """ + dparam = _opj2.set_default_decoder_parameters() + + infile = self.filename.encode() + nelts = _opj2.PATH_LEN - len(infile) + infile += b'0' * nelts + dparam.infile = infile + + dparam.decod_format = self._codec_format + + dparam.cp_layer = layer + + if rlevel == -1: + # Get the lowest resolution thumbnail. + codestream = self.get_codestream() + rlevel = codestream.segment[2].spcod[4] + dparam.cp_reduce = rlevel + + if area is not None: + if area[0] < 0 or area[1] < 0 or area[2] <= 0 or area[3] <= 0: + msg = "Upper left corner coordinates must be nonnegative and " + msg += "lower right corner coordinates must be positive: {0}" + raise IOError(msg.format(area)) + dparam.DA_y0 = area[0] + dparam.DA_x0 = area[1] + dparam.DA_y1 = area[2] + dparam.DA_x1 = area[3] + + if tile is not None: + dparam.tile_index = tile + dparam.nb_tile_to_decode = 1 + + return dparam + def _read_common(self, rlevel=0, layer=0, area=None, tile=None, verbose=False, as_bands=False): """Read a JPEG 2000 image. @@ -845,36 +940,7 @@ class Jp2k(Jp2kBox): img_array : ndarray The individual image components or a single array. """ - dparam = _opj2.set_default_decoder_parameters() - - infile = self.filename.encode() - nelts = _opj2.PATH_LEN - len(infile) - infile += b'0' * nelts - dparam.infile = infile - - dparam.decod_format = self._codec_format - - dparam.cp_layer = layer - - if rlevel == -1: - # Get the lowest resolution thumbnail. - codestream = self.get_codestream() - rlevel = codestream.segment[2].spcod[4] - - dparam.cp_reduce = rlevel - if area is not None: - if area[0] < 0 or area[1] < 0 or area[2] <= 0 or area[3] <= 0: - msg = "Upper left corner coordinates must be nonnegative and " - msg += "lower right corner coordinates must be positive: {0}" - raise IOError(msg.format(area)) - dparam.DA_y0 = area[0] - dparam.DA_x0 = area[1] - dparam.DA_y1 = area[2] - dparam.DA_x1 = area[3] - - if tile is not None: - dparam.tile_index = tile - dparam.nb_tile_to_decode = 1 + dparam = self._populate_dparam(layer, rlevel, area, tile) with ExitStack() as stack: if hasattr(_opj2.OPENJP2, @@ -911,34 +977,10 @@ class Jp2k(Jp2kBox): _opj2.decode(codec, stream, image) _opj2.end_decompress(codec, stream) - component = image.contents.comps[0] - dtype = component2dtype(component) - if as_bands: - data = [] + data = extract_image_bands(image) else: - nrows = image.contents.comps[0].h - ncols = image.contents.comps[0].w - ncomps = image.contents.numcomps - data = np.zeros((nrows, ncols, ncomps), dtype) - - for k in range(image.contents.numcomps): - component = image.contents.comps[k] - nrows = component.h - ncols = component.w - - _validate_nonzero_image_size(nrows, ncols, k) - - addr = ctypes.addressof(component.data.contents) - with warnings.catch_warnings(): - warnings.simplefilter("ignore") - band = np.ctypeslib.as_array( - (ctypes.c_int32 * nrows * ncols).from_address(addr)) - if as_bands: - data.append(np.reshape(band.astype(dtype), (nrows, ncols))) - else: - data[:, :, k] = np.reshape(band.astype(dtype), - (nrows, ncols)) + data = extract_image_cube(image) return data @@ -1170,3 +1212,98 @@ def _validate_jp2_box_sequence(boxes): msg += "channel definition box." raise IOError(msg) +def extract_image_cube(image): + """Extract 3D image from openjpeg data structure. + """ + ncomps = image.contents.numcomps + component = image.contents.comps[0] + dtype = component2dtype(component) + + nrows = component.h + ncols = component.w + data = np.zeros((nrows, ncols, ncomps), dtype) + + for k in range(image.contents.numcomps): + component = image.contents.comps[k] + nrows = component.h + ncols = component.w + + _validate_nonzero_image_size(nrows, ncols, k) + + addr = ctypes.addressof(component.data.contents) + with warnings.catch_warnings(): + warnings.simplefilter("ignore") + nelts = nrows * ncols + band = np.ctypeslib.as_array( + (ctypes.c_int32 * nelts).from_address(addr)) + data[:, :, k] = np.reshape(band.astype(dtype), (nrows, ncols)) + + return data + +def extract_image_bands(image): + """Extract unequally-sized image bands. + + This routine need only be called when subsampling differs across image + components, such as is often the case with YCbCr imagery. + """ + data = [] + for k in range(image.contents.numcomps): + component = image.contents.comps[k] + + dtype = component2dtype(component) + nrows = component.h + ncols = component.w + + _validate_nonzero_image_size(nrows, ncols, k) + + addr = ctypes.addressof(component.data.contents) + with warnings.catch_warnings(): + warnings.simplefilter("ignore") + band = np.ctypeslib.as_array( + (ctypes.c_int32 * nrows * ncols).from_address(addr)) + data.append(np.reshape(band.astype(dtype), (nrows, ncols))) + + return data + +def _unpack_colorspace(colorspace, img_array, cparams): + """Determine the colorspace from the supplied inputs. + + Parameters + ---------- + colorspace : int + Either CLRSPC_SRGB or CLRSPC_GRAY + img_array : ndarray + Image data to be written to file. + cparams : CompressionParametersType(ctypes.Structure) + Corresponds to cparameters_t type in openjp2 headers. + """ + if colorspace is None: + # Must infer the colorspace from the image dimensions. + if img_array.ndim < 3: + # A single channel image is grayscale. + colorspace = _opj2.CLRSPC_GRAY + elif img_array.shape[2] == 1 or img_array.shape[2] == 2: + # A single channel image or an image with two channels is going + # to be greyscale. + colorspace = _opj2.CLRSPC_GRAY + else: + # Anything else must be RGB, right? + colorspace = _opj2.CLRSPC_SRGB + else: + # Supplied a string colorspace, so we must validate it. + if cparams.codec_fmt == _opj2.CODEC_J2K: + msg = 'Do not specify a colorspace when writing a raw ' + msg += 'codestream.' + raise IOError(msg) + if colorspace.lower() not in ('rgb', 'grey', 'gray'): + msg = 'Invalid colorspace "{0}"'.format(colorspace) + raise IOError(msg) + elif colorspace.lower() == 'rgb' and img_array.shape[2] < 3: + msg = 'RGB colorspace requires at least 3 components.' + raise IOError(msg) + + # Turn the colorspace from a string to the enumerated value that + # the library expects. + colorspace = _COLORSPACE_MAP[colorspace.lower()] + + return colorspace From 0eb58e4ae48a44edbea4954e18b868dcbb412bf3 Mon Sep 17 00:00:00 2001 From: John Evans Date: Sat, 10 Aug 2013 07:12:31 -0400 Subject: [PATCH 04/20] pylint work, #99 --- glymur/jp2k.py | 54 ++++++++++++-------------------- glymur/lib/openjp2.py | 1 - glymur/lib/test/__init__.py | 4 ++- glymur/lib/test/test_openjpeg.py | 49 ++++++++++++++--------------- 4 files changed, 47 insertions(+), 61 deletions(-) diff --git a/glymur/jp2k.py b/glymur/jp2k.py index 0785178..75eca03 100644 --- a/glymur/jp2k.py +++ b/glymur/jp2k.py @@ -187,8 +187,6 @@ class Jp2k(Jp2kBox): msg += "profile if the file type box brand is 'jp2 '." warnings.warn(msg) - #def _populate_cparams(self, cbsize, cratios, eph, grid_offset, modesw, - # numres, prog, psnr, psizes, sop, subsam, tilesize): def _populate_cparams(self, **kwargs): """Populate compression parameters structure from input arguments. @@ -374,36 +372,6 @@ class Jp2k(Jp2kBox): msg = "Only uint8 and uint16 images are currently supported." raise RuntimeError(msg) - def _set_multi_component_transform(self, colorspace, cparams, mct=None): - """Set multi component transform usage. - - Parameters - ---------- - colorspace : int - Either CLRSPC_SRGB or CLRSPC_GRAY - cparams : CompressionParametersType(ctypes.Structure) - Corresponds to cparameters_t type in openjp2 headers. - mct : bool, optional - Specifies usage of the multi component transform. If not - specified, defaults to True if the colorspace is RGB. - """ - if mct is None: - # If the multi component transform was not specified, we infer - # that it should be used if the color space is RGB. - if colorspace == _opj2.CLRSPC_SRGB: - cparams.tcp_mct = 1 - else: - cparams.tcp_mct = 0 - else: - # MCT was specified. Does it make sense? - if mct and colorspace == _opj2.CLRSPC_GRAY: - # Cannot check for this in the validate routine, as we need - # to know what the target colorspace has been determined to be. - msg = "Cannot specify usage of the multi component transform " - msg += "if the colorspace is gray." - raise IOError(msg) - cparams.tcp_mct = 1 if mct else 0 - def _process_write_inputs(self, img_array, colorspace=None, **kwargs): """Directs processing of write method arguments. @@ -414,6 +382,10 @@ class Jp2k(Jp2kBox): Parameters ---------- + img_array : ndarray + Image data to be written to file. + colorspace : str, optional + Either 'rgb' or 'gray'. Returns ------- @@ -421,6 +393,9 @@ class Jp2k(Jp2kBox): Corresponds to cparameters_t type in openjp2 headers. colorspace : int Either CLRSPC_SRGB or CLRSPC_GRAY + mct : bool, optional + Specifies usage of the multi component transform. If not + specified, defaults to True if the colorspace is RGB. """ if 'cratios' in kwargs and 'psnr' in kwargs: @@ -434,9 +409,20 @@ class Jp2k(Jp2kBox): try: mct = kwargs['mct'] + if mct and colorspace == _opj2.CLRSPC_GRAY: + # Cannot check for this in the validate routine, as we need + # to know what the target colorspace has been determined to be. + msg = "Cannot specify usage of the multi component transform " + msg += "if the colorspace is gray." + raise IOError(msg) + cparams.tcp_mct = 1 if mct else 0 except KeyError: - mct = None - self._set_multi_component_transform(colorspace, cparams, mct) + # If the multi component transform was not specified, we infer + # that it should be used if the color space is RGB. + if colorspace == _opj2.CLRSPC_SRGB: + cparams.tcp_mct = 1 + else: + cparams.tcp_mct = 0 return cparams, colorspace diff --git a/glymur/lib/openjp2.py b/glymur/lib/openjp2.py index 66a3cba..468bb51 100644 --- a/glymur/lib/openjp2.py +++ b/glymur/lib/openjp2.py @@ -1381,7 +1381,6 @@ def write_tile(codec, tile_index, data, data_size, stream): def set_error_message(msg): """The openjpeg error handler has recorded an error message.""" - global ERROR_MSG_LST ERROR_MSG_LST.append(msg) diff --git a/glymur/lib/test/__init__.py b/glymur/lib/test/__init__.py index 5aea3ab..47a3d86 100644 --- a/glymur/lib/test/__init__.py +++ b/glymur/lib/test/__init__.py @@ -1 +1,3 @@ -#from .test_openjp2 import TestOpenJP2 as openjp2 +""" +Test suite for openjp2, openjpeg low-level functionality. +""" diff --git a/glymur/lib/test/test_openjpeg.py b/glymur/lib/test/test_openjpeg.py index 3dc7628..5363a1f 100644 --- a/glymur/lib/test/test_openjpeg.py +++ b/glymur/lib/test/test_openjpeg.py @@ -1,4 +1,6 @@ -#pylint: disable-all +""" +Tests for OpenJPEG module. +""" import ctypes import re import sys @@ -10,43 +12,40 @@ else: import glymur +# pylint: disable=E1101,R0904 -@unittest.skipIf(glymur.lib._openjpeg.OPENJPEG is None, +@unittest.skipIf(glymur.lib.openjpeg.OPENJPEG is None, "Missing openjpeg library.") class TestOpenJPEG(unittest.TestCase): - - def setUp(self): - pass - - def tearDown(self): - pass + """Test suite for openjpeg functions we choose to expose.""" def test_version(self): - version = glymur.lib._openjpeg.version() + """Only versions 1.3, 1.4, and 1.5 are supported.""" + version = glymur.lib.openjpeg.version() regex = re.compile('1.[345].[0-9]') if sys.hexversion <= 0x03020000: self.assertRegexpMatches(version, regex) else: self.assertRegex(version, regex) - def test_set_default_decoder_parameters(self): - # Verify that we properly set the default decode parameters. - version = glymur.lib._openjpeg.version() + def test_default_decoder_parameters(self): + """Verify that we properly set the default decode parameters.""" + version = glymur.lib.openjpeg.version() minor = int(version.split('.')[1]) - dp = glymur.lib._openjpeg.DecompressionParametersType() - glymur.lib._openjpeg.set_default_decoder_parameters(ctypes.byref(dp)) + dcp = glymur.lib.openjpeg.DecompressionParametersType() + glymur.lib.openjpeg.set_default_decoder_parameters(ctypes.byref(dcp)) - self.assertEqual(dp.cp_reduce, 0) - self.assertEqual(dp.cp_layer, 0) - self.assertEqual(dp.infile, b'') - self.assertEqual(dp.outfile, b'') - self.assertEqual(dp.decod_format, -1) - self.assertEqual(dp.cod_format, -1) - self.assertEqual(dp.jpwl_correct, 0) - self.assertEqual(dp.jpwl_exp_comps, 0) - self.assertEqual(dp.jpwl_max_tiles, 0) - self.assertEqual(dp.cp_limit_decoding, 0) + self.assertEqual(dcp.cp_reduce, 0) + self.assertEqual(dcp.cp_layer, 0) + self.assertEqual(dcp.infile, b'') + self.assertEqual(dcp.outfile, b'') + self.assertEqual(dcp.decod_format, -1) + self.assertEqual(dcp.cod_format, -1) + self.assertEqual(dcp.jpwl_correct, 0) + self.assertEqual(dcp.jpwl_exp_comps, 0) + self.assertEqual(dcp.jpwl_max_tiles, 0) + self.assertEqual(dcp.cp_limit_decoding, 0) if minor > 4: # Introduced in 1.5.x - self.assertEqual(dp.flags, 0) + self.assertEqual(dcp.flags, 0) From d7a06f29edb6c88fe79a5a8b9b225e9ae8cee095 Mon Sep 17 00:00:00 2001 From: John Evans Date: Sat, 10 Aug 2013 13:04:58 -0400 Subject: [PATCH 05/20] pylint work, #99 --- glymur/lib/test/test_openjp2.py | 538 +++++++++++++++++--------------- 1 file changed, 284 insertions(+), 254 deletions(-) diff --git a/glymur/lib/test/test_openjp2.py b/glymur/lib/test/test_openjp2.py index 710f265..13c5975 100644 --- a/glymur/lib/test/test_openjp2.py +++ b/glymur/lib/test/test_openjp2.py @@ -1,9 +1,10 @@ -#pylint: disable-all -import doctest +""" +Tests for libopenjp2 wrapping functions. +""" +# R0904: Seems like pylint is fooled in this situation +# W0142: using kwargs is ok in this context +# pylint: disable=R0904,W0142 import os -import pkg_resources -import shutil -import struct import sys import tempfile @@ -15,28 +16,28 @@ else: import numpy as np import glymur +from glymur.lib import openjp2 OPENJP2_IS_V2_OFFICIAL = False -if glymur.lib.openjp2.OPENJP2 is not None: - if not hasattr(glymur.lib.openjp2.OPENJP2, +if openjp2.OPENJP2 is not None: + if not hasattr(openjp2.OPENJP2, 'opj_stream_create_default_file_stream_v3'): OPENJP2_IS_V2_OFFICIAL = True @unittest.skipIf(os.name == "nt", "Temporary file issue on window.") -@unittest.skipIf(glymur.lib.openjp2.OPENJP2 is None, +@unittest.skipIf(openjp2.OPENJP2 is None, "Missing openjp2 library.") @unittest.skipIf(OPENJP2_IS_V2_OFFICIAL, "API followed here specific to V2.0+") class TestOpenJP2(unittest.TestCase): + """Test openjp2 library functionality. - def setUp(self): - pass + Some tests correspond to those in the openjpeg test suite. + """ - def tearDown(self): - pass - - def test_set_default_encoder_parameters(self): - cparams = glymur.lib._openjp2.set_default_encoder_parameters() + def test_default_encoder_parameters(self): + """Ensure that the encoder structure is clean upon init.""" + cparams = openjp2.set_default_encoder_parameters() self.assertEqual(cparams.res_spec, 0) self.assertEqual(cparams.cblockw_init, 64) @@ -52,8 +53,9 @@ class TestOpenJP2(unittest.TestCase): self.assertEqual(cparams.irreversible, 0) - def test_set_default_decoder_parameters(self): - dparams = glymur.lib._openjp2.set_default_decoder_parameters() + def test_default_decoder_parameters(self): + """Tests that the structure is clean upon initialization""" + dparams = openjp2.set_default_decoder_parameters() self.assertEqual(dparams.DA_x0, 0) self.assertEqual(dparams.DA_y0, 0) @@ -61,35 +63,34 @@ class TestOpenJP2(unittest.TestCase): self.assertEqual(dparams.DA_y1, 0) def tile_macro(self, codec, stream, imagep, tidx): - # called only by j2k_random_tile_access - glymur.lib._openjp2.get_decoded_tile(codec, stream, imagep, tidx) + """called only by j2k_random_tile_access""" + openjp2.get_decoded_tile(codec, stream, imagep, tidx) for j in range(imagep.contents.numcomps): self.assertIsNotNone(imagep.contents.comps[j].data) def j2k_random_tile_access(self, filename, codec_format=None): - # called by the test_rtaX methods - dparam = glymur.lib._openjp2.set_default_decoder_parameters() + """fixture called by the test_rtaX methods""" + dparam = openjp2.set_default_decoder_parameters() infile = filename.encode() - nelts = glymur.lib._openjp2.PATH_LEN - len(infile) + nelts = openjp2.PATH_LEN - len(infile) infile += b'0' * nelts dparam.infile = infile dparam.decod_format = codec_format - codec = glymur.lib._openjp2.create_decompress(codec_format) + codec = openjp2.create_decompress(codec_format) - glymur.lib._openjp2.set_info_handler(codec, None) - glymur.lib._openjp2.set_warning_handler(codec, None) - glymur.lib._openjp2.set_error_handler(codec, None) + openjp2.set_info_handler(codec, None) + openjp2.set_warning_handler(codec, None) + openjp2.set_error_handler(codec, None) - x = (filename, True) - stream = glymur.lib._openjp2.stream_create_default_file_stream_v3(*x) + stream = openjp2.stream_create_default_file_stream_v3(filename, True) - glymur.lib._openjp2.setup_decoder(codec, dparam) - image = glymur.lib._openjp2.read_header(stream, codec) + openjp2.setup_decoder(codec, dparam) + image = openjp2.read_header(stream, codec) - cstr_info = glymur.lib._openjp2.get_cstr_info(codec) + cstr_info = openjp2.get_cstr_info(codec) tile_ul = 0 tile_ur = cstr_info.contents.tw - 1 @@ -101,159 +102,39 @@ class TestOpenJP2(unittest.TestCase): self.tile_macro(codec, stream, image, tile_lr) self.tile_macro(codec, stream, image, tile_ll) - glymur.lib._openjp2.destroy_cstr_info(cstr_info) + openjp2.destroy_cstr_info(cstr_info) - glymur.lib._openjp2.end_decompress(codec, stream) - glymur.lib._openjp2.destroy_codec(codec) - glymur.lib._openjp2.stream_destroy_v3(stream) - glymur.lib._openjp2.image_destroy(image) - - def tile_decoder(self, x0=None, y0=None, x1=None, y1=None, filename=None, - codec_format=None): - x = (filename, True) - stream = glymur.lib._openjp2.stream_create_default_file_stream_v3(*x) - dparam = glymur.lib._openjp2.set_default_decoder_parameters() - - dparam.decod_format = codec_format - - # Do not use layer decoding limitation. - dparam.cp_layer = 0 - - # do not use resolution reductions. - dparam.cp_reduce = 0 - - codec = glymur.lib._openjp2.create_decompress(codec_format) - - glymur.lib._openjp2.set_info_handler(codec, None) - glymur.lib._openjp2.set_warning_handler(codec, None) - glymur.lib._openjp2.set_error_handler(codec, None) - - glymur.lib._openjp2.setup_decoder(codec, dparam) - image = glymur.lib._openjp2.read_header(stream, codec) - glymur.lib._openjp2.set_decode_area(codec, image, x0, y0, x1, y1) - - data = np.zeros((1150, 2048, 3), dtype=np.uint8) - while True: - rargs = glymur.lib._openjp2.read_tile_header(codec, stream) - tidx = rargs[0] - sz = rargs[1] - go_on = rargs[-1] - if not go_on: - break - glymur.lib._openjp2.decode_tile_data(codec, tidx, data, sz, stream) - - glymur.lib._openjp2.end_decompress(codec, stream) - glymur.lib._openjp2.destroy_codec(codec) - glymur.lib._openjp2.stream_destroy_v3(stream) - glymur.lib._openjp2.image_destroy(image) - - def tile_encoder(self, num_comps=None, tile_width=None, tile_height=None, - filename=None, codec=None, comp_prec=None, - image_width=None, image_height=None, - irreversible=None): - num_tiles = (image_width / tile_width) * (image_height / tile_height) - tile_size = tile_width * tile_height * num_comps * comp_prec / 8 - - data = np.random.random((tile_height, tile_width, num_comps)) - data = (data * 255).astype(np.uint8) - - l_param = glymur.lib._openjp2.set_default_encoder_parameters() - - l_param.tcp_numlayers = 1 - l_param.cp_fixed_quality = 1 - l_param.tcp_distoratio[0] = 20 - - # position of the tile grid aligned with the image - l_param.cp_tx0 = 0 - l_param.cp_ty0 = 0 - - # tile size, we are using tile based encoding - l_param.tile_size_on = 1 - l_param.cp_tdx = tile_width - l_param.cp_tdy = tile_height - - # use irreversible encoding - l_param.irreversible = irreversible - - l_param.numresolution = 6 - - l_param.prog_order = glymur.core.LRCP - - l_params = (glymur.lib._openjp2.ImageComptParmType * num_comps)() - for j in range(num_comps): - l_params[j].dx = 1 - l_params[j].dy = 1 - l_params[j].h = image_height - l_params[j].w = image_width - l_params[j].sgnd = 0 - l_params[j].prec = comp_prec - l_params[j].x0 = 0 - l_params[j].y0 = 0 - - codec = glymur.lib._openjp2.create_compress(codec) - - glymur.lib._openjp2.set_info_handler(codec, None) - glymur.lib._openjp2.set_warning_handler(codec, None) - glymur.lib._openjp2.set_error_handler(codec, None) - - cspace = glymur.lib._openjp2.CLRSPC_SRGB - l_image = glymur.lib._openjp2.image_tile_create(l_params, cspace) - - l_image.contents.x0 = 0 - l_image.contents.y0 = 0 - l_image.contents.x1 = image_width - l_image.contents.y1 = image_height - l_image.contents.color_space = glymur.lib._openjp2.CLRSPC_SRGB - - glymur.lib._openjp2.setup_encoder(codec, l_param, l_image) - - x = (filename, False) - stream = glymur.lib._openjp2.stream_create_default_file_stream_v3(*x) - glymur.lib._openjp2.start_compress(codec, l_image, stream) - - for j in np.arange(num_tiles): - glymur.lib._openjp2.write_tile(codec, j, data, tile_size, stream) - - glymur.lib._openjp2.end_compress(codec, stream) - glymur.lib._openjp2.stream_destroy_v3(stream) - glymur.lib._openjp2.destroy_codec(codec) - glymur.lib._openjp2.image_destroy(l_image) - - def tte0_setup(self, filename): - kwargs = {'filename': filename, - 'codec': glymur.lib._openjp2.CODEC_J2K, - 'comp_prec': 8, - 'irreversible': 1, - 'num_comps': 3, - 'image_height': 200, - 'image_width': 200, - 'tile_height': 100, - 'tile_width': 100} - self.tile_encoder(**kwargs) + openjp2.end_decompress(codec, stream) + openjp2.destroy_codec(codec) + openjp2.stream_destroy_v3(stream) + openjp2.image_destroy(image) def test_tte0(self): - # Runs test designated tte0 in OpenJPEG test suite. + """Runs test designated tte0 in OpenJPEG test suite.""" with tempfile.NamedTemporaryFile(suffix=".j2k") as tfile: - self.tte0_setup(tfile.name) + ttx0_setup(tfile.name) + self.assertTrue(True) def test_ttd0(self): - # Runs test designated ttd0 in OpenJPEG test suite. + """Runs test designated ttd0 in OpenJPEG test suite.""" with tempfile.NamedTemporaryFile(suffix=".j2k") as tfile: # Produce the tte0 output file for ttd0 input. - self.tte0_setup(tfile.name) + ttx0_setup(tfile.name) kwargs = {'x0': 0, 'y0': 0, 'x1': 1000, 'y1': 1000, 'filename': tfile.name, - 'codec_format': glymur.lib._openjp2.CODEC_J2K} - self.tile_decoder(**kwargs) + 'codec_format': openjp2.CODEC_J2K} + tile_decoder(**kwargs) + self.assertTrue(True) - def tte1_setup(self, filename): + def xtx1_setup(self, filename): + """Runs tests tte1, rta1.""" kwargs = {'filename': filename, - 'codec': glymur.lib._openjp2.CODEC_J2K, + 'codec': openjp2.CODEC_J2K, 'comp_prec': 8, 'irreversible': 1, 'num_comps': 3, @@ -261,149 +142,298 @@ class TestOpenJP2(unittest.TestCase): 'image_width': 256, 'tile_height': 128, 'tile_width': 128} - self.tile_encoder(**kwargs) + tile_encoder(**kwargs) + self.assertTrue(True) def test_tte1(self): + """Runs test designated tte1 in OpenJPEG test suite.""" with tempfile.NamedTemporaryFile(suffix=".j2k") as tfile: - # Runs test designated tte1 in OpenJPEG test suite. - self.tte1_setup(tfile.name) + self.xtx1_setup(tfile.name) def test_ttd1(self): - # Runs test designated ttd1 in OpenJPEG test suite. + """Runs test designated ttd1 in OpenJPEG test suite.""" with tempfile.NamedTemporaryFile(suffix=".j2k") as tfile: # Produce the tte0 output file for ttd0 input. - self.tte1_setup(tfile.name) + self.xtx1_setup(tfile.name) kwargs = {'x0': 0, 'y0': 0, 'x1': 128, 'y1': 128, 'filename': tfile.name, - 'codec_format': glymur.lib._openjp2.CODEC_J2K} - self.tile_decoder(**kwargs) + 'codec_format': openjp2.CODEC_J2K} + tile_decoder(**kwargs) + self.assertTrue(True) def test_rta1(self): + """Runs test designated rta1 in OpenJPEG test suite.""" with tempfile.NamedTemporaryFile(suffix=".j2k") as tfile: - # Runs test designated rta1 in OpenJPEG test suite. - self.tte1_setup(tfile.name) + self.xtx1_setup(tfile.name) - kwargs = {'codec_format': glymur.lib._openjp2.CODEC_J2K} - self.j2k_random_tile_access(tfile.name, **kwargs) - - def tte2_setup(self, filename): - kwargs = {'filename': filename, - 'codec': glymur.lib._openjp2.CODEC_JP2, - 'comp_prec': 8, - 'irreversible': 1, - 'num_comps': 3, - 'image_height': 256, - 'image_width': 256, - 'tile_height': 128, - 'tile_width': 128} - self.tile_encoder(**kwargs) + codec_format = openjp2.CODEC_J2K + self.j2k_random_tile_access(tfile.name, codec_format) + self.assertTrue(True) def test_tte2(self): - # Runs test designated tte2 in OpenJPEG test suite. + """Runs test designated tte2 in OpenJPEG test suite.""" with tempfile.NamedTemporaryFile(suffix=".jp2") as tfile: - self.tte2_setup(tfile.name) + xtx2_setup(tfile.name) + self.assertTrue(True) def test_ttd2(self): - # Runs test designated ttd2 in OpenJPEG test suite. + """Runs test designated ttd2 in OpenJPEG test suite.""" with tempfile.NamedTemporaryFile(suffix=".jp2") as tfile: # Produce the tte0 output file for ttd0 input. - self.tte2_setup(tfile.name) + xtx2_setup(tfile.name) kwargs = {'x0': 0, 'y0': 0, 'x1': 128, 'y1': 128, 'filename': tfile.name, - 'codec_format': glymur.lib._openjp2.CODEC_JP2} - self.tile_decoder(**kwargs) + 'codec_format': openjp2.CODEC_JP2} + tile_decoder(**kwargs) + self.assertTrue(True) def test_rta2(self): + """Runs test designated rta2 in OpenJPEG test suite.""" with tempfile.NamedTemporaryFile(suffix=".jp2") as tfile: - # Runs test designated rta2 in OpenJPEG test suite. - self.tte2_setup(tfile.name) + xtx2_setup(tfile.name) - kwargs = {'codec_format': glymur.lib._openjp2.CODEC_JP2} - self.j2k_random_tile_access(tfile.name, **kwargs) - - def tte3_setup(self, filename): - kwargs = {'filename': filename, - 'codec': glymur.lib._openjp2.CODEC_J2K, - 'comp_prec': 8, - 'irreversible': 1, - 'num_comps': 1, - 'image_height': 256, - 'image_width': 256, - 'tile_height': 128, - 'tile_width': 128} - self.tile_encoder(**kwargs) + codec_format = openjp2.CODEC_JP2 + self.j2k_random_tile_access(tfile.name, codec_format) def test_tte3(self): + """Runs test designated tte3 in OpenJPEG test suite.""" with tempfile.NamedTemporaryFile(suffix=".j2k") as tfile: - # Runs test designated tte3 in OpenJPEG test suite. - self.tte3_setup(tfile.name) + xtx3_setup(tfile.name) + self.assertTrue(True) def test_rta3(self): - # Runs test designated rta3 in OpenJPEG test suite. + """Runs test designated rta3 in OpenJPEG test suite.""" with tempfile.NamedTemporaryFile(suffix=".j2k") as tfile: - self.tte3_setup(tfile.name) + xtx3_setup(tfile.name) - kwargs = {'codec_format': glymur.lib._openjp2.CODEC_J2K} - self.j2k_random_tile_access(tfile.name, **kwargs) - - def tte4_setup(self, filename): - kwargs = {'filename': filename, - 'codec': glymur.lib._openjp2.CODEC_J2K, - 'comp_prec': 8, - 'irreversible': 0, - 'num_comps': 1, - 'image_height': 256, - 'image_width': 256, - 'tile_height': 128, - 'tile_width': 128} - self.tile_encoder(**kwargs) + codec_format = openjp2.CODEC_J2K + self.j2k_random_tile_access(tfile.name, codec_format) + self.assertTrue(True) 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: - self.tte4_setup(tfile.name) + xtx4_setup(tfile.name) + self.assertTrue(True) def test_rta4(self): - # Runs test designated rta4 in OpenJPEG test suite. + """Runs test designated rta4 in OpenJPEG test suite.""" with tempfile.NamedTemporaryFile(suffix=".j2k") as tfile: - self.tte4_setup(tfile.name) + xtx4_setup(tfile.name) - kwargs = {'codec_format': glymur.lib._openjp2.CODEC_J2K} - self.j2k_random_tile_access(tfile.name, **kwargs) - - def tte5_setup(self, filename): - kwargs = {'filename': filename, - 'codec': glymur.lib._openjp2.CODEC_J2K, - 'comp_prec': 8, - 'irreversible': 0, - 'num_comps': 1, - 'image_height': 512, - 'image_width': 512, - 'tile_height': 256, - 'tile_width': 256} - self.tile_encoder(**kwargs) + codec_format = openjp2.CODEC_J2K + self.j2k_random_tile_access(tfile.name, codec_format) def test_tte5(self): - # Runs test designated tte5 in OpenJPEG test suite. + """Runs test designated tte5 in OpenJPEG test suite.""" with tempfile.NamedTemporaryFile(suffix=".j2k") as tfile: - self.tte5_setup(tfile.name) + xtx5_setup(tfile.name) + self.assertTrue(True) def test_rta5(self): - # Runs test designated rta5 in OpenJPEG test suite. + """Runs test designated rta5 in OpenJPEG test suite.""" with tempfile.NamedTemporaryFile(suffix=".j2k") as tfile: - self.tte5_setup(tfile.name) + xtx5_setup(tfile.name) - kwargs = {'codec_format': glymur.lib._openjp2.CODEC_J2K} - self.j2k_random_tile_access(tfile.name, **kwargs) + codec_format = openjp2.CODEC_J2K + self.j2k_random_tile_access(tfile.name, codec_format) + + +#def tile_encoder(num_comps=None, tile_width=None, tile_height=None, +# filename=None, codec=None, comp_prec=None, +# image_width=None, image_height=None, +# irreversible=None): +def tile_encoder(**kwargs): + """Fixture used by many tests.""" + num_tiles = ((kwargs['image_width'] / kwargs['tile_width']) * + (kwargs['image_height'] / kwargs['tile_height'])) + tile_size = ((kwargs['tile_width'] * kwargs['tile_height']) * + (kwargs['num_comps'] * kwargs['comp_prec'] / 8)) + + data = np.random.random((kwargs['tile_height'], + kwargs['tile_width'], + kwargs['num_comps'])) + data = (data * 255).astype(np.uint8) + + l_param = openjp2.set_default_encoder_parameters() + + l_param.tcp_numlayers = 1 + l_param.cp_fixed_quality = 1 + l_param.tcp_distoratio[0] = 20 + + # position of the tile grid aligned with the image + l_param.cp_tx0 = 0 + l_param.cp_ty0 = 0 + + # tile size, we are using tile based encoding + l_param.tile_size_on = 1 + l_param.cp_tdx = kwargs['tile_width'] + l_param.cp_tdy = kwargs['tile_height'] + + # use irreversible encoding + l_param.irreversible = kwargs['irreversible'] + + l_param.numresolution = 6 + + l_param.prog_order = glymur.core.LRCP + + l_params = (openjp2.ImageComptParmType * kwargs['num_comps'])() + for j in range(kwargs['num_comps']): + l_params[j].dx = 1 + l_params[j].dy = 1 + l_params[j].h = kwargs['image_height'] + l_params[j].w = kwargs['image_width'] + l_params[j].sgnd = 0 + l_params[j].prec = kwargs['comp_prec'] + l_params[j].x0 = 0 + l_params[j].y0 = 0 + + codec = openjp2.create_compress(kwargs['codec']) + + openjp2.set_info_handler(codec, None) + openjp2.set_warning_handler(codec, None) + openjp2.set_error_handler(codec, None) + + cspace = openjp2.CLRSPC_SRGB + l_image = openjp2.image_tile_create(l_params, cspace) + + l_image.contents.x0 = 0 + l_image.contents.y0 = 0 + l_image.contents.x1 = kwargs['image_width'] + l_image.contents.y1 = kwargs['image_height'] + l_image.contents.color_space = openjp2.CLRSPC_SRGB + + openjp2.setup_encoder(codec, l_param, l_image) + + stream = openjp2.stream_create_default_file_stream_v3(kwargs['filename'], + False) + openjp2.start_compress(codec, l_image, stream) + + for j in np.arange(num_tiles): + openjp2.write_tile(codec, j, data, tile_size, stream) + + openjp2.end_compress(codec, stream) + openjp2.stream_destroy_v3(stream) + openjp2.destroy_codec(codec) + openjp2.image_destroy(l_image) + +def tile_decoder(**kwargs): + """Fixture called with various configurations by many tests. + + Reads a tile. That's all it does. + """ + stream = openjp2.stream_create_default_file_stream_v3(kwargs['filename'], + True) + dparam = openjp2.set_default_decoder_parameters() + + dparam.decod_format = kwargs['codec_format'] + + # Do not use layer decoding limitation. + dparam.cp_layer = 0 + + # do not use resolution reductions. + dparam.cp_reduce = 0 + + codec = openjp2.create_decompress(kwargs['codec_format']) + + openjp2.set_info_handler(codec, None) + openjp2.set_warning_handler(codec, None) + openjp2.set_error_handler(codec, None) + + openjp2.setup_decoder(codec, dparam) + image = openjp2.read_header(stream, codec) + openjp2.set_decode_area(codec, image, + kwargs['x0'], kwargs['y0'], + kwargs['x1'], kwargs['y1']) + + data = np.zeros((1150, 2048, 3), dtype=np.uint8) + while True: + rargs = openjp2.read_tile_header(codec, stream) + tidx = rargs[0] + size = rargs[1] + go_on = rargs[-1] + if not go_on: + break + openjp2.decode_tile_data(codec, tidx, data, size, stream) + + openjp2.end_decompress(codec, stream) + openjp2.destroy_codec(codec) + openjp2.stream_destroy_v3(stream) + openjp2.image_destroy(image) + +def ttx0_setup(filename): + """Runs tests tte0, tte0.""" + kwargs = {'filename': filename, + 'codec': openjp2.CODEC_J2K, + 'comp_prec': 8, + 'irreversible': 1, + 'num_comps': 3, + 'image_height': 200, + 'image_width': 200, + 'tile_height': 100, + 'tile_width': 100} + tile_encoder(**kwargs) + +def xtx2_setup(filename): + """Runs tests rta2, tte2, ttd2.""" + kwargs = {'filename': filename, + 'codec': openjp2.CODEC_JP2, + 'comp_prec': 8, + 'irreversible': 1, + 'num_comps': 3, + 'image_height': 256, + 'image_width': 256, + 'tile_height': 128, + 'tile_width': 128} + tile_encoder(**kwargs) + +def xtx3_setup(filename): + """Runs tests tte3, rta3.""" + kwargs = {'filename': filename, + 'codec': openjp2.CODEC_J2K, + 'comp_prec': 8, + 'irreversible': 1, + 'num_comps': 1, + 'image_height': 256, + 'image_width': 256, + 'tile_height': 128, + 'tile_width': 128} + tile_encoder(**kwargs) + +def xtx4_setup(filename): + """Runs tests rta4, tte4.""" + kwargs = {'filename': filename, + 'codec': openjp2.CODEC_J2K, + 'comp_prec': 8, + 'irreversible': 0, + 'num_comps': 1, + 'image_height': 256, + 'image_width': 256, + 'tile_height': 128, + 'tile_width': 128} + tile_encoder(**kwargs) + +def xtx5_setup(filename): + """Runs tests rta5, tte5.""" + kwargs = {'filename': filename, + 'codec': openjp2.CODEC_J2K, + 'comp_prec': 8, + 'irreversible': 0, + 'num_comps': 1, + 'image_height': 512, + 'image_width': 512, + 'tile_height': 256, + 'tile_width': 256} + tile_encoder(**kwargs) if __name__ == "__main__": unittest.main() From 8a8b4cb0ad21d0c63dbbc903ff2ea4a2ac9262fc Mon Sep 17 00:00:00 2001 From: John Evans Date: Sat, 10 Aug 2013 13:05:10 -0400 Subject: [PATCH 06/20] pep8 work, #99 --- glymur/jp2box.py | 24 ++++-- glymur/jp2k.py | 185 +++++++++++++++++++++------------------- glymur/lib/__init__.py | 4 +- glymur/test/fixtures.py | 7 +- 4 files changed, 120 insertions(+), 100 deletions(-) diff --git a/glymur/jp2box.py b/glymur/jp2box.py index 56021b9..6d5c3ee 100644 --- a/glymur/jp2box.py +++ b/glymur/jp2box.py @@ -1249,14 +1249,28 @@ class PaletteBox(Jp2kBox): # This means that we store the palette as a list of 1D arrays, # which reverses the usual indexing scheme. read_buffer = fptr.read(num_entries * row_nbytes) - palette = buffer2palette(read_buffer, num_entries, num_columns, bps) + palette = _buffer2palette(read_buffer, num_entries, num_columns, bps) - box = PaletteBox(palette, bps, signed, length=length, - offset=offset) + box = PaletteBox(palette, bps, signed, length=length, offset=offset) return box -def buffer2palette(read_buffer, num_rows, num_cols, bps): + +def _buffer2palette(read_buffer, num_rows, num_cols, bps): """Construct the palette from the buffer read from file. + + Parameters + ---------- + read_buffer : iterable + Byte array of palette information read from file. + num_rows, num_cols : int + Size of palette. + bps : iterable + Bits per sample for each channel. + + Returns + ------- + palette : list of 1D arrays + Each 1D array corresponds to a channel. """ row_nbytes = 0 palette = [] @@ -1278,7 +1292,6 @@ def buffer2palette(read_buffer, num_rows, num_cols, bps): msg = 'Unsupported palette bitdepth (%d).'.format(bps[j]) raise IOError(msg) - for j in range(num_rows): row_buffer = read_buffer[(row_nbytes * j):(row_nbytes * (j + 1))] row = struct.unpack(fmt, row_buffer) @@ -1498,6 +1511,7 @@ def _parse_standard_flag(fptr, mask_length): return standard_flag, standard_mask + def _parse_vendor_features(fptr, mask_length): """Construct vendor features, vendor mask data from the file. diff --git a/glymur/jp2k.py b/glymur/jp2k.py index 75eca03..fade3a8 100644 --- a/glymur/jp2k.py +++ b/glymur/jp2k.py @@ -30,22 +30,22 @@ from .jp2box import JP2HeaderBox from .jp2box import ContiguousCodestreamBox from .jp2box import ImageHeaderBox from .jp2box import ColourSpecificationBox -from .lib import _openjpeg as _opj -from .lib import _openjp2 as _opj2 +from .lib import openjpeg as opj +from .lib import openjp2 as opj2 from .lib import c as _libc # Need to known if openjp2 library is the officially release v2.0.0 or not. _OPENJP2_IS_OFFICIAL_V2 = False -if _opj2.OPENJP2 is not None: - if _opj2.version() == '2.0.0': - if not hasattr(_opj2.OPENJP2, +if opj2.OPENJP2 is not None: + if opj2.version() == '2.0.0': + if not hasattr(opj2.OPENJP2, 'opj_stream_create_default_file_stream_v3'): _OPENJP2_IS_OFFICIAL_V2 = True -_COLORSPACE_MAP = {'rgb': _opj2.CLRSPC_SRGB, - 'gray': _opj2.CLRSPC_GRAY, - 'grey': _opj2.CLRSPC_GRAY, - 'ycc': _opj2.CLRSPC_YCC} +_COLORSPACE_MAP = {'rgb': opj2.CLRSPC_SRGB, + 'gray': opj2.CLRSPC_GRAY, + 'grey': opj2.CLRSPC_GRAY, + 'ycc': opj2.CLRSPC_YCC} # Setup the default callback handlers. See the callback functions subsection # in the ctypes section of the Python documentation for a solid explanation of @@ -56,7 +56,7 @@ _CMPFUNC = ctypes.CFUNCTYPE(ctypes.c_void_p, ctypes.c_char_p, ctypes.c_void_p) def _default_error_handler(msg, _): """Default error handler callback for openjpeg library.""" msg = "OpenJPEG library error: {0}".format(msg.decode('utf-8').rstrip()) - _opj2.set_error_message(msg) + opj2.set_error_message(msg) def _default_info_handler(msg, _): @@ -143,12 +143,12 @@ class Jp2k(Jp2kBox): read_buffer = fptr.read(2) signature, = struct.unpack('>H', read_buffer) if signature == 0xff4f: - self._codec_format = _opj2.CODEC_J2K + self._codec_format = opj2.CODEC_J2K # That's it, we're done. The codestream object is only # produced upon explicit request. return - self._codec_format = _opj2.CODEC_JP2 + self._codec_format = opj2.CODEC_JP2 # Should be JP2. # First 4 bytes should be 12, the length of the 'jP ' box. @@ -234,17 +234,17 @@ class Jp2k(Jp2kBox): Corresponds to cparameters_t type in openjp2 headers. """ - cparams = _opj2.set_default_encoder_parameters() + cparams = opj2.set_default_encoder_parameters() outfile = self.filename.encode() - num_pad_bytes = _opj2.PATH_LEN - len(outfile) + num_pad_bytes = opj2.PATH_LEN - len(outfile) outfile += b'0' * num_pad_bytes cparams.outfile = outfile if self.filename[-4:].lower() == '.jp2': - cparams.codec_fmt = _opj2.CODEC_JP2 + cparams.codec_fmt = opj2.CODEC_JP2 else: - cparams.codec_fmt = _opj2.CODEC_J2K + cparams.codec_fmt = opj2.CODEC_J2K # Set defaults to lossless to begin. cparams.tcp_rates[0] = 0 @@ -304,13 +304,13 @@ class Jp2k(Jp2kBox): if 'tilesize' in kwargs: cparams.cp_tdx = kwargs['tilesize'][1] cparams.cp_tdy = kwargs['tilesize'][0] - cparams.tile_size_on = _opj2.TRUE + cparams.tile_size_on = opj2.TRUE return cparams def _validate_compression_params(self, img_array, cparams): """Check that the compression parameters are valid. - + Parameters ---------- img_array : ndarray @@ -335,7 +335,7 @@ class Jp2k(Jp2kBox): msg = "Bad code block size ({0}, {1}), " msg += "must be powers of 2." raise IOError(msg.format(height, width)) - + # Precinct size if cparams.res_spec != 0: # precinct size was not specified if this field is zero. @@ -353,12 +353,12 @@ class Jp2k(Jp2kBox): msg = "Bad precinct sizes ({0}, {1}), " msg += "must be powers of 2." raise IOError(msg.format(prch, prcw)) - + # What would the point of 1D images be? if img_array.ndim == 1 or img_array.ndim > 3: msg = "{0}D imagery is not allowed.".format(img_array.ndim) raise IOError(msg) - + if _OPENJP2_IS_OFFICIAL_V2: if (((img_array.ndim != 2) and (img_array.shape[2] != 1 and img_array.shape[2] != 3))): @@ -367,16 +367,16 @@ class Jp2k(Jp2kBox): msg += "the OpenJPEG library version is the official 2.0.0 " msg += "release." raise IOError(msg) - + if img_array.dtype != np.uint8 and img_array.dtype != np.uint16: msg = "Only uint8 and uint16 images are currently supported." raise RuntimeError(msg) - + def _process_write_inputs(self, img_array, colorspace=None, **kwargs): """Directs processing of write method arguments. It's somewhat awkward to process all the kwargs arguments at once. - The "colorspace" is not a parameter that gets processed into the + The "colorspace" is not a parameter that gets processed into the compression parameters structure, and it unfortunately must be handled in the middle of the compression parameter processing. @@ -409,7 +409,7 @@ class Jp2k(Jp2kBox): try: mct = kwargs['mct'] - if mct and colorspace == _opj2.CLRSPC_GRAY: + if mct and colorspace == opj2.CLRSPC_GRAY: # Cannot check for this in the validate routine, as we need # to know what the target colorspace has been determined to be. msg = "Cannot specify usage of the multi component transform " @@ -419,7 +419,7 @@ class Jp2k(Jp2kBox): except KeyError: # If the multi component transform was not specified, we infer # that it should be used if the color space is RGB. - if colorspace == _opj2.CLRSPC_SRGB: + if colorspace == opj2.CLRSPC_SRGB: cparams.tcp_mct = 1 else: cparams.tcp_mct = 0 @@ -525,7 +525,7 @@ class Jp2k(Jp2kBox): glymur.LibraryNotFoundError If glymur is unable to load the openjp2 library. """ - if _opj2.OPENJP2 is None: + if opj2.OPENJP2 is None: raise LibraryNotFoundError("You must have the openjp2 library " "installed before using this " "functionality.") @@ -537,11 +537,11 @@ class Jp2k(Jp2kBox): numrows, numcols = img_array.shape img_array = img_array.reshape(numrows, numcols, 1) - # Only two precisions are possible. + # Only two precisions are possible. comp_prec = 8 if img_array.dtype == np.uint8 else 16 numrows, numcols, num_comps = img_array.shape - comptparms = (_opj2.ImageComptParmType * num_comps)() + comptparms = (opj2.ImageComptParmType * num_comps)() for j in range(num_comps): comptparms[j].dx = cparams.subsampling_dx comptparms[j].dy = cparams.subsampling_dy @@ -553,40 +553,40 @@ class Jp2k(Jp2kBox): comptparms[j].bpp = comp_prec comptparms[j].sgnd = 0 - image = _opj2.image_create(comptparms, colorspace) + image = opj2.image_create(comptparms, colorspace) self._populate_image_struct(cparams, image, img_array) - codec = _opj2.create_compress(cparams.codec_fmt) + codec = opj2.create_compress(cparams.codec_fmt) info_handler = _INFO_CALLBACK if verbose else None - _opj2.set_info_handler(codec, info_handler) - _opj2.set_warning_handler(codec, _WARNING_CALLBACK) - _opj2.set_error_handler(codec, _ERROR_CALLBACK) + opj2.set_info_handler(codec, info_handler) + opj2.set_warning_handler(codec, _WARNING_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: fptr = _libc.fopen(self.filename, 'wb') - strm = _opj2.stream_create_default_file_stream(fptr, False) + strm = opj2.stream_create_default_file_stream(fptr, False) else: # This routine introduced in 2.0 devel series. - strm = _opj2.stream_create_default_file_stream_v3(self.filename, - False) + strm = opj2.stream_create_default_file_stream_v3(self.filename, + False) # Start to clean up after ourselves. - _opj2.start_compress(codec, image, strm) - _opj2.encode(codec, strm) - _opj2.end_compress(codec, strm) + opj2.start_compress(codec, image, strm) + opj2.encode(codec, strm) + opj2.end_compress(codec, strm) if _OPENJP2_IS_OFFICIAL_V2: - _opj2.stream_destroy(strm) + opj2.stream_destroy(strm) _libc.fclose(fptr) else: # This routine introduced in 2.0 devel series. - _opj2.stream_destroy_v3(strm) + opj2.stream_destroy_v3(strm) - _opj2.destroy_codec(codec) - _opj2.image_destroy(image) + opj2.destroy_codec(codec) + opj2.image_destroy(image) # Refresh the metadata. self.parse() @@ -713,9 +713,9 @@ class Jp2k(Jp2kBox): >>> thumbnail.shape (728, 1296, 3) """ - if _opj2.OPENJP2 is not None: + if opj2.OPENJP2 is not None: img = self._read_openjp2(**kwargs) - elif _opj.OPENJPEG is not None: + elif opj.OPENJPEG is not None: img = self._read_openjpeg(**kwargs) else: raise LibraryNotFoundError("You must have either a recent version " @@ -761,38 +761,38 @@ class Jp2k(Jp2kBox): with ExitStack() as stack: # Set decoding parameters. - dparameters = _opj.DecompressionParametersType() - _opj.set_default_decoder_parameters(ctypes.byref(dparameters)) + dparameters = opj.DecompressionParametersType() + opj.set_default_decoder_parameters(ctypes.byref(dparameters)) dparameters.cp_reduce = rlevel dparameters.decod_format = self._codec_format infile = self.filename.encode() - nelts = _opj.PATH_LEN - len(infile) + nelts = opj.PATH_LEN - len(infile) infile += b'0' * nelts dparameters.infile = infile - dinfo = _opj.create_decompress(dparameters.decod_format) + dinfo = opj.create_decompress(dparameters.decod_format) - event_mgr = _opj.EventMgrType() + event_mgr = opj.EventMgrType() info_handler = ctypes.cast(_INFO_CALLBACK, ctypes.c_void_p) event_mgr.info_handler = info_handler if verbose else None event_mgr.warning_handler = ctypes.cast(_WARNING_CALLBACK, ctypes.c_void_p) event_mgr.error_handler = ctypes.cast(_ERROR_CALLBACK, ctypes.c_void_p) - _opj.set_event_mgr(dinfo, ctypes.byref(event_mgr)) + opj.set_event_mgr(dinfo, ctypes.byref(event_mgr)) - _opj.setup_decoder(dinfo, dparameters) + opj.setup_decoder(dinfo, dparameters) with open(self.filename, 'rb') as fptr: src = fptr.read() - cio = _opj.cio_open(dinfo, src) + cio = opj.cio_open(dinfo, src) - image = _opj.decode(dinfo, cio) + image = opj.decode(dinfo, cio) - stack.callback(_opj.image_destroy, image) - stack.callback(_opj.destroy_decompress, dinfo) - stack.callback(_opj.cio_close, cio) + stack.callback(opj.image_destroy, image) + stack.callback(opj.destroy_decompress, dinfo) + stack.callback(opj.cio_close, cio) data = extract_image_cube(image) @@ -850,7 +850,7 @@ class Jp2k(Jp2kBox): def _populate_dparam(self, layer, rlevel, area, tile): """Populate decompression structure with appropriate input parameters. - + Parameters ---------- layer : int, optional @@ -868,10 +868,10 @@ class Jp2k(Jp2kBox): dparam : DecompressionParametersType (ctypes) Corresponds to openjp2 decompression parameters structure. """ - dparam = _opj2.set_default_decoder_parameters() + dparam = opj2.set_default_decoder_parameters() infile = self.filename.encode() - nelts = _opj2.PATH_LEN - len(infile) + nelts = opj2.PATH_LEN - len(infile) infile += b'0' * nelts dparam.infile = infile @@ -929,39 +929,39 @@ class Jp2k(Jp2kBox): dparam = self._populate_dparam(layer, rlevel, area, tile) with ExitStack() as stack: - if hasattr(_opj2.OPENJP2, + if hasattr(opj2.OPENJP2, 'opj_stream_create_default_file_stream_v3'): filename = self.filename - stream = _opj2.stream_create_default_file_stream_v3(filename, - True) - stack.callback(_opj2.stream_destroy_v3, stream) + stream = opj2.stream_create_default_file_stream_v3(filename, + True) + stack.callback(opj2.stream_destroy_v3, stream) else: fptr = _libc.fopen(self.filename, 'rb') stack.callback(_libc.fclose, fptr) - stream = _opj2.stream_create_default_file_stream(fptr, True) - stack.callback(_opj2.stream_destroy, stream) - codec = _opj2.create_decompress(self._codec_format) - stack.callback(_opj2.destroy_codec, codec) + stream = opj2.stream_create_default_file_stream(fptr, True) + stack.callback(opj2.stream_destroy, stream) + codec = opj2.create_decompress(self._codec_format) + stack.callback(opj2.destroy_codec, codec) - _opj2.set_error_handler(codec, _ERROR_CALLBACK) - _opj2.set_warning_handler(codec, _WARNING_CALLBACK) + opj2.set_error_handler(codec, _ERROR_CALLBACK) + opj2.set_warning_handler(codec, _WARNING_CALLBACK) if verbose: - _opj2.set_info_handler(codec, _INFO_CALLBACK) + opj2.set_info_handler(codec, _INFO_CALLBACK) else: - _opj2.set_info_handler(codec, None) + opj2.set_info_handler(codec, None) - _opj2.setup_decoder(codec, dparam) - image = _opj2.read_header(stream, codec) - stack.callback(_opj2.image_destroy, image) + opj2.setup_decoder(codec, dparam) + image = opj2.read_header(stream, codec) + stack.callback(opj2.image_destroy, image) if dparam.nb_tile_to_decode: - _opj2.get_decoded_tile(codec, stream, image, dparam.tile_index) + opj2.get_decoded_tile(codec, stream, image, dparam.tile_index) else: - _opj2.set_decode_area(codec, image, - dparam.DA_x0, dparam.DA_y0, - dparam.DA_x1, dparam.DA_y1) - _opj2.decode(codec, stream, image) - _opj2.end_decompress(codec, stream) + opj2.set_decode_area(codec, image, + dparam.DA_x0, dparam.DA_y0, + dparam.DA_x1, dparam.DA_y1) + opj2.decode(codec, stream, image) + opj2.end_decompress(codec, stream) if as_bands: data = extract_image_bands(image) @@ -1013,7 +1013,7 @@ class Jp2k(Jp2kBox): glymur.LibraryNotFoundError If glymur is unable to load the openjp2 library. """ - if _opj2.OPENJP2 is None: + if opj2.OPENJP2 is None: raise LibraryNotFoundError("You must have the development version " "of OpenJP2 installed before using " "this functionality.") @@ -1063,7 +1063,7 @@ class Jp2k(Jp2kBox): If the file is JPX with more than one codestream. """ with open(self.filename, 'rb') as fptr: - if self._codec_format == _opj2.CODEC_J2K: + if self._codec_format == opj2.CODEC_J2K: codestream = Codestream(fptr, self.length, header_only=header_only) else: @@ -1087,6 +1087,7 @@ class Jp2k(Jp2kBox): return codestream + def component2dtype(component): """Take an OpenJPEG component structure and determine the numpy datatype. @@ -1127,6 +1128,7 @@ def _validate_nonzero_image_size(nrows, ncols, component_index): msg = msg.format(component_index, nrows, ncols) raise IOError(msg) + def _validate_jp2_box_sequence(boxes): """Run through series of tests for JP2 box legality. @@ -1198,6 +1200,7 @@ def _validate_jp2_box_sequence(boxes): msg += "channel definition box." raise IOError(msg) + def extract_image_cube(image): """Extract 3D image from openjpeg data structure. """ @@ -1226,6 +1229,7 @@ def extract_image_cube(image): return data + def extract_image_bands(image): """Extract unequally-sized image bands. @@ -1246,11 +1250,12 @@ def extract_image_bands(image): with warnings.catch_warnings(): warnings.simplefilter("ignore") band = np.ctypeslib.as_array( - (ctypes.c_int32 * nrows * ncols).from_address(addr)) + (ctypes.c_int32 * nrows * ncols).from_address(addr)) data.append(np.reshape(band.astype(dtype), (nrows, ncols))) return data + def _unpack_colorspace(colorspace, img_array, cparams): """Determine the colorspace from the supplied inputs. @@ -1267,17 +1272,17 @@ def _unpack_colorspace(colorspace, img_array, cparams): # Must infer the colorspace from the image dimensions. if img_array.ndim < 3: # A single channel image is grayscale. - colorspace = _opj2.CLRSPC_GRAY + colorspace = opj2.CLRSPC_GRAY elif img_array.shape[2] == 1 or img_array.shape[2] == 2: # A single channel image or an image with two channels is going # to be greyscale. - colorspace = _opj2.CLRSPC_GRAY + colorspace = opj2.CLRSPC_GRAY else: # Anything else must be RGB, right? - colorspace = _opj2.CLRSPC_SRGB + colorspace = opj2.CLRSPC_SRGB else: # Supplied a string colorspace, so we must validate it. - if cparams.codec_fmt == _opj2.CODEC_J2K: + if cparams.codec_fmt == opj2.CODEC_J2K: msg = 'Do not specify a colorspace when writing a raw ' msg += 'codestream.' raise IOError(msg) diff --git a/glymur/lib/__init__.py b/glymur/lib/__init__.py index 20fee5f..a283f7f 100644 --- a/glymur/lib/__init__.py +++ b/glymur/lib/__init__.py @@ -1,4 +1,4 @@ """This package organizes individual libraries employed by glymur.""" -from . import openjp2 as _openjp2 -from . import openjpeg as _openjpeg +from . import openjp2 as openjp2 +from . import openjpeg as openjpeg from . import c diff --git a/glymur/test/fixtures.py b/glymur/test/fixtures.py index b6ba85d..ad4fe6d 100644 --- a/glymur/test/fixtures.py +++ b/glymur/test/fixtures.py @@ -36,8 +36,8 @@ except ImportError: def read_image(infile): """Read image using matplotlib backend. - - Hopefully PIL(low) is installed as matplotlib's backend. It issues + + Hopefully PIL(low) is installed as matplotlib's backend. It issues warnings which we do not care about, so suppress them. """ with warnings.catch_warnings(): @@ -101,6 +101,7 @@ def read_pgx(pgx_file): return(data.byteswap(swapbytes)) + def determine_pgx_datatype(signed, bitdepth): """Determine the datatype of the PGX file. @@ -128,6 +129,7 @@ def determine_pgx_datatype(signed, bitdepth): return dtype + def read_pgx_header(pgx_file): """Open the file in ascii mode (not really) and read the header line. Will look something like @@ -150,4 +152,3 @@ def read_pgx_header(pgx_file): header = header.rstrip() return header, pos - From fbc9bbcf14d533d59206f905d6a94a2dcdd27178 Mon Sep 17 00:00:00 2001 From: John Evans Date: Sat, 10 Aug 2013 14:39:25 -0400 Subject: [PATCH 07/20] Pylint work, #99 --- glymur/codestream.py | 62 ++- glymur/test/test_opj_suite.py | 504 ++++++++++---------- glymur/test/test_opj_suite_write.py | 689 ++++++++++++++++------------ 3 files changed, 673 insertions(+), 582 deletions(-) diff --git a/glymur/codestream.py b/glymur/codestream.py index 2c24bef..7bd0215 100644 --- a/glymur/codestream.py +++ b/glymur/codestream.py @@ -807,6 +807,8 @@ class COCsegment(Segment): Coding style for this component. spcoc : byte array Coding style parameters for this component. + precinct_size : list of tuples + Dimensions of precinct. References ---------- @@ -820,13 +822,13 @@ class COCsegment(Segment): self.scoc = scoc self.spcoc = spcoc - self._code_block_size = (4 * math.pow(2, self.spcoc[2]), - 4 * math.pow(2, self.spcoc[1])) + self.code_block_size = (4 * math.pow(2, self.spcoc[2]), + 4 * math.pow(2, self.spcoc[1])) if len(self.spcoc) > 5: - self._precinct_size = _parse_precinct_size(self.spcoc[5:]) + self.precinct_size = _parse_precinct_size(self.spcoc[5:]) else: - self._precinct_size = None + self.precinct_size = None self.length = length self.offset = offset @@ -847,16 +849,16 @@ class COCsegment(Segment): msg += '\n Code block height, width: ({1} x {2})' msg += '\n Wavelet transform: {3}' msg = msg.format(self.spcoc[0] + 1, - int(self._code_block_size[0]), - int(self._code_block_size[1]), + int(self.code_block_size[0]), + int(self.code_block_size[1]), _WAVELET_TRANSFORM_DISPLAY[self.spcoc[4]]) msg += '\n ' msg += _context_string(self.spcoc[3]) - if self._precinct_size is not None: + if self.precinct_size is not None: msg += '\n Precinct size: ' - for pps in self._precinct_size: + for pps in self.precinct_size: msg += '(%d, %d)'.format(pps) return msg @@ -876,10 +878,16 @@ class CODsegment(Segment): two bytes constituting the marker. scod : int Default coding style. + layers : int + Quality layers. + code_block_size : tuple + Size of code block. spcod : bytes - Coding style parameters, including quality layers, multicomponent - transform usage, decomposition levels, code block size, style of code- - block passes, and which wavelet transform is used. + Encoded coding style parameters, including quality layers, + multi component transform usage, decomposition levels, code block size, + style of code-block passes, and which wavelet transform is used. + precinct_size : list of tuples + Dimensions of precinct. References ---------- @@ -895,7 +903,7 @@ class CODsegment(Segment): self.offset = offset params = struct.unpack('>BHBBBBBB', self.spcod[0:9]) - self._layers = params[1] + self.layers = params[1] self._numresolutions = params[3] if params[3] > opj2.J2K_MAXRLVLS: @@ -906,12 +914,12 @@ class CODsegment(Segment): cblk_width = 4 * math.pow(2, params[4]) cblk_height = 4 * math.pow(2, params[5]) code_block_size = (cblk_height, cblk_width) - self._code_block_size = code_block_size + self.code_block_size = code_block_size if len(self.spcod) > 9: - self._precinct_size = _parse_precinct_size(self.spcod[9:]) + self.precinct_size = _parse_precinct_size(self.spcod[9:]) else: - self._precinct_size = None + self.precinct_size = None def __str__(self): msg = Segment.__str__(self) @@ -944,18 +952,18 @@ class CODsegment(Segment): msg += '\n '.join(lines) msg = msg.format(_PROGRESSION_ORDER_DISPLAY[self.spcod[0]], - self._layers, + self.layers, mct, self.spcod[4] + 1, - int(self._code_block_size[0]), - int(self._code_block_size[1]), + int(self.code_block_size[0]), + int(self.code_block_size[1]), _WAVELET_TRANSFORM_DISPLAY[self.spcod[8]]) msg += '\n Precinct size: ' - if self._precinct_size is None: + if self.precinct_size is None: msg += 'default, 2^15 x 2^15' else: - for pps in self._precinct_size: + for pps in self.precinct_size: msg += '({0}, {1})'.format(pps[0], pps[1]) msg += '\n ' @@ -1411,7 +1419,11 @@ class SIZsegment(Segment): xtosiz, ytosiz : int Horizontal and vertical offsets of tile from origin of reference grid. ssiz : iterable bytes - Precision (depth) in bits and sign of each component. + Encoded precision (depth) in bits and sign of each component. + bitdepth : iterable bytes + Precision (depth) in bits of each component. + signed : iterable bool + Signedness of each component. xrsiz, yrsiz : int Horizontal and vertical sample separations with respect to reference grid. @@ -1459,8 +1471,8 @@ class SIZsegment(Segment): self.xrsiz = data[1::3] self.yrsiz = data[2::3] - self._bitdepth = tuple(((x & 0x7f) + 1) for x in self.ssiz) - self._signed = tuple(((x & 0xb0) > 0) for x in self.ssiz) + self.bitdepth = tuple(((x & 0x7f) + 1) for x in self.ssiz) + self.signed = tuple(((x & 0xb0) > 0) for x in self.ssiz) self.length = length self.offset = offset @@ -1483,8 +1495,8 @@ class SIZsegment(Segment): self.yosiz, self.xosiz, self.ytsiz, self.xtsiz, self.ytosiz, self.xtosiz, - self._bitdepth, - self._signed, + self.bitdepth, + self.signed, tuple(zip(self.yrsiz, self.xrsiz))) return msg diff --git a/glymur/test/test_opj_suite.py b/glymur/test/test_opj_suite.py index 102b145..0a15879 100644 --- a/glymur/test/test_opj_suite.py +++ b/glymur/test/test_opj_suite.py @@ -1549,9 +1549,9 @@ class TestSuiteDump(unittest.TestCase): # Tile offset self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz), (0, 0)) # bitdepth - self.assertEqual(c.segment[1]._bitdepth, (8,)) + self.assertEqual(c.segment[1].bitdepth, (8,)) # signed - self.assertEqual(c.segment[1]._signed, (False,)) + self.assertEqual(c.segment[1].signed, (False,)) # subsampling self.assertEqual(list(zip(c.segment[1].xrsiz, c.segment[1].yrsiz)), [(1, 1)]) @@ -1568,10 +1568,10 @@ class TestSuiteDump(unittest.TestCase): self.assertFalse(c.segment[3].scod & 2) # no sop self.assertFalse(c.segment[3].scod & 4) # no eph self.assertEqual(c.segment[3].spcod[0], glymur.core.RLCP) - self.assertEqual(c.segment[3]._layers, 1) # layers = 1 + self.assertEqual(c.segment[3].layers, 1) # layers = 1 self.assertEqual(c.segment[3].spcod[3], 0) # mct self.assertEqual(c.segment[3].spcod[4], 3) # layers - self.assertEqual(tuple(c.segment[3]._code_block_size), + self.assertEqual(tuple(c.segment[3].code_block_size), (64, 64)) # cblk # Selective arithmetic coding bypass self.assertFalse(c.segment[3].spcod[7] & 0x01) @@ -1611,9 +1611,9 @@ class TestSuiteDump(unittest.TestCase): # Tile offset self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz), (0, 0)) # bitdepth - self.assertEqual(c.segment[1]._bitdepth, (8,)) + self.assertEqual(c.segment[1].bitdepth, (8,)) # signed - self.assertEqual(c.segment[1]._signed, (False,)) + self.assertEqual(c.segment[1].signed, (False,)) # subsampling self.assertEqual(list(zip(c.segment[1].xrsiz, c.segment[1].yrsiz)), [(2, 1)]) @@ -1622,10 +1622,10 @@ class TestSuiteDump(unittest.TestCase): self.assertTrue(c.segment[2].scod & 2) # sop self.assertTrue(c.segment[2].scod & 4) # eph self.assertEqual(c.segment[2].spcod[0], glymur.core.LRCP) - self.assertEqual(c.segment[2]._layers, 6) # layers = 6 + self.assertEqual(c.segment[2].layers, 6) # layers = 6 self.assertEqual(c.segment[2].spcod[3], 0) # mct self.assertEqual(c.segment[2].spcod[4], 3) # levels - self.assertEqual(tuple(c.segment[2]._code_block_size), + self.assertEqual(tuple(c.segment[2].code_block_size), (64, 64)) # cblk # Selective arithmetic coding bypass self.assertFalse(c.segment[2].spcod[7] & 0x01) @@ -1645,7 +1645,7 @@ class TestSuiteDump(unittest.TestCase): # COC: Coding style component self.assertEqual(c.segment[3].ccoc, 0) self.assertEqual(c.segment[3].spcoc[0], 3) # levels - self.assertEqual(tuple(c.segment[3]._code_block_size), + self.assertEqual(tuple(c.segment[3].code_block_size), (32, 32)) # cblk # Selective arithmetic coding bypass self.assertFalse(c.segment[3].spcoc[3] & 0x01) @@ -1717,9 +1717,9 @@ class TestSuiteDump(unittest.TestCase): # Tile offset self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz), (0, 0)) # bitdepth - self.assertEqual(c.segment[1]._bitdepth, (4,)) + self.assertEqual(c.segment[1].bitdepth, (4,)) # signed - self.assertEqual(c.segment[1]._signed, (True,)) + self.assertEqual(c.segment[1].signed, (True,)) # subsampling self.assertEqual(list(zip(c.segment[1].xrsiz, c.segment[1].yrsiz)), [(1, 1)]) @@ -1728,10 +1728,10 @@ class TestSuiteDump(unittest.TestCase): self.assertTrue(c.segment[2].scod & 2) self.assertFalse(c.segment[2].scod & 4) self.assertEqual(c.segment[2].spcod[0], glymur.core.PCRL) - self.assertEqual(c.segment[2]._layers, 8) # 8 + self.assertEqual(c.segment[2].layers, 8) # 8 self.assertEqual(c.segment[2].spcod[3], 0) # mct self.assertEqual(c.segment[2].spcod[4], 1) # levels - self.assertEqual(tuple(c.segment[2]._code_block_size), + self.assertEqual(tuple(c.segment[2].code_block_size), (64, 64)) # cblk # Selective arithmetic coding bypass self.assertFalse(c.segment[2].spcod[7] & 0x01) @@ -1834,9 +1834,9 @@ class TestSuiteDump(unittest.TestCase): # Tile offset self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz), (0, 0)) # bitdepth - self.assertEqual(c.segment[1]._bitdepth, (8, 8, 8)) + self.assertEqual(c.segment[1].bitdepth, (8, 8, 8)) # signed - self.assertEqual(c.segment[1]._signed, (False, False, False)) + self.assertEqual(c.segment[1].signed, (False, False, False)) # subsampling self.assertEqual(list(zip(c.segment[1].xrsiz, c.segment[1].yrsiz)), [(1, 1), (1, 1), (1, 1)]) @@ -1845,10 +1845,10 @@ class TestSuiteDump(unittest.TestCase): self.assertFalse(c.segment[2].scod & 2) self.assertFalse(c.segment[2].scod & 4) self.assertEqual(c.segment[2].spcod[0], glymur.core.RLCP) - self.assertEqual(c.segment[2]._layers, 20) # 20 + self.assertEqual(c.segment[2].layers, 20) # 20 self.assertEqual(c.segment[2].spcod[3], 1) # mct self.assertEqual(c.segment[2].spcod[4], 6) # levels - self.assertEqual(tuple(c.segment[2]._code_block_size), + self.assertEqual(tuple(c.segment[2].code_block_size), (64, 64)) # cblk # Selective arithmetic coding bypass self.assertFalse(c.segment[2].spcod[7] & 0x01) @@ -1864,7 +1864,7 @@ class TestSuiteDump(unittest.TestCase): self.assertFalse(c.segment[2].spcod[7] & 0x0020) self.assertEqual(c.segment[2].spcod[8], glymur.core.WAVELET_XFORM_9X7_IRREVERSIBLE) - self.assertEqual(c.segment[2]._precinct_size, + self.assertEqual(c.segment[2].precinct_size, [(128, 128), (128, 128), (128, 128), (128, 128), (128, 128), (128, 128), (128, 128)]) @@ -1943,9 +1943,9 @@ class TestSuiteDump(unittest.TestCase): # Tile offset self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz), (0, 0)) # bitdepth - self.assertEqual(c.segment[1]._bitdepth, (8, 8, 8, 8)) + self.assertEqual(c.segment[1].bitdepth, (8, 8, 8, 8)) # signed - self.assertEqual(c.segment[1]._signed, (False, False, False, False)) + self.assertEqual(c.segment[1].signed, (False, False, False, False)) # subsampling self.assertEqual(list(zip(c.segment[1].xrsiz, c.segment[1].yrsiz)), [(1, 1), (1, 1), (2, 2), (2, 2)]) @@ -1954,10 +1954,10 @@ class TestSuiteDump(unittest.TestCase): self.assertFalse(c.segment[2].scod & 2) self.assertFalse(c.segment[2].scod & 4) self.assertEqual(c.segment[2].spcod[0], glymur.core.PCRL) - self.assertEqual(c.segment[2]._layers, 7) # 7 + self.assertEqual(c.segment[2].layers, 7) # 7 self.assertEqual(c.segment[2].spcod[3], 0) # mct self.assertEqual(c.segment[2].spcod[4], 6) # levels - self.assertEqual(tuple(c.segment[2]._code_block_size), + self.assertEqual(tuple(c.segment[2].code_block_size), (32, 32)) # cblk # Selective arithmetic coding bypass self.assertFalse(c.segment[2].spcod[7] & 0x01) @@ -1978,7 +1978,7 @@ class TestSuiteDump(unittest.TestCase): # COC: Coding style component self.assertEqual(c.segment[3].ccoc, 1) self.assertEqual(c.segment[3].spcoc[0], 3) # levels - self.assertEqual(tuple(c.segment[3]._code_block_size), + self.assertEqual(tuple(c.segment[3].code_block_size), (32, 32)) # cblk # Selective arithmetic coding bypass self.assertFalse(c.segment[3].spcoc[3] & 0x01) @@ -1998,7 +1998,7 @@ class TestSuiteDump(unittest.TestCase): # COC: Coding style component self.assertEqual(c.segment[4].ccoc, 3) self.assertEqual(c.segment[4].spcoc[0], 6) # levels - self.assertEqual(tuple(c.segment[4]._code_block_size), + self.assertEqual(tuple(c.segment[4].code_block_size), (32, 32)) # cblk # Selective arithmetic coding bypass self.assertFalse(c.segment[4].spcoc[3] & 0x01) @@ -2086,9 +2086,9 @@ class TestSuiteDump(unittest.TestCase): # Tile offset self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz), (0, 0)) # bitdepth - self.assertEqual(c.segment[1]._bitdepth, (12, 12, 12, 12)) + self.assertEqual(c.segment[1].bitdepth, (12, 12, 12, 12)) # signed - self.assertEqual(c.segment[1]._signed, (False, False, False, False)) + self.assertEqual(c.segment[1].signed, (False, False, False, False)) # subsampling self.assertEqual(list(zip(c.segment[1].xrsiz, c.segment[1].yrsiz)), [(1, 1), (2, 1), (1, 2), (2, 2)]) @@ -2097,10 +2097,10 @@ class TestSuiteDump(unittest.TestCase): self.assertFalse(c.segment[2].scod & 2) self.assertFalse(c.segment[2].scod & 4) self.assertEqual(c.segment[2].spcod[0], glymur.core.RPCL) - self.assertEqual(c.segment[2]._layers, 4) # 4 + self.assertEqual(c.segment[2].layers, 4) # 4 self.assertEqual(c.segment[2].spcod[3], 0) # mct self.assertEqual(c.segment[2].spcod[4], 6) # levels - self.assertEqual(tuple(c.segment[2]._code_block_size), + self.assertEqual(tuple(c.segment[2].code_block_size), (64, 64)) # cblk # Selective arithmetic coding bypass self.assertFalse(c.segment[2].spcod[7] & 0x01) @@ -2169,7 +2169,7 @@ class TestSuiteDump(unittest.TestCase): # COC: Coding style component self.assertEqual(c.segment[7].ccoc, 3) self.assertEqual(c.segment[7].spcoc[0], 6) # levels - self.assertEqual(tuple(c.segment[7]._code_block_size), + self.assertEqual(tuple(c.segment[7].code_block_size), (64, 64)) # cblk # Selective arithmetic coding bypass self.assertFalse(c.segment[7].spcoc[3] & 0x01) @@ -2223,9 +2223,9 @@ class TestSuiteDump(unittest.TestCase): # Tile offset self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz), (0, 0)) # bitdepth - self.assertEqual(c.segment[1]._bitdepth, (12, 12, 12)) + self.assertEqual(c.segment[1].bitdepth, (12, 12, 12)) # signed - self.assertEqual(c.segment[1]._signed, (True, True, True)) + self.assertEqual(c.segment[1].signed, (True, True, True)) # subsampling self.assertEqual(list(zip(c.segment[1].xrsiz, c.segment[1].yrsiz)), [(1, 1), (1, 1), (1, 1)]) @@ -2234,10 +2234,10 @@ class TestSuiteDump(unittest.TestCase): self.assertTrue(c.segment[2].scod & 2) self.assertTrue(c.segment[2].scod & 4) self.assertEqual(c.segment[2].spcod[0], glymur.core.RLCP) - self.assertEqual(c.segment[2]._layers, 8) # 8 + self.assertEqual(c.segment[2].layers, 8) # 8 self.assertEqual(c.segment[2].spcod[3], 0) # mct self.assertEqual(c.segment[2].spcod[4], 3) # levels - self.assertEqual(tuple(c.segment[2]._code_block_size), + self.assertEqual(tuple(c.segment[2].code_block_size), (64, 64)) # cblk # Selective arithmetic coding bypass self.assertFalse(c.segment[2].spcod[7] & 0x01) @@ -2308,9 +2308,9 @@ class TestSuiteDump(unittest.TestCase): # Tile offset self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz), (0, 0)) # bitdepth - self.assertEqual(c.segment[1]._bitdepth, (12, 12, 12)) + self.assertEqual(c.segment[1].bitdepth, (12, 12, 12)) # signed - self.assertEqual(c.segment[1]._signed, (True, True, True)) + self.assertEqual(c.segment[1].signed, (True, True, True)) # subsampling self.assertEqual(list(zip(c.segment[1].xrsiz, c.segment[1].yrsiz)), [(1, 1), (1, 1), (1, 1)]) @@ -2319,10 +2319,10 @@ class TestSuiteDump(unittest.TestCase): self.assertTrue(c.segment[2].scod & 2) self.assertTrue(c.segment[2].scod & 4) self.assertEqual(c.segment[2].spcod[0], glymur.core.CPRL) - self.assertEqual(c.segment[2]._layers, 30) # 30 + self.assertEqual(c.segment[2].layers, 30) # 30 self.assertEqual(c.segment[2].spcod[3], 0) # mct self.assertEqual(c.segment[2].spcod[4], 7) # levels - self.assertEqual(tuple(c.segment[2]._code_block_size), + self.assertEqual(tuple(c.segment[2].code_block_size), (64, 64)) # cblk # Selective arithmetic coding bypass self.assertFalse(c.segment[2].spcod[7] & 0x01) @@ -2343,7 +2343,7 @@ class TestSuiteDump(unittest.TestCase): # COC: Coding style component self.assertEqual(c.segment[3].ccoc, 0) self.assertEqual(c.segment[3].spcoc[0], 6) # levels - self.assertEqual(tuple(c.segment[3]._code_block_size), + self.assertEqual(tuple(c.segment[3].code_block_size), (64, 64)) # cblk # Selective arithmetic coding bypass self.assertFalse(c.segment[3].spcoc[3] & 0x01) @@ -2363,7 +2363,7 @@ class TestSuiteDump(unittest.TestCase): # COC: Coding style component self.assertEqual(c.segment[4].ccoc, 1) self.assertEqual(c.segment[4].spcoc[0], 7) # levels - self.assertEqual(tuple(c.segment[4]._code_block_size), + self.assertEqual(tuple(c.segment[4].code_block_size), (32, 32)) # cblk # Selective arithmetic coding bypass self.assertFalse(c.segment[4].spcoc[3] & 0x01) @@ -2383,7 +2383,7 @@ class TestSuiteDump(unittest.TestCase): # COC: Coding style component self.assertEqual(c.segment[5].ccoc, 2) self.assertEqual(c.segment[5].spcoc[0], 8) # levels - self.assertEqual(tuple(c.segment[5]._code_block_size), + self.assertEqual(tuple(c.segment[5].code_block_size), (64, 64)) # cblk # Selective arithmetic coding bypass self.assertFalse(c.segment[5].spcoc[3] & 0x01) @@ -2461,9 +2461,9 @@ class TestSuiteDump(unittest.TestCase): # Tile offset self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz), (0, 0)) # bitdepth - self.assertEqual(c.segment[1]._bitdepth, (8,)) + self.assertEqual(c.segment[1].bitdepth, (8,)) # signed - self.assertEqual(c.segment[1]._signed, (False,)) + self.assertEqual(c.segment[1].signed, (False,)) # subsampling self.assertEqual(list(zip(c.segment[1].xrsiz, c.segment[1].yrsiz)), [(1, 1)]) @@ -2472,10 +2472,10 @@ class TestSuiteDump(unittest.TestCase): self.assertFalse(c.segment[2].scod & 2) self.assertFalse(c.segment[2].scod & 4) self.assertEqual(c.segment[2].spcod[0], glymur.core.LRCP) - self.assertEqual(c.segment[2]._layers, 1) # 1 + self.assertEqual(c.segment[2].layers, 1) # 1 self.assertEqual(c.segment[2].spcod[3], 0) # mct self.assertEqual(c.segment[2].spcod[4], 5) # levels - self.assertEqual(tuple(c.segment[2]._code_block_size), + self.assertEqual(tuple(c.segment[2].code_block_size), (64, 64)) # cblk # Selective arithmetic coding bypass self.assertFalse(c.segment[2].spcod[7] & 0x01) @@ -2541,9 +2541,9 @@ class TestSuiteDump(unittest.TestCase): # Tile offset self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz), (0, 0)) # bitdepth - self.assertEqual(c.segment[1]._bitdepth, (8, 8, 8)) + self.assertEqual(c.segment[1].bitdepth, (8, 8, 8)) # signed - self.assertEqual(c.segment[1]._signed, (False, False, False)) + self.assertEqual(c.segment[1].signed, (False, False, False)) # subsampling self.assertEqual(list(zip(c.segment[1].xrsiz, c.segment[1].yrsiz)), [(4, 4), (4, 4), (4, 4)]) @@ -2552,10 +2552,10 @@ class TestSuiteDump(unittest.TestCase): self.assertFalse(c.segment[2].scod & 2) self.assertFalse(c.segment[2].scod & 4) self.assertEqual(c.segment[2].spcod[0], glymur.core.LRCP) - self.assertEqual(c.segment[2]._layers, 2) # 2 + self.assertEqual(c.segment[2].layers, 2) # 2 self.assertEqual(c.segment[2].spcod[3], 1) # mct self.assertEqual(c.segment[2].spcod[4], 3) # levels - self.assertEqual(tuple(c.segment[2]._code_block_size), + self.assertEqual(tuple(c.segment[2].code_block_size), (64, 64)) # cblk # Selective arithmetic coding bypass self.assertFalse(c.segment[2].spcod[7] & 0x01) @@ -2682,9 +2682,9 @@ class TestSuiteDump(unittest.TestCase): # Tile offset self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz), (0, 0)) # bitdepth - self.assertEqual(c.segment[1]._bitdepth, (8,)) + self.assertEqual(c.segment[1].bitdepth, (8,)) # signed - self.assertEqual(c.segment[1]._signed, (False,)) + self.assertEqual(c.segment[1].signed, (False,)) # subsampling self.assertEqual(list(zip(c.segment[1].xrsiz, c.segment[1].yrsiz)), [(1, 1)]) @@ -2693,10 +2693,10 @@ class TestSuiteDump(unittest.TestCase): self.assertFalse(c.segment[2].scod & 2) self.assertTrue(c.segment[2].scod & 4) self.assertEqual(c.segment[2].spcod[0], glymur.core.LRCP) - self.assertEqual(c.segment[2]._layers, 1) # 1 + self.assertEqual(c.segment[2].layers, 1) # 1 self.assertEqual(c.segment[2].spcod[3], 0) # mct self.assertEqual(c.segment[2].spcod[4], 0) # levels - self.assertEqual(tuple(c.segment[2]._code_block_size), + self.assertEqual(tuple(c.segment[2].code_block_size), (64, 64)) # cblk # Selective arithmetic coding bypass self.assertFalse(c.segment[2].spcod[7] & 0x01) @@ -2712,7 +2712,7 @@ class TestSuiteDump(unittest.TestCase): self.assertTrue(c.segment[2].spcod[7] & 0x0020) self.assertEqual(c.segment[2].spcod[8], glymur.core.WAVELET_XFORM_5X3_REVERSIBLE) - self.assertEqual(c.segment[2]._precinct_size, [(128, 2)]) + self.assertEqual(c.segment[2].precinct_size, [(128, 2)]) # QCD: Quantization default # quantization type @@ -2763,9 +2763,9 @@ class TestSuiteDump(unittest.TestCase): # Tile offset self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz), (0, 0)) # bitdepth - self.assertEqual(c.segment[1]._bitdepth, (8,)) + self.assertEqual(c.segment[1].bitdepth, (8,)) # signed - self.assertEqual(c.segment[1]._signed, (False,)) + self.assertEqual(c.segment[1].signed, (False,)) # subsampling self.assertEqual(list(zip(c.segment[1].xrsiz, c.segment[1].yrsiz)), [(1, 1)]) @@ -2774,10 +2774,10 @@ class TestSuiteDump(unittest.TestCase): self.assertTrue(c.segment[2].scod & 2) self.assertFalse(c.segment[2].scod & 4) self.assertEqual(c.segment[2].spcod[0], glymur.core.LRCP) - self.assertEqual(c.segment[2]._layers, 1) # 1 + self.assertEqual(c.segment[2].layers, 1) # 1 self.assertEqual(c.segment[2].spcod[3], 0) # mct self.assertEqual(c.segment[2].spcod[4], 3) # levels - self.assertEqual(tuple(c.segment[2]._code_block_size), + self.assertEqual(tuple(c.segment[2].code_block_size), (32, 32)) # cblk # Selective arithmetic coding bypass self.assertFalse(c.segment[2].spcod[7] & 0x01) @@ -2845,9 +2845,9 @@ class TestSuiteDump(unittest.TestCase): # Tile offset self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz), (0, 0)) # bitdepth - self.assertEqual(c.segment[1]._bitdepth, tuple([8] * 257)) + self.assertEqual(c.segment[1].bitdepth, tuple([8] * 257)) # signed - self.assertEqual(c.segment[1]._signed, tuple([False] * 257)) + self.assertEqual(c.segment[1].signed, tuple([False] * 257)) # subsampling self.assertEqual(list(zip(c.segment[1].xrsiz, c.segment[1].yrsiz)), [(1, 1)] * 257) @@ -2856,10 +2856,10 @@ class TestSuiteDump(unittest.TestCase): self.assertFalse(c.segment[2].scod & 2) # no sop self.assertFalse(c.segment[2].scod & 4) # no eph self.assertEqual(c.segment[2].spcod[0], glymur.core.RLCP) - self.assertEqual(c.segment[2]._layers, 1) # layers = 1 + self.assertEqual(c.segment[2].layers, 1) # layers = 1 self.assertEqual(c.segment[2].spcod[3], 1) # mct self.assertEqual(c.segment[2].spcod[4], 1) # levels - self.assertEqual(tuple(c.segment[2]._code_block_size), (32, 32)) + self.assertEqual(tuple(c.segment[2].code_block_size), (32, 32)) # Selective arithmetic coding bypass self.assertFalse(c.segment[2].spcod[7] & 0x01) # Reset context probabilities @@ -2879,7 +2879,7 @@ class TestSuiteDump(unittest.TestCase): # COC: Coding style component self.assertEqual(c.segment[3].ccoc, 2) self.assertEqual(c.segment[3].spcoc[0], 1) # levels - self.assertEqual(tuple(c.segment[3]._code_block_size), (64, 64)) + self.assertEqual(tuple(c.segment[3].code_block_size), (64, 64)) # Selective arithmetic coding bypass self.assertFalse(c.segment[3].spcoc[3] & 0x01) # Reset context probabilities @@ -2971,9 +2971,9 @@ class TestSuiteDump(unittest.TestCase): # Tile offset self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz), (0, 0)) # bitdepth - self.assertEqual(c.segment[1]._bitdepth, (8, 8, 8)) + self.assertEqual(c.segment[1].bitdepth, (8, 8, 8)) # signed - self.assertEqual(c.segment[1]._signed, (False, False, False)) + self.assertEqual(c.segment[1].signed, (False, False, False)) # subsampling self.assertEqual(list(zip(c.segment[1].xrsiz, c.segment[1].yrsiz)), [(1, 1)] * 3) @@ -2982,10 +2982,10 @@ class TestSuiteDump(unittest.TestCase): self.assertFalse(c.segment[2].scod & 2) self.assertFalse(c.segment[2].scod & 4) self.assertEqual(c.segment[2].spcod[0], glymur.core.LRCP) - self.assertEqual(c.segment[2]._layers, 1) # 1 layer + self.assertEqual(c.segment[2].layers, 1) # 1 layer self.assertEqual(c.segment[2].spcod[3], 1) # mct self.assertEqual(c.segment[2].spcod[4], 5) # levels - self.assertEqual(tuple(c.segment[2]._code_block_size), (64, 64)) + self.assertEqual(tuple(c.segment[2].code_block_size), (64, 64)) # Selective arithmetic coding bypass self.assertFalse(c.segment[2].spcod[7] & 0x01) # Reset context probabilities @@ -3047,9 +3047,9 @@ class TestSuiteDump(unittest.TestCase): # Tile offset self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz), (0, 0)) # bitdepth - self.assertEqual(c.segment[1]._bitdepth, (4,)) + self.assertEqual(c.segment[1].bitdepth, (4,)) # signed - self.assertEqual(c.segment[1]._signed, (True,)) + self.assertEqual(c.segment[1].signed, (True,)) # subsampling self.assertEqual(list(zip(c.segment[1].xrsiz, c.segment[1].yrsiz)), [(1, 1)]) @@ -3058,10 +3058,10 @@ class TestSuiteDump(unittest.TestCase): self.assertTrue(c.segment[2].scod & 2) self.assertFalse(c.segment[2].scod & 4) self.assertEqual(c.segment[2].spcod[0], glymur.core.PCRL) - self.assertEqual(c.segment[2]._layers, 8) # layers = 8 + self.assertEqual(c.segment[2].layers, 8) # layers = 8 self.assertEqual(c.segment[2].spcod[3], 0) # mct self.assertEqual(c.segment[2].spcod[4], 1) # levels - self.assertEqual(tuple(c.segment[2]._code_block_size), (64, 64)) + self.assertEqual(tuple(c.segment[2].code_block_size), (64, 64)) # Selective arithmetic coding bypass self.assertFalse(c.segment[2].spcod[7] & 0x01) # Reset context probabilities @@ -3201,9 +3201,9 @@ class TestSuiteDump(unittest.TestCase): # Tile offset self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz), (0, 0)) # bitdepth - self.assertEqual(c.segment[1]._bitdepth, (8,)) + self.assertEqual(c.segment[1].bitdepth, (8,)) # signed - self.assertEqual(c.segment[1]._signed, (False,)) + self.assertEqual(c.segment[1].signed, (False,)) # subsampling self.assertEqual(list(zip(c.segment[1].xrsiz, c.segment[1].yrsiz)), [(1, 1)]) @@ -3212,10 +3212,10 @@ class TestSuiteDump(unittest.TestCase): self.assertFalse(c.segment[2].scod & 2) self.assertFalse(c.segment[2].scod & 4) self.assertEqual(c.segment[2].spcod[0], glymur.core.RLCP) - self.assertEqual(c.segment[2]._layers, 3) # layers = 3 + self.assertEqual(c.segment[2].layers, 3) # layers = 3 self.assertEqual(c.segment[2].spcod[3], 0) # mct self.assertEqual(c.segment[2].spcod[4], 3) # levels - self.assertEqual(tuple(c.segment[2]._code_block_size), (64, 64)) + self.assertEqual(tuple(c.segment[2].code_block_size), (64, 64)) # Selective arithmetic coding bypass self.assertFalse(c.segment[2].spcod[7] & 0x01) # Reset context probabilities @@ -3269,9 +3269,9 @@ class TestSuiteDump(unittest.TestCase): # Tile offset self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz), (1, 101)) # bitdepth - self.assertEqual(c.segment[1]._bitdepth, (8,)) + self.assertEqual(c.segment[1].bitdepth, (8,)) # signed - self.assertEqual(c.segment[1]._signed, (False,)) + self.assertEqual(c.segment[1].signed, (False,)) # subsampling self.assertEqual(list(zip(c.segment[1].xrsiz, c.segment[1].yrsiz)), [(2, 1)]) @@ -3280,10 +3280,10 @@ class TestSuiteDump(unittest.TestCase): self.assertTrue(c.segment[2].scod & 2) # SOP self.assertTrue(c.segment[2].scod & 4) # EPH self.assertEqual(c.segment[2].spcod[0], glymur.core.LRCP) - self.assertEqual(c.segment[2]._layers, 5) # layers = 5 + self.assertEqual(c.segment[2].layers, 5) # layers = 5 self.assertEqual(c.segment[2].spcod[3], 0) # mct self.assertEqual(c.segment[2].spcod[4], 3) # level - self.assertEqual(tuple(c.segment[2]._code_block_size), (64, 64)) + self.assertEqual(tuple(c.segment[2].code_block_size), (64, 64)) # Selective arithmetic coding bypass self.assertFalse(c.segment[2].spcod[7] & 0x01) # Reset context probabilities @@ -3303,7 +3303,7 @@ class TestSuiteDump(unittest.TestCase): # COC: Coding style component self.assertEqual(c.segment[3].ccoc, 0) self.assertEqual(c.segment[3].spcoc[0], 3) # level - self.assertEqual(tuple(c.segment[3]._code_block_size), (32, 32)) + self.assertEqual(tuple(c.segment[3].code_block_size), (32, 32)) # Selective arithmetic coding bypass self.assertFalse(c.segment[3].spcoc[3] & 0x01) # Reset context probabilities @@ -3369,9 +3369,9 @@ class TestSuiteDump(unittest.TestCase): # Tile offset self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz), (0, 0)) # bitdepth - self.assertEqual(c.segment[1]._bitdepth, tuple([8] * 3)) + self.assertEqual(c.segment[1].bitdepth, tuple([8] * 3)) # signed - self.assertEqual(c.segment[1]._signed, tuple([False] * 3)) + self.assertEqual(c.segment[1].signed, tuple([False] * 3)) # subsampling self.assertEqual(list(zip(c.segment[1].xrsiz, c.segment[1].yrsiz)), [(1, 1)] * 3) @@ -3380,10 +3380,10 @@ class TestSuiteDump(unittest.TestCase): self.assertFalse(c.segment[2].scod & 2) # no sop self.assertFalse(c.segment[2].scod & 4) # no eph self.assertEqual(c.segment[2].spcod[0], glymur.core.LRCP) - self.assertEqual(c.segment[2]._layers, 19) # layers = 19 + self.assertEqual(c.segment[2].layers, 19) # layers = 19 self.assertEqual(c.segment[2].spcod[3], 1) # mct self.assertEqual(c.segment[2].spcod[4], 6) # level - self.assertEqual(tuple(c.segment[2]._code_block_size), + self.assertEqual(tuple(c.segment[2].code_block_size), (64, 64)) # cblk # Selective arithmetic coding bypass self.assertFalse(c.segment[2].spcod[7] & 0x01) @@ -3399,7 +3399,7 @@ class TestSuiteDump(unittest.TestCase): self.assertFalse(c.segment[2].spcod[7] & 0x0020) self.assertEqual(c.segment[2].spcod[8], glymur.core.WAVELET_XFORM_9X7_IRREVERSIBLE) - self.assertEqual(c.segment[2]._precinct_size, + self.assertEqual(c.segment[2].precinct_size, [(128, 128), (256, 256), (512, 512), (1024, 1024), (2048, 2048), (4096, 4096), (8192, 8192)]) @@ -3484,9 +3484,9 @@ class TestSuiteDump(unittest.TestCase): # Tile offset self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz), (0, 0)) # bitdepth - self.assertEqual(c.segment[1]._bitdepth, tuple([8] * 4)) + self.assertEqual(c.segment[1].bitdepth, tuple([8] * 4)) # signed - self.assertEqual(c.segment[1]._signed, tuple([False] * 4)) + self.assertEqual(c.segment[1].signed, tuple([False] * 4)) # subsampling self.assertEqual(list(zip(c.segment[1].xrsiz, c.segment[1].yrsiz)), [(1, 1), (1, 1), (2, 2), (2, 2)]) @@ -3495,10 +3495,10 @@ class TestSuiteDump(unittest.TestCase): self.assertFalse(c.segment[2].scod & 2) # no sop self.assertFalse(c.segment[2].scod & 4) # no eph self.assertEqual(c.segment[2].spcod[0], glymur.core.PCRL) - self.assertEqual(c.segment[2]._layers, 10) # layers = 10 + self.assertEqual(c.segment[2].layers, 10) # layers = 10 self.assertEqual(c.segment[2].spcod[3], 0) # mct self.assertEqual(c.segment[2].spcod[4], 6) # level - self.assertEqual(tuple(c.segment[2]._code_block_size), (32, 32)) + self.assertEqual(tuple(c.segment[2].code_block_size), (32, 32)) # Selective arithmetic coding bypass self.assertTrue(c.segment[2].spcod[7] & 0x01) # Reset context probabilities @@ -3518,7 +3518,7 @@ class TestSuiteDump(unittest.TestCase): # COC: Coding style component self.assertEqual(c.segment[3].ccoc, 1) self.assertEqual(c.segment[3].spcoc[0], 3) # level - self.assertEqual(tuple(c.segment[3]._code_block_size), (32, 32)) + self.assertEqual(tuple(c.segment[3].code_block_size), (32, 32)) # Selective arithmetic coding bypass self.assertTrue(c.segment[3].spcoc[3] & 0x01) # Reset context probabilities @@ -3537,7 +3537,7 @@ class TestSuiteDump(unittest.TestCase): # COC: Coding style component self.assertEqual(c.segment[4].ccoc, 3) self.assertEqual(c.segment[4].spcoc[0], 6) # level - self.assertEqual(tuple(c.segment[4]._code_block_size), (32, 32)) + self.assertEqual(tuple(c.segment[4].code_block_size), (32, 32)) # Selective arithmetic coding bypass self.assertTrue(c.segment[4].spcoc[3] & 0x01) # Reset context probabilities @@ -3630,9 +3630,9 @@ class TestSuiteDump(unittest.TestCase): # Tile offset self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz), (0, 0)) # bitdepth - self.assertEqual(c.segment[1]._bitdepth, (12,)) + self.assertEqual(c.segment[1].bitdepth, (12,)) # signed - self.assertEqual(c.segment[1]._signed, (False,)) + self.assertEqual(c.segment[1].signed, (False,)) # subsampling self.assertEqual(list(zip(c.segment[1].xrsiz, c.segment[1].yrsiz)), [(1, 1)]) @@ -3641,10 +3641,10 @@ class TestSuiteDump(unittest.TestCase): self.assertFalse(c.segment[2].scod & 2) # no sop self.assertFalse(c.segment[2].scod & 4) # no eph self.assertEqual(c.segment[2].spcod[0], glymur.core.LRCP) - self.assertEqual(c.segment[2]._layers, 1) # layers = 1 + self.assertEqual(c.segment[2].layers, 1) # layers = 1 self.assertEqual(c.segment[2].spcod[3], 0) # mct self.assertEqual(c.segment[2].spcod[4], 3) # level - self.assertEqual(tuple(c.segment[2]._code_block_size), (64, 64)) + self.assertEqual(tuple(c.segment[2].code_block_size), (64, 64)) # Selective arithmetic coding bypass self.assertFalse(c.segment[2].spcod[7] & 0x01) # Reset context probabilities @@ -3757,9 +3757,9 @@ class TestSuiteDump(unittest.TestCase): # Tile offset self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz), (8, 2)) # bitdepth - self.assertEqual(c.segment[1]._bitdepth, (8, 8, 8)) + self.assertEqual(c.segment[1].bitdepth, (8, 8, 8)) # signed - self.assertEqual(c.segment[1]._signed, (False, False, False)) + self.assertEqual(c.segment[1].signed, (False, False, False)) # subsampling self.assertEqual(list(zip(c.segment[1].xrsiz, c.segment[1].yrsiz)), [(1, 1)] * 3) @@ -3768,10 +3768,10 @@ class TestSuiteDump(unittest.TestCase): self.assertTrue(c.segment[2].scod & 2) # sop self.assertTrue(c.segment[2].scod & 4) # eph self.assertEqual(c.segment[2].spcod[0], glymur.core.PCRL) - self.assertEqual(c.segment[2]._layers, 2) # levels = 2 + self.assertEqual(c.segment[2].layers, 2) # levels = 2 self.assertEqual(c.segment[2].spcod[3], 1) # mct self.assertEqual(c.segment[2].spcod[4], 7) # level - self.assertEqual(tuple(c.segment[2]._code_block_size), (64, 8)) # cblk + self.assertEqual(tuple(c.segment[2].code_block_size), (64, 8)) # cblk # Selective arithmetic coding bypass self.assertTrue(c.segment[2].spcod[7] & 0x01) # Reset context probabilities @@ -3786,7 +3786,7 @@ class TestSuiteDump(unittest.TestCase): self.assertFalse(c.segment[2].spcod[7] & 0x0020) self.assertEqual(c.segment[2].spcod[8], glymur.core.WAVELET_XFORM_9X7_IRREVERSIBLE) - self.assertEqual(c.segment[2]._precinct_size, [(16, 16)] * 8) + self.assertEqual(c.segment[2].precinct_size, [(16, 16)] * 8) self.assertEqual(c.segment[3].sqcd & 0x1f, 2) # expounded self.assertEqual(c.segment[3]._guard_bits, 3) @@ -3845,9 +3845,9 @@ class TestSuiteDump(unittest.TestCase): # Tile offset self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz), (0, 0)) # bitdepth - self.assertEqual(c.segment[1]._bitdepth, (8, 8, 8)) + self.assertEqual(c.segment[1].bitdepth, (8, 8, 8)) # signed - self.assertEqual(c.segment[1]._signed, (False, False, False)) + self.assertEqual(c.segment[1].signed, (False, False, False)) # subsampling self.assertEqual(list(zip(c.segment[1].xrsiz, c.segment[1].yrsiz)), [(1, 1)] * 3) @@ -3856,10 +3856,10 @@ class TestSuiteDump(unittest.TestCase): self.assertTrue(c.segment[2].scod & 2) # sop self.assertTrue(c.segment[2].scod & 4) # eph self.assertEqual(c.segment[2].spcod[0], glymur.core.PCRL) - self.assertEqual(c.segment[2]._layers, 1) # layers = 1 + self.assertEqual(c.segment[2].layers, 1) # layers = 1 self.assertEqual(c.segment[2].spcod[3], 1) # mct self.assertEqual(c.segment[2].spcod[4], 4) # level - self.assertEqual(tuple(c.segment[2]._code_block_size), (32, 64)) + self.assertEqual(tuple(c.segment[2].code_block_size), (32, 64)) # Selective arithmetic coding bypass self.assertFalse(c.segment[2].spcod[7] & 0x01) # Reset context probabilities @@ -3938,9 +3938,9 @@ class TestSuiteDump(unittest.TestCase): # Tile offset self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz), (4, 0)) # bitdepth - self.assertEqual(c.segment[1]._bitdepth, (8, 8)) + self.assertEqual(c.segment[1].bitdepth, (8, 8)) # signed - self.assertEqual(c.segment[1]._signed, (False, False)) + self.assertEqual(c.segment[1].signed, (False, False)) # subsampling self.assertEqual(list(zip(c.segment[1].xrsiz, c.segment[1].yrsiz)), [(4, 1), (1, 1)]) @@ -3949,10 +3949,10 @@ class TestSuiteDump(unittest.TestCase): self.assertTrue(c.segment[2].scod & 2) # sop self.assertTrue(c.segment[2].scod & 4) # eph self.assertEqual(c.segment[2].spcod[0], glymur.core.RPCL) - self.assertEqual(c.segment[2]._layers, 1) # layers = 1 + self.assertEqual(c.segment[2].layers, 1) # layers = 1 self.assertEqual(c.segment[2].spcod[3], 0) # mct self.assertEqual(c.segment[2].spcod[4], 1) # level - self.assertEqual(tuple(c.segment[2]._code_block_size), (64, 64)) + self.assertEqual(tuple(c.segment[2].code_block_size), (64, 64)) # Selective arithmetic coding bypass self.assertFalse(c.segment[2].spcod[7] & 0x01) # Reset context probabilities @@ -3967,12 +3967,12 @@ class TestSuiteDump(unittest.TestCase): self.assertFalse(c.segment[2].spcod[7] & 0x0020) self.assertEqual(c.segment[2].spcod[8], glymur.core.WAVELET_XFORM_5X3_REVERSIBLE) - self.assertEqual(c.segment[2]._precinct_size, [(1, 1), (2, 2)]) + self.assertEqual(c.segment[2].precinct_size, [(1, 1), (2, 2)]) # COC: Coding style component self.assertEqual(c.segment[3].ccoc, 1) self.assertEqual(c.segment[3].spcoc[0], 1) # level - self.assertEqual(tuple(c.segment[3]._code_block_size), (64, 64)) + self.assertEqual(tuple(c.segment[3].code_block_size), (64, 64)) # Selective arithmetic coding bypass self.assertFalse(c.segment[3].spcoc[3] & 0x01) # Reset context probabilities @@ -3987,7 +3987,7 @@ class TestSuiteDump(unittest.TestCase): self.assertFalse(c.segment[3].spcoc[3] & 0x0020) self.assertEqual(c.segment[3].spcoc[4], glymur.core.WAVELET_XFORM_5X3_REVERSIBLE) - self.assertEqual(c.segment[3]._precinct_size, [(2, 2), (4, 4)]) + self.assertEqual(c.segment[3].precinct_size, [(2, 2), (4, 4)]) # QCD: Quantization default # quantization type @@ -4481,9 +4481,9 @@ class TestSuiteDump(unittest.TestCase): # Tile offset self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz), (0, 0)) # bitdepth - self.assertEqual(c.segment[1]._bitdepth, (12, 12, 12)) + self.assertEqual(c.segment[1].bitdepth, (12, 12, 12)) # signed - self.assertEqual(c.segment[1]._signed, (False, False, False)) + self.assertEqual(c.segment[1].signed, (False, False, False)) # subsampling self.assertEqual(list(zip(c.segment[1].xrsiz, c.segment[1].yrsiz)), [(1, 1)] * 3) @@ -4492,10 +4492,10 @@ class TestSuiteDump(unittest.TestCase): self.assertFalse(c.segment[2].scod & 2) # no sop self.assertFalse(c.segment[2].scod & 4) # no eph self.assertEqual(c.segment[2].spcod[0], glymur.core.CPRL) - self.assertEqual(c.segment[2]._layers, 1) # layers = 1 + self.assertEqual(c.segment[2].layers, 1) # layers = 1 self.assertEqual(c.segment[2].spcod[3], 1) # mct self.assertEqual(c.segment[2].spcod[4], 5) # level - self.assertEqual(tuple(c.segment[2]._code_block_size), (32, 32)) + self.assertEqual(tuple(c.segment[2].code_block_size), (32, 32)) # Selective arithmetic coding bypass self.assertFalse(c.segment[2].spcod[7] & 0x01) # Reset context probabilities @@ -4510,8 +4510,8 @@ class TestSuiteDump(unittest.TestCase): self.assertFalse(c.segment[2].spcod[7] & 0x0020) self.assertEqual(c.segment[2].spcod[8], glymur.core.WAVELET_XFORM_9X7_IRREVERSIBLE) - self.assertEqual(c.segment[2]._precinct_size[0], (128, 128)) - self.assertEqual(c.segment[2]._precinct_size[1:], [(256, 256)] * 5) + self.assertEqual(c.segment[2].precinct_size[0], (128, 128)) + self.assertEqual(c.segment[2].precinct_size[1:], [(256, 256)] * 5) # QCD: Quantization default # quantization type @@ -4527,7 +4527,7 @@ class TestSuiteDump(unittest.TestCase): # COC: Coding style component self.assertEqual(c.segment[4].ccoc, 1) self.assertEqual(c.segment[4].spcoc[0], 5) # level - self.assertEqual(tuple(c.segment[4]._code_block_size), (32, 32)) + self.assertEqual(tuple(c.segment[4].code_block_size), (32, 32)) # Selective arithmetic coding bypass self.assertFalse(c.segment[4].spcoc[3] & 0x01) # Reset context probabilities @@ -4559,7 +4559,7 @@ class TestSuiteDump(unittest.TestCase): # COC: Coding style component self.assertEqual(c.segment[6].ccoc, 2) self.assertEqual(c.segment[6].spcoc[0], 5) # level - self.assertEqual(tuple(c.segment[6]._code_block_size), (32, 32)) + self.assertEqual(tuple(c.segment[6].code_block_size), (32, 32)) # Selective arithmetic coding bypass self.assertFalse(c.segment[6].spcoc[3] & 0x01) # Reset context probabilities @@ -4633,9 +4633,9 @@ class TestSuiteDump(unittest.TestCase): # Tile offset self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz), (0, 0)) # bitdepth - self.assertEqual(c.segment[1]._bitdepth, (8, 8, 8)) + self.assertEqual(c.segment[1].bitdepth, (8, 8, 8)) # signed - self.assertEqual(c.segment[1]._signed, (False, False, False)) + self.assertEqual(c.segment[1].signed, (False, False, False)) # subsampling self.assertEqual(list(zip(c.segment[1].xrsiz, c.segment[1].yrsiz)), [(1, 1)] * 3) @@ -4644,10 +4644,10 @@ class TestSuiteDump(unittest.TestCase): self.assertFalse(c.segment[2].scod & 2) # no sop self.assertFalse(c.segment[2].scod & 4) # no eph self.assertEqual(c.segment[2].spcod[0], glymur.core.LRCP) - self.assertEqual(c.segment[2]._layers, 3) # layers = 3 + self.assertEqual(c.segment[2].layers, 3) # layers = 3 self.assertEqual(c.segment[2].spcod[3], 1) # mct self.assertEqual(c.segment[2].spcod[4], 5) # level - self.assertEqual(tuple(c.segment[2]._code_block_size), (32, 32)) + self.assertEqual(tuple(c.segment[2].code_block_size), (32, 32)) # Selective arithmetic coding bypass self.assertFalse(c.segment[2].spcod[7] & 0x01) # Reset context probabilities @@ -4662,7 +4662,7 @@ class TestSuiteDump(unittest.TestCase): self.assertFalse(c.segment[2].spcod[7] & 0x0020) self.assertEqual(c.segment[2].spcod[8], glymur.core.WAVELET_XFORM_5X3_REVERSIBLE) - self.assertEqual(c.segment[2]._precinct_size, + self.assertEqual(c.segment[2].precinct_size, [(16, 16), (32, 32), (64, 64), (128, 128), (128, 128), (128, 128)]) @@ -4690,9 +4690,9 @@ class TestSuiteDump(unittest.TestCase): # Tile offset self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz), (0, 0)) # bitdepth - self.assertEqual(c.segment[1]._bitdepth, (16,)) + self.assertEqual(c.segment[1].bitdepth, (16,)) # signed - self.assertEqual(c.segment[1]._signed, (False,)) + self.assertEqual(c.segment[1].signed, (False,)) # subsampling self.assertEqual(list(zip(c.segment[1].xrsiz, c.segment[1].yrsiz)), [(1, 1)] * 1) @@ -4701,10 +4701,10 @@ class TestSuiteDump(unittest.TestCase): self.assertFalse(c.segment[2].scod & 2) # no sop self.assertFalse(c.segment[2].scod & 4) # no eph self.assertEqual(c.segment[2].spcod[0], glymur.core.LRCP) - self.assertEqual(c.segment[2]._layers, 2) # layers = 2 + self.assertEqual(c.segment[2].layers, 2) # layers = 2 self.assertEqual(c.segment[2].spcod[3], 0) # mct self.assertEqual(c.segment[2].spcod[4], 5) # level - self.assertEqual(tuple(c.segment[2]._code_block_size), (64, 64)) + self.assertEqual(tuple(c.segment[2].code_block_size), (64, 64)) # Selective arithmetic coding bypass self.assertFalse(c.segment[2].spcod[7] & 0x01) # Reset context probabilities @@ -4743,9 +4743,9 @@ class TestSuiteDump(unittest.TestCase): # Tile offset self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz), (0, 0)) # bitdepth - self.assertEqual(c.segment[1]._bitdepth, (16,)) + self.assertEqual(c.segment[1].bitdepth, (16,)) # signed - self.assertEqual(c.segment[1]._signed, (False,)) + self.assertEqual(c.segment[1].signed, (False,)) # subsampling self.assertEqual(list(zip(c.segment[1].xrsiz, c.segment[1].yrsiz)), [(1, 1)] * 1) @@ -4754,10 +4754,10 @@ class TestSuiteDump(unittest.TestCase): self.assertFalse(c.segment[2].scod & 2) # no sop self.assertFalse(c.segment[2].scod & 4) # no eph self.assertEqual(c.segment[2].spcod[0], glymur.core.LRCP) - self.assertEqual(c.segment[2]._layers, 2) # layers = 2 + self.assertEqual(c.segment[2].layers, 2) # layers = 2 self.assertEqual(c.segment[2].spcod[3], 0) # mct self.assertEqual(c.segment[2].spcod[4], 5) # level - self.assertEqual(tuple(c.segment[2]._code_block_size), (64, 64)) + self.assertEqual(tuple(c.segment[2].code_block_size), (64, 64)) # Selective arithmetic coding bypass self.assertFalse(c.segment[2].spcod[7] & 0x01) # Reset context probabilities @@ -4805,9 +4805,9 @@ class TestSuiteDump(unittest.TestCase): # Tile offset self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz), (0, 0)) # bitdepth - self.assertEqual(c.segment[1]._bitdepth, (16,)) + self.assertEqual(c.segment[1].bitdepth, (16,)) # signed - self.assertEqual(c.segment[1]._signed, (False,)) + self.assertEqual(c.segment[1].signed, (False,)) # subsampling self.assertEqual(list(zip(c.segment[1].xrsiz, c.segment[1].yrsiz)), [(1, 1)] * 1) @@ -4816,10 +4816,10 @@ class TestSuiteDump(unittest.TestCase): self.assertFalse(c.segment[2].scod & 2) # no sop self.assertFalse(c.segment[2].scod & 4) # no eph self.assertEqual(c.segment[2].spcod[0], glymur.core.LRCP) - self.assertEqual(c.segment[2]._layers, 1) # layers = 1 + self.assertEqual(c.segment[2].layers, 1) # layers = 1 self.assertEqual(c.segment[2].spcod[3], 0) # mct self.assertEqual(c.segment[2].spcod[4], 11) # level - self.assertEqual(tuple(c.segment[2]._code_block_size), (64, 64)) + self.assertEqual(tuple(c.segment[2].code_block_size), (64, 64)) # Selective arithmetic coding bypass self.assertFalse(c.segment[2].spcod[7] & 0x01) # Reset context probabilities @@ -4867,9 +4867,9 @@ class TestSuiteDump(unittest.TestCase): # Tile offset self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz), (0, 0)) # bitdepth - self.assertEqual(c.segment[1]._bitdepth, (12,)) + self.assertEqual(c.segment[1].bitdepth, (12,)) # signed - self.assertEqual(c.segment[1]._signed, (False,)) + self.assertEqual(c.segment[1].signed, (False,)) # subsampling self.assertEqual(list(zip(c.segment[1].xrsiz, c.segment[1].yrsiz)), [(1, 1)] * 1) @@ -4878,10 +4878,10 @@ class TestSuiteDump(unittest.TestCase): self.assertFalse(c.segment[2].scod & 2) # no sop self.assertFalse(c.segment[2].scod & 4) # no eph self.assertEqual(c.segment[2].spcod[0], glymur.core.LRCP) - self.assertEqual(c.segment[2]._layers, 1) # layers = 1 + self.assertEqual(c.segment[2].layers, 1) # layers = 1 self.assertEqual(c.segment[2].spcod[3], 0) # mct self.assertEqual(c.segment[2].spcod[4], 5) # level - self.assertEqual(tuple(c.segment[2]._code_block_size), (64, 64)) + self.assertEqual(tuple(c.segment[2].code_block_size), (64, 64)) # Selective arithmetic coding bypass self.assertFalse(c.segment[2].spcod[7] & 0x01) # Reset context probabilities @@ -4938,9 +4938,9 @@ class TestSuiteDump(unittest.TestCase): # Tile offset self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz), (0, 0)) # bitdepth - self.assertEqual(c.segment[1]._bitdepth, (8,)) + self.assertEqual(c.segment[1].bitdepth, (8,)) # signed - self.assertEqual(c.segment[1]._signed, (False,)) + self.assertEqual(c.segment[1].signed, (False,)) # subsampling self.assertEqual(list(zip(c.segment[1].xrsiz, c.segment[1].yrsiz)), [(1, 1)] * 1) @@ -4949,10 +4949,10 @@ class TestSuiteDump(unittest.TestCase): self.assertFalse(c.segment[2].scod & 2) # no sop self.assertFalse(c.segment[2].scod & 4) # no eph self.assertEqual(c.segment[2].spcod[0], glymur.core.LRCP) - self.assertEqual(c.segment[2]._layers, 1) # layers = 1 + self.assertEqual(c.segment[2].layers, 1) # layers = 1 self.assertEqual(c.segment[2].spcod[3], 0) # mct self.assertEqual(c.segment[2].spcod[4], 5) # level - self.assertEqual(tuple(c.segment[2]._code_block_size), (64, 64)) + self.assertEqual(tuple(c.segment[2].code_block_size), (64, 64)) # Selective arithmetic coding bypass self.assertFalse(c.segment[2].spcod[7] & 0x01) # Reset context probabilities @@ -5015,9 +5015,9 @@ class TestSuiteDump(unittest.TestCase): # Tile offset self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz), (0, 0)) # bitdepth - self.assertEqual(c.segment[1]._bitdepth, (16,)) + self.assertEqual(c.segment[1].bitdepth, (16,)) # signed - self.assertEqual(c.segment[1]._signed, (False,)) + self.assertEqual(c.segment[1].signed, (False,)) # subsampling self.assertEqual(list(zip(c.segment[1].xrsiz, c.segment[1].yrsiz)), [(1, 1)] * 1) @@ -5026,10 +5026,10 @@ class TestSuiteDump(unittest.TestCase): self.assertFalse(c.segment[2].scod & 2) # no sop self.assertFalse(c.segment[2].scod & 4) # no eph self.assertEqual(c.segment[2].spcod[0], glymur.core.LRCP) - self.assertEqual(c.segment[2]._layers, 1) # layers = 1 + self.assertEqual(c.segment[2].layers, 1) # layers = 1 self.assertEqual(c.segment[2].spcod[3], 1) # mct self.assertEqual(c.segment[2].spcod[4], 11) # level - self.assertEqual(tuple(c.segment[2]._code_block_size), (64, 64)) + self.assertEqual(tuple(c.segment[2].code_block_size), (64, 64)) # Selective arithmetic coding bypass self.assertFalse(c.segment[2].spcod[7] & 0x01) # Reset context probabilities @@ -5075,9 +5075,9 @@ class TestSuiteDump(unittest.TestCase): # Tile offset self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz), (0, 0)) # bitdepth - self.assertEqual(c.segment[1]._bitdepth, (8, 8, 8)) + self.assertEqual(c.segment[1].bitdepth, (8, 8, 8)) # signed - self.assertEqual(c.segment[1]._signed, (True, True, True)) + self.assertEqual(c.segment[1].signed, (True, True, True)) # subsampling self.assertEqual(list(zip(c.segment[1].xrsiz, c.segment[1].yrsiz)), [(1, 1)] * 3) @@ -5086,10 +5086,10 @@ class TestSuiteDump(unittest.TestCase): self.assertFalse(c.segment[2].scod & 2) # no sop self.assertFalse(c.segment[2].scod & 4) # no eph self.assertEqual(c.segment[2].spcod[0], glymur.core.LRCP) - self.assertEqual(c.segment[2]._layers, 1) # layers = 1 + self.assertEqual(c.segment[2].layers, 1) # layers = 1 self.assertEqual(c.segment[2].spcod[3], 1) # mct self.assertEqual(c.segment[2].spcod[4], 5) # level - self.assertEqual(tuple(c.segment[2]._code_block_size), (64, 64)) + self.assertEqual(tuple(c.segment[2].code_block_size), (64, 64)) # Selective arithmetic coding bypass self.assertFalse(c.segment[2].spcod[7] & 0x01) # Reset context probabilities @@ -5141,9 +5141,9 @@ class TestSuiteDump(unittest.TestCase): # Tile offset self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz), (0, 0)) # bitdepth - self.assertEqual(c.segment[1]._bitdepth, (16,)) + self.assertEqual(c.segment[1].bitdepth, (16,)) # signed - self.assertEqual(c.segment[1]._signed, (False,)) + self.assertEqual(c.segment[1].signed, (False,)) # subsampling self.assertEqual(list(zip(c.segment[1].xrsiz, c.segment[1].yrsiz)), [(1, 1)] * 1) @@ -5152,10 +5152,10 @@ class TestSuiteDump(unittest.TestCase): self.assertFalse(c.segment[2].scod & 2) # no sop self.assertFalse(c.segment[2].scod & 4) # no eph self.assertEqual(c.segment[2].spcod[0], glymur.core.LRCP) - self.assertEqual(c.segment[2]._layers, 12) # layers = 12 + self.assertEqual(c.segment[2].layers, 12) # layers = 12 self.assertEqual(c.segment[2].spcod[3], 0) # mct self.assertEqual(c.segment[2].spcod[4], 8) # level - self.assertEqual(tuple(c.segment[2]._code_block_size), (64, 64)) + self.assertEqual(tuple(c.segment[2].code_block_size), (64, 64)) # Selective arithmetic coding bypass self.assertFalse(c.segment[2].spcod[7] & 0x01) # Reset context probabilities @@ -5226,9 +5226,9 @@ class TestSuiteDump(unittest.TestCase): # Tile offset self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz), (0, 0)) # bitdepth - self.assertEqual(c.segment[1]._bitdepth, (16,)) + self.assertEqual(c.segment[1].bitdepth, (16,)) # signed - self.assertEqual(c.segment[1]._signed, (False,)) + self.assertEqual(c.segment[1].signed, (False,)) # subsampling self.assertEqual(list(zip(c.segment[1].xrsiz, c.segment[1].yrsiz)), [(1, 1)] * 1) @@ -5237,10 +5237,10 @@ class TestSuiteDump(unittest.TestCase): self.assertFalse(c.segment[2].scod & 2) # no sop self.assertFalse(c.segment[2].scod & 4) # no eph self.assertEqual(c.segment[2].spcod[0], glymur.core.LRCP) - self.assertEqual(c.segment[2]._layers, 1) # layers = 1 + self.assertEqual(c.segment[2].layers, 1) # layers = 1 self.assertEqual(c.segment[2].spcod[3], 0) # mct self.assertEqual(c.segment[2].spcod[4], 11) # level - self.assertEqual(tuple(c.segment[2]._code_block_size), (64, 64)) + self.assertEqual(tuple(c.segment[2].code_block_size), (64, 64)) # Selective arithmetic coding bypass self.assertFalse(c.segment[2].spcod[7] & 0x01) # Reset context probabilities @@ -5286,9 +5286,9 @@ class TestSuiteDump(unittest.TestCase): # Tile offset self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz), (0, 0)) # bitdepth - self.assertEqual(c.segment[1]._bitdepth, (8, 8, 8)) + self.assertEqual(c.segment[1].bitdepth, (8, 8, 8)) # signed - self.assertEqual(c.segment[1]._signed, (False, False, False)) + self.assertEqual(c.segment[1].signed, (False, False, False)) # subsampling self.assertEqual(list(zip(c.segment[1].xrsiz, c.segment[1].yrsiz)), [(1, 1)] * 3) @@ -5297,10 +5297,10 @@ class TestSuiteDump(unittest.TestCase): self.assertFalse(c.segment[2].scod & 2) # no sop self.assertFalse(c.segment[2].scod & 4) # no eph self.assertEqual(c.segment[2].spcod[0], glymur.core.LRCP) - self.assertEqual(c.segment[2]._layers, 1) # layers = 1 + self.assertEqual(c.segment[2].layers, 1) # layers = 1 self.assertEqual(c.segment[2].spcod[3], 1) # mct self.assertEqual(c.segment[2].spcod[4], 5) # level - self.assertEqual(tuple(c.segment[2]._code_block_size), (64, 64)) + self.assertEqual(tuple(c.segment[2].code_block_size), (64, 64)) # Selective arithmetic coding bypass self.assertFalse(c.segment[2].spcod[7] & 0x01) # Reset context probabilities @@ -5344,9 +5344,9 @@ class TestSuiteDump(unittest.TestCase): # Tile offset self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz), (0, 0)) # bitdepth - self.assertEqual(c.segment[1]._bitdepth, (8, 8, 8)) + self.assertEqual(c.segment[1].bitdepth, (8, 8, 8)) # signed - self.assertEqual(c.segment[1]._signed, (False, False, False)) + self.assertEqual(c.segment[1].signed, (False, False, False)) # subsampling self.assertEqual(list(zip(c.segment[1].xrsiz, c.segment[1].yrsiz)), [(1, 1)] * 3) @@ -5355,10 +5355,10 @@ class TestSuiteDump(unittest.TestCase): self.assertFalse(c.segment[2].scod & 2) # no sop self.assertFalse(c.segment[2].scod & 4) # no eph self.assertEqual(c.segment[2].spcod[0], glymur.core.LRCP) - self.assertEqual(c.segment[2]._layers, 1) # layers = 1 + self.assertEqual(c.segment[2].layers, 1) # layers = 1 self.assertEqual(c.segment[2].spcod[3], 1) # mct self.assertEqual(c.segment[2].spcod[4], 5) # level - self.assertEqual(tuple(c.segment[2]._code_block_size), (64, 64)) + self.assertEqual(tuple(c.segment[2].code_block_size), (64, 64)) # Selective arithmetic coding bypass self.assertFalse(c.segment[2].spcod[7] & 0x01) # Reset context probabilities @@ -5402,9 +5402,9 @@ class TestSuiteDump(unittest.TestCase): # Tile offset self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz), (0, 0)) # bitdepth - self.assertEqual(c.segment[1]._bitdepth, (8, 8, 8)) + self.assertEqual(c.segment[1].bitdepth, (8, 8, 8)) # signed - self.assertEqual(c.segment[1]._signed, (False, False, False)) + self.assertEqual(c.segment[1].signed, (False, False, False)) # subsampling self.assertEqual(list(zip(c.segment[1].xrsiz, c.segment[1].yrsiz)), [(1, 1)] * 3) @@ -5413,10 +5413,10 @@ class TestSuiteDump(unittest.TestCase): self.assertFalse(c.segment[2].scod & 2) # no sop self.assertFalse(c.segment[2].scod & 4) # no eph self.assertEqual(c.segment[2].spcod[0], glymur.core.LRCP) - self.assertEqual(c.segment[2]._layers, 1) # layers = 1 + self.assertEqual(c.segment[2].layers, 1) # layers = 1 self.assertEqual(c.segment[2].spcod[3], 1) # mct self.assertEqual(c.segment[2].spcod[4], 5) # level - self.assertEqual(tuple(c.segment[2]._code_block_size), (64, 64)) + self.assertEqual(tuple(c.segment[2].code_block_size), (64, 64)) # Selective arithmetic coding bypass self.assertFalse(c.segment[2].spcod[7] & 0x01) # Reset context probabilities @@ -5463,9 +5463,9 @@ class TestSuiteDump(unittest.TestCase): # Tile offset self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz), (0, 0)) # bitdepth - self.assertEqual(c.segment[1]._bitdepth, (8, 8, 8, 8)) + self.assertEqual(c.segment[1].bitdepth, (8, 8, 8, 8)) # signed - self.assertEqual(c.segment[1]._signed, (False, False, False, False)) + self.assertEqual(c.segment[1].signed, (False, False, False, False)) # subsampling self.assertEqual(list(zip(c.segment[1].xrsiz, c.segment[1].yrsiz)), [(1, 1)] * 4) @@ -5474,10 +5474,10 @@ class TestSuiteDump(unittest.TestCase): self.assertFalse(c.segment[2].scod & 2) # no sop self.assertFalse(c.segment[2].scod & 4) # no eph self.assertEqual(c.segment[2].spcod[0], glymur.core.LRCP) - self.assertEqual(c.segment[2]._layers, 1) # layers = 1 + self.assertEqual(c.segment[2].layers, 1) # layers = 1 self.assertEqual(c.segment[2].spcod[3], 0) # mct self.assertEqual(c.segment[2].spcod[4], 5) # level - self.assertEqual(tuple(c.segment[2]._code_block_size), (64, 64)) + self.assertEqual(tuple(c.segment[2].code_block_size), (64, 64)) # Selective arithmetic coding bypass self.assertFalse(c.segment[2].spcod[7] & 0x01) # Reset context probabilities @@ -5524,9 +5524,9 @@ class TestSuiteDump(unittest.TestCase): # Tile offset self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz), (0, 0)) # bitdepth - self.assertEqual(c.segment[1]._bitdepth, (8, 8, 8, 8)) + self.assertEqual(c.segment[1].bitdepth, (8, 8, 8, 8)) # signed - self.assertEqual(c.segment[1]._signed, (False, False, False, False)) + self.assertEqual(c.segment[1].signed, (False, False, False, False)) # subsampling self.assertEqual(list(zip(c.segment[1].xrsiz, c.segment[1].yrsiz)), [(1, 1)] * 4) @@ -5535,10 +5535,10 @@ class TestSuiteDump(unittest.TestCase): self.assertFalse(c.segment[2].scod & 2) # no sop self.assertFalse(c.segment[2].scod & 4) # no eph self.assertEqual(c.segment[2].spcod[0], glymur.core.LRCP) - self.assertEqual(c.segment[2]._layers, 1) # layers = 1 + self.assertEqual(c.segment[2].layers, 1) # layers = 1 self.assertEqual(c.segment[2].spcod[3], 0) # mct self.assertEqual(c.segment[2].spcod[4], 5) # level - self.assertEqual(tuple(c.segment[2]._code_block_size), (64, 64)) + self.assertEqual(tuple(c.segment[2].code_block_size), (64, 64)) # Selective arithmetic coding bypass self.assertFalse(c.segment[2].spcod[7] & 0x01) # Reset context probabilities @@ -5584,9 +5584,9 @@ class TestSuiteDump(unittest.TestCase): # Tile offset self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz), (0, 0)) # bitdepth - self.assertEqual(c.segment[1]._bitdepth, (16,)) + self.assertEqual(c.segment[1].bitdepth, (16,)) # signed - self.assertEqual(c.segment[1]._signed, (True,)) + self.assertEqual(c.segment[1].signed, (True,)) # subsampling self.assertEqual(list(zip(c.segment[1].xrsiz, c.segment[1].yrsiz)), [(1, 1)] * 1) @@ -5595,10 +5595,10 @@ class TestSuiteDump(unittest.TestCase): self.assertFalse(c.segment[2].scod & 2) # no sop self.assertFalse(c.segment[2].scod & 4) # no eph self.assertEqual(c.segment[2].spcod[0], glymur.core.LRCP) - self.assertEqual(c.segment[2]._layers, 16) # layers = 16 + self.assertEqual(c.segment[2].layers, 16) # layers = 16 self.assertEqual(c.segment[2].spcod[3], 0) # mct self.assertEqual(c.segment[2].spcod[4], 5) # level - self.assertEqual(tuple(c.segment[2]._code_block_size), (64, 64)) + self.assertEqual(tuple(c.segment[2].code_block_size), (64, 64)) # Selective arithmetic coding bypass self.assertFalse(c.segment[2].spcod[7] & 0x01) # Reset context probabilities @@ -5654,9 +5654,9 @@ class TestSuiteDump(unittest.TestCase): # Tile offset self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz), (0, 0)) # bitdepth - self.assertEqual(c.segment[1]._bitdepth, (12,)) + self.assertEqual(c.segment[1].bitdepth, (12,)) # signed - self.assertEqual(c.segment[1]._signed, (False,)) + self.assertEqual(c.segment[1].signed, (False,)) # subsampling self.assertEqual(list(zip(c.segment[1].xrsiz, c.segment[1].yrsiz)), [(1, 1)] * 1) @@ -5665,10 +5665,10 @@ class TestSuiteDump(unittest.TestCase): self.assertFalse(c.segment[2].scod & 2) # no sop self.assertFalse(c.segment[2].scod & 4) # no eph self.assertEqual(c.segment[2].spcod[0], glymur.core.LRCP) - self.assertEqual(c.segment[2]._layers, 1) # layers = 1 + self.assertEqual(c.segment[2].layers, 1) # layers = 1 self.assertEqual(c.segment[2].spcod[3], 0) # mct self.assertEqual(c.segment[2].spcod[4], 5) # level - self.assertEqual(tuple(c.segment[2]._code_block_size), (64, 64)) + self.assertEqual(tuple(c.segment[2].code_block_size), (64, 64)) # Selective arithmetic coding bypass self.assertFalse(c.segment[2].spcod[7] & 0x01) # Reset context probabilities @@ -5723,9 +5723,9 @@ class TestSuiteDump(unittest.TestCase): # Tile offset self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz), (0, 0)) # bitdepth - self.assertEqual(c.segment[1]._bitdepth, (16,)) + self.assertEqual(c.segment[1].bitdepth, (16,)) # signed - self.assertEqual(c.segment[1]._signed, (False,)) + self.assertEqual(c.segment[1].signed, (False,)) # subsampling self.assertEqual(list(zip(c.segment[1].xrsiz, c.segment[1].yrsiz)), [(1, 1)] * 1) @@ -5734,10 +5734,10 @@ class TestSuiteDump(unittest.TestCase): self.assertFalse(c.segment[2].scod & 2) # no sop self.assertFalse(c.segment[2].scod & 4) # no eph self.assertEqual(c.segment[2].spcod[0], glymur.core.LRCP) - self.assertEqual(c.segment[2]._layers, 1) # layers = 1 + self.assertEqual(c.segment[2].layers, 1) # layers = 1 self.assertEqual(c.segment[2].spcod[3], 1) # mct self.assertEqual(c.segment[2].spcod[4], 11) # level - self.assertEqual(tuple(c.segment[2]._code_block_size), + self.assertEqual(tuple(c.segment[2].code_block_size), (64, 64)) # cblk # Selective arithmetic coding bypass self.assertFalse(c.segment[2].spcod[7] & 0x01) @@ -5785,9 +5785,9 @@ class TestSuiteDump(unittest.TestCase): # Tile offset self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz), (0, 0)) # bitdepth - self.assertEqual(c.segment[1]._bitdepth, (16,)) + self.assertEqual(c.segment[1].bitdepth, (16,)) # signed - self.assertEqual(c.segment[1]._signed, (False,)) + self.assertEqual(c.segment[1].signed, (False,)) # subsampling self.assertEqual(list(zip(c.segment[1].xrsiz, c.segment[1].yrsiz)), [(1, 1)] * 1) @@ -5796,10 +5796,10 @@ class TestSuiteDump(unittest.TestCase): self.assertFalse(c.segment[2].scod & 2) # no sop self.assertFalse(c.segment[2].scod & 4) # no eph self.assertEqual(c.segment[2].spcod[0], glymur.core.LRCP) - self.assertEqual(c.segment[2]._layers, 1) # layers = 1 + self.assertEqual(c.segment[2].layers, 1) # layers = 1 self.assertEqual(c.segment[2].spcod[3], 1) # mct self.assertEqual(c.segment[2].spcod[4], 11) # level - self.assertEqual(tuple(c.segment[2]._code_block_size), + self.assertEqual(tuple(c.segment[2].code_block_size), (64, 64)) # cblk # Selective arithmetic coding bypass self.assertFalse(c.segment[2].spcod[7] & 0x01) @@ -5848,9 +5848,9 @@ class TestSuiteDump(unittest.TestCase): # Tile offset self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz), (0, 0)) # bitdepth - self.assertEqual(c.segment[1]._bitdepth, (12, 12, 12)) + self.assertEqual(c.segment[1].bitdepth, (12, 12, 12)) # signed - self.assertEqual(c.segment[1]._signed, (False, False, False)) + self.assertEqual(c.segment[1].signed, (False, False, False)) # subsampling self.assertEqual(list(zip(c.segment[1].xrsiz, c.segment[1].yrsiz)), [(1, 1)] * 3) @@ -5859,10 +5859,10 @@ class TestSuiteDump(unittest.TestCase): self.assertFalse(c.segment[2].scod & 2) # no sop self.assertFalse(c.segment[2].scod & 4) # no eph self.assertEqual(c.segment[2].spcod[0], glymur.core.LRCP) - self.assertEqual(c.segment[2]._layers, 2) # layers = 2 + self.assertEqual(c.segment[2].layers, 2) # layers = 2 self.assertEqual(c.segment[2].spcod[3], 1) # mct self.assertEqual(c.segment[2].spcod[4], 5) # level - self.assertEqual(tuple(c.segment[2]._code_block_size), + self.assertEqual(tuple(c.segment[2].code_block_size), (32, 32)) # cblk # Selective arithmetic coding bypass self.assertFalse(c.segment[2].spcod[7] & 0x01) @@ -5878,7 +5878,7 @@ class TestSuiteDump(unittest.TestCase): self.assertFalse(c.segment[2].spcod[7] & 0x0020) self.assertEqual(c.segment[2].spcod[8], glymur.core.WAVELET_XFORM_9X7_IRREVERSIBLE) - self.assertEqual(c.segment[2]._precinct_size, + self.assertEqual(c.segment[2].precinct_size, [(128, 128)] + [(256, 256)] * 5) # QCD: Quantization default @@ -5957,9 +5957,9 @@ class TestSuiteDump(unittest.TestCase): # Tile offset self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz), (0, 0)) # bitdepth - self.assertEqual(c.segment[1]._bitdepth, (8, 8, 8)) + self.assertEqual(c.segment[1].bitdepth, (8, 8, 8)) # signed - self.assertEqual(c.segment[1]._signed, (False, False, False)) + self.assertEqual(c.segment[1].signed, (False, False, False)) # subsampling self.assertEqual(list(zip(c.segment[1].xrsiz, c.segment[1].yrsiz)), [(1, 1)] * 3) @@ -5975,10 +5975,10 @@ class TestSuiteDump(unittest.TestCase): self.assertFalse(c.segment[3].scod & 2) # no sop self.assertFalse(c.segment[3].scod & 4) # no eph self.assertEqual(c.segment[3].spcod[0], glymur.core.LRCP) - self.assertEqual(c.segment[3]._layers, 1) # layers = 1 + self.assertEqual(c.segment[3].layers, 1) # layers = 1 self.assertEqual(c.segment[3].spcod[3], 1) # mct self.assertEqual(c.segment[3].spcod[4], 5) # level - self.assertEqual(tuple(c.segment[3]._code_block_size), + self.assertEqual(tuple(c.segment[3].code_block_size), (64, 64)) # cblk # Selective arithmetic coding bypass self.assertFalse(c.segment[3].spcod[7] & 0x01) @@ -6094,9 +6094,9 @@ class TestSuiteDump(unittest.TestCase): # Tile offset self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz), (0, 0)) # bitdepth - self.assertEqual(c.segment[1]._bitdepth, (8, 8, 8)) + self.assertEqual(c.segment[1].bitdepth, (8, 8, 8)) # signed - self.assertEqual(c.segment[1]._signed, (False, False, False)) + self.assertEqual(c.segment[1].signed, (False, False, False)) # subsampling self.assertEqual(list(zip(c.segment[1].xrsiz, c.segment[1].yrsiz)), [(1, 1)] * 3) @@ -6112,10 +6112,10 @@ class TestSuiteDump(unittest.TestCase): self.assertFalse(c.segment[3].scod & 2) # no sop self.assertFalse(c.segment[3].scod & 4) # no eph self.assertEqual(c.segment[3].spcod[0], glymur.core.LRCP) - self.assertEqual(c.segment[3]._layers, 1) # layers = 1 + self.assertEqual(c.segment[3].layers, 1) # layers = 1 self.assertEqual(c.segment[3].spcod[3], 1) # mct self.assertEqual(c.segment[3].spcod[4], 5) # level - self.assertEqual(tuple(c.segment[3]._code_block_size), + self.assertEqual(tuple(c.segment[3].code_block_size), (64, 64)) # cblk # Selective arithmetic coding bypass self.assertFalse(c.segment[3].spcod[7] & 0x01) @@ -6227,9 +6227,9 @@ class TestSuiteDump(unittest.TestCase): # Tile offset self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz), (0, 0)) # bitdepth - self.assertEqual(c.segment[1]._bitdepth, (8, 8, 8)) + self.assertEqual(c.segment[1].bitdepth, (8, 8, 8)) # signed - self.assertEqual(c.segment[1]._signed, (False, False, False)) + self.assertEqual(c.segment[1].signed, (False, False, False)) # subsampling self.assertEqual(list(zip(c.segment[1].xrsiz, c.segment[1].yrsiz)), [(1, 1), (2, 1), (2, 1)]) @@ -6238,10 +6238,10 @@ class TestSuiteDump(unittest.TestCase): self.assertFalse(c.segment[2].scod & 2) # no sop self.assertFalse(c.segment[2].scod & 4) # no eph self.assertEqual(c.segment[2].spcod[0], glymur.core.LRCP) - self.assertEqual(c.segment[2]._layers, 1) # layers = 1 + self.assertEqual(c.segment[2].layers, 1) # layers = 1 self.assertEqual(c.segment[2].spcod[3], 0) # mct self.assertEqual(c.segment[2].spcod[4], 5) # level - self.assertEqual(tuple(c.segment[2]._code_block_size), + self.assertEqual(tuple(c.segment[2].code_block_size), (32, 128)) # cblk # Selective arithmetic coding bypass self.assertFalse(c.segment[2].spcod[7] & 0x01) @@ -6381,9 +6381,9 @@ class TestSuiteDump(unittest.TestCase): # Tile offset self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz), (0, 0)) # bitdepth - self.assertEqual(c.segment[1]._bitdepth, (8,)) + self.assertEqual(c.segment[1].bitdepth, (8,)) # signed - self.assertEqual(c.segment[1]._signed, (False,)) + self.assertEqual(c.segment[1].signed, (False,)) # subsampling self.assertEqual(list(zip(c.segment[1].xrsiz, c.segment[1].yrsiz)), [(1, 1)]) @@ -6392,10 +6392,10 @@ class TestSuiteDump(unittest.TestCase): self.assertFalse(c.segment[2].scod & 2) # no sop self.assertFalse(c.segment[2].scod & 4) # no eph self.assertEqual(c.segment[2].spcod[0], glymur.core.RLCP) - self.assertEqual(c.segment[2]._layers, 1) # layers = 1 + self.assertEqual(c.segment[2].layers, 1) # layers = 1 self.assertEqual(c.segment[2].spcod[3], 0) # mct self.assertEqual(c.segment[2].spcod[4], 5) # level - self.assertEqual(tuple(c.segment[2]._code_block_size), + self.assertEqual(tuple(c.segment[2].code_block_size), (32, 32)) # cblk # Selective arithmetic coding bypass self.assertFalse(c.segment[2].spcod[7] & 0x01) @@ -6482,9 +6482,9 @@ class TestSuiteDump(unittest.TestCase): # Tile offset self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz), (0, 0)) # bitdepth - self.assertEqual(c.segment[1]._bitdepth, (8, 8, 8)) + self.assertEqual(c.segment[1].bitdepth, (8, 8, 8)) # signed - self.assertEqual(c.segment[1]._signed, (False, False, False)) + self.assertEqual(c.segment[1].signed, (False, False, False)) # subsampling self.assertEqual(list(zip(c.segment[1].xrsiz, c.segment[1].yrsiz)), [(1, 1)] * 3) @@ -6493,10 +6493,10 @@ class TestSuiteDump(unittest.TestCase): self.assertFalse(c.segment[2].scod & 2) # no sop self.assertFalse(c.segment[2].scod & 4) # no eph self.assertEqual(c.segment[2].spcod[0], glymur.core.LRCP) - self.assertEqual(c.segment[2]._layers, 1) # layers = 1 + self.assertEqual(c.segment[2].layers, 1) # layers = 1 self.assertEqual(c.segment[2].spcod[3], 1) # mct self.assertEqual(c.segment[2].spcod[4], 5) # level - self.assertEqual(tuple(c.segment[2]._code_block_size), + self.assertEqual(tuple(c.segment[2].code_block_size), (64, 64)) # cblk # Selective arithmetic coding bypass self.assertFalse(c.segment[2].spcod[7] & 0x01) @@ -6581,9 +6581,9 @@ class TestSuiteDump(unittest.TestCase): # Tile offset self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz), (0, 0)) # bitdepth - self.assertEqual(c.segment[1]._bitdepth, (8, 8, 8)) + self.assertEqual(c.segment[1].bitdepth, (8, 8, 8)) # signed - self.assertEqual(c.segment[1]._signed, (False, False, False)) + self.assertEqual(c.segment[1].signed, (False, False, False)) # subsampling self.assertEqual(list(zip(c.segment[1].xrsiz, c.segment[1].yrsiz)), [(1, 1)] * 3) @@ -6592,10 +6592,10 @@ class TestSuiteDump(unittest.TestCase): self.assertFalse(c.segment[2].scod & 2) # no sop self.assertFalse(c.segment[2].scod & 4) # no eph self.assertEqual(c.segment[2].spcod[0], glymur.core.RLCP) - self.assertEqual(c.segment[2]._layers, 1) # layers = 1 + self.assertEqual(c.segment[2].layers, 1) # layers = 1 self.assertEqual(c.segment[2].spcod[3], 1) # mct self.assertEqual(c.segment[2].spcod[4], 5) # level - self.assertEqual(tuple(c.segment[2]._code_block_size), + self.assertEqual(tuple(c.segment[2].code_block_size), (32, 32)) # cblk # Selective arithmetic coding bypass self.assertFalse(c.segment[2].spcod[7] & 0x01) @@ -6685,9 +6685,9 @@ class TestSuiteDump(unittest.TestCase): # Tile offset self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz), (0, 0)) # bitdepth - self.assertEqual(c.segment[1]._bitdepth, (8, 8)) + self.assertEqual(c.segment[1].bitdepth, (8, 8)) # signed - self.assertEqual(c.segment[1]._signed, (False, False)) + self.assertEqual(c.segment[1].signed, (False, False)) # subsampling self.assertEqual(list(zip(c.segment[1].xrsiz, c.segment[1].yrsiz)), [(1, 1)] * 2) @@ -6696,10 +6696,10 @@ class TestSuiteDump(unittest.TestCase): self.assertFalse(c.segment[2].scod & 2) # no sop self.assertFalse(c.segment[2].scod & 4) # no eph self.assertEqual(c.segment[2].spcod[0], glymur.core.LRCP) - self.assertEqual(c.segment[2]._layers, 2) # layers = 2 + self.assertEqual(c.segment[2].layers, 2) # layers = 2 self.assertEqual(c.segment[2].spcod[3], 0) # mct self.assertEqual(c.segment[2].spcod[4], 5) # level - self.assertEqual(tuple(c.segment[2]._code_block_size), + self.assertEqual(tuple(c.segment[2].code_block_size), (64, 64)) # cblk # Selective arithmetic coding bypass self.assertFalse(c.segment[2].spcod[7] & 0x01) @@ -6813,9 +6813,9 @@ class TestSuiteDump(unittest.TestCase): # Tile offset self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz), (0, 0)) # bitdepth - self.assertEqual(c.segment[1]._bitdepth, (1,)) + self.assertEqual(c.segment[1].bitdepth, (1,)) # signed - self.assertEqual(c.segment[1]._signed, (False,)) + self.assertEqual(c.segment[1].signed, (False,)) # subsampling self.assertEqual(list(zip(c.segment[1].xrsiz, c.segment[1].yrsiz)), [(1, 1)]) @@ -6824,10 +6824,10 @@ class TestSuiteDump(unittest.TestCase): self.assertFalse(c.segment[2].scod & 2) # no sop self.assertFalse(c.segment[2].scod & 4) # no eph self.assertEqual(c.segment[2].spcod[0], glymur.core.RLCP) - self.assertEqual(c.segment[2]._layers, 1) # layers = 1 + self.assertEqual(c.segment[2].layers, 1) # layers = 1 self.assertEqual(c.segment[2].spcod[3], 0) # mct self.assertEqual(c.segment[2].spcod[4], 5) # level - self.assertEqual(tuple(c.segment[2]._code_block_size), + self.assertEqual(tuple(c.segment[2].code_block_size), (32, 32)) # cblk # Selective arithmetic coding bypass self.assertFalse(c.segment[2].spcod[7] & 0x01) @@ -6928,9 +6928,9 @@ class TestSuiteDump(unittest.TestCase): # Tile offset self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz), (0, 0)) # bitdepth - self.assertEqual(c.segment[1]._bitdepth, (4,)) + self.assertEqual(c.segment[1].bitdepth, (4,)) # signed - self.assertEqual(c.segment[1]._signed, (False,)) + self.assertEqual(c.segment[1].signed, (False,)) # subsampling self.assertEqual(list(zip(c.segment[1].xrsiz, c.segment[1].yrsiz)), [(1, 1)]) @@ -6939,10 +6939,10 @@ class TestSuiteDump(unittest.TestCase): self.assertFalse(c.segment[2].scod & 2) # no sop self.assertFalse(c.segment[2].scod & 4) # no eph self.assertEqual(c.segment[2].spcod[0], glymur.core.RLCP) - self.assertEqual(c.segment[2]._layers, 1) # layers = 1 + self.assertEqual(c.segment[2].layers, 1) # layers = 1 self.assertEqual(c.segment[2].spcod[3], 0) # mct self.assertEqual(c.segment[2].spcod[4], 5) # level - self.assertEqual(tuple(c.segment[2]._code_block_size), + self.assertEqual(tuple(c.segment[2].code_block_size), (32, 32)) # cblk # Selective arithmetic coding bypass self.assertFalse(c.segment[2].spcod[7] & 0x01) @@ -7022,9 +7022,9 @@ class TestSuiteDump(unittest.TestCase): # Tile offset self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz), (0, 0)) # bitdepth - self.assertEqual(c.segment[1]._bitdepth, (8, 8, 8)) + self.assertEqual(c.segment[1].bitdepth, (8, 8, 8)) # signed - self.assertEqual(c.segment[1]._signed, (False, False, False)) + self.assertEqual(c.segment[1].signed, (False, False, False)) # subsampling self.assertEqual(list(zip(c.segment[1].xrsiz, c.segment[1].yrsiz)), [(1, 1), (2, 1), (2, 1)]) @@ -7033,10 +7033,10 @@ class TestSuiteDump(unittest.TestCase): self.assertFalse(c.segment[2].scod & 2) # no sop self.assertFalse(c.segment[2].scod & 4) # no eph self.assertEqual(c.segment[2].spcod[0], glymur.core.LRCP) - self.assertEqual(c.segment[2]._layers, 1) # layers = 1 + self.assertEqual(c.segment[2].layers, 1) # layers = 1 self.assertEqual(c.segment[2].spcod[3], 0) # mct self.assertEqual(c.segment[2].spcod[4], 5) # level - self.assertEqual(tuple(c.segment[2]._code_block_size), + self.assertEqual(tuple(c.segment[2].code_block_size), (32, 128)) # cblk # Selective arithmetic coding bypass self.assertFalse(c.segment[2].spcod[7] & 0x01) @@ -7131,9 +7131,9 @@ class TestSuiteDump(unittest.TestCase): # Tile offset self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz), (0, 0)) # bitdepth - self.assertEqual(c.segment[1]._bitdepth, (8, 8, 8, 8)) + self.assertEqual(c.segment[1].bitdepth, (8, 8, 8, 8)) # signed - self.assertEqual(c.segment[1]._signed, (False, False, False, False)) + self.assertEqual(c.segment[1].signed, (False, False, False, False)) # subsampling self.assertEqual(list(zip(c.segment[1].xrsiz, c.segment[1].yrsiz)), [(1, 1)] * 4) @@ -7142,10 +7142,10 @@ class TestSuiteDump(unittest.TestCase): self.assertFalse(c.segment[2].scod & 2) # no sop self.assertFalse(c.segment[2].scod & 4) # no eph self.assertEqual(c.segment[2].spcod[0], glymur.core.LRCP) - self.assertEqual(c.segment[2]._layers, 1) # layers = 1 + self.assertEqual(c.segment[2].layers, 1) # layers = 1 self.assertEqual(c.segment[2].spcod[3], 0) # mct self.assertEqual(c.segment[2].spcod[4], 5) # level - self.assertEqual(tuple(c.segment[2]._code_block_size), + self.assertEqual(tuple(c.segment[2].code_block_size), (64, 64)) # cblk # Selective arithmetic coding bypass self.assertFalse(c.segment[2].spcod[7] & 0x01) @@ -7231,9 +7231,9 @@ class TestSuiteDump(unittest.TestCase): # Tile offset self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz), (0, 0)) # bitdepth - self.assertEqual(c.segment[1]._bitdepth, (8, 8, 8, 8)) + self.assertEqual(c.segment[1].bitdepth, (8, 8, 8, 8)) # signed - self.assertEqual(c.segment[1]._signed, (False, False, False, False)) + self.assertEqual(c.segment[1].signed, (False, False, False, False)) # subsampling self.assertEqual(list(zip(c.segment[1].xrsiz, c.segment[1].yrsiz)), [(1, 1)] * 4) @@ -7242,10 +7242,10 @@ class TestSuiteDump(unittest.TestCase): self.assertFalse(c.segment[2].scod & 2) # no sop self.assertFalse(c.segment[2].scod & 4) # no eph self.assertEqual(c.segment[2].spcod[0], glymur.core.LRCP) - self.assertEqual(c.segment[2]._layers, 1) # layers = 1 + self.assertEqual(c.segment[2].layers, 1) # layers = 1 self.assertEqual(c.segment[2].spcod[3], 0) # mct self.assertEqual(c.segment[2].spcod[4], 5) # level - self.assertEqual(tuple(c.segment[2]._code_block_size), + self.assertEqual(tuple(c.segment[2].code_block_size), (64, 64)) # cblk # Selective arithmetic coding bypass self.assertFalse(c.segment[2].spcod[7] & 0x01) @@ -7343,9 +7343,9 @@ class TestSuiteDump(unittest.TestCase): # Tile offset self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz), (0, 0)) # bitdepth - self.assertEqual(c.segment[1]._bitdepth, (8, 8, 8)) + self.assertEqual(c.segment[1].bitdepth, (8, 8, 8)) # signed - self.assertEqual(c.segment[1]._signed, (False, False, False)) + self.assertEqual(c.segment[1].signed, (False, False, False)) # subsampling self.assertEqual(list(zip(c.segment[1].xrsiz, c.segment[1].yrsiz)), [(1, 1)] * 3) @@ -7354,10 +7354,10 @@ class TestSuiteDump(unittest.TestCase): self.assertFalse(c.segment[2].scod & 2) # no sop self.assertFalse(c.segment[2].scod & 4) # no eph self.assertEqual(c.segment[2].spcod[0], glymur.core.RLCP) - self.assertEqual(c.segment[2]._layers, 6) # layers = 6 + self.assertEqual(c.segment[2].layers, 6) # layers = 6 self.assertEqual(c.segment[2].spcod[3], 1) # mct self.assertEqual(c.segment[2].spcod[4], 5) # level - self.assertEqual(tuple(c.segment[2]._code_block_size), + self.assertEqual(tuple(c.segment[2].code_block_size), (32, 32)) # cblk # Selective arithmetic coding bypass self.assertFalse(c.segment[2].spcod[7] & 0x01) diff --git a/glymur/test/test_opj_suite_write.py b/glymur/test/test_opj_suite_write.py index 766297b..09722dc 100644 --- a/glymur/test/test_opj_suite_write.py +++ b/glymur/test/test_opj_suite_write.py @@ -2,9 +2,10 @@ The tests defined here roughly correspond to what is in the OpenJPEG test suite. """ -#pylint: disable-all +# C0103: method names longer that 30 chars are ok in tests, IMHO +# R0904: Seems like pylint is fooled in this situation +# pylint: disable=R0904,C0103 import os -import platform import sys import tempfile @@ -13,10 +14,6 @@ if sys.hexversion < 0x02070000: else: import unittest -import numpy as np - -from glymur.lib import openjp2 as opj2 - from .fixtures import read_image, NO_READ_BACKEND, NO_READ_BACKEND_MSG from glymur import Jp2k @@ -37,7 +34,11 @@ except: @unittest.skipIf(data_root is None, "OPJ_DATA_ROOT environment variable not set") class TestSuiteWrite(unittest.TestCase): + """Tests for writing with openjp2 backend. + These tests roughly correspond with those tests with similar names in the + OpenJPEG test suite. + """ def setUp(self): pass @@ -45,7 +46,7 @@ class TestSuiteWrite(unittest.TestCase): pass def test_NR_ENC_Bretagne1_ppm_1_encode(self): - # NR-ENC-Bretagne1.ppm-1-encode + """NR-ENC-Bretagne1.ppm-1-encode""" infile = os.path.join(data_root, 'input/nonregression/Bretagne1.ppm') data = read_image(infile) with tempfile.NamedTemporaryFile(suffix='.j2k') as tfile: @@ -53,57 +54,63 @@ class TestSuiteWrite(unittest.TestCase): j.write(data, cratios=[200, 100, 50]) # Should be three layers. - c = j.get_codestream() + codestream = j.get_codestream() # SIZ: Image and tile size # Profile: "0" means profile 2 - self.assertEqual(c.segment[1].rsiz, 0) + self.assertEqual(codestream.segment[1].rsiz, 0) # Reference grid size - self.assertEqual((c.segment[1].xsiz, c.segment[1].ysiz), + self.assertEqual((codestream.segment[1].xsiz, + codestream.segment[1].ysiz), (640, 480)) # Reference grid offset - self.assertEqual((c.segment[1].xosiz, c.segment[1].yosiz), (0, 0)) + self.assertEqual((codestream.segment[1].xosiz, + codestream.segment[1].yosiz), (0, 0)) # Tile size - self.assertEqual((c.segment[1].xtsiz, c.segment[1].ytsiz), + self.assertEqual((codestream.segment[1].xtsiz, + codestream.segment[1].ytsiz), (640, 480)) # Tile offset - self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz), + self.assertEqual((codestream.segment[1].xtosiz, + codestream.segment[1].ytosiz), (0, 0)) # bitdepth - self.assertEqual(c.segment[1]._bitdepth, (8, 8, 8)) + self.assertEqual(codestream.segment[1].bitdepth, (8, 8, 8)) # signed - self.assertEqual(c.segment[1]._signed, (False, False, False)) + self.assertEqual(codestream.segment[1].signed, + (False, False, False)) # subsampling - self.assertEqual(list(zip(c.segment[1].xrsiz, c.segment[1].yrsiz)), + self.assertEqual(list(zip(codestream.segment[1].xrsiz, + codestream.segment[1].yrsiz)), [(1, 1)] * 3) # COD: Coding style default - self.assertFalse(c.segment[2].scod & 2) # no sop - self.assertFalse(c.segment[2].scod & 4) # no eph - self.assertEqual(c.segment[2].spcod[0], glymur.core.LRCP) - self.assertEqual(c.segment[2]._layers, 3) # layers = 3 - self.assertEqual(c.segment[2].spcod[3], 1) # mct - self.assertEqual(c.segment[2].spcod[4], 5) # levels - self.assertEqual(tuple(c.segment[2]._code_block_size), + self.assertFalse(codestream.segment[2].scod & 2) # no sop + self.assertFalse(codestream.segment[2].scod & 4) # no eph + self.assertEqual(codestream.segment[2].spcod[0], glymur.core.LRCP) + self.assertEqual(codestream.segment[2].layers, 3) # layers = 3 + self.assertEqual(codestream.segment[2].spcod[3], 1) # mct + self.assertEqual(codestream.segment[2].spcod[4], 5) # levels + self.assertEqual(tuple(codestream.segment[2].code_block_size), (64, 64)) # cblksz # Selective arithmetic coding bypass - self.assertFalse(c.segment[2].spcod[7] & 0x01) + self.assertFalse(codestream.segment[2].spcod[7] & 0x01) # Reset context probabilities - self.assertFalse(c.segment[2].spcod[7] & 0x02) + self.assertFalse(codestream.segment[2].spcod[7] & 0x02) # Termination on each coding pass - self.assertFalse(c.segment[2].spcod[7] & 0x04) + self.assertFalse(codestream.segment[2].spcod[7] & 0x04) # Vertically causal context - self.assertFalse(c.segment[2].spcod[7] & 0x08) + self.assertFalse(codestream.segment[2].spcod[7] & 0x08) # Predictable termination - self.assertFalse(c.segment[2].spcod[7] & 0x0010) + self.assertFalse(codestream.segment[2].spcod[7] & 0x0010) # Segmentation symbols - self.assertFalse(c.segment[2].spcod[7] & 0x0020) - self.assertEqual(c.segment[2].spcod[8], + self.assertFalse(codestream.segment[2].spcod[7] & 0x0020) + self.assertEqual(codestream.segment[2].spcod[8], glymur.core.WAVELET_XFORM_5X3_REVERSIBLE) - self.assertEqual(len(c.segment[2].spcod), 9) + self.assertEqual(len(codestream.segment[2].spcod), 9) def test_NR_ENC_Bretagne1_ppm_2_encode(self): - # NR-ENC-Bretagne1.ppm-2-encode + """NR-ENC-Bretagne1.ppm-2-encode""" infile = os.path.join(data_root, 'input/nonregression/Bretagne1.ppm') data = read_image(infile) with tempfile.NamedTemporaryFile(suffix='.j2k') as tfile: @@ -111,57 +118,64 @@ class TestSuiteWrite(unittest.TestCase): j.write(data, psnr=[30, 35, 40], numres=2) # Should be three layers. - c = j.get_codestream() + codestream = j.get_codestream() # SIZ: Image and tile size # Profile: "0" means profile 2 - self.assertEqual(c.segment[1].rsiz, 0) + self.assertEqual(codestream.segment[1].rsiz, 0) # Reference grid size - self.assertEqual((c.segment[1].xsiz, c.segment[1].ysiz), + self.assertEqual((codestream.segment[1].xsiz, + codestream.segment[1].ysiz), (640, 480)) # Reference grid offset - self.assertEqual((c.segment[1].xosiz, c.segment[1].yosiz), (0, 0)) + self.assertEqual((codestream.segment[1].xosiz, + codestream.segment[1].yosiz), (0, 0)) # Tile size - self.assertEqual((c.segment[1].xtsiz, c.segment[1].ytsiz), + self.assertEqual((codestream.segment[1].xtsiz, + codestream.segment[1].ytsiz), (640, 480)) # Tile offset - self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz), + self.assertEqual((codestream.segment[1].xtosiz, + codestream.segment[1].ytosiz), (0, 0)) # bitdepth - self.assertEqual(c.segment[1]._bitdepth, (8, 8, 8)) + self.assertEqual(codestream.segment[1].bitdepth, + (8, 8, 8)) # signed - self.assertEqual(c.segment[1]._signed, (False, False, False)) + self.assertEqual(codestream.segment[1].signed, + (False, False, False)) # subsampling - self.assertEqual(list(zip(c.segment[1].xrsiz, c.segment[1].yrsiz)), + self.assertEqual(list(zip(codestream.segment[1].xrsiz, + codestream.segment[1].yrsiz)), [(1, 1)] * 3) # COD: Coding style default - self.assertFalse(c.segment[2].scod & 2) # no sop - self.assertFalse(c.segment[2].scod & 4) # no eph - self.assertEqual(c.segment[2].spcod[0], glymur.core.LRCP) - self.assertEqual(c.segment[2]._layers, 3) # layers = 3 - self.assertEqual(c.segment[2].spcod[3], 1) # mct - self.assertEqual(c.segment[2].spcod[4], 1) # levels - self.assertEqual(tuple(c.segment[2]._code_block_size), + self.assertFalse(codestream.segment[2].scod & 2) # no sop + self.assertFalse(codestream.segment[2].scod & 4) # no eph + self.assertEqual(codestream.segment[2].spcod[0], glymur.core.LRCP) + self.assertEqual(codestream.segment[2].layers, 3) # layers = 3 + self.assertEqual(codestream.segment[2].spcod[3], 1) # mct + self.assertEqual(codestream.segment[2].spcod[4], 1) # levels + self.assertEqual(tuple(codestream.segment[2].code_block_size), (64, 64)) # cblksz # Selective arithmetic coding bypass - self.assertFalse(c.segment[2].spcod[7] & 0x01) + self.assertFalse(codestream.segment[2].spcod[7] & 0x01) # Reset context probabilities - self.assertFalse(c.segment[2].spcod[7] & 0x02) + self.assertFalse(codestream.segment[2].spcod[7] & 0x02) # Termination on each coding pass - self.assertFalse(c.segment[2].spcod[7] & 0x04) + self.assertFalse(codestream.segment[2].spcod[7] & 0x04) # Vertically causal context - self.assertFalse(c.segment[2].spcod[7] & 0x08) + self.assertFalse(codestream.segment[2].spcod[7] & 0x08) # Predictable termination - self.assertFalse(c.segment[2].spcod[7] & 0x0010) + self.assertFalse(codestream.segment[2].spcod[7] & 0x0010) # Segmentation symbols - self.assertFalse(c.segment[2].spcod[7] & 0x0020) - self.assertEqual(c.segment[2].spcod[8], + self.assertFalse(codestream.segment[2].spcod[7] & 0x0020) + self.assertEqual(codestream.segment[2].spcod[8], glymur.core.WAVELET_XFORM_5X3_REVERSIBLE) - self.assertEqual(len(c.segment[2].spcod), 9) + self.assertEqual(len(codestream.segment[2].spcod), 9) def test_NR_ENC_Bretagne1_ppm_3_encode(self): - # NR-ENC-Bretagne1.ppm-3-encode + """NR-ENC-Bretagne1.ppm-3-encode""" infile = os.path.join(data_root, 'input/nonregression/Bretagne1.ppm') data = read_image(infile) with tempfile.NamedTemporaryFile(suffix='.j2k') as tfile: @@ -170,58 +184,65 @@ class TestSuiteWrite(unittest.TestCase): psizes=[(64, 64)]) # Should be three layers. - c = j.get_codestream() + codestream = j.get_codestream() # SIZ: Image and tile size # Profile: "0" means profile 2 - self.assertEqual(c.segment[1].rsiz, 0) + self.assertEqual(codestream.segment[1].rsiz, 0) # Reference grid size - self.assertEqual((c.segment[1].xsiz, c.segment[1].ysiz), + self.assertEqual((codestream.segment[1].xsiz, + codestream.segment[1].ysiz), (640, 480)) # Reference grid offset - self.assertEqual((c.segment[1].xosiz, c.segment[1].yosiz), (0, 0)) + self.assertEqual((codestream.segment[1].xosiz, + codestream.segment[1].yosiz), (0, 0)) # Tile size - self.assertEqual((c.segment[1].xtsiz, c.segment[1].ytsiz), + self.assertEqual((codestream.segment[1].xtsiz, + codestream.segment[1].ytsiz), (640, 480)) # Tile offset - self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz), + self.assertEqual((codestream.segment[1].xtosiz, + codestream.segment[1].ytosiz), (0, 0)) # bitdepth - self.assertEqual(c.segment[1]._bitdepth, (8, 8, 8)) + self.assertEqual(codestream.segment[1].bitdepth, (8, 8, 8)) # signed - self.assertEqual(c.segment[1]._signed, (False, False, False)) + self.assertEqual(codestream.segment[1].signed, + (False, False, False)) # subsampling - self.assertEqual(list(zip(c.segment[1].xrsiz, c.segment[1].yrsiz)), + self.assertEqual(list(zip(codestream.segment[1].xrsiz, + codestream.segment[1].yrsiz)), [(1, 1)] * 3) # COD: Coding style default - self.assertFalse(c.segment[2].scod & 2) # no sop - self.assertFalse(c.segment[2].scod & 4) # no eph - self.assertEqual(c.segment[2].spcod[0], glymur.core.LRCP) - self.assertEqual(c.segment[2]._layers, 3) # layers = 3 - self.assertEqual(c.segment[2].spcod[3], 1) # mct - self.assertEqual(c.segment[2].spcod[4], 5) # levels - self.assertEqual(tuple(c.segment[2]._code_block_size), + self.assertFalse(codestream.segment[2].scod & 2) # no sop + self.assertFalse(codestream.segment[2].scod & 4) # no eph + self.assertEqual(codestream.segment[2].spcod[0], glymur.core.LRCP) + self.assertEqual(codestream.segment[2].layers, 3) # layers = 3 + self.assertEqual(codestream.segment[2].spcod[3], 1) # mct + self.assertEqual(codestream.segment[2].spcod[4], 5) # levels + self.assertEqual(tuple(codestream.segment[2].code_block_size), (16, 16)) # cblksz # Selective arithmetic coding bypass - self.assertFalse(c.segment[2].spcod[7] & 0x01) + self.assertFalse(codestream.segment[2].spcod[7] & 0x01) # Reset context probabilities - self.assertFalse(c.segment[2].spcod[7] & 0x02) + self.assertFalse(codestream.segment[2].spcod[7] & 0x02) # Termination on each coding pass - self.assertFalse(c.segment[2].spcod[7] & 0x04) + self.assertFalse(codestream.segment[2].spcod[7] & 0x04) # Vertically causal context - self.assertFalse(c.segment[2].spcod[7] & 0x08) + self.assertFalse(codestream.segment[2].spcod[7] & 0x08) # Predictable termination - self.assertFalse(c.segment[2].spcod[7] & 0x0010) + self.assertFalse(codestream.segment[2].spcod[7] & 0x0010) # Segmentation symbols - self.assertFalse(c.segment[2].spcod[7] & 0x0020) - self.assertEqual(c.segment[2].spcod[8], + self.assertFalse(codestream.segment[2].spcod[7] & 0x0020) + self.assertEqual(codestream.segment[2].spcod[8], glymur.core.WAVELET_XFORM_5X3_REVERSIBLE) - self.assertEqual(c.segment[2]._precinct_size, + self.assertEqual(codestream.segment[2].precinct_size, [(2, 2), (4, 4), (8, 8), (16, 16), (32, 32), (64, 64)]) def test_NR_ENC_Bretagne2_ppm_4_encode(self): + """NR-ENC-Bretagne2.ppm-4-encode""" infile = os.path.join(data_root, 'input/nonregression/Bretagne2.ppm') data = read_image(infile) with tempfile.NamedTemporaryFile(suffix='.j2k') as tfile: @@ -233,413 +254,459 @@ class TestSuiteWrite(unittest.TestCase): cbsize=(32, 32)) # Should be three layers. - c = j.get_codestream() + codestream = j.get_codestream() # SIZ: Image and tile size # Profile: "0" means profile 2 - self.assertEqual(c.segment[1].rsiz, 0) + self.assertEqual(codestream.segment[1].rsiz, 0) # Reference grid size - self.assertEqual((c.segment[1].xsiz, c.segment[1].ysiz), + self.assertEqual((codestream.segment[1].xsiz, + codestream.segment[1].ysiz), (data.shape[1], data.shape[0])) # Reference grid offset - self.assertEqual((c.segment[1].xosiz, c.segment[1].yosiz), (0, 0)) + self.assertEqual((codestream.segment[1].xosiz, + codestream.segment[1].yosiz), (0, 0)) # Tile size. Reported as XY, not RC. - self.assertEqual((c.segment[1].xtsiz, c.segment[1].ytsiz), + self.assertEqual((codestream.segment[1].xtsiz, + codestream.segment[1].ytsiz), (640, 480)) # Tile offset - self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz), + self.assertEqual((codestream.segment[1].xtosiz, + codestream.segment[1].ytosiz), (0, 0)) # bitdepth - self.assertEqual(c.segment[1]._bitdepth, (8, 8, 8)) + self.assertEqual(codestream.segment[1].bitdepth, (8, 8, 8)) # signed - self.assertEqual(c.segment[1]._signed, (False, False, False)) + self.assertEqual(codestream.segment[1].signed, + (False, False, False)) # subsampling - self.assertEqual(list(zip(c.segment[1].xrsiz, c.segment[1].yrsiz)), + self.assertEqual(list(zip(codestream.segment[1].xrsiz, + codestream.segment[1].yrsiz)), [(1, 1)] * 3) # COD: Coding style default - self.assertFalse(c.segment[2].scod & 2) # no sop - self.assertFalse(c.segment[2].scod & 4) # no eph - self.assertEqual(c.segment[2].spcod[0], glymur.core.LRCP) - self.assertEqual(c.segment[2]._layers, 3) # layers = 3 - self.assertEqual(c.segment[2].spcod[3], 1) # mct - self.assertEqual(c.segment[2].spcod[4], 5) # levels - self.assertEqual(tuple(c.segment[2]._code_block_size), + self.assertFalse(codestream.segment[2].scod & 2) # no sop + self.assertFalse(codestream.segment[2].scod & 4) # no eph + self.assertEqual(codestream.segment[2].spcod[0], glymur.core.LRCP) + self.assertEqual(codestream.segment[2].layers, 3) # layers = 3 + self.assertEqual(codestream.segment[2].spcod[3], 1) # mct + self.assertEqual(codestream.segment[2].spcod[4], 5) # levels + self.assertEqual(tuple(codestream.segment[2].code_block_size), (32, 32)) # cblksz # Selective arithmetic coding bypass - self.assertFalse(c.segment[2].spcod[7] & 0x01) + self.assertFalse(codestream.segment[2].spcod[7] & 0x01) # Reset context probabilities - self.assertFalse(c.segment[2].spcod[7] & 0x02) + self.assertFalse(codestream.segment[2].spcod[7] & 0x02) # Termination on each coding pass - self.assertFalse(c.segment[2].spcod[7] & 0x04) + self.assertFalse(codestream.segment[2].spcod[7] & 0x04) # Vertically causal context - self.assertFalse(c.segment[2].spcod[7] & 0x08) + self.assertFalse(codestream.segment[2].spcod[7] & 0x08) # Predictable termination - self.assertFalse(c.segment[2].spcod[7] & 0x0010) + self.assertFalse(codestream.segment[2].spcod[7] & 0x0010) # Segmentation symbols - self.assertFalse(c.segment[2].spcod[7] & 0x0020) - self.assertEqual(c.segment[2].spcod[8], + self.assertFalse(codestream.segment[2].spcod[7] & 0x0020) + self.assertEqual(codestream.segment[2].spcod[8], glymur.core.WAVELET_XFORM_5X3_REVERSIBLE) - self.assertEqual(c.segment[2]._precinct_size, + self.assertEqual(codestream.segment[2].precinct_size, [(16, 16), (32, 32), (64, 64)] + [(128, 128)] * 3) def test_NR_ENC_Bretagne2_ppm_5_encode(self): - # NR-ENC-Bretagne2.ppm-4-encode + """NR-ENC-Bretagne2.ppm-5-encode""" infile = os.path.join(data_root, 'input/nonregression/Bretagne2.ppm') data = read_image(infile) with tempfile.NamedTemporaryFile(suffix='.j2k') as tfile: j = Jp2k(tfile.name, 'wb') j.write(data, tilesize=(127, 127), prog="PCRL") - c = j.get_codestream() + codestream = j.get_codestream() # SIZ: Image and tile size # Profile: "0" means profile 2 - self.assertEqual(c.segment[1].rsiz, 0) + self.assertEqual(codestream.segment[1].rsiz, 0) # Reference grid size - self.assertEqual((c.segment[1].xsiz, c.segment[1].ysiz), + self.assertEqual((codestream.segment[1].xsiz, + codestream.segment[1].ysiz), (data.shape[1], data.shape[0])) # Reference grid offset - self.assertEqual((c.segment[1].xosiz, c.segment[1].yosiz), (0, 0)) + self.assertEqual((codestream.segment[1].xosiz, + codestream.segment[1].yosiz), (0, 0)) # Tile size - self.assertEqual((c.segment[1].xtsiz, c.segment[1].ytsiz), + self.assertEqual((codestream.segment[1].xtsiz, + codestream.segment[1].ytsiz), (127, 127)) # Tile offset - self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz), + self.assertEqual((codestream.segment[1].xtosiz, + codestream.segment[1].ytosiz), (0, 0)) # bitdepth - self.assertEqual(c.segment[1]._bitdepth, (8, 8, 8)) + self.assertEqual(codestream.segment[1].bitdepth, (8, 8, 8)) # signed - self.assertEqual(c.segment[1]._signed, (False, False, False)) + self.assertEqual(codestream.segment[1].signed, + (False, False, False)) # subsampling - self.assertEqual(list(zip(c.segment[1].xrsiz, c.segment[1].yrsiz)), + self.assertEqual(list(zip(codestream.segment[1].xrsiz, + codestream.segment[1].yrsiz)), [(1, 1)] * 3) # COD: Coding style default - self.assertFalse(c.segment[2].scod & 2) # no sop - self.assertFalse(c.segment[2].scod & 4) # no eph - self.assertEqual(c.segment[2].spcod[0], glymur.core.PCRL) - self.assertEqual(c.segment[2]._layers, 1) # layers = 1 - self.assertEqual(c.segment[2].spcod[3], 1) # mct - self.assertEqual(c.segment[2].spcod[4], 5) # levels - self.assertEqual(tuple(c.segment[2]._code_block_size), + self.assertFalse(codestream.segment[2].scod & 2) # no sop + self.assertFalse(codestream.segment[2].scod & 4) # no eph + self.assertEqual(codestream.segment[2].spcod[0], glymur.core.PCRL) + self.assertEqual(codestream.segment[2].layers, 1) # layers = 1 + self.assertEqual(codestream.segment[2].spcod[3], 1) # mct + self.assertEqual(codestream.segment[2].spcod[4], 5) # levels + self.assertEqual(tuple(codestream.segment[2].code_block_size), (64, 64)) # cblksz # Selective arithmetic coding bypass - self.assertFalse(c.segment[2].spcod[7] & 0x01) + self.assertFalse(codestream.segment[2].spcod[7] & 0x01) # Reset context probabilities - self.assertFalse(c.segment[2].spcod[7] & 0x02) + self.assertFalse(codestream.segment[2].spcod[7] & 0x02) # Termination on each coding pass - self.assertFalse(c.segment[2].spcod[7] & 0x04) + self.assertFalse(codestream.segment[2].spcod[7] & 0x04) # Vertically causal context - self.assertFalse(c.segment[2].spcod[7] & 0x08) + self.assertFalse(codestream.segment[2].spcod[7] & 0x08) # Predictable termination - self.assertFalse(c.segment[2].spcod[7] & 0x0010) + self.assertFalse(codestream.segment[2].spcod[7] & 0x0010) # Segmentation symbols - self.assertFalse(c.segment[2].spcod[7] & 0x0020) - self.assertEqual(c.segment[2].spcod[8], + self.assertFalse(codestream.segment[2].spcod[7] & 0x0020) + self.assertEqual(codestream.segment[2].spcod[8], glymur.core.WAVELET_XFORM_5X3_REVERSIBLE) - self.assertEqual(len(c.segment[2].spcod), 9) + self.assertEqual(len(codestream.segment[2].spcod), 9) def test_NR_ENC_Bretagne2_ppm_6_encode(self): - # NR-ENC-Bretagne2.ppm-6-encode + """NR-ENC-Bretagne2.ppm-6-encode""" infile = os.path.join(data_root, 'input/nonregression/Bretagne2.ppm') data = read_image(infile) with tempfile.NamedTemporaryFile(suffix='.j2k') as tfile: j = Jp2k(tfile.name, 'wb') j.write(data, subsam=(2, 2), sop=True) - c = j.get_codestream(header_only=False) + codestream = j.get_codestream(header_only=False) # SIZ: Image and tile size # Profile: "0" means profile 2 - self.assertEqual(c.segment[1].rsiz, 0) + self.assertEqual(codestream.segment[1].rsiz, 0) # Reference grid size - self.assertEqual((c.segment[1].xsiz, c.segment[1].ysiz), + self.assertEqual((codestream.segment[1].xsiz, + codestream.segment[1].ysiz), (5183, 3887)) # Reference grid offset - self.assertEqual((c.segment[1].xosiz, c.segment[1].yosiz), (0, 0)) + self.assertEqual((codestream.segment[1].xosiz, + codestream.segment[1].yosiz), (0, 0)) # Tile size - self.assertEqual((c.segment[1].xtsiz, c.segment[1].ytsiz), + self.assertEqual((codestream.segment[1].xtsiz, + codestream.segment[1].ytsiz), (5183, 3887)) # Tile offset - self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz), + self.assertEqual((codestream.segment[1].xtosiz, + codestream.segment[1].ytosiz), (0, 0)) # bitdepth - self.assertEqual(c.segment[1]._bitdepth, (8, 8, 8)) + self.assertEqual(codestream.segment[1].bitdepth, (8, 8, 8)) # signed - self.assertEqual(c.segment[1]._signed, (False, False, False)) + self.assertEqual(codestream.segment[1].signed, + (False, False, False)) # subsampling - self.assertEqual(list(zip(c.segment[1].xrsiz, c.segment[1].yrsiz)), + self.assertEqual(list(zip(codestream.segment[1].xrsiz, + codestream.segment[1].yrsiz)), [(2, 2)] * 3) # COD: Coding style default - self.assertTrue(c.segment[2].scod & 2) # sop - self.assertFalse(c.segment[2].scod & 4) # no eph - self.assertEqual(c.segment[2].spcod[0], glymur.core.LRCP) - self.assertEqual(c.segment[2]._layers, 1) # layers = 1 - self.assertEqual(c.segment[2].spcod[3], 1) # mct - self.assertEqual(c.segment[2].spcod[4], 5) # levels - self.assertEqual(tuple(c.segment[2]._code_block_size), + self.assertTrue(codestream.segment[2].scod & 2) # sop + self.assertFalse(codestream.segment[2].scod & 4) # no eph + self.assertEqual(codestream.segment[2].spcod[0], glymur.core.LRCP) + self.assertEqual(codestream.segment[2].layers, 1) # layers = 1 + self.assertEqual(codestream.segment[2].spcod[3], 1) # mct + self.assertEqual(codestream.segment[2].spcod[4], 5) # levels + self.assertEqual(tuple(codestream.segment[2].code_block_size), (64, 64)) # cblksz # Selective arithmetic coding bypass - self.assertFalse(c.segment[2].spcod[7] & 0x01) + self.assertFalse(codestream.segment[2].spcod[7] & 0x01) # Reset context probabilities - self.assertFalse(c.segment[2].spcod[7] & 0x02) + self.assertFalse(codestream.segment[2].spcod[7] & 0x02) # Termination on each coding pass - self.assertFalse(c.segment[2].spcod[7] & 0x04) + self.assertFalse(codestream.segment[2].spcod[7] & 0x04) # Vertically causal context - self.assertFalse(c.segment[2].spcod[7] & 0x08) + self.assertFalse(codestream.segment[2].spcod[7] & 0x08) # Predictable termination - self.assertFalse(c.segment[2].spcod[7] & 0x0010) + self.assertFalse(codestream.segment[2].spcod[7] & 0x0010) # Segmentation symbols - self.assertFalse(c.segment[2].spcod[7] & 0x0020) - self.assertEqual(c.segment[2].spcod[8], + self.assertFalse(codestream.segment[2].spcod[7] & 0x0020) + self.assertEqual(codestream.segment[2].spcod[8], glymur.core.WAVELET_XFORM_5X3_REVERSIBLE) - self.assertEqual(len(c.segment[2].spcod), 9) + self.assertEqual(len(codestream.segment[2].spcod), 9) # 18 SOP segments. - nsops = [x.nsop for x in c.segment if x.marker_id == 'SOP'] + nsops = [x.nsop for x in codestream.segment if x.marker_id == 'SOP'] self.assertEqual(nsops, list(range(18))) def test_NR_ENC_Bretagne2_ppm_7_encode(self): + """NR-ENC-Bretagne2.ppm-7-encode""" infile = os.path.join(data_root, 'input/nonregression/Bretagne2.ppm') data = read_image(infile) with tempfile.NamedTemporaryFile(suffix='.j2k') as tfile: j = Jp2k(tfile.name, 'wb') j.write(data, modesw=38, eph=True) - c = j.get_codestream(header_only=False) + codestream = j.get_codestream(header_only=False) # SIZ: Image and tile size # Profile: "0" means profile 2 - self.assertEqual(c.segment[1].rsiz, 0) + self.assertEqual(codestream.segment[1].rsiz, 0) # Reference grid size - self.assertEqual((c.segment[1].xsiz, c.segment[1].ysiz), + self.assertEqual((codestream.segment[1].xsiz, + codestream.segment[1].ysiz), (2592, 1944)) # Reference grid offset - self.assertEqual((c.segment[1].xosiz, c.segment[1].yosiz), (0, 0)) + self.assertEqual((codestream.segment[1].xosiz, + codestream.segment[1].yosiz), (0, 0)) # Tile size - self.assertEqual((c.segment[1].xtsiz, c.segment[1].ytsiz), + self.assertEqual((codestream.segment[1].xtsiz, + codestream.segment[1].ytsiz), (2592, 1944)) # Tile offset - self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz), + self.assertEqual((codestream.segment[1].xtosiz, + codestream.segment[1].ytosiz), (0, 0)) # bitdepth - self.assertEqual(c.segment[1]._bitdepth, (8, 8, 8)) + self.assertEqual(codestream.segment[1].bitdepth, (8, 8, 8)) # signed - self.assertEqual(c.segment[1]._signed, (False, False, False)) + self.assertEqual(codestream.segment[1].signed, + (False, False, False)) # subsampling - self.assertEqual(list(zip(c.segment[1].xrsiz, c.segment[1].yrsiz)), + self.assertEqual(list(zip(codestream.segment[1].xrsiz, + codestream.segment[1].yrsiz)), [(1, 1)] * 3) # COD: Coding style default - self.assertFalse(c.segment[2].scod & 2) # no sop - self.assertTrue(c.segment[2].scod & 4) # eph - self.assertEqual(c.segment[2].spcod[0], glymur.core.LRCP) - self.assertEqual(c.segment[2]._layers, 1) # layers = 1 - self.assertEqual(c.segment[2].spcod[3], 1) # mct - self.assertEqual(c.segment[2].spcod[4], 5) # levels - self.assertEqual(tuple(c.segment[2]._code_block_size), + self.assertFalse(codestream.segment[2].scod & 2) # no sop + self.assertTrue(codestream.segment[2].scod & 4) # eph + self.assertEqual(codestream.segment[2].spcod[0], glymur.core.LRCP) + self.assertEqual(codestream.segment[2].layers, 1) # layers = 1 + self.assertEqual(codestream.segment[2].spcod[3], 1) # mct + self.assertEqual(codestream.segment[2].spcod[4], 5) # levels + self.assertEqual(tuple(codestream.segment[2].code_block_size), (64, 64)) # cblksz # Selective arithmetic coding BYPASS - self.assertFalse(c.segment[2].spcod[7] & 0x01) + self.assertFalse(codestream.segment[2].spcod[7] & 0x01) # RESET context probabilities (RESET) - self.assertTrue(c.segment[2].spcod[7] & 0x02) + self.assertTrue(codestream.segment[2].spcod[7] & 0x02) # Termination on each coding pass, RESTART(TERMALL) - self.assertTrue(c.segment[2].spcod[7] & 0x04) + self.assertTrue(codestream.segment[2].spcod[7] & 0x04) # Vertically causal context (VSC) - self.assertFalse(c.segment[2].spcod[7] & 0x08) + self.assertFalse(codestream.segment[2].spcod[7] & 0x08) # Predictable termination, ERTERM(SEGTERM) - self.assertFalse(c.segment[2].spcod[7] & 0x0010) + self.assertFalse(codestream.segment[2].spcod[7] & 0x0010) # Segmentation symbols, SEGMARK(SEGSYSM) - self.assertTrue(c.segment[2].spcod[7] & 0x0020) - self.assertEqual(c.segment[2].spcod[8], + self.assertTrue(codestream.segment[2].spcod[7] & 0x0020) + self.assertEqual(codestream.segment[2].spcod[8], glymur.core.WAVELET_XFORM_5X3_REVERSIBLE) - self.assertEqual(len(c.segment[2].spcod), 9) + self.assertEqual(len(codestream.segment[2].spcod), 9) # 18 EPH segments. - ephs = [x for x in c.segment if x.marker_id == 'EPH'] + ephs = [x for x in codestream.segment if x.marker_id == 'EPH'] self.assertEqual(len(ephs), 18) def test_NR_ENC_Bretagne2_ppm_8_encode(self): + """NR-ENC-Bretagne2.ppm-8-encode""" infile = os.path.join(data_root, 'input/nonregression/Bretagne2.ppm') data = read_image(infile) with tempfile.NamedTemporaryFile(suffix='.j2k') as tfile: j = Jp2k(tfile.name, 'wb') j.write(data, grid_offset=[300, 150], cratios=[800]) - c = j.get_codestream(header_only=False) + codestream = j.get_codestream(header_only=False) # SIZ: Image and tile size # Profile: "0" means profile 2 - self.assertEqual(c.segment[1].rsiz, 0) + self.assertEqual(codestream.segment[1].rsiz, 0) # Reference grid size - self.assertEqual((c.segment[1].xsiz, c.segment[1].ysiz), + self.assertEqual((codestream.segment[1].xsiz, + codestream.segment[1].ysiz), (2742, 2244)) # Reference grid offset - self.assertEqual((c.segment[1].xosiz, c.segment[1].yosiz), + self.assertEqual((codestream.segment[1].xosiz, + codestream.segment[1].yosiz), (150, 300)) # Tile size - self.assertEqual((c.segment[1].xtsiz, c.segment[1].ytsiz), + self.assertEqual((codestream.segment[1].xtsiz, + codestream.segment[1].ytsiz), (2742, 2244)) # Tile offset - self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz), + self.assertEqual((codestream.segment[1].xtosiz, + codestream.segment[1].ytosiz), (0, 0)) # bitdepth - self.assertEqual(c.segment[1]._bitdepth, (8, 8, 8)) + self.assertEqual(codestream.segment[1].bitdepth, (8, 8, 8)) # signed - self.assertEqual(c.segment[1]._signed, (False, False, False)) + self.assertEqual(codestream.segment[1].signed, + (False, False, False)) # subsampling - self.assertEqual(list(zip(c.segment[1].xrsiz, c.segment[1].yrsiz)), + self.assertEqual(list(zip(codestream.segment[1].xrsiz, + codestream.segment[1].yrsiz)), [(1, 1)] * 3) # COD: Coding style default - self.assertFalse(c.segment[2].scod & 2) # no sop - self.assertFalse(c.segment[2].scod & 4) # no eph - self.assertEqual(c.segment[2].spcod[0], glymur.core.LRCP) - self.assertEqual(c.segment[2]._layers, 1) # layers = 1 - self.assertEqual(c.segment[2].spcod[3], 1) # mct - self.assertEqual(c.segment[2].spcod[4], 5) # levels - self.assertEqual(tuple(c.segment[2]._code_block_size), + self.assertFalse(codestream.segment[2].scod & 2) # no sop + self.assertFalse(codestream.segment[2].scod & 4) # no eph + self.assertEqual(codestream.segment[2].spcod[0], glymur.core.LRCP) + self.assertEqual(codestream.segment[2].layers, 1) # layers = 1 + self.assertEqual(codestream.segment[2].spcod[3], 1) # mct + self.assertEqual(codestream.segment[2].spcod[4], 5) # levels + self.assertEqual(tuple(codestream.segment[2].code_block_size), (64, 64)) # cblksz # Selective arithmetic coding BYPASS - self.assertFalse(c.segment[2].spcod[7] & 0x01) + self.assertFalse(codestream.segment[2].spcod[7] & 0x01) # RESET context probabilities (RESET) - self.assertFalse(c.segment[2].spcod[7] & 0x02) + self.assertFalse(codestream.segment[2].spcod[7] & 0x02) # Termination on each coding pass, RESTART(TERMALL) - self.assertFalse(c.segment[2].spcod[7] & 0x04) + self.assertFalse(codestream.segment[2].spcod[7] & 0x04) # Vertically causal context (VSC) - self.assertFalse(c.segment[2].spcod[7] & 0x08) + self.assertFalse(codestream.segment[2].spcod[7] & 0x08) # Predictable termination, ERTERM(SEGTERM) - self.assertFalse(c.segment[2].spcod[7] & 0x0010) + self.assertFalse(codestream.segment[2].spcod[7] & 0x0010) # Segmentation symbols, SEGMARK(SEGSYSM) - self.assertFalse(c.segment[2].spcod[7] & 0x0020) - self.assertEqual(c.segment[2].spcod[8], + self.assertFalse(codestream.segment[2].spcod[7] & 0x0020) + self.assertEqual(codestream.segment[2].spcod[8], glymur.core.WAVELET_XFORM_5X3_REVERSIBLE) - self.assertEqual(len(c.segment[2].spcod), 9) + self.assertEqual(len(codestream.segment[2].spcod), 9) def test_NR_ENC_Cevennes1_bmp_9_encode(self): + """NR-ENC-Cevennes1.bmp-9-encode""" infile = os.path.join(data_root, 'input/nonregression/Cevennes1.bmp') data = read_image(infile) with tempfile.NamedTemporaryFile(suffix='.j2k') as tfile: j = Jp2k(tfile.name, 'wb') j.write(data, cratios=[800]) - c = j.get_codestream(header_only=False) + codestream = j.get_codestream(header_only=False) # SIZ: Image and tile size # Profile: "0" means profile 2 - self.assertEqual(c.segment[1].rsiz, 0) + self.assertEqual(codestream.segment[1].rsiz, 0) # Reference grid size - self.assertEqual((c.segment[1].xsiz, c.segment[1].ysiz), + self.assertEqual((codestream.segment[1].xsiz, + codestream.segment[1].ysiz), (2592, 1944)) # Reference grid offset - self.assertEqual((c.segment[1].xosiz, c.segment[1].yosiz), (0, 0)) + self.assertEqual((codestream.segment[1].xosiz, + codestream.segment[1].yosiz), (0, 0)) # Tile size - self.assertEqual((c.segment[1].xtsiz, c.segment[1].ytsiz), + self.assertEqual((codestream.segment[1].xtsiz, + codestream.segment[1].ytsiz), (2592, 1944)) # Tile offset - self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz), + self.assertEqual((codestream.segment[1].xtosiz, + codestream.segment[1].ytosiz), (0, 0)) # bitdepth - self.assertEqual(c.segment[1]._bitdepth, (8, 8, 8)) + self.assertEqual(codestream.segment[1].bitdepth, (8, 8, 8)) # signed - self.assertEqual(c.segment[1]._signed, (False, False, False)) + self.assertEqual(codestream.segment[1].signed, + (False, False, False)) # subsampling - self.assertEqual(list(zip(c.segment[1].xrsiz, c.segment[1].yrsiz)), + self.assertEqual(list(zip(codestream.segment[1].xrsiz, + codestream.segment[1].yrsiz)), [(1, 1)] * 3) # COD: Coding style default - self.assertFalse(c.segment[2].scod & 2) # no sop - self.assertFalse(c.segment[2].scod & 4) # no eph - self.assertEqual(c.segment[2].spcod[0], glymur.core.LRCP) - self.assertEqual(c.segment[2]._layers, 1) # layers = 1 - self.assertEqual(c.segment[2].spcod[3], 1) # mct - self.assertEqual(c.segment[2].spcod[4], 5) # levels - self.assertEqual(tuple(c.segment[2]._code_block_size), + self.assertFalse(codestream.segment[2].scod & 2) # no sop + self.assertFalse(codestream.segment[2].scod & 4) # no eph + self.assertEqual(codestream.segment[2].spcod[0], glymur.core.LRCP) + self.assertEqual(codestream.segment[2].layers, 1) # layers = 1 + self.assertEqual(codestream.segment[2].spcod[3], 1) # mct + self.assertEqual(codestream.segment[2].spcod[4], 5) # levels + self.assertEqual(tuple(codestream.segment[2].code_block_size), (64, 64)) # cblksz # Selective arithmetic coding BYPASS - self.assertFalse(c.segment[2].spcod[7] & 0x01) + self.assertFalse(codestream.segment[2].spcod[7] & 0x01) # RESET context probabilities (RESET) - self.assertFalse(c.segment[2].spcod[7] & 0x02) + self.assertFalse(codestream.segment[2].spcod[7] & 0x02) # Termination on each coding pass, RESTART(TERMALL) - self.assertFalse(c.segment[2].spcod[7] & 0x04) + self.assertFalse(codestream.segment[2].spcod[7] & 0x04) # Vertically causal context (VSC) - self.assertFalse(c.segment[2].spcod[7] & 0x08) + self.assertFalse(codestream.segment[2].spcod[7] & 0x08) # Predictable termination, ERTERM(SEGTERM) - self.assertFalse(c.segment[2].spcod[7] & 0x0010) + self.assertFalse(codestream.segment[2].spcod[7] & 0x0010) # Segmentation symbols, SEGMARK(SEGSYSM) - self.assertFalse(c.segment[2].spcod[7] & 0x0020) - self.assertEqual(c.segment[2].spcod[8], + self.assertFalse(codestream.segment[2].spcod[7] & 0x0020) + self.assertEqual(codestream.segment[2].spcod[8], glymur.core.WAVELET_XFORM_5X3_REVERSIBLE) - self.assertEqual(len(c.segment[2].spcod), 9) + self.assertEqual(len(codestream.segment[2].spcod), 9) def test_NR_ENC_Cevennes2_ppm_10_encode(self): + """NR-ENC-Cevennes2.ppm-10-encode""" infile = os.path.join(data_root, 'input/nonregression/Cevennes2.ppm') data = read_image(infile) with tempfile.NamedTemporaryFile(suffix='.j2k') as tfile: j = Jp2k(tfile.name, 'wb') j.write(data, cratios=[50]) - c = j.get_codestream(header_only=False) + codestream = j.get_codestream(header_only=False) # SIZ: Image and tile size # Profile: "0" means profile 2 - self.assertEqual(c.segment[1].rsiz, 0) + self.assertEqual(codestream.segment[1].rsiz, 0) # Reference grid size - self.assertEqual((c.segment[1].xsiz, c.segment[1].ysiz), + self.assertEqual((codestream.segment[1].xsiz, + codestream.segment[1].ysiz), (640, 480)) # Reference grid offset - self.assertEqual((c.segment[1].xosiz, c.segment[1].yosiz), (0, 0)) + self.assertEqual((codestream.segment[1].xosiz, + codestream.segment[1].yosiz), (0, 0)) # Tile size - self.assertEqual((c.segment[1].xtsiz, c.segment[1].ytsiz), + self.assertEqual((codestream.segment[1].xtsiz, + codestream.segment[1].ytsiz), (640, 480)) # Tile offset - self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz), + self.assertEqual((codestream.segment[1].xtosiz, + codestream.segment[1].ytosiz), (0, 0)) # bitdepth - self.assertEqual(c.segment[1]._bitdepth, (8, 8, 8)) + self.assertEqual(codestream.segment[1].bitdepth, (8, 8, 8)) # signed - self.assertEqual(c.segment[1]._signed, (False, False, False)) + self.assertEqual(codestream.segment[1].signed, + (False, False, False)) # subsampling - self.assertEqual(list(zip(c.segment[1].xrsiz, c.segment[1].yrsiz)), + self.assertEqual(list(zip(codestream.segment[1].xrsiz, + codestream.segment[1].yrsiz)), [(1, 1)] * 3) # COD: Coding style default - self.assertFalse(c.segment[2].scod & 2) # no sop - self.assertFalse(c.segment[2].scod & 4) # no eph - self.assertEqual(c.segment[2].spcod[0], glymur.core.LRCP) - self.assertEqual(c.segment[2]._layers, 1) # layers = 1 - self.assertEqual(c.segment[2].spcod[3], 1) # mct - self.assertEqual(c.segment[2].spcod[4], 5) # levels - self.assertEqual(tuple(c.segment[2]._code_block_size), + self.assertFalse(codestream.segment[2].scod & 2) # no sop + self.assertFalse(codestream.segment[2].scod & 4) # no eph + self.assertEqual(codestream.segment[2].spcod[0], glymur.core.LRCP) + self.assertEqual(codestream.segment[2].layers, 1) # layers = 1 + self.assertEqual(codestream.segment[2].spcod[3], 1) # mct + self.assertEqual(codestream.segment[2].spcod[4], 5) # levels + self.assertEqual(tuple(codestream.segment[2].code_block_size), (64, 64)) # cblksz # Selective arithmetic coding BYPASS - self.assertFalse(c.segment[2].spcod[7] & 0x01) + self.assertFalse(codestream.segment[2].spcod[7] & 0x01) # RESET context probabilities (RESET) - self.assertFalse(c.segment[2].spcod[7] & 0x02) + self.assertFalse(codestream.segment[2].spcod[7] & 0x02) # Termination on each coding pass, RESTART(TERMALL) - self.assertFalse(c.segment[2].spcod[7] & 0x04) + self.assertFalse(codestream.segment[2].spcod[7] & 0x04) # Vertically causal context (VSC) - self.assertFalse(c.segment[2].spcod[7] & 0x08) + self.assertFalse(codestream.segment[2].spcod[7] & 0x08) # Predictable termination, ERTERM(SEGTERM) - self.assertFalse(c.segment[2].spcod[7] & 0x0010) + self.assertFalse(codestream.segment[2].spcod[7] & 0x0010) # Segmentation symbols, SEGMARK(SEGSYSM) - self.assertFalse(c.segment[2].spcod[7] & 0x0020) - self.assertEqual(c.segment[2].spcod[8], + self.assertFalse(codestream.segment[2].spcod[7] & 0x0020) + self.assertEqual(codestream.segment[2].spcod[8], glymur.core.WAVELET_XFORM_5X3_REVERSIBLE) - self.assertEqual(len(c.segment[2].spcod), 9) + self.assertEqual(len(codestream.segment[2].spcod), 9) def test_NR_ENC_Rome_bmp_11_encode(self): - infile = os.path.join(data_root, 'input/nonregression/Rome.bmp') - data = read_image(infile) + """NR-ENC-Rome.bmp-11-encode""" + data = read_image(os.path.join(data_root, + 'input/nonregression/Rome.bmp')) with tempfile.NamedTemporaryFile(suffix='.jp2') as tfile: jp2 = Jp2k(tfile.name, 'wb') jp2.write(data, psnr=[30, 35, 50], prog='LRCP', numres=3) ids = [box.box_id for box in jp2.box] - lst = ['jP ', 'ftyp', 'jp2h', 'jp2c'] - self.assertEqual(ids, lst) + self.assertEqual(ids, ['jP ', 'ftyp', 'jp2h', 'jp2c']) ids = [box.box_id for box in jp2.box[2].box] self.assertEqual(ids, ['ihdr', 'colr']) @@ -671,58 +738,65 @@ class TestSuiteWrite(unittest.TestCase): self.assertIsNone(jp2.box[2].box[1].icc_profile) self.assertEqual(jp2.box[2].box[1].colorspace, glymur.core.SRGB) - c = jp2.box[3].main_header + codestream = jp2.box[3].main_header # SIZ: Image and tile size # Profile: "0" means profile 2 - self.assertEqual(c.segment[1].rsiz, 0) + self.assertEqual(codestream.segment[1].rsiz, 0) # Reference grid size - self.assertEqual((c.segment[1].xsiz, c.segment[1].ysiz), + self.assertEqual((codestream.segment[1].xsiz, + codestream.segment[1].ysiz), (640, 480)) # Reference grid offset - self.assertEqual((c.segment[1].xosiz, c.segment[1].yosiz), + self.assertEqual((codestream.segment[1].xosiz, + codestream.segment[1].yosiz), (0, 0)) # Tile size - self.assertEqual((c.segment[1].xtsiz, c.segment[1].ytsiz), + self.assertEqual((codestream.segment[1].xtsiz, + codestream.segment[1].ytsiz), (640, 480)) # Tile offset - self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz), + self.assertEqual((codestream.segment[1].xtosiz, + codestream.segment[1].ytosiz), (0, 0)) # bitdepth - self.assertEqual(c.segment[1]._bitdepth, (8, 8, 8)) + self.assertEqual(codestream.segment[1].bitdepth, (8, 8, 8)) # signed - self.assertEqual(c.segment[1]._signed, (False, False, False)) + self.assertEqual(codestream.segment[1].signed, + (False, False, False)) # subsampling - self.assertEqual(list(zip(c.segment[1].xrsiz, c.segment[1].yrsiz)), + self.assertEqual(list(zip(codestream.segment[1].xrsiz, + codestream.segment[1].yrsiz)), [(1, 1)] * 3) # COD: Coding style default - self.assertFalse(c.segment[2].scod & 2) # no sop - self.assertFalse(c.segment[2].scod & 4) # no eph - self.assertEqual(c.segment[2].spcod[0], glymur.core.LRCP) - self.assertEqual(c.segment[2]._layers, 3) # layers = 3 - self.assertEqual(c.segment[2].spcod[3], 1) # mct - self.assertEqual(c.segment[2].spcod[4], 2) # levels - self.assertEqual(tuple(c.segment[2]._code_block_size), + self.assertFalse(codestream.segment[2].scod & 2) # no sop + self.assertFalse(codestream.segment[2].scod & 4) # no eph + self.assertEqual(codestream.segment[2].spcod[0], glymur.core.LRCP) + self.assertEqual(codestream.segment[2].layers, 3) # layers = 3 + self.assertEqual(codestream.segment[2].spcod[3], 1) # mct + self.assertEqual(codestream.segment[2].spcod[4], 2) # levels + self.assertEqual(tuple(codestream.segment[2].code_block_size), (64, 64)) # cblksz # Selective arithmetic coding BYPASS - self.assertFalse(c.segment[2].spcod[7] & 0x01) + self.assertFalse(codestream.segment[2].spcod[7] & 0x01) # RESET context probabilities (RESET) - self.assertFalse(c.segment[2].spcod[7] & 0x02) + self.assertFalse(codestream.segment[2].spcod[7] & 0x02) # Termination on each coding pass, RESTART(TERMALL) - self.assertFalse(c.segment[2].spcod[7] & 0x04) + self.assertFalse(codestream.segment[2].spcod[7] & 0x04) # Vertically causal context (VSC) - self.assertFalse(c.segment[2].spcod[7] & 0x08) + self.assertFalse(codestream.segment[2].spcod[7] & 0x08) # Predictable termination, ERTERM(SEGTERM) - self.assertFalse(c.segment[2].spcod[7] & 0x0010) + self.assertFalse(codestream.segment[2].spcod[7] & 0x0010) # Segmentation symbols, SEGMARK(SEGSYSM) - self.assertFalse(c.segment[2].spcod[7] & 0x0020) - self.assertEqual(c.segment[2].spcod[8], + self.assertFalse(codestream.segment[2].spcod[7] & 0x0020) + self.assertEqual(codestream.segment[2].spcod[8], glymur.core.WAVELET_XFORM_5X3_REVERSIBLE) - self.assertEqual(len(c.segment[2].spcod), 9) + self.assertEqual(len(codestream.segment[2].spcod), 9) @unittest.skip("Known failure in openjpeg test suite.") def test_NR_ENC_random_issue_0005_tif_12_encode(self): + """NR-ENC-random-issue-0005.tif-12-encode""" # opj_decompress has trouble reading it, but that is not an issue here. # The nature of the image itself seems to give the compressor trouble. infile = os.path.join(data_root, @@ -732,54 +806,59 @@ class TestSuiteWrite(unittest.TestCase): j = Jp2k(tfile.name, 'wb') j.write(data) - c = j.get_codestream(header_only=False) + codestream = j.get_codestream(header_only=False) # SIZ: Image and tile size # Profile: "0" means profile 2 - self.assertEqual(c.segment[1].rsiz, 0) + self.assertEqual(codestream.segment[1].rsiz, 0) # Reference grid size - self.assertEqual((c.segment[1].xsiz, c.segment[1].ysiz), + self.assertEqual((codestream.segment[1].xsiz, + codestream.segment[1].ysiz), (1024, 1024)) # Reference grid offset - self.assertEqual((c.segment[1].xosiz, c.segment[1].yosiz), (0, 0)) + self.assertEqual((codestream.segment[1].xosiz, + codestream.segment[1].yosiz), (0, 0)) # Tile size - self.assertEqual((c.segment[1].xtsiz, c.segment[1].ytsiz), + self.assertEqual((codestream.segment[1].xtsiz, + codestream.segment[1].ytsiz), (1024, 1024)) # Tile offset - self.assertEqual((c.segment[1].xtosiz, c.segment[1].ytosiz), + self.assertEqual((codestream.segment[1].xtosiz, + codestream.segment[1].ytosiz), (0, 0)) # bitdepth - self.assertEqual(c.segment[1]._bitdepth, (16,)) + self.assertEqual(codestream.segment[1].bitdepth, (16,)) # signed - self.assertEqual(c.segment[1]._signed, (False,)) + self.assertEqual(codestream.segment[1].signed, (False,)) # subsampling - self.assertEqual(list(zip(c.segment[1].xrsiz, c.segment[1].yrsiz)), + self.assertEqual(list(zip(codestream.segment[1].xrsiz, + codestream.segment[1].yrsiz)), [(1, 1)]) # COD: Coding style default - self.assertFalse(c.segment[2].scod & 2) # no sop - self.assertFalse(c.segment[2].scod & 4) # no eph - self.assertEqual(c.segment[2].spcod[0], glymur.core.LRCP) - self.assertEqual(c.segment[2]._layers, 1) # layers = 1 - self.assertEqual(c.segment[2].spcod[3], 0) # mct - self.assertEqual(c.segment[2].spcod[4], 5) # levels - self.assertEqual(tuple(c.segment[2]._code_block_size), + self.assertFalse(codestream.segment[2].scod & 2) # no sop + self.assertFalse(codestream.segment[2].scod & 4) # no eph + self.assertEqual(codestream.segment[2].spcod[0], glymur.core.LRCP) + self.assertEqual(codestream.segment[2].layers, 1) # layers = 1 + self.assertEqual(codestream.segment[2].spcod[3], 0) # mct + self.assertEqual(codestream.segment[2].spcod[4], 5) # levels + self.assertEqual(tuple(codestream.segment[2].code_block_size), (64, 64)) # cblksz # Selective arithmetic coding BYPASS - self.assertFalse(c.segment[2].spcod[7] & 0x01) + self.assertFalse(codestream.segment[2].spcod[7] & 0x01) # RESET context probabilities (RESET) - self.assertFalse(c.segment[2].spcod[7] & 0x02) + self.assertFalse(codestream.segment[2].spcod[7] & 0x02) # Termination on each coding pass, RESTART(TERMALL) - self.assertFalse(c.segment[2].spcod[7] & 0x04) + self.assertFalse(codestream.segment[2].spcod[7] & 0x04) # Vertically causal context (VSC) - self.assertFalse(c.segment[2].spcod[7] & 0x08) + self.assertFalse(codestream.segment[2].spcod[7] & 0x08) # Predictable termination, ERTERM(SEGTERM) - self.assertFalse(c.segment[2].spcod[7] & 0x0010) + self.assertFalse(codestream.segment[2].spcod[7] & 0x0010) # Segmentation symbols, SEGMARK(SEGSYSM) - self.assertFalse(c.segment[2].spcod[7] & 0x0020) - self.assertEqual(c.segment[2].spcod[8], + self.assertFalse(codestream.segment[2].spcod[7] & 0x0020) + self.assertEqual(codestream.segment[2].spcod[8], glymur.core.WAVELET_XFORM_5X3_REVERSIBLE) - self.assertEqual(len(c.segment[2].spcod), 9) + self.assertEqual(len(codestream.segment[2].spcod), 9) if __name__ == "__main__": unittest.main() From 63168e6b3ae538261489b95993e15ada35777ab4 Mon Sep 17 00:00:00 2001 From: jevans Date: Sat, 10 Aug 2013 16:42:08 -0400 Subject: [PATCH 08/20] pylint work, #99 --- glymur/jp2k.py | 287 ++++++++++++++++++++++-------------------- glymur/lib/openjp2.py | 2 +- 2 files changed, 151 insertions(+), 138 deletions(-) diff --git a/glymur/jp2k.py b/glymur/jp2k.py index fade3a8..9518c22 100644 --- a/glymur/jp2k.py +++ b/glymur/jp2k.py @@ -3,7 +3,9 @@ License: MIT """ -# pylint: disable=C0302 +# W0201: Since we are using ctypes Structures, we often have to access +# attributes that are not defined in __init__ but in _fields_ instead. +# pylint: disable=W0201 import sys if sys.hexversion >= 0x03030000: @@ -32,7 +34,7 @@ from .jp2box import ImageHeaderBox from .jp2box import ColourSpecificationBox from .lib import openjpeg as opj from .lib import openjp2 as opj2 -from .lib import c as _libc +from .lib import c as libc # Need to known if openjp2 library is the officially release v2.0.0 or not. _OPENJP2_IS_OFFICIAL_V2 = False @@ -233,7 +235,6 @@ class Jp2k(Jp2kBox): cparams : CompressionParametersType(ctypes.Structure) Corresponds to cparameters_t type in openjp2 headers. """ - cparams = opj2.set_default_encoder_parameters() outfile = self.filename.encode() @@ -308,70 +309,6 @@ class Jp2k(Jp2kBox): return cparams - def _validate_compression_params(self, img_array, cparams): - """Check that the compression parameters are valid. - - Parameters - ---------- - img_array : ndarray - Image data to be written to file. - cparams : CompressionParametersType(ctypes.Structure) - Corresponds to cparameters_t type in openjp2 headers. - """ - - # Code block size - code_block_specified = False - if cparams.cblockw_init != 0 and cparams.cblockh_init != 0: - # These fields ARE zero if uninitialized. - width = cparams.cblockw_init - height = cparams.cblockh_init - code_block_specified = True - if height * width > 4096 or height < 4 or width < 4: - msg = "Code block area cannot exceed 4096. " - msg += "Code block height and width must be larger than 4." - raise IOError(msg) - if ((math.log(height, 2) != math.floor(math.log(height, 2)) or - math.log(width, 2) != math.floor(math.log(width, 2)))): - msg = "Bad code block size ({0}, {1}), " - msg += "must be powers of 2." - raise IOError(msg.format(height, width)) - - # Precinct size - if cparams.res_spec != 0: - # precinct size was not specified if this field is zero. - for j in range(cparams.res_spec): - prch = cparams.prch_init[j] - prcw = cparams.prcw_init[j] - if j == 0 and code_block_specified: - height, width = cparams.cblockh_init, cparams.cblockw_init - if height * 2 > prch or width * 2 > prcw: - msg = "Highest Resolution precinct size must be at " - msg += "least twice that of the code block dimensions." - raise IOError(msg) - if ((math.log(prch, 2) != math.floor(math.log(prch, 2)) or - math.log(prcw, 2) != math.floor(math.log(prcw, 2)))): - msg = "Bad precinct sizes ({0}, {1}), " - msg += "must be powers of 2." - raise IOError(msg.format(prch, prcw)) - - # What would the point of 1D images be? - if img_array.ndim == 1 or img_array.ndim > 3: - msg = "{0}D imagery is not allowed.".format(img_array.ndim) - raise IOError(msg) - - if _OPENJP2_IS_OFFICIAL_V2: - if (((img_array.ndim != 2) and - (img_array.shape[2] != 1 and img_array.shape[2] != 3))): - msg = "Writing images is restricted to single-channel " - msg += "greyscale images or three-channel RGB images when " - msg += "the OpenJPEG library version is the official 2.0.0 " - msg += "release." - raise IOError(msg) - - if img_array.dtype != np.uint8 and img_array.dtype != np.uint16: - msg = "Only uint8 and uint16 images are currently supported." - raise RuntimeError(msg) - def _process_write_inputs(self, img_array, colorspace=None, **kwargs): """Directs processing of write method arguments. @@ -403,7 +340,7 @@ class Jp2k(Jp2kBox): raise IOError(msg) cparams = self._populate_cparams(**kwargs) - self._validate_compression_params(img_array, cparams) + _validate_compression_params(img_array, cparams) colorspace = _unpack_colorspace(colorspace, img_array, cparams) @@ -426,38 +363,6 @@ class Jp2k(Jp2kBox): return cparams, colorspace - def _populate_image_struct(self, cparams, image, imgdata): - """Populates image struct needed for compression. - - Parameters - ---------- - cparams : CompressionParametersType(ctypes.Structure) - Corresponds to cparameters_t type in openjp2 headers. - image : ImageType(ctypes.Structure) - Corresponds to image_t type in openjp2 headers. - imgarray : ndarray - Image data to be written to file. - """ - - numrows, numcols, num_comps = imgdata.shape - - # set image offset and reference grid - image.contents.x0 = cparams.image_offset_x0 - image.contents.y0 = cparams.image_offset_y0 - image.contents.x1 = (image.contents.x0 + - (numcols - 1) * cparams.subsampling_dx + 1) - image.contents.y1 = (image.contents.y0 + - (numrows - 1) * cparams.subsampling_dy + 1) - - # Stage the image data to the openjpeg data structure. - for k in range(0, num_comps): - layer = np.ascontiguousarray(imgdata[:, :, k], dtype=np.int32) - dest = image.contents.comps[k].data - src = layer.ctypes.data - ctypes.memmove(dest, src, layer.nbytes) - - return image - def write(self, img_array, verbose=False, **kwargs): """Write image data to a JP2/JPX/J2k file. Intended usage of the various parameters follows that of OpenJPEG's opj_compress utility. @@ -537,24 +442,10 @@ class Jp2k(Jp2kBox): numrows, numcols = img_array.shape img_array = img_array.reshape(numrows, numcols, 1) - # Only two precisions are possible. - comp_prec = 8 if img_array.dtype == np.uint8 else 16 - - numrows, numcols, num_comps = img_array.shape - comptparms = (opj2.ImageComptParmType * num_comps)() - for j in range(num_comps): - comptparms[j].dx = cparams.subsampling_dx - comptparms[j].dy = cparams.subsampling_dy - comptparms[j].w = numcols - comptparms[j].h = numrows - comptparms[j].x0 = cparams.image_offset_x0 - comptparms[j].y0 = cparams.image_offset_y0 - comptparms[j].prec = comp_prec - comptparms[j].bpp = comp_prec - comptparms[j].sgnd = 0 + comptparms = _populate_comptparms(img_array, cparams) image = opj2.image_create(comptparms, colorspace) - self._populate_image_struct(cparams, image, img_array) + _populate_image_struct(cparams, image, img_array) codec = opj2.create_compress(cparams.codec_fmt) @@ -566,7 +457,7 @@ class Jp2k(Jp2kBox): opj2.setup_encoder(codec, cparams, image) 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) else: # This routine introduced in 2.0 devel series. @@ -580,7 +471,7 @@ class Jp2k(Jp2kBox): if _OPENJP2_IS_OFFICIAL_V2: opj2.stream_destroy(strm) - _libc.fclose(fptr) + libc.fclose(fptr) else: # This routine introduced in 2.0 devel series. opj2.stream_destroy_v3(strm) @@ -804,8 +695,7 @@ class Jp2k(Jp2kBox): return data - def _read_openjp2(self, rlevel=0, layer=0, area=None, tile=None, - verbose=False): + def _read_openjp2(self, **kwargs): """Read a JPEG 2000 image using libopenjp2. Parameters @@ -835,12 +725,7 @@ class Jp2k(Jp2kBox): """ self._subsampling_sanity_check() - img_array = self._read_common(rlevel=rlevel, - layer=layer, - area=area, - tile=tile, - verbose=verbose, - as_bands=False) + img_array = self._read_common(as_bands=False, **kwargs) if img_array.shape[2] == 1: img_array = img_array.view() @@ -936,8 +821,8 @@ class Jp2k(Jp2kBox): True) stack.callback(opj2.stream_destroy_v3, stream) else: - fptr = _libc.fopen(self.filename, 'rb') - stack.callback(_libc.fclose, fptr) + fptr = libc.fopen(self.filename, 'rb') + stack.callback(libc.fclose, fptr) stream = opj2.stream_create_default_file_stream(fptr, True) stack.callback(opj2.stream_destroy, stream) codec = opj2.create_decompress(self._codec_format) @@ -970,8 +855,7 @@ class Jp2k(Jp2kBox): return data - def read_bands(self, rlevel=0, layer=0, area=None, tile=None, - verbose=False): + def read_bands(self, **kwargs): """Read a JPEG 2000 image. The only time you should use this method is when the image has @@ -1018,13 +902,7 @@ class Jp2k(Jp2kBox): "of OpenJP2 installed before using " "this functionality.") - lst = self._read_common(rlevel=rlevel, - layer=layer, - area=area, - tile=tile, - verbose=verbose, - as_bands=True) - + lst = self._read_common(as_bands=True, **kwargs) return lst def get_codestream(self, header_only=True): @@ -1298,3 +1176,138 @@ def _unpack_colorspace(colorspace, img_array, cparams): colorspace = _COLORSPACE_MAP[colorspace.lower()] return colorspace + +def _populate_comptparms(img_array, cparams): + """Instantiate and populate comptparms structure. + + This structure defines the image components. + + Parameters + ---------- + img_array : ndarray + Image data to be written to file. + cparams : CompressionParametersType(ctypes.Structure) + Corresponds to cparameters_t type in openjp2 headers. + + Returns + ------- + comptparms : ImageCompType(ctypes.Structure) + Corresponds to image_comp_t type in openjp2 headers. + """ + # Only two precisions are possible. + if img_array.dtype == np.uint8: + comp_prec = 8 + else: + comp_prec = 16 + + numrows, numcols, num_comps = img_array.shape + comptparms = (opj2.ImageComptParmType * num_comps)() + for j in range(num_comps): + comptparms[j].dx = cparams.subsampling_dx + comptparms[j].dy = cparams.subsampling_dy + comptparms[j].w = numcols + comptparms[j].h = numrows + comptparms[j].x0 = cparams.image_offset_x0 + comptparms[j].y0 = cparams.image_offset_y0 + comptparms[j].prec = comp_prec + comptparms[j].bpp = comp_prec + comptparms[j].sgnd = 0 + + return comptparms + +def _populate_image_struct(cparams, image, imgdata): + """Populates image struct needed for compression. + + Parameters + ---------- + cparams : CompressionParametersType(ctypes.Structure) + Corresponds to cparameters_t type in openjp2 headers. + image : ImageType(ctypes.Structure) + Corresponds to image_t type in openjp2 headers. + imgarray : ndarray + Image data to be written to file. + """ + + numrows, numcols, num_comps = imgdata.shape + + # set image offset and reference grid + image.contents.x0 = cparams.image_offset_x0 + image.contents.y0 = cparams.image_offset_y0 + image.contents.x1 = (image.contents.x0 + + (numcols - 1) * cparams.subsampling_dx + 1) + image.contents.y1 = (image.contents.y0 + + (numrows - 1) * cparams.subsampling_dy + 1) + + # Stage the image data to the openjpeg data structure. + for k in range(0, num_comps): + layer = np.ascontiguousarray(imgdata[:, :, k], dtype=np.int32) + dest = image.contents.comps[k].data + src = layer.ctypes.data + ctypes.memmove(dest, src, layer.nbytes) + + return image + +def _validate_compression_params(img_array, cparams): + """Check that the compression parameters are valid. + + Parameters + ---------- + img_array : ndarray + Image data to be written to file. + cparams : CompressionParametersType(ctypes.Structure) + Corresponds to cparameters_t type in openjp2 headers. + """ + + # Code block size + code_block_specified = False + if cparams.cblockw_init != 0 and cparams.cblockh_init != 0: + # These fields ARE zero if uninitialized. + width = cparams.cblockw_init + height = cparams.cblockh_init + code_block_specified = True + if height * width > 4096 or height < 4 or width < 4: + msg = "Code block area cannot exceed 4096. " + msg += "Code block height and width must be larger than 4." + raise IOError(msg) + if ((math.log(height, 2) != math.floor(math.log(height, 2)) or + math.log(width, 2) != math.floor(math.log(width, 2)))): + msg = "Bad code block size ({0}, {1}), " + msg += "must be powers of 2." + raise IOError(msg.format(height, width)) + + # Precinct size + if cparams.res_spec != 0: + # precinct size was not specified if this field is zero. + for j in range(cparams.res_spec): + prch = cparams.prch_init[j] + prcw = cparams.prcw_init[j] + if j == 0 and code_block_specified: + height, width = cparams.cblockh_init, cparams.cblockw_init + if height * 2 > prch or width * 2 > prcw: + msg = "Highest Resolution precinct size must be at " + msg += "least twice that of the code block dimensions." + raise IOError(msg) + if ((math.log(prch, 2) != math.floor(math.log(prch, 2)) or + math.log(prcw, 2) != math.floor(math.log(prcw, 2)))): + msg = "Bad precinct sizes ({0}, {1}), " + msg += "must be powers of 2." + raise IOError(msg.format(prch, prcw)) + + # What would the point of 1D images be? + if img_array.ndim == 1 or img_array.ndim > 3: + msg = "{0}D imagery is not allowed.".format(img_array.ndim) + raise IOError(msg) + + if _OPENJP2_IS_OFFICIAL_V2: + if (((img_array.ndim != 2) and + (img_array.shape[2] != 1 and img_array.shape[2] != 3))): + msg = "Writing images is restricted to single-channel " + msg += "greyscale images or three-channel RGB images when " + msg += "the OpenJPEG library version is the official 2.0.0 " + msg += "release." + raise IOError(msg) + + if img_array.dtype != np.uint8 and img_array.dtype != np.uint16: + msg = "Only uint8 and uint16 images are currently supported." + raise RuntimeError(msg) + diff --git a/glymur/lib/openjp2.py b/glymur/lib/openjp2.py index 468bb51..f0f72c0 100644 --- a/glymur/lib/openjp2.py +++ b/glymur/lib/openjp2.py @@ -2,7 +2,7 @@ Wraps individual functions in openjp2 library. """ -# pylint: disable=C0302,R0903 +# pylint: disable=C0302,R0903,W0201 import ctypes import sys From ee2f9505000ce4b490351d3bcf21235e132a933d Mon Sep 17 00:00:00 2001 From: jevans Date: Sat, 10 Aug 2013 21:51:59 -0400 Subject: [PATCH 09/20] pylint work, #99 --- glymur/jp2k.py | 4 ---- glymur/test/test_callbacks.py | 32 ++++++++++++++++++++++++-------- glymur/test/test_config.py | 35 ++++++++++++++++++++++------------- glymur/test/test_icc.py | 35 ++++++++++++++++++++--------------- 4 files changed, 66 insertions(+), 40 deletions(-) diff --git a/glymur/jp2k.py b/glymur/jp2k.py index 9518c22..37cad71 100644 --- a/glymur/jp2k.py +++ b/glymur/jp2k.py @@ -3,10 +3,6 @@ License: MIT """ -# W0201: Since we are using ctypes Structures, we often have to access -# attributes that are not defined in __init__ but in _fields_ instead. -# pylint: disable=W0201 - import sys if sys.hexversion >= 0x03030000: from contextlib import ExitStack diff --git a/glymur/test/test_callbacks.py b/glymur/test/test_callbacks.py index 712dd5f..992ca3a 100644 --- a/glymur/test/test_callbacks.py +++ b/glymur/test/test_callbacks.py @@ -1,6 +1,13 @@ -#pylint: disable-all +""" +Test suite for openjpeg's callback functions. +""" +# R0904: Seems like pylint is fooled in this situation +# pylint: disable=R0904 + +# 'mock' most certainly is in unittest (Python 3.3) +# pylint: disable=E0611,F0401 + import os -import pkg_resources import re import sys import tempfile @@ -24,6 +31,7 @@ import glymur @unittest.skipIf(glymur.lib.openjp2.OPENJP2 is None, "Missing openjp2 library.") class TestCallbacks(unittest.TestCase): + """Test suite for callbacks.""" def setUp(self): self.jp2file = glymur.data.nemo() @@ -34,7 +42,7 @@ class TestCallbacks(unittest.TestCase): @unittest.skipIf(os.name == "nt", "Temporary file issue on window.") def test_info_callback_on_write(self): - # Verify the messages printed when writing an image in verbose mode. + """Verify messages printed when writing an image in verbose mode.""" j = glymur.Jp2k(self.jp2file) with warnings.catch_warnings(): warnings.simplefilter("ignore") @@ -47,12 +55,14 @@ class TestCallbacks(unittest.TestCase): expected = '[INFO] tile number 1 / 1' self.assertEqual(actual, expected) - def test_info_warning_callbacks_on_read(self): + def test_info_callbacks_on_read(self): + """stdio output when info callback handler is enabled""" + # Verify that we get the expected stdio output when our internal info # callback handler is enabled. j = glymur.Jp2k(self.j2kfile) with patch('sys.stdout', new=StringIO()) as fake_out: - d = j.read(rlevel=1, verbose=True, area=(0, 0, 200, 150)) + j.read(rlevel=1, verbose=True, area=(0, 0, 200, 150)) actual = fake_out.getvalue().strip() lines = ['[INFO] Start to read j2k main header (0).', @@ -80,13 +90,16 @@ class TestCallbacks15(unittest.TestCase): pass def test_info_callbacks_on_read(self): - # Verify that we get the expected stdio output when our internal info - # callback handler is enabled. + """Verify stdout when reading. + + Verify that we get the expected stdio output when our internal info + callback handler is enabled. + """ with patch('glymur.lib.openjp2.OPENJP2', new=None): # Force to use OPENJPEG instead of OPENJP2. j = glymur.Jp2k(self.j2kfile) with patch('sys.stdout', new=StringIO()) as fake_out: - d = j.read(rlevel=1, verbose=True) + j.read(rlevel=1, verbose=True) actual = fake_out.getvalue().strip() regex = re.compile(r"""\[INFO\]\stile\s1\sof\s1\s+ @@ -97,6 +110,9 @@ class TestCallbacks15(unittest.TestCase): \[INFO\]\s-\stile\sdecoded\sin\s [0-9]+\.[0-9]+\ss""", re.VERBOSE) + + # assertRegex in Python 3.3 (python2.7/pylint issue) + # pylint: disable=E1101 if sys.hexversion <= 0x03020000: self.assertRegexpMatches(actual, regex) else: diff --git a/glymur/test/test_config.py b/glymur/test/test_config.py index 7833865..b475b91 100644 --- a/glymur/test/test_config.py +++ b/glymur/test/test_config.py @@ -1,7 +1,15 @@ """These tests are for edge cases where OPENJPEG does not exist, but OPENJP2 may be present in some form or other. """ -#pylint: disable-all +# unittest doesn't work well with R0904. +# pylint: disable=R0904 + +# tempfile.TemporaryDirectory, unittest.assertWarns introduced in 3.2 +# pylint: disable=E1101 + +# unittest.mock only in Python 3.3 (python2.7/pylint import issue) +# pylint: disable=E0611,F0401 + import imp import os @@ -17,13 +25,9 @@ if sys.hexversion <= 0x03030000: from mock import patch else: from unittest.mock import patch -import warnings - -import pkg_resources import glymur from glymur import Jp2k -from glymur.lib import openjp2 as opj2 @unittest.skipIf(sys.hexversion < 0x03020000, @@ -31,6 +35,7 @@ from glymur.lib import openjp2 as opj2 @unittest.skipIf(glymur.lib.openjp2.OPENJP2 is None, "Needs openjp2 library first before these tests make sense.") class TestSuite(unittest.TestCase): + """Test suite for configuration file operation.""" @classmethod def setUpClass(cls): @@ -56,29 +61,33 @@ class TestSuite(unittest.TestCase): filename = os.path.join(configdir, 'glymurrc') with open(filename, 'wt') as tfile: tfile.write('[library]\n') + + # Need to reliably recover the location of the openjp2 library, + # so using '_name' appears to be the only way to do it. + # pylint: disable=W0212 libloc = glymur.lib.openjp2.OPENJP2._name line = 'openjp2: {0}\n'.format(libloc) tfile.write(line) tfile.flush() with patch.dict('os.environ', {'XDG_CONFIG_HOME': tdir}): imp.reload(glymur.lib.openjp2) - j = Jp2k(self.jp2file) + Jp2k(self.jp2file) - def test_config_file_via_environ_is_wrong(self): - # A non-existant library location should be rejected. + def test_xdg_env_config_file_is_bad(self): + """A non-existant library location should be rejected.""" with tempfile.TemporaryDirectory() as tdir: configdir = os.path.join(tdir, 'glymur') os.mkdir(configdir) fname = os.path.join(configdir, 'glymurrc') - with open(fname, 'w') as fp: + with open(fname, 'w') as fptr: with tempfile.NamedTemporaryFile(suffix='.dylib') as tfile: - fp.write('[library]\n') - fp.write('openjp2: {0}.not.there\n'.format(tfile.name)) - fp.flush() + fptr.write('[library]\n') + fptr.write('openjp2: {0}.not.there\n'.format(tfile.name)) + fptr.flush() with patch.dict('os.environ', {'XDG_CONFIG_HOME': tdir}): # Misconfigured new configuration file should # be rejected. - with self.assertWarns(UserWarning) as cw: + with self.assertWarns(UserWarning): imp.reload(glymur.lib.openjp2) if __name__ == "__main__": diff --git a/glymur/test/test_icc.py b/glymur/test/test_icc.py index 4334645..fc2f7c1 100644 --- a/glymur/test/test_icc.py +++ b/glymur/test/test_icc.py @@ -1,35 +1,35 @@ -#pylint: disable-all +""" +ICC profile tests. +""" + +# unittest doesn't work well with R0904. +# pylint: disable=R0904 + import datetime import os -import struct import sys -import tempfile if sys.hexversion < 0x02070000: import unittest2 as unittest else: import unittest -import warnings -from xml.etree import cElementTree as ET - import numpy as np -import pkg_resources from glymur import Jp2k -import glymur try: - data_root = os.environ['OPJ_DATA_ROOT'] + DATA_ROOT = os.environ['OPJ_DATA_ROOT'] except KeyError: - data_root = None + DATA_ROOT = None except: raise -@unittest.skipIf(data_root is None, +@unittest.skipIf(DATA_ROOT is None, "OPJ_DATA_ROOT environment variable not set") class TestICC(unittest.TestCase): + """ICC profile tests""" def setUp(self): pass @@ -38,7 +38,8 @@ class TestICC(unittest.TestCase): pass def test_file5(self): - filename = os.path.join(data_root, 'input/conformance/file5.jp2') + """basic ICC profile""" + filename = os.path.join(DATA_ROOT, 'input/conformance/file5.jp2') j = Jp2k(filename) profile = j.box[3].box[1].icc_profile self.assertEqual(profile['Size'], 546) @@ -70,10 +71,14 @@ class TestICC(unittest.TestCase): @unittest.skipIf(sys.hexversion < 0x03020000, "Uses features introduced in 3.2.") def test_invalid_profile_header(self): - jfile = os.path.join(data_root, + """invalid ICC header data should cause UserWarning""" + jfile = os.path.join(DATA_ROOT, 'input/nonregression/orb-blue10-lin-jp2.jp2') - with self.assertWarns(UserWarning) as cw: - j = Jp2k(jfile) + + # assertWarns in Python 3.3 (python2.7/pylint issue) + # pylint: disable=E1101 + with self.assertWarns(UserWarning): + Jp2k(jfile) if __name__ == "__main__": unittest.main() From 1fe62a9d9e366a333f94d4ec7511cdc7dbddaf19 Mon Sep 17 00:00:00 2001 From: John Evans Date: Sun, 11 Aug 2013 07:34:40 -0400 Subject: [PATCH 10/20] pylint work, #99 --- glymur/codestream.py | 11 +++-- glymur/test/test_codestream.py | 78 +++++++++++++++++++--------------- 2 files changed, 50 insertions(+), 39 deletions(-) diff --git a/glymur/codestream.py b/glymur/codestream.py index 7bd0215..bb3caf6 100644 --- a/glymur/codestream.py +++ b/glymur/codestream.py @@ -775,12 +775,15 @@ class Segment(object): length : int Length of marker segment in bytes. This number does not include the two bytes constituting the marker. + data : bytes iterable or None + Uninterpreted buffer of raw bytes, only used where a segment is not + well understood. """ def __init__(self, marker_id='', offset=-1, length=-1, data=None): self.marker_id = marker_id self.offset = offset self.length = length - self._data = data + self.data = data def __str__(self): msg = '{0} marker segment @ ({1}, {2})'.format(self.marker_id, @@ -1203,8 +1206,8 @@ class PPMsegment(Segment): Segment.__init__(self, marker_id='PPM') self.zppm = zppm - # both Nppm and Ippms information stored in _data - self._data = data + # both Nppm and Ippms information stored in data + self.data = data self.length = length self.offset = offset @@ -1213,7 +1216,7 @@ class PPMsegment(Segment): msg = Segment.__str__(self) msg += '\n Index: {0}' msg += '\n Data: {1} uninterpreted bytes' - msg = msg.format(self.zppm, len(self._data)) + msg = msg.format(self.zppm, len(self.data)) return msg diff --git a/glymur/test/test_codestream.py b/glymur/test/test_codestream.py index f0d3e8a..3913d44 100644 --- a/glymur/test/test_codestream.py +++ b/glymur/test/test_codestream.py @@ -1,4 +1,13 @@ -#pylint: disable-all +""" +Test suite for codestream parsing. +""" + +# unittest doesn't work well with R0904. +# pylint: disable=R0904 + +# tempfile.TemporaryDirectory, unittest.assertWarns introduced in 3.2 +# pylint: disable=E1101 + import os import struct import sys @@ -9,23 +18,21 @@ if sys.hexversion < 0x02070000: else: import unittest -import numpy as np -import pkg_resources - from glymur import Jp2k import glymur try: - data_root = os.environ['OPJ_DATA_ROOT'] + DATA_ROOT = os.environ['OPJ_DATA_ROOT'] except KeyError: - data_root = None + DATA_ROOT = None except: raise -@unittest.skipIf(data_root is None, +@unittest.skipIf(DATA_ROOT is None, "OPJ_DATA_ROOT environment variable not set") class TestCodestream(unittest.TestCase): + """Test suite for unusual codestream cases.""" def setUp(self): self.jp2file = glymur.data.nemo() @@ -35,75 +42,76 @@ class TestCodestream(unittest.TestCase): @unittest.skipIf(os.name == "nt", "Temporary file issue on window.") def test_reserved_marker_segment(self): + """Reserved marker segments are ok.""" + # Some marker segments were reserved in FCD15444-1. Since that # standard is old, some of them may have come into use. # # Let's inject a reserved marker segment into a file that # we know something about to make sure we can still parse it. - filename = os.path.join(data_root, 'input/conformance/p0_01.j2k') + filename = os.path.join(DATA_ROOT, 'input/conformance/p0_01.j2k') with tempfile.NamedTemporaryFile(suffix='.j2k') as tfile: with open(filename, 'rb') as ifile: # Everything up until the first QCD marker. - buffer = ifile.read(45) - tfile.write(buffer) + read_buffer = ifile.read(45) + tfile.write(read_buffer) # Write the new marker segment, 0xff6f = 65391 - buffer = struct.pack('>HHB', int(65391), int(3), int(0)) - tfile.write(buffer) + read_buffer = struct.pack('>HHB', int(65391), int(3), int(0)) + tfile.write(read_buffer) # Get the rest of the input file. - buffer = ifile.read() - tfile.write(buffer) + read_buffer = ifile.read() + tfile.write(read_buffer) tfile.flush() - j = Jp2k(tfile.name) - c = j.get_codestream() + codestream = Jp2k(tfile.name).get_codestream() - self.assertEqual(c.segment[2].marker_id, '0xff6f') - self.assertEqual(c.segment[2].length, 3) - self.assertEqual(c.segment[2]._data, b'\x00') + self.assertEqual(codestream.segment[2].marker_id, '0xff6f') + self.assertEqual(codestream.segment[2].length, 3) + self.assertEqual(codestream.segment[2].data, b'\x00') @unittest.skipIf(sys.hexversion < 0x03020000, "Uses features introduced in 3.2.") @unittest.skipIf(os.name == "nt", "Temporary file issue on window.") def test_unknown_marker_segment(self): + """Should warn for an unknown marker.""" # Let's inject a marker segment whose marker does not appear to # be valid. We still parse the file, but warn about the offending # marker. - filename = os.path.join(data_root, 'input/conformance/p0_01.j2k') + filename = os.path.join(DATA_ROOT, 'input/conformance/p0_01.j2k') with tempfile.NamedTemporaryFile(suffix='.j2k') as tfile: with open(filename, 'rb') as ifile: # Everything up until the first QCD marker. - buffer = ifile.read(45) - tfile.write(buffer) + read_buffer = ifile.read(45) + tfile.write(read_buffer) # Write the new marker segment, 0xff79 = 65401 - buffer = struct.pack('>HHB', int(65401), int(3), int(0)) - tfile.write(buffer) + read_buffer = struct.pack('>HHB', int(65401), int(3), int(0)) + tfile.write(read_buffer) # Get the rest of the input file. - buffer = ifile.read() - tfile.write(buffer) + read_buffer = ifile.read() + tfile.write(read_buffer) tfile.flush() with self.assertWarns(UserWarning): - j = Jp2k(tfile.name) - c = j.get_codestream() + codestream = Jp2k(tfile.name).get_codestream() - self.assertEqual(c.segment[2].marker_id, '0xff79') - self.assertEqual(c.segment[2].length, 3) - self.assertEqual(c.segment[2]._data, b'\x00') + self.assertEqual(codestream.segment[2].marker_id, '0xff79') + self.assertEqual(codestream.segment[2].length, 3) + self.assertEqual(codestream.segment[2].data, b'\x00') def test_psot_is_zero(self): - # Psot=0 in SOT is perfectly legal. Issue #78. - filename = os.path.join(data_root, + """Psot=0 in SOT is perfectly legal. Issue #78.""" + filename = os.path.join(DATA_ROOT, 'input/nonregression/123.j2c') j = Jp2k(filename) - c = j.get_codestream(header_only=False) + codestream = j.get_codestream(header_only=False) # The codestream is valid, so we should be able to get the entire # codestream, so the last one is EOC. - self.assertEqual(c.segment[-1].marker_id, 'EOC') + self.assertEqual(codestream.segment[-1].marker_id, 'EOC') if __name__ == "__main__": unittest.main() From 2acb8d6c9469682bbea0e076e7adb4a765946750 Mon Sep 17 00:00:00 2001 From: John Evans Date: Sun, 11 Aug 2013 14:49:44 -0400 Subject: [PATCH 11/20] pylint work, #99 --- glymur/test/test_jp2box.py | 310 +++++++++++++++++++++---------------- 1 file changed, 175 insertions(+), 135 deletions(-) diff --git a/glymur/test/test_jp2box.py b/glymur/test/test_jp2box.py index a563b58..15c0209 100644 --- a/glymur/test/test_jp2box.py +++ b/glymur/test/test_jp2box.py @@ -1,4 +1,21 @@ -#pylint: disable-all +""" +Test suite specifically targeting JP2 box layout. +""" +# E1103: return value from read may be list or np array +# pylint: disable=E1103 + +# F0401: unittest2 is needed on python-2.6 (pylint on 2.7) +# pylint: disable=F0401 + +# R0902: More than 7 instance attributes are just fine for testing. +# pylint: disable=R0902 + +# R0904: Seems like pylint is fooled in this situation +# pylint: disable=R0904 + +# W0613: load_tests doesn't need to use ignore or loader arguments. +# pylint: disable=W0613 + import doctest import os import sys @@ -11,24 +28,25 @@ else: import unittest import numpy as np -import pkg_resources import glymur from glymur import Jp2k -from glymur.jp2box import * +from glymur.jp2box import ColourSpecificationBox, ContiguousCodestreamBox +from glymur.jp2box import FileTypeBox, ImageHeaderBox, JP2HeaderBox +from glymur.jp2box import JPEG2000SignatureBox from glymur.core import COLOR, OPACITY from glymur.core import RED, GREEN, BLUE, GREY, WHOLE_IMAGE from .fixtures import OPENJP2_IS_V2_OFFICIAL try: - format_corpus_data_root = os.environ['FORMAT_CORPUS_DATA_ROOT'] + FORMAT_CORPUS_DATA_ROOT = os.environ['FORMAT_CORPUS_DATA_ROOT'] except KeyError: - format_corpus_data_root = None + FORMAT_CORPUS_DATA_ROOT = None -# Doc tests should be run as well. def load_tests(loader, tests, ignore): + """Run doc tests as well.""" if os.name == "nt": # Can't do it on windows, temporary file issue. return tests @@ -42,6 +60,7 @@ def load_tests(loader, tests, ignore): @unittest.skipIf(glymur.lib.openjp2.OPENJP2 is None, "Missing openjp2 library.") class TestChannelDefinition(unittest.TestCase): + """Test suite for channel definition boxes.""" @classmethod def setUpClass(cls): @@ -78,12 +97,12 @@ class TestChannelDefinition(unittest.TestCase): self.j2kfile = glymur.data.goodstuff() j2k = Jp2k(self.j2kfile) - c = j2k.get_codestream() - height = c.segment[1].ysiz - width = c.segment[1].xsiz - num_components = len(c.segment[1].xrsiz) + codestream = j2k.get_codestream() + height = codestream.segment[1].ysiz + width = codestream.segment[1].xsiz + num_components = len(codestream.segment[1].xrsiz) - self.jP = JPEG2000SignatureBox() + self.jp2b = JPEG2000SignatureBox() self.ftyp = FileTypeBox() self.jp2h = JP2HeaderBox() self.jp2c = ContiguousCodestreamBox() @@ -110,7 +129,7 @@ class TestChannelDefinition(unittest.TestCase): association=association) boxes = [self.ihdr, self.colr_rgb, cdef] self.jp2h.box = boxes - boxes = [self.jP, self.ftyp, self.jp2h, self.jp2c] + boxes = [self.jp2b, self.ftyp, self.jp2h, self.jp2c] with tempfile.NamedTemporaryFile(suffix=".jp2") as tfile: j2k.wrap(tfile.name, boxes=boxes) @@ -133,7 +152,7 @@ class TestChannelDefinition(unittest.TestCase): association=association) boxes = [self.ihdr, self.colr_rgb, cdef] self.jp2h.box = boxes - boxes = [self.jP, self.ftyp, self.jp2h, self.jp2c] + boxes = [self.jp2b, self.ftyp, self.jp2h, self.jp2c] with tempfile.NamedTemporaryFile(suffix=".jp2") as tfile: j2k.wrap(tfile.name, boxes=boxes) @@ -156,7 +175,7 @@ class TestChannelDefinition(unittest.TestCase): association=association) boxes = [self.ihdr, self.colr_rgb, cdef] self.jp2h.box = boxes - boxes = [self.jP, self.ftyp, self.jp2h, self.jp2c] + boxes = [self.jp2b, self.ftyp, self.jp2h, self.jp2c] with tempfile.NamedTemporaryFile(suffix=".jp2") as tfile: j2k.wrap(tfile.name, boxes=boxes) @@ -177,9 +196,9 @@ class TestChannelDefinition(unittest.TestCase): association=association) boxes = [self.ihdr, self.colr_rgb, cdef] self.jp2h.box = boxes - boxes = [self.jP, self.ftyp, self.jp2h, self.jp2c] + boxes = [self.jp2b, self.ftyp, self.jp2h, self.jp2c] with tempfile.NamedTemporaryFile(suffix=".jp2") as tfile: - with self.assertRaises(IOError) as ce: + with self.assertRaises(IOError): j2k.wrap(tfile.name, boxes=boxes) def test_grey(self): @@ -191,7 +210,7 @@ class TestChannelDefinition(unittest.TestCase): association=association) boxes = [self.ihdr, self.colr_gr, cdef] self.jp2h.box = boxes - boxes = [self.jP, self.ftyp, self.jp2h, self.jp2c] + boxes = [self.jp2b, self.ftyp, self.jp2h, self.jp2c] with tempfile.NamedTemporaryFile(suffix=".jp2") as tfile: j2k.wrap(tfile.name, boxes=boxes) @@ -212,7 +231,7 @@ class TestChannelDefinition(unittest.TestCase): association=association) boxes = [self.ihdr, self.colr_gr, cdef] self.jp2h.box = boxes - boxes = [self.jP, self.ftyp, self.jp2h, self.jp2c] + boxes = [self.jp2b, self.ftyp, self.jp2h, self.jp2c] with tempfile.NamedTemporaryFile(suffix=".jp2") as tfile: j2k.wrap(tfile.name, boxes=boxes) @@ -236,12 +255,12 @@ class TestChannelDefinition(unittest.TestCase): association=association) boxes = [self.ihdr, self.colr_gr, cdef] self.jp2h.box = boxes - boxes = [self.jP, self.ftyp, self.jp2h, self.jp2c] + boxes = [self.jp2b, self.ftyp, self.jp2h, self.jp2c] with tempfile.NamedTemporaryFile(suffix=".jp2") as tfile: - with self.assertRaises((OSError, IOError)) as ce: + with self.assertRaises((OSError, IOError)): j2k.wrap(tfile.name, boxes=boxes) - def test_only_one_cdef_in_jp2_header(self): + def test_only_one_cdef_in_jp2h(self): """There can only be one channel definition box in the jp2 header.""" j2k = Jp2k(self.j2kfile) @@ -253,13 +272,14 @@ class TestChannelDefinition(unittest.TestCase): boxes = [self.ihdr, cdef, self.colr_rgb, cdef] self.jp2h.box = boxes - boxes = [self.jP, self.ftyp, self.jp2h, self.jp2c] + boxes = [self.jp2b, self.ftyp, self.jp2h, self.jp2c] with tempfile.NamedTemporaryFile(suffix=".jp2") as tfile: with self.assertRaises(IOError): j2k.wrap(tfile.name, boxes=boxes) - def test_not_in_jp2_header(self): + def test_not_in_jp2h(self): + """need cdef in jp2h""" j2k = Jp2k(self.j2kfile) boxes = [self.ihdr, self.colr_rgb] self.jp2h.box = boxes @@ -269,34 +289,37 @@ class TestChannelDefinition(unittest.TestCase): cdef = glymur.jp2box.ChannelDefinitionBox(channel_type=channel_type, association=association) - boxes = [self.jP, self.ftyp, self.jp2h, cdef, self.jp2c] + boxes = [self.jp2b, self.ftyp, self.jp2h, cdef, self.jp2c] with tempfile.NamedTemporaryFile(suffix=".jp2") as tfile: with self.assertRaises(IOError): j2k.wrap(tfile.name, boxes=boxes) def test_bad_type(self): - # Channel types are limited to 0, 1, 2, 65535 - # Should reject if not all of index, channel_type, association the - # same length. + """Channel types are limited to 0, 1, 2, 65535 + Should reject if not all of index, channel_type, association the + same length. + """ channel_type = (COLOR, COLOR, 3) association = (RED, GREEN, BLUE) with self.assertRaises(IOError): - box = glymur.jp2box.ChannelDefinitionBox(channel_type=channel_type, - association=association) + glymur.jp2box.ChannelDefinitionBox(channel_type=channel_type, + association=association) def test_wrong_lengths(self): - # Should reject if not all of index, channel_type, association the - # same length. + """Should reject if not all of index, channel_type, association the + same length. + """ channel_type = (COLOR, COLOR) association = (RED, GREEN, BLUE) with self.assertRaises(IOError): - box = glymur.jp2box.ChannelDefinitionBox(channel_type=channel_type, - association=association) + glymur.jp2box.ChannelDefinitionBox(channel_type=channel_type, + association=association) @unittest.skipIf(os.name == "nt", "Temporary file issue on window.") class TestXML(unittest.TestCase): + """Test suite for XML boxes.""" def setUp(self): self.jp2file = glymur.data.nemo() @@ -331,12 +354,12 @@ class TestXML(unittest.TestCase): self.xmlfile = tfile.name j2k = Jp2k(self.j2kfile) - c = j2k.get_codestream() - height = c.segment[1].ysiz - width = c.segment[1].xsiz - num_components = len(c.segment[1].xrsiz) + codestream = j2k.get_codestream() + height = codestream.segment[1].ysiz + width = codestream.segment[1].xsiz + num_components = len(codestream.segment[1].xrsiz) - self.jP = JPEG2000SignatureBox() + self.jp2b = JPEG2000SignatureBox() self.ftyp = FileTypeBox() self.jp2h = JP2HeaderBox() self.jp2c = ContiguousCodestreamBox() @@ -346,19 +369,17 @@ class TestXML(unittest.TestCase): def tearDown(self): os.unlink(self.xmlfile) - pass - def test_negative_both_file_and_xml_provided(self): + def test_negative_file_and_xml(self): """The XML should come from only one source.""" - j2k = Jp2k(self.j2kfile) xml_object = ET.parse(self.xmlfile) - with self.assertRaises((IOError, OSError)) as ce: - xmlb = glymur.jp2box.XMLBox(filename=self.xmlfile, xml=xml_object) + with self.assertRaises((IOError, OSError)): + glymur.jp2box.XMLBox(filename=self.xmlfile, xml=xml_object) @unittest.skipIf(os.name == "nt", "Problems using NamedTemporaryFile on windows.") def test_basic_xml(self): - # Should be able to write an XMLBox. + """Should be able to write a basic XMLBox""" j2k = Jp2k(self.j2kfile) self.jp2h.box = [self.ihdr, self.colr] @@ -368,7 +389,7 @@ class TestXML(unittest.TestCase): self.assertEqual(ET.tostring(xmlb.xml), b'0') - boxes = [self.jP, self.ftyp, self.jp2h, xmlb, self.jp2c] + boxes = [self.jp2b, self.ftyp, self.jp2h, xmlb, self.jp2c] with tempfile.NamedTemporaryFile(suffix=".jp2") as tfile: j2k.wrap(tfile.name, boxes=boxes) @@ -380,12 +401,13 @@ class TestXML(unittest.TestCase): @unittest.skipIf(os.name == "nt", "Problems using NamedTemporaryFile on windows.") def test_xml_from_file(self): + """Must be able to create an XML box from an XML file.""" j2k = Jp2k(self.j2kfile) self.jp2h.box = [self.ihdr, self.colr] xmlb = glymur.jp2box.XMLBox(filename=self.xmlfile) - boxes = [self.jP, self.ftyp, self.jp2h, xmlb, self.jp2c] + boxes = [self.jp2b, self.ftyp, self.jp2h, xmlb, self.jp2c] with tempfile.NamedTemporaryFile(suffix=".jp2") as tfile: j2k.wrap(tfile.name, boxes=boxes) jp2 = Jp2k(tfile.name) @@ -403,17 +425,18 @@ class TestXML(unittest.TestCase): class TestColourSpecificationBox(unittest.TestCase): + """Test suite for colr box instantiation.""" def setUp(self): self.j2kfile = glymur.data.goodstuff() j2k = Jp2k(self.j2kfile) - c = j2k.get_codestream() - height = c.segment[1].ysiz - width = c.segment[1].xsiz - num_components = len(c.segment[1].xrsiz) + codestream = j2k.get_codestream() + height = codestream.segment[1].ysiz + width = codestream.segment[1].xsiz + num_components = len(codestream.segment[1].xrsiz) - self.jP = JPEG2000SignatureBox() + self.jp2b = JPEG2000SignatureBox() self.ftyp = FileTypeBox() self.jp2h = JP2HeaderBox() self.jp2c = ContiguousCodestreamBox() @@ -425,10 +448,11 @@ class TestColourSpecificationBox(unittest.TestCase): @unittest.skipIf(os.name == "nt", "Problems using NamedTemporaryFile on windows.") - def test_color_specification_box_with_out_enumerated_colorspace(self): + def test_colr_with_out_enum_cspace(self): + """must supply an enumerated colorspace when writing""" j2k = Jp2k(self.j2kfile) - boxes = [self.jP, self.ftyp, self.jp2h, self.jp2c] + boxes = [self.jp2b, self.ftyp, self.jp2h, self.jp2c] boxes[2].box = [self.ihdr, ColourSpecificationBox(colorspace=None)] with tempfile.NamedTemporaryFile(suffix=".jp2") as tfile: with self.assertRaises(NotImplementedError): @@ -436,47 +460,52 @@ class TestColourSpecificationBox(unittest.TestCase): @unittest.skipIf(os.name == "nt", "Temporary file issue on window.") def test_missing_colr_box(self): + """jp2h must have a colr box""" j2k = Jp2k(self.j2kfile) - boxes = [self.jP, self.ftyp, self.jp2h, self.jp2c] + boxes = [self.jp2b, self.ftyp, self.jp2h, self.jp2c] boxes[2].box = [self.ihdr] with tempfile.NamedTemporaryFile(suffix=".jp2") as tfile: with self.assertRaises(IOError): j2k.wrap(tfile.name, boxes=boxes) - def test_default_ColourSpecificationBox(self): - b = glymur.jp2box.ColourSpecificationBox(colorspace=glymur.core.SRGB) - self.assertEqual(b.method, glymur.core.ENUMERATED_COLORSPACE) - self.assertEqual(b.precedence, 0) - self.assertEqual(b.approximation, 0) - self.assertEqual(b.colorspace, glymur.core.SRGB) - self.assertIsNone(b.icc_profile) + def test_default_colr(self): + """basic colr instantiation""" + colr = ColourSpecificationBox(colorspace=glymur.core.SRGB) + self.assertEqual(colr.method, glymur.core.ENUMERATED_COLORSPACE) + self.assertEqual(colr.precedence, 0) + self.assertEqual(colr.approximation, 0) + self.assertEqual(colr.colorspace, glymur.core.SRGB) + self.assertIsNone(colr.icc_profile) - def test_ColourSpecificationBox_with_colorspace_and_icc(self): - # Colour specification boxes can't have both. + def test_colr_with_cspace_and_icc(self): + """Colour specification boxes can't have both.""" with self.assertRaises((OSError, IOError)): colorspace = glymur.core.SRGB - icc_profile = b'\x01\x02\x03\x04' - b = glymur.jp2box.ColourSpecificationBox(colorspace=colorspace, - icc_profile=icc_profile) + rawb = b'\x01\x02\x03\x04' + glymur.jp2box.ColourSpecificationBox(colorspace=colorspace, + icc_profile=rawb) - def test_ColourSpecificationBox_with_bad_method(self): + def test_colr_with_bad_method(self): + """colr must have a valid method field""" colorspace = glymur.core.SRGB method = -1 with self.assertRaises(IOError): - b = glymur.jp2box.ColourSpecificationBox(colorspace=colorspace, - method=method) + glymur.jp2box.ColourSpecificationBox(colorspace=colorspace, + method=method) - def test_ColourSpecificationBox_with_bad_approximation(self): + def test_colr_with_bad_approx(self): + """colr must have a valid approximation field""" colorspace = glymur.core.SRGB approx = -1 with self.assertRaises(IOError): - b = glymur.jp2box.ColourSpecificationBox(colorspace=colorspace, - approximation=approx) + glymur.jp2box.ColourSpecificationBox(colorspace=colorspace, + approximation=approx) @unittest.skipIf(glymur.lib.openjp2.OPENJP2 is None, "Missing openjp2 library.") class TestWrap(unittest.TestCase): + """Tests for wrap method.""" def setUp(self): self.j2kfile = glymur.data.goodstuff() @@ -486,7 +515,7 @@ class TestWrap(unittest.TestCase): pass def verify_wrapped_raw(self, jp2file): - # Shared method by at least two tests. + """Shared fixture""" jp2 = Jp2k(jp2file) self.assertEqual(len(jp2.box), 4) @@ -536,6 +565,7 @@ class TestWrap(unittest.TestCase): @unittest.skipIf(os.name == "nt", "Temporary file issue on window.") def test_wrap(self): + """basic test for rewrapping a j2c file, no specified boxes""" j2k = Jp2k(self.j2kfile) with tempfile.NamedTemporaryFile(suffix=".jp2") as tfile: j2k.wrap(tfile.name) @@ -543,6 +573,7 @@ class TestWrap(unittest.TestCase): @unittest.skipIf(os.name == "nt", "Temporary file issue on window.") def test_wrap_jp2(self): + """basic test for rewrapping a jp2 file, no specified boxes""" j2k = Jp2k(self.jp2file) with tempfile.NamedTemporaryFile(suffix=".jp2") as tfile: jp2 = j2k.wrap(tfile.name) @@ -550,16 +581,17 @@ class TestWrap(unittest.TestCase): self.assertEqual(boxes, ['jP ', 'ftyp', 'jp2h', 'jp2c']) @unittest.skipIf(os.name == "nt", "Temporary file issue on window.") - def test_default_layout_but_with_specified_boxes(self): + def test_default_layout_with_boxes(self): + """basic test for rewrapping a jp2 file, boxes specified""" j2k = Jp2k(self.j2kfile) boxes = [JPEG2000SignatureBox(), FileTypeBox(), JP2HeaderBox(), ContiguousCodestreamBox()] - c = j2k.get_codestream() - height = c.segment[1].ysiz - width = c.segment[1].xsiz - num_components = len(c.segment[1].xrsiz) + codestream = j2k.get_codestream() + height = codestream.segment[1].ysiz + width = codestream.segment[1].xsiz + num_components = len(codestream.segment[1].xrsiz) boxes[2].box = [ImageHeaderBox(height=height, width=width, num_components=num_components), @@ -569,17 +601,17 @@ class TestWrap(unittest.TestCase): self.verify_wrapped_raw(tfile.name) @unittest.skipIf(os.name == "nt", "Temporary file issue on window.") - def test_image_header_box_not_first_in_jp2_header(self): - # The specification says that ihdr must be the first box in jp2h. + def test_ihdr_not_first_in_jp2h(self): + """The specification says that ihdr must be the first box in jp2h.""" j2k = Jp2k(self.j2kfile) boxes = [JPEG2000SignatureBox(), FileTypeBox(), JP2HeaderBox(), ContiguousCodestreamBox()] - c = j2k.get_codestream() - height = c.segment[1].ysiz - width = c.segment[1].xsiz - num_components = len(c.segment[1].xrsiz) + codestream = j2k.get_codestream() + height = codestream.segment[1].ysiz + width = codestream.segment[1].xsiz + num_components = len(codestream.segment[1].xrsiz) boxes[2].box = [ColourSpecificationBox(colorspace=glymur.core.SRGB), ImageHeaderBox(height=height, width=width, @@ -589,14 +621,15 @@ class TestWrap(unittest.TestCase): j2k.wrap(tfile.name, boxes=boxes) @unittest.skipIf(os.name == "nt", "Temporary file issue on window.") - def test_first_2_boxes_not_jP_and_ftyp(self): + def test_first_boxes_jp_and_ftyp(self): + """first two boxes must be jP followed by ftyp""" j2k = Jp2k(self.j2kfile) - c = j2k.get_codestream() - height = c.segment[1].ysiz - width = c.segment[1].xsiz - num_components = len(c.segment[1].xrsiz) + codestream = j2k.get_codestream() + height = codestream.segment[1].ysiz + width = codestream.segment[1].xsiz + num_components = len(codestream.segment[1].xrsiz) - jP = JPEG2000SignatureBox() + jp2b = JPEG2000SignatureBox() ftyp = FileTypeBox() jp2h = JP2HeaderBox() jp2c = ContiguousCodestreamBox() @@ -604,20 +637,21 @@ class TestWrap(unittest.TestCase): ihdr = ImageHeaderBox(height=height, width=width, num_components=num_components) jp2h.box = [ihdr, colr] - boxes = [ftyp, jP, jp2h, jp2c] + boxes = [ftyp, jp2b, jp2h, jp2c] with tempfile.NamedTemporaryFile(suffix=".jp2") as tfile: with self.assertRaises(IOError): j2k.wrap(tfile.name, boxes=boxes) @unittest.skipIf(os.name == "nt", "Temporary file issue on window.") def test_jp2h_not_preceeding_jp2c(self): + """jp2h must precede jp2c""" j2k = Jp2k(self.j2kfile) - c = j2k.get_codestream() - height = c.segment[1].ysiz - width = c.segment[1].xsiz - num_components = len(c.segment[1].xrsiz) + codestream = j2k.get_codestream() + height = codestream.segment[1].ysiz + width = codestream.segment[1].xsiz + num_components = len(codestream.segment[1].xrsiz) - jP = JPEG2000SignatureBox() + jp2b = JPEG2000SignatureBox() ftyp = FileTypeBox() jp2h = JP2HeaderBox() jp2c = ContiguousCodestreamBox() @@ -625,68 +659,74 @@ class TestWrap(unittest.TestCase): ihdr = ImageHeaderBox(height=height, width=width, num_components=num_components) jp2h.box = [ihdr, colr] - boxes = [jP, ftyp, jp2c, jp2h] + boxes = [jp2b, ftyp, jp2c, jp2h] with tempfile.NamedTemporaryFile(suffix=".jp2") as tfile: with self.assertRaises(IOError): j2k.wrap(tfile.name, boxes=boxes) @unittest.skipIf(os.name == "nt", "Temporary file issue on window.") def test_missing_codestream(self): + """Need a codestream box in order to call wrap method.""" j2k = Jp2k(self.j2kfile) - c = j2k.get_codestream() - height = c.segment[1].ysiz - width = c.segment[1].xsiz - num_components = len(c.segment[1].xrsiz) + codestream = j2k.get_codestream() + height = codestream.segment[1].ysiz + width = codestream.segment[1].xsiz + num_components = len(codestream.segment[1].xrsiz) - jP = JPEG2000SignatureBox() + jp2k = JPEG2000SignatureBox() ftyp = FileTypeBox() jp2h = JP2HeaderBox() ihdr = ImageHeaderBox(height=height, width=width, num_components=num_components) jp2h.box = [ihdr] - boxes = [jP, ftyp, jp2h] + boxes = [jp2k, ftyp, jp2h] with tempfile.NamedTemporaryFile(suffix=".jp2") as tfile: with self.assertRaises(IOError): j2k.wrap(tfile.name, boxes=boxes) class TestJp2Boxes(unittest.TestCase): + """Tests for canonical JP2 boxes.""" - def test_default_JPEG2000SignatureBox(self): - # Should be able to instantiate a JPEG2000SignatureBox - b = glymur.jp2box.JPEG2000SignatureBox() - self.assertEqual(b.signature, (13, 10, 135, 10)) + def test_default_jp2k(self): + """Should be able to instantiate a JPEG2000SignatureBox""" + jp2k = glymur.jp2box.JPEG2000SignatureBox() + self.assertEqual(jp2k.signature, (13, 10, 135, 10)) - def test_default_FileTypeBox(self): - # Should be able to instantiate a FileTypeBox - b = glymur.jp2box.FileTypeBox() - self.assertEqual(b.brand, 'jp2 ') - self.assertEqual(b.minor_version, 0) - self.assertEqual(b.compatibility_list, ['jp2 ']) + def test_default_ftyp(self): + """Should be able to instantiate a FileTypeBox""" + ftyp = glymur.jp2box.FileTypeBox() + self.assertEqual(ftyp.brand, 'jp2 ') + self.assertEqual(ftyp.minor_version, 0) + self.assertEqual(ftyp.compatibility_list, ['jp2 ']) - def test_default_ImageHeaderBox(self): - # Should be able to instantiate an image header box. - b = glymur.jp2box.ImageHeaderBox(height=512, width=256, + def test_default_ihdr(self): + """Should be able to instantiate an image header box.""" + ihdr = glymur.jp2box.ImageHeaderBox(height=512, width=256, num_components=3) - self.assertEqual(b.height, 512) - self.assertEqual(b.width, 256) - self.assertEqual(b.num_components, 3) - self.assertEqual(b.bits_per_component, 8) - self.assertFalse(b.signed) - self.assertFalse(b.colorspace_unknown) + self.assertEqual(ihdr.height, 512) + self.assertEqual(ihdr.width, 256) + self.assertEqual(ihdr.num_components, 3) + self.assertEqual(ihdr.bits_per_component, 8) + self.assertFalse(ihdr.signed) + self.assertFalse(ihdr.colorspace_unknown) - def test_default_JP2HeaderBox(self): - b1 = JP2HeaderBox() - b1.box = [ImageHeaderBox(height=512, width=256), + def test_default_jp2headerbox(self): + """Should be able to set jp2h boxes.""" + box = JP2HeaderBox() + box.box = [ImageHeaderBox(height=512, width=256), ColourSpecificationBox(colorspace=glymur.core.GREYSCALE)] + self.assertTrue(True) - def test_default_ContiguousCodestreamBox(self): - b = ContiguousCodestreamBox() - self.assertEqual(b.box_id, 'jp2c') - self.assertIsNone(b.main_header) + def test_default_ccodestreambox(self): + """Raw instantiation should not produce a main_header.""" + box = ContiguousCodestreamBox() + self.assertEqual(box.box_id, 'jp2c') + self.assertIsNone(box.main_header) class TestJpxBoxes(unittest.TestCase): + """Tests for JPX boxes.""" def setUp(self): pass @@ -694,11 +734,11 @@ class TestJpxBoxes(unittest.TestCase): def tearDown(self): pass - @unittest.skipIf(format_corpus_data_root is None, + @unittest.skipIf(FORMAT_CORPUS_DATA_ROOT is None, "FORMAT_CORPUS_DATA_ROOT environment variable not set") def test_codestream_header(self): - # Should recognize codestream header box. - jfile = os.path.join(format_corpus_data_root, + """Should recognize codestream header box.""" + jfile = os.path.join(FORMAT_CORPUS_DATA_ROOT, 'jp2k-formats/balloon.jpf') jpx = Jp2k(jfile) @@ -706,11 +746,11 @@ class TestJpxBoxes(unittest.TestCase): self.assertEqual(jpx.box[4].box_id, 'jpch') self.assertEqual(len(jpx.box[4].box), 0) - @unittest.skipIf(format_corpus_data_root is None, + @unittest.skipIf(FORMAT_CORPUS_DATA_ROOT is None, "FORMAT_CORPUS_DATA_ROOT environment variable not set") def test_compositing_layer_header(self): - # Should recognize compositing layer header box. - jfile = os.path.join(format_corpus_data_root, + """Should recognize compositing layer header box.""" + jfile = os.path.join(FORMAT_CORPUS_DATA_ROOT, 'jp2k-formats/balloon.jpf') jpx = Jp2k(jfile) From 0497576e6fb7157ef8bc01e5fa8a46939ea5cb6b Mon Sep 17 00:00:00 2001 From: jevans Date: Sun, 11 Aug 2013 19:16:34 -0400 Subject: [PATCH 12/20] pylint work, #99 --- glymur/test/test_jp2k.py | 321 +++++++++++++++++++++------------------ 1 file changed, 177 insertions(+), 144 deletions(-) diff --git a/glymur/test/test_jp2k.py b/glymur/test/test_jp2k.py index 1371a05..8b04dfa 100644 --- a/glymur/test/test_jp2k.py +++ b/glymur/test/test_jp2k.py @@ -1,4 +1,15 @@ -# pylint: disable-all +""" +Tests for general glymur functionality. +""" +# E1101: assertWarns introduced in python 3.2 +# pylint: disable=E1101 + +# R0904: Not too many methods in unittest. +# pylint: disable=R0904 + +# E0611: unittest.mock is unknown to python2.7/pylint +# pylint: disable=E0611,F0401 + import doctest import os import re @@ -25,20 +36,24 @@ import pkg_resources import glymur from glymur import Jp2k -from glymur.lib import openjp2 as opj2 from .fixtures import OPENJP2_IS_V2_OFFICIAL try: - data_root = os.environ['OPJ_DATA_ROOT'] + DATA_ROOT = os.environ['OPJ_DATA_ROOT'] except KeyError: - data_root = None + DATA_ROOT = None except: raise # Doc tests should be run as well. def load_tests(loader, tests, ignore): + # W0613: "loader" and "ignore" are necessary for the protocol + # They are unused here, however. + # pylint: disable=W0613 + + """Should run doc tests as well""" if os.name == "nt": # Can't do it on windows, temporary file issue. return tests @@ -54,6 +69,7 @@ def load_tests(loader, tests, ignore): glymur.lib.openjpeg.OPENJPEG is None, "Missing openjp2 library.") class TestConfig(unittest.TestCase): + """Test suite for reading without proper library in place.""" def setUp(self): self.jp2file = glymur.data.nemo() @@ -62,24 +78,24 @@ class TestConfig(unittest.TestCase): def tearDown(self): pass - def test_read_without_library_backing_us_up(self): + def test_read_without_library(self): """Don't have either openjp2 or openjpeg libraries? Must error out. """ with patch('glymur.lib.openjp2.OPENJP2', new=None): with patch('glymur.lib.openjpeg.OPENJPEG', new=None): with self.assertRaises(glymur.jp2k.LibraryNotFoundError): - d = glymur.Jp2k(self.jp2file).read() + glymur.Jp2k(self.jp2file).read() - def test_read_bands_without_library_backing_us_up(self): + def test_read_bands_without_library(self): """Don't have openjp2 library? Must error out. """ with patch('glymur.lib.openjp2.OPENJP2', new=None): with patch('glymur.lib.openjpeg.OPENJPEG', new=None): with self.assertRaises(glymur.jp2k.LibraryNotFoundError): - d = glymur.Jp2k(self.jp2file).read_bands() + glymur.Jp2k(self.jp2file).read_bands() @unittest.skipIf(os.name == "nt", "NamedTemporaryFile issue on windows") - def test_write_without_library_backing_us_up(self): + def test_write_without_library(self): """Don't have openjp2 library? Must error out. """ data = glymur.Jp2k(self.j2kfile).read() @@ -95,32 +111,34 @@ class TestConfig(unittest.TestCase): @unittest.skipIf(glymur.lib.openjp2.OPENJP2 is None, "Missing openjp2 library.") class TestJp2kBadXmlFile(unittest.TestCase): + """Test suite for bad XML box situations""" @classmethod def setUpClass(cls): - # Setup a JP2 file with a bad XML box. We only need to do this once - # per class rather than once per test. + """Setup a JP2 file with a bad XML box. We only need to do this once + per class rather than once per test. + """ jp2file = pkg_resources.resource_filename(glymur.__name__, "data/nemo.jp2") with tempfile.NamedTemporaryFile(suffix='.jp2', delete=False) as tfile: cls._bad_xml_file = tfile.name with open(jp2file, 'rb') as ifile: # Everything up until the jp2c box. - buffer = ifile.read(77) - tfile.write(buffer) + write_buffer = ifile.read(77) + tfile.write(write_buffer) # Write the xml box with bad xml # Length = 28, id is 'xml '. - buffer = struct.pack('>I4s', int(28), b'xml ') - tfile.write(buffer) + write_buffer = struct.pack('>I4s', int(28), b'xml ') + tfile.write(write_buffer) - buffer = 'this is a test' - buffer = buffer.encode() - tfile.write(buffer) + write_buffer = 'this is a test' + write_buffer = write_buffer.encode() + tfile.write(write_buffer) # Get the rest of the input file. - buffer = ifile.read() - tfile.write(buffer) + write_buffer = ifile.read() + tfile.write(write_buffer) tfile.flush() @classmethod @@ -137,13 +155,12 @@ class TestJp2kBadXmlFile(unittest.TestCase): @unittest.skipIf(sys.hexversion < 0x03020000, "Uses features introduced in 3.2.") def test_invalid_xml_box_warning(self): - # Should be able to recover from xml box with bad xml. - # Just verify that a warning is issued on 3.3+ - with self.assertWarns(UserWarning) as cw: - jp2k = Jp2k(self._bad_xml_file) + """Should warn in case of bad XML""" + with self.assertWarns(UserWarning): + Jp2k(self._bad_xml_file) def test_invalid_xml_box(self): - # Should be able to recover from xml box with bad xml. + """Should be able to recover info from xml box with bad xml.""" with warnings.catch_warnings(): warnings.simplefilter("ignore") jp2k = Jp2k(self._bad_xml_file) @@ -157,6 +174,7 @@ class TestJp2kBadXmlFile(unittest.TestCase): @unittest.skipIf(glymur.lib.openjp2.OPENJP2 is None, "Missing openjp2 library.") class TestJp2k(unittest.TestCase): + """Test suite for version 2.0/2.0+ of openjpeg""" def setUp(self): self.jp2file = glymur.data.nemo() @@ -166,7 +184,7 @@ class TestJp2k(unittest.TestCase): pass def test_rlevel_max(self): - # Verify that rlevel=-1 gets us the lowest resolution image + """Verify that rlevel=-1 gets us the lowest resolution image""" j = Jp2k(self.j2kfile) thumbnail1 = j.read(rlevel=-1) thumbnail2 = j.read(rlevel=5) @@ -174,43 +192,41 @@ class TestJp2k(unittest.TestCase): self.assertEqual(thumbnail1.shape, (25, 15, 3)) def test_bad_area_parameter(self): - # Verify that we error out appropriately if given a bad area parameter. + """Should error out appropriately if given a bad area parameter.""" j = Jp2k(self.jp2file) with self.assertRaises(IOError): # Start corner must be >= 0 - d = j.read(area=(-1, -1, 1, 1)) + j.read(area=(-1, -1, 1, 1)) with self.assertRaises(IOError): # End corner must be > 0 - d = j.read(area=(10, 10, 0, 0)) + j.read(area=(10, 10, 0, 0)) with self.assertRaises(IOError): # End corner must be >= start corner - d = j.read(area=(10, 10, 8, 8)) + j.read(area=(10, 10, 8, 8)) def test_rlevel_too_high(self): - # Verify that we error out appropriately if not given a JPEG 2000 file. + """Should error out appropriately if reduce level too high""" j = Jp2k(self.jp2file) with self.assertRaises(IOError): - d = j.read(rlevel=6) + j.read(rlevel=6) - def test_not_JPEG2000(self): - # Verify that we error out appropriately if not given a JPEG 2000 file. + def test_not_jpeg2000(self): + """Should error out appropriately if not given a JPEG 2000 file.""" filename = pkg_resources.resource_filename(glymur.__name__, "jp2k.py") with self.assertRaises(IOError): - jp2k = Jp2k(filename) + Jp2k(filename) def test_file_not_present(self): + """Should error out if reading from a file that does not exist""" # Verify that we error out appropriately if not given an existing file # at all. - if sys.hexversion < 0x03030000: - error = OSError - else: - error = IOError - with self.assertRaises(error): + with self.assertRaises(OSError): filename = 'this file does not actually exist on the file system.' - jp2k = Jp2k(filename) + Jp2k(filename) @unittest.skipIf(os.name == "nt", "NamedTemporaryFile issue on windows") def test_write_srgb_without_mct(self): + """should be able to write RGB without specifying mct""" j2k = Jp2k(self.j2kfile) expdata = j2k.read() with tempfile.NamedTemporaryFile(suffix='.jp2') as tfile: @@ -219,12 +235,12 @@ class TestJp2k(unittest.TestCase): actdata = ofile.read() np.testing.assert_array_equal(actdata, expdata) - c = ofile.get_codestream() - self.assertEqual(c.segment[2].spcod[3], 0) # no mct + codestream = ofile.get_codestream() + self.assertEqual(codestream.segment[2].spcod[3], 0) # no mct @unittest.skipIf(os.name == "nt", "NamedTemporaryFile issue on windows") def test_write_grayscale_with_mct(self): - # MCT usage makes no sense for grayscale images. + """MCT usage makes no sense for grayscale images.""" j2k = Jp2k(self.j2kfile) expdata = j2k.read() with tempfile.NamedTemporaryFile(suffix='.jp2') as tfile: @@ -234,6 +250,7 @@ class TestJp2k(unittest.TestCase): @unittest.skipIf(os.name == "nt", "NamedTemporaryFile issue on windows") def test_write_cprl(self): + """Must be able to write a CPRL progression order file""" # Issue 17 j = Jp2k(self.jp2file) expdata = j.read(rlevel=1) @@ -243,11 +260,11 @@ class TestJp2k(unittest.TestCase): actdata = ofile.read() np.testing.assert_array_equal(actdata, expdata) - c = ofile.get_codestream() - self.assertEqual(c.segment[2].spcod[0], glymur.core.CPRL) + codestream = ofile.get_codestream() + self.assertEqual(codestream.segment[2].spcod[0], glymur.core.CPRL) def test_jp2_boxes(self): - # Verify the boxes of a JP2 file. + """Verify the boxes of a JP2 file. Basic jp2 test.""" jp2k = Jp2k(self.jp2file) # top-level boxes @@ -305,39 +322,41 @@ class TestJp2k(unittest.TestCase): self.assertEqual(jp2k.box[2].box[1].colorspace, glymur.core.SRGB) self.assertIsNone(jp2k.box[2].box[1].icc_profile) - @unittest.skipIf(data_root is None, + @unittest.skipIf(DATA_ROOT is None, "OPJ_DATA_ROOT environment variable not set") def test_j2k_box(self): + """A J2K/J2C file must not have any boxes.""" # Verify that a J2K file has no boxes. - filename = os.path.join(data_root, 'input/conformance/p0_01.j2k') + filename = os.path.join(DATA_ROOT, 'input/conformance/p0_01.j2k') jp2k = Jp2k(filename) self.assertEqual(len(jp2k.box), 0) @unittest.skipIf(os.name == "nt", "NamedTemporaryFile issue on windows") - def test_64bit_XL_field(self): + def test_64bit_xl_field(self): + """XL field should be supported""" # Verify that boxes with the XL field are properly read. # Don't have such a file on hand, so we create one. Copy our example # file, but making the codestream have a 64-bit XL field. with tempfile.NamedTemporaryFile(suffix='.jp2') as tfile: with open(self.jp2file, 'rb') as ifile: # Everything up until the jp2c box. - buffer = ifile.read(3127) - tfile.write(buffer) + write_buffer = ifile.read(3127) + tfile.write(write_buffer) # The L field must be 1 in order to signal the presence of the # XL field. The actual length of the jp2c box increased by 8 # (8 bytes for the XL field). - L = 1 - T = b'jp2c' - XL = 1133427 + 8 - buffer = struct.pack('>I4sQ', int(L), T, XL) - tfile.write(buffer) + length = 1 + typ = b'jp2c' + xlen = 1133427 + 8 + write_buffer = struct.pack('>I4sQ', int(length), typ, xlen) + tfile.write(write_buffer) # Get the rest of the input file (minus the 8 bytes for L and # T. ifile.seek(8, 1) - buffer = ifile.read() - tfile.write(buffer) + write_buffer = ifile.read() + tfile.write(write_buffer) tfile.flush() jp2k = Jp2k(tfile.name) @@ -347,7 +366,8 @@ class TestJp2k(unittest.TestCase): self.assertEqual(jp2k.box[5].length, 1133427 + 8) @unittest.skipIf(os.name == "nt", "NamedTemporaryFile issue on windows") - def test_L_is_zero(self): + def test_length_field_is_zero(self): + """L=0 (length field in box header) is allowed""" # Verify that boxes with the L field as zero are correctly read. # This should only happen in the last box of a JPEG 2000 file. # Our example image has its last box at byte 588458. @@ -355,19 +375,19 @@ class TestJp2k(unittest.TestCase): with tempfile.NamedTemporaryFile(suffix='.jp2') as tfile: with open(self.jp2file, 'rb') as ifile: # Everything up until the jp2c box. - buffer = ifile.read(588458) - tfile.write(buffer) + write_buffer = ifile.read(588458) + tfile.write(write_buffer) - L = 0 - T = b'uuid' - buffer = struct.pack('>I4s', int(L), T) - tfile.write(buffer) + length = 0 + typ = b'uuid' + write_buffer = struct.pack('>I4s', int(length), typ) + tfile.write(write_buffer) # Get the rest of the input file (minus the 8 bytes for L and # T. ifile.seek(8, 1) - buffer = ifile.read() - tfile.write(buffer) + write_buffer = ifile.read() + tfile.write(write_buffer) tfile.flush() new_jp2 = Jp2k(tfile.name) @@ -381,31 +401,34 @@ class TestJp2k(unittest.TestCase): self.assertEqual(new_jp2.box[j].length, baseline_jp2.box[j].length) - @unittest.skipIf(data_root is None, + @unittest.skipIf(DATA_ROOT is None, "OPJ_DATA_ROOT environment variable not set") def test_read_differing_subsamples(self): + """should error out with read used on differently subsampled images""" # Verify that we error out appropriately if we use the read method # on an image with differing subsamples # # Issue 86. - filename = os.path.join(data_root, 'input/conformance/p0_05.j2k') + filename = os.path.join(DATA_ROOT, 'input/conformance/p0_05.j2k') j = Jp2k(filename) with self.assertRaises(RuntimeError): j.read() - @unittest.skipIf(data_root is None, + @unittest.skipIf(DATA_ROOT is None, "OPJ_DATA_ROOT environment variable not set") def test_empty_box_with_j2k(self): - # Verify that the list of boxes in a J2C/J2K file is present, but - # empty. - filename = os.path.join(data_root, 'input/conformance/p0_05.j2k') + """Verify that the list of boxes in a J2C/J2K file is present, but + empty. + """ + filename = os.path.join(DATA_ROOT, 'input/conformance/p0_05.j2k') j = Jp2k(filename) self.assertEqual(j.box, []) @unittest.skipIf(os.name == "nt", "NamedTemporaryFile issue on windows") - def test_code_block_height_different_than_width(self): - # Verify that we can set a code block size where height does not equal - # width. + def test_cblkh_different_than_width(self): + """Verify that we can set a code block size where height does not equal + width. + """ data = np.zeros((128, 128), dtype=np.uint8) with tempfile.NamedTemporaryFile(suffix='.j2k') as tfile: j = Jp2k(tfile.name, 'wb') @@ -413,49 +436,50 @@ class TestJp2k(unittest.TestCase): # The code block dimensions are given as rows x columns. j.write(data, cbsize=(16, 32)) - c = j.get_codestream() + codestream = j.get_codestream() # Code block size is reported as XY in the codestream. - self.assertEqual(tuple(c.segment[2].spcod[5:7]), (3, 2)) + self.assertEqual(tuple(codestream.segment[2].spcod[5:7]), (3, 2)) @unittest.skipIf(os.name == "nt", "NamedTemporaryFile issue on windows") - def test_negative_too_many_dimensions(self): - # OpenJP2 only allows 2D or 3D images. + def test_too_many_dimensions(self): + """OpenJP2 only allows 2D or 3D images.""" with tempfile.NamedTemporaryFile(suffix='.j2k') as tfile: j = Jp2k(tfile.name, 'wb') - with self.assertRaises(IOError) as ce: + with self.assertRaises(IOError): data = np.zeros((128, 128, 2, 2), dtype=np.uint8) j.write(data) @unittest.skipIf(os.name == "nt", "NamedTemporaryFile issue on windows") - def test_unrecognized_jp2_colorspace(self): - # We only allow RGB and GRAYSCALE. + def test_unrecognized_jp2_clrspace(self): + """We only allow RGB and GRAYSCALE. Should error out with others""" with tempfile.NamedTemporaryFile(suffix='.jp2') as tfile: j = Jp2k(tfile.name, 'wb') - with self.assertRaises(IOError) as ce: + with self.assertRaises(IOError): data = np.zeros((128, 128, 3), dtype=np.uint8) j.write(data, colorspace='cmyk') @unittest.skipIf(os.name == "nt", "NamedTemporaryFile issue on windows") - def test_2D_rgb(self): - # RGB must have at least 3 components. + def test_2d_rgb(self): + """RGB must have at least 3 components.""" with tempfile.NamedTemporaryFile(suffix='.jp2') as tfile: j = Jp2k(tfile.name, 'wb') - with self.assertRaises(IOError) as ce: + with self.assertRaises(IOError): data = np.zeros((128, 128, 2), dtype=np.uint8) j.write(data, colorspace='rgb') @unittest.skipIf(os.name == "nt", "NamedTemporaryFile issue on windows") def test_colorspace_with_j2k(self): - # Specifying a colorspace with J2K does not make sense. + """Specifying a colorspace with J2K does not make sense""" with tempfile.NamedTemporaryFile(suffix='.j2k') as tfile: j = Jp2k(tfile.name, 'wb') - with self.assertRaises(IOError) as ce: + with self.assertRaises(IOError): data = np.zeros((128, 128, 3), dtype=np.uint8) j.write(data, colorspace='rgb') @unittest.skipIf(os.name == "nt", "NamedTemporaryFile issue on windows") def test_specify_rgb(self): + """specify RGB explicitly""" with tempfile.NamedTemporaryFile(suffix='.jp2') as tfile: j = Jp2k(tfile.name, 'wb') data = np.zeros((128, 128, 3), dtype=np.uint8) @@ -464,6 +488,7 @@ class TestJp2k(unittest.TestCase): @unittest.skipIf(os.name == "nt", "NamedTemporaryFile issue on windows") def test_specify_gray(self): + """test gray explicitly specified (that's GRAY, not GREY)""" with tempfile.NamedTemporaryFile(suffix='.jp2') as tfile: j = Jp2k(tfile.name, 'wb') data = np.zeros((128, 128), dtype=np.uint8) @@ -473,6 +498,7 @@ class TestJp2k(unittest.TestCase): @unittest.skipIf(os.name == "nt", "NamedTemporaryFile issue on windows") def test_specify_grey(self): + """test grey explicitly specified""" with tempfile.NamedTemporaryFile(suffix='.jp2') as tfile: j = Jp2k(tfile.name, 'wb') data = np.zeros((128, 128), dtype=np.uint8) @@ -484,6 +510,7 @@ class TestJp2k(unittest.TestCase): "Does not seem to work on official v2.0.0 release.") @unittest.skipIf(os.name == "nt", "NamedTemporaryFile issue on windows") def test_grey_with_extra_component(self): + """version 2.0 cannot write gray + extra""" with tempfile.NamedTemporaryFile(suffix='.jp2') as tfile: j = Jp2k(tfile.name, 'wb') data = np.zeros((128, 128, 2), dtype=np.uint8) @@ -495,7 +522,8 @@ class TestJp2k(unittest.TestCase): glymur.core.GREYSCALE) @unittest.skipIf(os.name == "nt", "NamedTemporaryFile issue on windows") - def test_grey_with_two_extra_components(self): + def test_grey_with_two_extra_comps(self): + """should be able to write gray + two extra components""" with tempfile.NamedTemporaryFile(suffix='.jp2') as tfile: j = Jp2k(tfile.name, 'wb') data = np.zeros((128, 128, 3), dtype=np.uint8) @@ -510,6 +538,7 @@ class TestJp2k(unittest.TestCase): "Does not seem to work on official v2.0.0 release.") @unittest.skipIf(os.name == "nt", "NamedTemporaryFile issue on windows") def test_rgb_with_extra_component(self): + """v2.0+ should be able to write extra components""" with tempfile.NamedTemporaryFile(suffix='.jp2') as tfile: j = Jp2k(tfile.name, 'wb') data = np.zeros((128, 128, 4), dtype=np.uint8) @@ -522,7 +551,8 @@ class TestJp2k(unittest.TestCase): @unittest.skipIf(OPENJP2_IS_V2_OFFICIAL is False, "Test is specific for v2.0.0 release") @unittest.skipIf(os.name == "nt", "NamedTemporaryFile issue on windows") - def test_extra_components_on_v2_official(self): + def test_extra_components_on_v2(self): + """must error out in 1.x with extra components.""" # Extra components seems to require 2.0+. Verify that we error out. with self.assertRaises(IOError): with tempfile.NamedTemporaryFile(suffix='.jp2') as tfile: @@ -531,48 +561,50 @@ class TestJp2k(unittest.TestCase): j.write(data) def test_specify_ycc(self): - # We don't support writing YCC at the moment. + """Should reject YCC""" with tempfile.NamedTemporaryFile(suffix='.jp2') as tfile: j = Jp2k(tfile.name, 'wb') - with self.assertRaises(IOError) as ce: + with self.assertRaises(IOError): data = np.zeros((128, 128, 3), dtype=np.uint8) j.write(data, colorspace='ycc') @unittest.skipIf(os.name == "nt", "NamedTemporaryFile issue on windows") def test_uinf_ulst_url_boxes(self): + """Verify that we can read UINF, ULST, and URL boxes""" # Verify that we can read UINF, ULST, and URL boxes. I don't have # easy access to such a file, and there's no such file in the # openjpeg repository, so I'll fake one. with tempfile.NamedTemporaryFile(suffix='.jp2') as tfile: with open(self.jp2file, 'rb') as ifile: # Everything up until the jp2c box. - buffer = ifile.read(77) - tfile.write(buffer) + write_buffer = ifile.read(77) + tfile.write(write_buffer) # Write the UINF superbox # Length = 50, id is uinf. - buffer = struct.pack('>I4s', int(50), b'uinf') - tfile.write(buffer) + write_buffer = struct.pack('>I4s', int(50), b'uinf') + tfile.write(write_buffer) # Write the ULST box. # Length is 26, 1 UUID, hard code that UUID as zeros. - buffer = struct.pack('>I4sHIIII', int(26), b'ulst', int(1), - int(0), int(0), int(0), int(0)) - tfile.write(buffer) + write_buffer = struct.pack('>I4sHIIII', int(26), b'ulst', + int(1), int(0), int(0), int(0), + int(0)) + tfile.write(write_buffer) # Write the URL box. # Length is 16, version is one byte, flag is 3 bytes, url # is the rest. - buffer = struct.pack('>I4sBBBB', - int(16), b'url ', - int(0), int(0), int(0), int(0)) - tfile.write(buffer) - buffer = struct.pack('>ssss', b'a', b'b', b'c', b'd') - tfile.write(buffer) + write_buffer = struct.pack('>I4sBBBB', + int(16), b'url ', + int(0), int(0), int(0), int(0)) + tfile.write(write_buffer) + write_buffer = struct.pack('>ssss', b'a', b'b', b'c', b'd') + tfile.write(write_buffer) # Get the rest of the input file. - buffer = ifile.read() - tfile.write(buffer) + write_buffer = ifile.read() + tfile.write(write_buffer) tfile.flush() jp2k = Jp2k(tfile.name) @@ -596,27 +628,26 @@ class TestJp2k(unittest.TestCase): self.assertEqual(jp2k.box[3].box[1].url, 'abcd') @unittest.skipIf(os.name == "nt", "NamedTemporaryFile issue on windows") - def test_xml_box_with_trailing_nulls(self): - # ElementTree does not like trailing null chars after valid XML - # text. + def test_xml_with_trailing_nulls(self): + """ElementTree doesn't like trailing null chars after valid XML text""" with tempfile.NamedTemporaryFile(suffix='.jp2') as tfile: with open(self.jp2file, 'rb') as ifile: # Everything up until the jp2c box. - buffer = ifile.read(77) - tfile.write(buffer) + write_buffer = ifile.read(77) + tfile.write(write_buffer) # Write the xml box # Length = 36, id is 'xml '. - buffer = struct.pack('>I4s', int(36), b'xml ') - tfile.write(buffer) + write_buffer = struct.pack('>I4s', int(36), b'xml ') + tfile.write(write_buffer) - buffer = 'this is a test' + chr(0) - buffer = buffer.encode() - tfile.write(buffer) + write_buffer = 'this is a test' + chr(0) + write_buffer = write_buffer.encode() + tfile.write(write_buffer) # Get the rest of the input file. - buffer = ifile.read() - tfile.write(buffer) + write_buffer = ifile.read() + tfile.write(write_buffer) tfile.flush() jp2k = Jp2k(tfile.name) @@ -629,6 +660,7 @@ class TestJp2k(unittest.TestCase): @unittest.skipIf(os.name == "nt", "NamedTemporaryFile issue on windows") def test_asoc_label_box(self): + """Test asoc and label box""" # Construct a fake file with an asoc and a label box, as # OpenJPEG doesn't have such a file. data = Jp2k(self.jp2file).read(rlevel=1) @@ -639,30 +671,30 @@ class TestJp2k(unittest.TestCase): with tempfile.NamedTemporaryFile(suffix='.jp2') as tfile2: # Offset of the codestream is where we start. - buffer = tfile.read(77) - tfile2.write(buffer) + read_buffer = tfile.read(77) + tfile2.write(read_buffer) # read the rest of the file, it's the codestream. codestream = tfile.read() # Write the asoc superbox. # Length = 36, id is 'asoc'. - buffer = struct.pack('>I4s', int(56), b'asoc') - tfile2.write(buffer) + write_buffer = struct.pack('>I4s', int(56), b'asoc') + tfile2.write(write_buffer) # Write the contained label box - buffer = struct.pack('>I4s', int(13), b'lbl ') - tfile2.write(buffer) + write_buffer = struct.pack('>I4s', int(13), b'lbl ') + tfile2.write(write_buffer) tfile2.write('label'.encode()) # Write the xml box # Length = 36, id is 'xml '. - buffer = struct.pack('>I4s', int(35), b'xml ') - tfile2.write(buffer) + write_buffer = struct.pack('>I4s', int(35), b'xml ') + tfile2.write(write_buffer) - buffer = 'this is a test' - buffer = buffer.encode() - tfile2.write(buffer) + write_buffer = 'this is a test' + write_buffer = write_buffer.encode() + tfile2.write(write_buffer) # Now append the codestream. tfile2.write(codestream) @@ -678,10 +710,10 @@ class TestJp2k(unittest.TestCase): @unittest.skipIf(OPENJP2_IS_V2_OFFICIAL, "Segfault on official v2.0.0 release.") def test_openjpeg_library_message(self): - # Verify the error message produced by the openjpeg library. + """Verify the error message produced by the openjpeg library""" # This will confirm that the error callback mechanism is working. - with open(self.jp2file, 'rb') as fp: - data = fp.read() + with open(self.jp2file, 'rb') as fptr: + data = fptr.read() with tempfile.NamedTemporaryFile(suffix='.jp2') as tfile: # Codestream starts at byte 3127. SIZ marker at 3137. # COD marker at 3186. Subsampling at 3180. @@ -705,13 +737,13 @@ class TestJp2k(unittest.TestCase): :\sdx=1\sdy=0''', re.VERBOSE) if sys.hexversion < 0x03020000: with self.assertRaisesRegexp((IOError, OSError), regexp): - d = j.read(rlevel=1) + j.read(rlevel=1) else: with self.assertRaisesRegex((IOError, OSError), regexp): - d = j.read(rlevel=1) + j.read(rlevel=1) def test_xmp_attribute(self): - # Verify that we can read the XMP packet in our shipping example file. + """Verify the XMP packet in the shipping example file can be read.""" j = Jp2k(self.jp2file) xmp = j.box[4].data ns0 = '{http://www.w3.org/1999/02/22-rdf-syntax-ns#}' @@ -723,7 +755,7 @@ class TestJp2k(unittest.TestCase): @unittest.skipIf(os.name == "nt", "NamedTemporaryFile issue on windows") def test_unrecognized_exif_tag(self): - # An unrecognized exif tag should be handled gracefully. + """An unrecognized exif tag should be handled gracefully.""" with tempfile.NamedTemporaryFile(suffix='.jp2') as tfile: shutil.copyfile(self.jp2file, tfile.name) @@ -733,10 +765,10 @@ class TestJp2k(unittest.TestCase): # the the Image IFD number of tags, where we finally find the first # tag, "Make" (271). We'll corrupt it by changing it into 171, # which does not correspond to any known Exif Image tag. - with open(tfile.name, 'r+b') as fp: - fp.seek(117) - buffer = struct.pack(' Date: Sun, 11 Aug 2013 20:08:15 -0400 Subject: [PATCH 13/20] pylint work, #99 --- glymur/test/test_opj_suite_neg.py | 84 +++++---- glymur/test/test_printing.py | 280 ++++++++++++++++-------------- 2 files changed, 197 insertions(+), 167 deletions(-) diff --git a/glymur/test/test_opj_suite_neg.py b/glymur/test/test_opj_suite_neg.py index f851926..2f61675 100644 --- a/glymur/test/test_opj_suite_neg.py +++ b/glymur/test/test_opj_suite_neg.py @@ -2,7 +2,12 @@ The tests here do not correspond directly to the OpenJPEG test suite, but seem like logical negative tests to add. """ -#pylint: disable-all +# E1101: assertWarns introduced in python 3.2 +# pylint: disable=E1101 + +# R0904: Not too many methods in unittest. +# pylint: disable=R0904 + import os import sys import tempfile @@ -13,9 +18,6 @@ else: import unittest import numpy as np -import pkg_resources - -from glymur.lib import openjp2 as opj2 from .fixtures import read_image, NO_READ_BACKEND, NO_READ_BACKEND_MSG @@ -23,9 +25,9 @@ from glymur import Jp2k import glymur try: - data_root = os.environ['OPJ_DATA_ROOT'] + DATA_ROOT = os.environ['OPJ_DATA_ROOT'] except KeyError: - data_root = None + DATA_ROOT = None except: raise @@ -33,9 +35,10 @@ except: @unittest.skipIf(glymur.lib.openjp2.OPENJP2 is None, "Missing openjp2 library.") @unittest.skipIf(NO_READ_BACKEND, NO_READ_BACKEND_MSG) -@unittest.skipIf(data_root is None, +@unittest.skipIf(DATA_ROOT is None, "OPJ_DATA_ROOT environment variable not set") class TestSuiteNegative(unittest.TestCase): + """Test suite for certain negative tests from openjpeg suite.""" def setUp(self): self.jp2file = glymur.data.nemo() @@ -45,45 +48,50 @@ class TestSuiteNegative(unittest.TestCase): pass @unittest.skipIf(os.name == "nt", "Temporary file issue on window.") - def test_negative_psnr_with_cratios(self): - # Using psnr with cratios options is not allowed. + def test_psnr_with_cratios(self): + """Using psnr with cratios options is not allowed.""" # Not an OpenJPEG test, but close. - infile = os.path.join(data_root, 'input/nonregression/Bretagne1.ppm') + infile = os.path.join(DATA_ROOT, 'input/nonregression/Bretagne1.ppm') data = read_image(infile) with tempfile.NamedTemporaryFile(suffix='.j2k') as tfile: j = Jp2k(tfile.name, 'wb') with self.assertRaises(IOError): j.write(data, psnr=[30, 35, 40], cratios=[2, 3, 4]) - def test_NR_MarkerIsNotCompliant_j2k_dump(self): + def test_nr_marker_not_compliant(self): + """non-compliant marker, should still be able to read""" relpath = 'input/nonregression/MarkerIsNotCompliant.j2k' - jfile = os.path.join(data_root, relpath) + jfile = os.path.join(DATA_ROOT, relpath) jp2k = Jp2k(jfile) - c = jp2k.get_codestream(header_only=False) + jp2k.get_codestream(header_only=False) + self.assertTrue(True) @unittest.skipIf(sys.hexversion < 0x03020000, "Uses features introduced in 3.2.") - def test_NR_illegalcolortransform_dump(self): - # EOC marker is bad + def test_nr_illegalclrtransform(self): + """EOC marker is bad""" relpath = 'input/nonregression/illegalcolortransform.j2k' - jfile = os.path.join(data_root, relpath) + jfile = os.path.join(DATA_ROOT, relpath) jp2k = Jp2k(jfile) - with self.assertWarns(UserWarning) as cw: - c = jp2k.get_codestream(header_only=False) + with self.assertWarns(UserWarning): + codestream = jp2k.get_codestream(header_only=False) # Verify that the last segment returned in the codestream is SOD, # not EOC. Codestream parsing should stop when we try to jump to # the end of SOT. - self.assertEqual(c.segment[-1].marker_id, 'SOD') + self.assertEqual(codestream.segment[-1].marker_id, 'SOD') - def test_NR_Cannotreaddatawithnosizeknown_j2k(self): + def test_nr_cannotreadwnosizeknown(self): + """not sure exactly what is wrong with this file""" relpath = 'input/nonregression/Cannotreaddatawithnosizeknown.j2k' - jfile = os.path.join(data_root, relpath) + jfile = os.path.join(DATA_ROOT, relpath) jp2k = Jp2k(jfile) - c = jp2k.get_codestream(header_only=False) + jp2k.get_codestream(header_only=False) + self.assertTrue(True) @unittest.skipIf(os.name == "nt", "Temporary file issue on window.") def test_code_block_dimensions(self): + """don't allow extreme codeblock sizes""" # opj_compress doesn't allow the dimensions of a codeblock # to be too small or too big, so neither will we. data = np.zeros((256, 256), dtype=np.uint8) @@ -91,55 +99,55 @@ class TestSuiteNegative(unittest.TestCase): j = Jp2k(tfile.name, 'wb') # opj_compress doesn't allow code block area to exceed 4096. - with self.assertRaises(IOError) as cr: + with self.assertRaises(IOError): j.write(data, cbsize=(256, 256)) # opj_compress doesn't allow either dimension to be less than 4. - with self.assertRaises(IOError) as cr: + with self.assertRaises(IOError): j.write(data, cbsize=(2048, 2)) - with self.assertRaises(IOError) as cr: + with self.assertRaises(IOError): j.write(data, cbsize=(2, 2048)) @unittest.skipIf(sys.hexversion < 0x03020000, "Uses features introduced in 3.2.") def test_exceeded_box(self): + """should warn if reading past end of a box""" # Verify that a warning is issued if we read past the end of a box # This file has a palette (pclr) box whose length is impossibly # short. - infile = os.path.join(data_root, + infile = os.path.join(DATA_ROOT, 'input/nonregression/mem-b2ace68c-1381.jp2') - with self.assertWarns(UserWarning) as cw: - j = Jp2k(infile) + with self.assertWarns(UserWarning): + Jp2k(infile) @unittest.skipIf(os.name == "nt", "Temporary file issue on window.") - def test_precinct_size_not_multiple_of_two(self): - # Seems like precinct sizes should be powers of two. + def test_precinct_size_not_p2(self): + """precinct sizes should be powers of two.""" ifile = Jp2k(self.j2kfile) data = ifile.read(rlevel=2) with tempfile.NamedTemporaryFile(suffix='.jp2') as tfile: ofile = Jp2k(tfile.name, 'wb') - with self.assertRaises(IOError) as ce: + with self.assertRaises(IOError): ofile.write(data, psizes=[(13, 13)]) @unittest.skipIf(os.name == "nt", "Temporary file issue on window.") - def test_codeblock_size_not_multiple_of_two(self): - # Seems like code block sizes should be powers of two. + def test_cblk_size_not_power_of_two(self): + """code block sizes should be powers of two.""" ifile = Jp2k(self.j2kfile) data = ifile.read(rlevel=2) with tempfile.NamedTemporaryFile(suffix='.jp2') as tfile: ofile = Jp2k(tfile.name, 'wb') - with self.assertRaises(IOError) as ce: + with self.assertRaises(IOError): ofile.write(data, cbsize=(13, 12)) @unittest.skipIf(os.name == "nt", "Temporary file issue on window.") - def test_codeblock_size_with_precinct_size(self): - # Seems like code block sizes should never exceed half that of - # precinct size. + def test_cblk_size_precinct_size(self): + """code block sizes should never exceed half that of precinct size.""" ifile = Jp2k(self.j2kfile) data = ifile.read(rlevel=2) with tempfile.NamedTemporaryFile(suffix='.jp2') as tfile: ofile = Jp2k(tfile.name, 'wb') - with self.assertRaises(IOError) as ce: + with self.assertRaises(IOError): ofile.write(data, cbsize=(64, 64), psizes=[(64, 64)]) diff --git a/glymur/test/test_printing.py b/glymur/test/test_printing.py index 50babe2..f533aa4 100644 --- a/glymur/test/test_printing.py +++ b/glymur/test/test_printing.py @@ -1,7 +1,15 @@ -#pylint: disable-all +"""Test suite for printing. +""" +# C0302: don't care too much about having too many lines in a test module +# pylint: disable=C0302 + +# E061: unittest.mock introduced in 3.3 (python-2.7/pylint issue) +# pylint: disable=E0611,F0401 + +# R0904: Not too many methods in unittest. +# pylint: disable=R0904 + import os -import pkg_resources -import re import struct import sys import tempfile @@ -26,9 +34,9 @@ import glymur from glymur import Jp2k try: - data_root = os.environ['OPJ_DATA_ROOT'] + DATA_ROOT = os.environ['OPJ_DATA_ROOT'] except KeyError: - data_root = None + DATA_ROOT = None except: raise @@ -122,12 +130,13 @@ class TestPrintingNeedsLib(unittest.TestCase): + '(0, 10), (0, 9), (0, 9), (0, 10), (0, 9), (0, 9), ' + '(0, 10), (0, 9), (0, 9), (0, 10), (0, 9), (0, 9), ' + '(0, 10)]'] - self.expectedPlain = '\n'.join(lines) + self.expected_plain = '\n'.join(lines) def tearDown(self): pass def test_asoc_label_box(self): + """verify printing of asoc, label boxes""" # Construct a fake file with an asoc and a label box, as # OpenJPEG doesn't have such a file. data = glymur.Jp2k(self.jp2file).read(rlevel=1) @@ -138,30 +147,30 @@ class TestPrintingNeedsLib(unittest.TestCase): with tempfile.NamedTemporaryFile(suffix='.jp2') as tfile2: # Offset of the codestream is where we start. - buffer = tfile.read(77) - tfile2.write(buffer) + wbuffer = tfile.read(77) + tfile2.write(wbuffer) # read the rest of the file, it's the codestream. codestream = tfile.read() # Write the asoc superbox. # Length = 36, id is 'asoc'. - buffer = struct.pack('>I4s', int(56), b'asoc') - tfile2.write(buffer) + wbuffer = struct.pack('>I4s', int(56), b'asoc') + tfile2.write(wbuffer) # Write the contained label box - buffer = struct.pack('>I4s', int(13), b'lbl ') - tfile2.write(buffer) + wbuffer = struct.pack('>I4s', int(13), b'lbl ') + tfile2.write(wbuffer) tfile2.write('label'.encode()) # Write the xml box # Length = 36, id is 'xml '. - buffer = struct.pack('>I4s', int(35), b'xml ') - tfile2.write(buffer) + wbuffer = struct.pack('>I4s', int(35), b'xml ') + tfile2.write(wbuffer) - buffer = 'this is a test' - buffer = buffer.encode() - tfile2.write(buffer) + wbuffer = 'this is a test' + wbuffer = wbuffer.encode() + tfile2.write(wbuffer) # Now append the codestream. tfile2.write(codestream) @@ -180,6 +189,7 @@ class TestPrintingNeedsLib(unittest.TestCase): self.assertEqual(actual, expected) def test_jp2dump(self): + """basic jp2dump test""" with patch('sys.stdout', new=StringIO()) as fake_out: glymur.jp2dump(self._plain_nemo_file) actual = fake_out.getvalue().strip() @@ -188,9 +198,10 @@ class TestPrintingNeedsLib(unittest.TestCase): lst = actual.split('\n') lst = lst[1:] actual = '\n'.join(lst) - self.assertEqual(actual, self.expectedPlain) + self.assertEqual(actual, self.expected_plain) def test_entire_file(self): + """verify output from printing entire file""" j = glymur.Jp2k(self._plain_nemo_file) with patch('sys.stdout', new=StringIO()) as fake_out: print(j) @@ -201,10 +212,11 @@ class TestPrintingNeedsLib(unittest.TestCase): lst = lst[1:] actual = '\n'.join(lst) - self.assertEqual(actual, self.expectedPlain) + self.assertEqual(actual, self.expected_plain) class TestPrinting(unittest.TestCase): + """Test suite for printing where the libraries are not needed""" def setUp(self): # Save sys.stdout. @@ -213,7 +225,8 @@ class TestPrinting(unittest.TestCase): def tearDown(self): pass - def test_COC_segment(self): + def test_coc_segment(self): + """verify printing of COC segment""" j = glymur.Jp2k(self.jp2file) codestream = j.get_codestream(header_only=False) with patch('sys.stdout', new=StringIO()) as fake_out: @@ -240,7 +253,8 @@ class TestPrinting(unittest.TestCase): expected = '\n'.join(lines) self.assertEqual(actual, expected) - def test_COD_segment(self): + def test_cod_segment(self): + """verify printing of COD segment""" j = glymur.Jp2k(self.jp2file) codestream = j.get_codestream() with patch('sys.stdout', new=StringIO()) as fake_out: @@ -271,14 +285,13 @@ class TestPrinting(unittest.TestCase): ' Segmentation symbols: False'] expected = '\n'.join(lines) - self.actual = actual - self.expected = expected self.assertEqual(actual, expected) - @unittest.skipIf(data_root is None, + @unittest.skipIf(DATA_ROOT is None, "OPJ_DATA_ROOT environment variable not set") def test_icc_profile(self): - filename = os.path.join(data_root, 'input/nonregression/text_GBR.jp2') + """verify printing of colr box with ICC profile""" + filename = os.path.join(DATA_ROOT, 'input/nonregression/text_GBR.jp2') with warnings.catch_warnings(): # brand is 'jp2 ', but has any icc profile. warnings.simplefilter("ignore") @@ -343,24 +356,26 @@ class TestPrinting(unittest.TestCase): expected = '\n'.join(lines) self.assertEqual(actual, expected) - @unittest.skipIf(data_root is None, + @unittest.skipIf(DATA_ROOT is None, "OPJ_DATA_ROOT environment variable not set") - def test_CRG(self): - filename = os.path.join(data_root, 'input/conformance/p0_03.j2k') + def test_crg(self): + """verify printing of CRG segment""" + filename = os.path.join(DATA_ROOT, 'input/conformance/p0_03.j2k') j = glymur.Jp2k(filename) codestream = j.get_codestream() with patch('sys.stdout', new=StringIO()) as fake_out: print(codestream.segment[-5]) actual = fake_out.getvalue().strip() - lines = ['CRG marker segment at (87, 6)', + lines = ['CRG marker segment @ (87, 6)', ' Vertical, Horizontal offset: (0.50, 1.00)'] expected = '\n'.join(lines) self.assertEqual(actual, expected) - @unittest.skipIf(data_root is None, + @unittest.skipIf(DATA_ROOT is None, "OPJ_DATA_ROOT environment variable not set") - def test_RGN(self): - filename = os.path.join(data_root, 'input/conformance/p0_03.j2k') + def test_rgn(self): + """verify printing of RGN segment""" + filename = os.path.join(DATA_ROOT, 'input/conformance/p0_03.j2k') j = glymur.Jp2k(filename) codestream = j.get_codestream(header_only=False) with patch('sys.stdout', new=StringIO()) as fake_out: @@ -373,10 +388,11 @@ class TestPrinting(unittest.TestCase): expected = '\n'.join(lines) self.assertEqual(actual, expected) - @unittest.skipIf(data_root is None, + @unittest.skipIf(DATA_ROOT is None, "OPJ_DATA_ROOT environment variable not set") - def test_SOP(self): - filename = os.path.join(data_root, 'input/conformance/p0_03.j2k') + def test_sop(self): + """verify printing of SOP segment""" + filename = os.path.join(DATA_ROOT, 'input/conformance/p0_03.j2k') j = glymur.Jp2k(filename) codestream = j.get_codestream(header_only=False) with patch('sys.stdout', new=StringIO()) as fake_out: @@ -387,11 +403,11 @@ class TestPrinting(unittest.TestCase): expected = '\n'.join(lines) self.assertEqual(actual, expected) - @unittest.skipIf(data_root is None, + @unittest.skipIf(DATA_ROOT is None, "OPJ_DATA_ROOT environment variable not set") - def test_CME(self): - # Test printing a CME or comment marker segment. - filename = os.path.join(data_root, 'input/conformance/p0_02.j2k') + def test_cme(self): + """Test printing a CME or comment marker segment.""" + filename = os.path.join(DATA_ROOT, 'input/conformance/p0_02.j2k') j = glymur.Jp2k(filename) codestream = j.get_codestream() # 2nd to last segment in the main header @@ -403,7 +419,8 @@ class TestPrinting(unittest.TestCase): expected = '\n'.join(lines) self.assertEqual(actual, expected) - def test_EOC_segment(self): + def test_eoc_segment(self): + """verify printing of eoc segment""" j = glymur.Jp2k(self.jp2file) codestream = j.get_codestream(header_only=False) with patch('sys.stdout', new=StringIO()) as fake_out: @@ -414,10 +431,11 @@ class TestPrinting(unittest.TestCase): expected = '\n'.join(lines) self.assertEqual(actual, expected) - @unittest.skipIf(data_root is None, + @unittest.skipIf(DATA_ROOT is None, "OPJ_DATA_ROOT environment variable not set") - def test_PLT_segment(self): - filename = os.path.join(data_root, 'input/conformance/p0_07.j2k') + def test_plt_segment(self): + """verify printing of PLT segment""" + filename = os.path.join(DATA_ROOT, 'input/conformance/p0_07.j2k') j = glymur.Jp2k(filename) codestream = j.get_codestream(header_only=False) with patch('sys.stdout', new=StringIO()) as fake_out: @@ -432,10 +450,11 @@ class TestPrinting(unittest.TestCase): expected = '\n'.join(lines) self.assertEqual(actual, expected) - @unittest.skipIf(data_root is None, + @unittest.skipIf(DATA_ROOT is None, "OPJ_DATA_ROOT environment variable not set") - def test_POD_segment(self): - filename = os.path.join(data_root, 'input/conformance/p0_13.j2k') + def test_pod_segment(self): + """verify printing of POD segment""" + filename = os.path.join(DATA_ROOT, 'input/conformance/p0_13.j2k') j = glymur.Jp2k(filename) codestream = j.get_codestream() with patch('sys.stdout', new=StringIO()) as fake_out: @@ -461,10 +480,11 @@ class TestPrinting(unittest.TestCase): expected = '\n'.join(lines) self.assertEqual(actual, expected) - @unittest.skipIf(data_root is None, + @unittest.skipIf(DATA_ROOT is None, "OPJ_DATA_ROOT environment variable not set") - def test_PPM_segment(self): - filename = os.path.join(data_root, 'input/conformance/p1_03.j2k') + def test_ppm_segment(self): + """verify printing of PPM segment""" + filename = os.path.join(DATA_ROOT, 'input/conformance/p1_03.j2k') j = glymur.Jp2k(filename) codestream = j.get_codestream() with patch('sys.stdout', new=StringIO()) as fake_out: @@ -478,10 +498,11 @@ class TestPrinting(unittest.TestCase): expected = '\n'.join(lines) self.assertEqual(actual, expected) - @unittest.skipIf(data_root is None, + @unittest.skipIf(DATA_ROOT is None, "OPJ_DATA_ROOT environment variable not set") - def test_PPT_segment(self): - filename = os.path.join(data_root, 'input/conformance/p1_06.j2k') + def test_ppt_segment(self): + """verify printing of ppt segment""" + filename = os.path.join(DATA_ROOT, 'input/conformance/p1_06.j2k') j = glymur.Jp2k(filename) codestream = j.get_codestream(header_only=False) with patch('sys.stdout', new=StringIO()) as fake_out: @@ -495,7 +516,8 @@ class TestPrinting(unittest.TestCase): expected = '\n'.join(lines) self.assertEqual(actual, expected) - def test_QCC_segment(self): + def test_qcc_segment(self): + """verify printing of qcc segment""" j = glymur.Jp2k(self.jp2file) codestream = j.get_codestream(header_only=False) with patch('sys.stdout', new=StringIO()) as fake_out: @@ -510,7 +532,8 @@ class TestPrinting(unittest.TestCase): expected = '\n'.join(lines) self.assertEqual(actual, expected) - def test_QCD_segment_5x3_transform(self): + def test_qcd_segment_5x3_transform(self): + """verify printing of qcd segment""" j = glymur.Jp2k(self.jp2file) codestream = j.get_codestream() with patch('sys.stdout', new=StringIO()) as fake_out: @@ -524,7 +547,8 @@ class TestPrinting(unittest.TestCase): expected = '\n'.join(lines) self.assertEqual(actual, expected) - def test_SIZ_segment(self): + def test_siz_segment(self): + """verify printing of SIZ segment""" j = glymur.Jp2k(self.jp2file) codestream = j.get_codestream() with patch('sys.stdout', new=StringIO()) as fake_out: @@ -545,7 +569,8 @@ class TestPrinting(unittest.TestCase): expected = '\n'.join(lines) self.assertEqual(actual, expected) - def test_SOC_segment(self): + def test_soc_segment(self): + """verify printing of SOC segment""" j = glymur.Jp2k(self.jp2file) codestream = j.get_codestream() with patch('sys.stdout', new=StringIO()) as fake_out: @@ -556,7 +581,8 @@ class TestPrinting(unittest.TestCase): expected = '\n'.join(lines) self.assertEqual(actual, expected) - def test_SOD_segment(self): + def test_sod_segment(self): + """verify printing of SOD segment""" j = glymur.Jp2k(self.jp2file) codestream = j.get_codestream(header_only=False) with patch('sys.stdout', new=StringIO()) as fake_out: @@ -567,7 +593,8 @@ class TestPrinting(unittest.TestCase): expected = '\n'.join(lines) self.assertEqual(actual, expected) - def test_SOT_segment(self): + def test_sot_segment(self): + """verify printing of SOT segment""" j = glymur.Jp2k(self.jp2file) codestream = j.get_codestream(header_only=False) with patch('sys.stdout', new=StringIO()) as fake_out: @@ -581,13 +608,13 @@ class TestPrinting(unittest.TestCase): ' Number of tile parts: 1'] expected = '\n'.join(lines) - self.maxDiff = None self.assertEqual(actual, expected) - @unittest.skipIf(data_root is None, + @unittest.skipIf(DATA_ROOT is None, "OPJ_DATA_ROOT environment variable not set") - def test_TLM_segment(self): - filename = os.path.join(data_root, 'input/conformance/p0_15.j2k') + def test_tlm_segment(self): + """verify printing of TLM segment""" + filename = os.path.join(DATA_ROOT, 'input/conformance/p0_15.j2k') j = glymur.Jp2k(filename) codestream = j.get_codestream() with patch('sys.stdout', new=StringIO()) as fake_out: @@ -605,7 +632,7 @@ class TestPrinting(unittest.TestCase): @unittest.skipIf(sys.hexversion < 0x02070000, "Differences in XML printing between 2.6 and 2.7") def test_xmp(self): - # Verify the printing of a UUID/XMP box. + """Verify the printing of a UUID/XMP box.""" j = glymur.Jp2k(self.jp2file) with patch('sys.stdout', new=StringIO()) as fake_out: print(j.box[4]) @@ -627,6 +654,7 @@ class TestPrinting(unittest.TestCase): self.assertEqual(actual, expected) def test_codestream(self): + """verify printing of entire codestream""" j = glymur.Jp2k(self.jp2file) with patch('sys.stdout', new=StringIO()) as fake_out: print(j.get_codestream()) @@ -672,15 +700,15 @@ class TestPrinting(unittest.TestCase): ' CME marker segment @ (3209, 37)', ' "Created by OpenJPEG version 2.0.0"'] expected = '\n'.join(lst) - self.maxDiff = None self.assertEqual(actual, expected) @unittest.skipIf(sys.hexversion < 0x02070000, "Differences in XML printing between 2.6 and 2.7") - @unittest.skipIf(data_root is None, + @unittest.skipIf(DATA_ROOT is None, "OPJ_DATA_ROOT environment variable not set") def test_xml(self): - filename = os.path.join(data_root, 'input/conformance/file1.jp2') + """verify printing of XML box""" + filename = os.path.join(DATA_ROOT, 'input/conformance/file1.jp2') j = glymur.Jp2k(filename) with patch('sys.stdout', new=StringIO()) as fake_out: print(j.box[2]) @@ -707,10 +735,11 @@ class TestPrinting(unittest.TestCase): expected = '\n'.join(lines) self.assertEqual(actual, expected) - @unittest.skipIf(data_root is None, + @unittest.skipIf(DATA_ROOT is None, "OPJ_DATA_ROOT environment variable not set") def test_channel_definition(self): - filename = os.path.join(data_root, 'input/conformance/file2.jp2') + """verify printing of cdef box""" + filename = os.path.join(DATA_ROOT, 'input/conformance/file2.jp2') j = glymur.Jp2k(filename) with patch('sys.stdout', new=StringIO()) as fake_out: print(j.box[2].box[2]) @@ -722,10 +751,11 @@ class TestPrinting(unittest.TestCase): expected = '\n'.join(lines) self.assertEqual(actual, expected) - @unittest.skipIf(data_root is None, + @unittest.skipIf(DATA_ROOT is None, "OPJ_DATA_ROOT environment variable not set") def test_component_mapping(self): - filename = os.path.join(data_root, 'input/conformance/file9.jp2') + """verify printing of cmap box""" + filename = os.path.join(DATA_ROOT, 'input/conformance/file9.jp2') j = glymur.Jp2k(filename) with patch('sys.stdout', new=StringIO()) as fake_out: print(j.box[2].box[2]) @@ -737,10 +767,11 @@ class TestPrinting(unittest.TestCase): expected = '\n'.join(lines) self.assertEqual(actual, expected) - @unittest.skipIf(data_root is None, + @unittest.skipIf(DATA_ROOT is None, "OPJ_DATA_ROOT environment variable not set") - def test_palette(self): - filename = os.path.join(data_root, 'input/conformance/file9.jp2') + def test_palette7(self): + """verify printing of pclr box""" + filename = os.path.join(DATA_ROOT, 'input/conformance/file9.jp2') j = glymur.Jp2k(filename) with patch('sys.stdout', new=StringIO()) as fake_out: print(j.box[2].box[1]) @@ -750,10 +781,11 @@ class TestPrinting(unittest.TestCase): expected = '\n'.join(lines) self.assertEqual(actual, expected) - @unittest.skipIf(data_root is None, + @unittest.skipIf(DATA_ROOT is None, "OPJ_DATA_ROOT environment variable not set") - def test_palette(self): - filename = os.path.join(data_root, 'input/conformance/file7.jp2') + def test_rreq(self): + """verify printing of reader requirements box""" + filename = os.path.join(DATA_ROOT, 'input/conformance/file7.jp2') j = glymur.Jp2k(filename) with patch('sys.stdout', new=StringIO()) as fake_out: print(j.box[2]) @@ -773,25 +805,11 @@ class TestPrinting(unittest.TestCase): expected = '\n'.join(lines) self.assertEqual(actual, expected) - @unittest.skipIf(data_root is None, - "OPJ_DATA_ROOT environment variable not set") - def test_CRG(self): - filename = os.path.join(data_root, 'input/conformance/p0_03.j2k') - j = glymur.Jp2k(filename) - codestream = j.get_codestream() - with patch('sys.stdout', new=StringIO()) as fake_out: - print(codestream.segment[6]) - actual = fake_out.getvalue().strip() - lines = ['CRG marker segment @ (87, 6)', - ' Vertical, Horizontal offset: (0.50, 1.00)'] - expected = '\n'.join(lines) - self.assertEqual(actual, expected) - - @unittest.skipIf(data_root is None, + @unittest.skipIf(DATA_ROOT is None, "OPJ_DATA_ROOT environment variable not set") def test_differing_subsamples(self): - # Issue 86. - filename = os.path.join(data_root, 'input/conformance/p0_05.j2k') + """verify printing of SIZ with different subsampling... Issue 86.""" + filename = os.path.join(DATA_ROOT, 'input/conformance/p0_05.j2k') j = glymur.Jp2k(filename) codestream = j.get_codestream() with patch('sys.stdout', new=StringIO()) as fake_out: @@ -810,11 +828,11 @@ class TestPrinting(unittest.TestCase): expected = '\n'.join(lines) self.assertEqual(actual, expected) - @unittest.skipIf(data_root is None, + @unittest.skipIf(DATA_ROOT is None, "OPJ_DATA_ROOT environment variable not set") def test_palette_box(self): - # Verify that palette (pclr) boxes are printed without error. - filename = os.path.join(data_root, 'input/conformance/file9.jp2') + """Verify that palette (pclr) boxes are printed without error.""" + filename = os.path.join(DATA_ROOT, 'input/conformance/file9.jp2') j = glymur.Jp2k(filename) with patch('sys.stdout', new=StringIO()) as fake_out: print(j.box[2].box[1]) @@ -826,54 +844,56 @@ class TestPrinting(unittest.TestCase): @unittest.skipIf(os.name == "nt", "Temporary file issue on window.") def test_less_common_boxes(self): + """verify uinf, ulst, url, res, resd, resc box printing""" with tempfile.NamedTemporaryFile(suffix='.jp2') as tfile: with open(self.jp2file, 'rb') as ifile: # Everything up until the jp2c box. - buffer = ifile.read(77) - tfile.write(buffer) + wbuffer = ifile.read(77) + tfile.write(wbuffer) # Write the UINF superbox # Length = 50, id is uinf. - buffer = struct.pack('>I4s', int(50), b'uinf') - tfile.write(buffer) + wbuffer = struct.pack('>I4s', int(50), b'uinf') + tfile.write(wbuffer) # Write the ULST box. # Length is 26, 1 UUID, hard code that UUID as zeros. - buffer = struct.pack('>I4sHIIII', int(26), b'ulst', int(1), - int(0), int(0), int(0), int(0)) - tfile.write(buffer) + wbuffer = struct.pack('>I4sHIIII', int(26), b'ulst', int(1), + int(0), int(0), int(0), int(0)) + tfile.write(wbuffer) # Write the URL box. # Length is 16, version is one byte, flag is 3 bytes, url # is the rest. - buffer = struct.pack('>I4sBBBB', - int(16), b'url ', - int(0), int(0), int(0), int(0)) - tfile.write(buffer) - buffer = struct.pack('>ssss', b'a', b'b', b'c', b'd') - tfile.write(buffer) + wbuffer = struct.pack('>I4sBBBB', + int(16), b'url ', + int(0), int(0), int(0), int(0)) + tfile.write(wbuffer) + + wbuffer = struct.pack('>ssss', b'a', b'b', b'c', b'd') + tfile.write(wbuffer) # Start the resolution superbox. - buffer = struct.pack('>I4s', int(44), b'res ') - tfile.write(buffer) + wbuffer = struct.pack('>I4s', int(44), b'res ') + tfile.write(wbuffer) # Write the capture resolution box. - buffer = struct.pack('>I4sHHHHBB', - int(18), b'resc', - int(1), int(1), int(1), int(1), - int(0), int(1)) - tfile.write(buffer) + wbuffer = struct.pack('>I4sHHHHBB', + int(18), b'resc', + int(1), int(1), int(1), int(1), + int(0), int(1)) + tfile.write(wbuffer) # Write the display resolution box. - buffer = struct.pack('>I4sHHHHBB', - int(18), b'resd', - int(1), int(1), int(1), int(1), - int(1), int(0)) - tfile.write(buffer) + wbuffer = struct.pack('>I4sHHHHBB', + int(18), b'resd', + int(1), int(1), int(1), int(1), + int(1), int(0)) + tfile.write(wbuffer) # Get the rest of the input file. - buffer = ifile.read() - tfile.write(buffer) + wbuffer = ifile.read() + tfile.write(wbuffer) tfile.flush() jp2k = glymur.Jp2k(tfile.name) @@ -901,12 +921,13 @@ class TestPrinting(unittest.TestCase): @unittest.skipIf(sys.hexversion < 0x03000000, "Ordered dicts not printing well in 2.7") - @unittest.skipIf(data_root is None, + @unittest.skipIf(DATA_ROOT is None, "OPJ_DATA_ROOT environment variable not set") - def test_jpx_approximation_with_icc_profile(self): + def test_jpx_approx_icc_profile(self): + """verify jpx with approx field equal to zero""" # ICC profiles may be used in JP2, but the approximation field should # be zero unless we have jpx. This file does both. - filename = os.path.join(data_root, 'input/nonregression/text_GBR.jp2') + filename = os.path.join(DATA_ROOT, 'input/nonregression/text_GBR.jp2') with warnings.catch_warnings(): # brand is 'jp2 ', but has any icc profile. warnings.simplefilter("ignore") @@ -945,11 +966,11 @@ class TestPrinting(unittest.TestCase): expected = '\n'.join(lines) self.assertEqual(actual, expected) - @unittest.skipIf(data_root is None, + @unittest.skipIf(DATA_ROOT is None, "OPJ_DATA_ROOT environment variable not set") def test_uuid(self): - # UUID box - filename = os.path.join(data_root, 'input/nonregression/text_GBR.jp2') + """verify printing of UUID box""" + filename = os.path.join(DATA_ROOT, 'input/nonregression/text_GBR.jp2') with warnings.catch_warnings(): # brand is 'jp2 ', but has any icc profile. warnings.simplefilter("ignore") @@ -968,6 +989,7 @@ class TestPrinting(unittest.TestCase): @unittest.skipIf(sys.hexversion < 0x03000000, "Ordered dicts not printing well in 2.7") def test_exif_uuid(self): + """Verify printing of exif information""" j = glymur.Jp2k(self.jp2file) with patch('sys.stdout', new=StringIO()) as fake_out: From 11b29028fc927b1259a54949fa84f225f31895a6 Mon Sep 17 00:00:00 2001 From: jevans Date: Sun, 11 Aug 2013 20:23:50 -0400 Subject: [PATCH 14/20] pylint work, #99 --- glymur/test/test_conformance.py | 82 ++++++++++++++++----------------- 1 file changed, 40 insertions(+), 42 deletions(-) diff --git a/glymur/test/test_conformance.py b/glymur/test/test_conformance.py index 9e1ad1a..8c022bb 100644 --- a/glymur/test/test_conformance.py +++ b/glymur/test/test_conformance.py @@ -1,9 +1,15 @@ """ These tests deal with JPX/JP2/J2K images in the format-corpus repository. """ -#pylint: disable-all +# R0904: Not too many methods in unittest. +# pylint: disable=R0904 + +# E1101: assertWarns introduced in python 3.2 +# pylint: disable=E1101 + import os +from os.path import join import sys if sys.hexversion < 0x02070000: @@ -11,106 +17,98 @@ if sys.hexversion < 0x02070000: else: import unittest -import warnings - from glymur import Jp2k -import glymur try: - format_corpus_data_root = os.environ['FORMAT_CORPUS_DATA_ROOT'] + FORMAT_CORPUS_DATA_ROOT = os.environ['FORMAT_CORPUS_DATA_ROOT'] except KeyError: - format_corpus_data_root = None + FORMAT_CORPUS_DATA_ROOT = None try: - opj_data_root = os.environ['OPJ_DATA_ROOT'] + OPJ_DATA_ROOT = os.environ['OPJ_DATA_ROOT'] except KeyError: - opj_data_root = None + OPJ_DATA_ROOT = None -@unittest.skipIf(format_corpus_data_root is None, +@unittest.skipIf(FORMAT_CORPUS_DATA_ROOT is None, "FORMAT_CORPUS_DATA_ROOT environment variable not set") @unittest.skipIf(sys.hexversion < 0x03020000, "Requires features introduced in 3.2 (assertWarns)") class TestSuiteFormatCorpus(unittest.TestCase): - - def setUp(self): - pass - - def tearDown(self): - pass + """Test suite for files in format corpus repository.""" def test_balloon_trunc1(self): - # Has one byte shaved off of EOC marker. - jfile = os.path.join(format_corpus_data_root, + """Has one byte shaved off of EOC marker.""" + jfile = os.path.join(FORMAT_CORPUS_DATA_ROOT, 'jp2k-test/byteCorruption/balloon_trunc1.jp2') j2k = Jp2k(jfile) with self.assertWarns(UserWarning): - c = j2k.get_codestream(header_only=False) + codestream = j2k.get_codestream(header_only=False) # The last segment is truncated, so there should not be an EOC marker. - self.assertNotEqual(c.segment[-1].marker_id, 'EOC') + self.assertNotEqual(codestream.segment[-1].marker_id, 'EOC') # The codestream is not as long as claimed. with self.assertRaises(OSError): j2k.read(rlevel=-1) def test_balloon_trunc2(self): - # Shortened by 5000 bytes. - jfile = os.path.join(format_corpus_data_root, + """Shortened by 5000 bytes.""" + jfile = os.path.join(FORMAT_CORPUS_DATA_ROOT, 'jp2k-test/byteCorruption/balloon_trunc2.jp2') j2k = Jp2k(jfile) with self.assertWarns(UserWarning): - c = j2k.get_codestream(header_only=False) + codestream = j2k.get_codestream(header_only=False) # The last segment is truncated, so there should not be an EOC marker. - self.assertNotEqual(c.segment[-1].marker_id, 'EOC') + self.assertNotEqual(codestream.segment[-1].marker_id, 'EOC') # The codestream is not as long as claimed. with self.assertRaises(OSError): j2k.read(rlevel=-1) def test_balloon_trunc3(self): - # Most of last tile is missing. - jfile = os.path.join(format_corpus_data_root, + """Most of last tile is missing.""" + jfile = os.path.join(FORMAT_CORPUS_DATA_ROOT, 'jp2k-test/byteCorruption/balloon_trunc3.jp2') j2k = Jp2k(jfile) with self.assertWarns(UserWarning): - c = j2k.get_codestream(header_only=False) + codestream = j2k.get_codestream(header_only=False) # The last segment is truncated, so there should not be an EOC marker. - self.assertNotEqual(c.segment[-1].marker_id, 'EOC') + self.assertNotEqual(codestream.segment[-1].marker_id, 'EOC') # Should error out, it does not. #with self.assertRaises(OSError): # j2k.read(rlevel=-1) - def test_jp2_brand_vs_any_icc_profile(self): - # If 'jp2 ', then the method cannot be any icc profile. - jfile = os.path.join(format_corpus_data_root, + def test_jp2_brand_any_icc_profile(self): + """If 'jp2 ', then the method cannot be any icc profile.""" + jfile = os.path.join(FORMAT_CORPUS_DATA_ROOT, 'jp2k-test', 'icc', 'balloon_eciRGBv2_ps_adobeplugin.jpf') with self.assertWarns(UserWarning): - j2k = Jp2k(jfile) + Jp2k(jfile) - def test_jp2_brand_vs_any_icc_profile_multiple_colr(self): - # Has colr box, one that conforms, one that does not. + def test_jp2_brand_iccpr_mult_colr(self): + """Has colr box, one that conforms, one that does not.""" # Wrong 'brand' field; contains two versions of ICC profile: one # embedded using "Any ICC" method; other embedded using "Restricted # ICC" method, with description ("Modified eciRGB v2") and profileClass # ("Input Device") changed relative to original profile. - lst = [format_corpus_data_root, 'jp2k-test', 'icc', - 'balloon_eciRGBv2_ps_adobeplugin_jp2compatible.jpf'] - jfile = os.path.join(*lst) + jfile = join(FORMAT_CORPUS_DATA_ROOT, 'jp2k-test', 'icc', + 'balloon_eciRGBv2_ps_adobeplugin_jp2compatible.jpf') with self.assertWarns(UserWarning): - j2k = Jp2k(jfile) + Jp2k(jfile) -@unittest.skipIf(opj_data_root is None, +@unittest.skipIf(OPJ_DATA_ROOT is None, "OPJ_DATA_ROOT environment variable not set") @unittest.skipIf(sys.hexversion < 0x03020000, "Requires features introduced in 3.2 (assertWarns)") class TestSuiteOpj(unittest.TestCase): + """Test suite for files in openjpeg repository.""" def setUp(self): pass @@ -118,12 +116,12 @@ class TestSuiteOpj(unittest.TestCase): def tearDown(self): pass - def test_jp2_brand_vs_any_icc_profile(self): - # If 'jp2 ', then the method cannot be any icc profile. - filename = os.path.join(opj_data_root, + def test_jp2_brand_any_icc_profile(self): + """If 'jp2 ', then the method cannot be any icc profile.""" + filename = os.path.join(OPJ_DATA_ROOT, 'input/nonregression/text_GBR.jp2') with self.assertWarns(UserWarning): - j2k = Jp2k(filename) + Jp2k(filename) if __name__ == "__main__": unittest.main() From fc95b9d54c9563a1d1d94b88ceeaabbaab47f1c3 Mon Sep 17 00:00:00 2001 From: John Evans Date: Mon, 12 Aug 2013 06:57:56 -0400 Subject: [PATCH 15/20] pylint work (head is now broken), #99 --- glymur/test/test_opj_suite.py | 176 +++++++++++++++++++--------------- 1 file changed, 98 insertions(+), 78 deletions(-) diff --git a/glymur/test/test_opj_suite.py b/glymur/test/test_opj_suite.py index 0a15879..4106e94 100644 --- a/glymur/test/test_opj_suite.py +++ b/glymur/test/test_opj_suite.py @@ -2,14 +2,20 @@ The tests defined here roughly correspond to what is in the OpenJPEG test suite. """ -#pylint: disable-all -from contextlib import contextmanager +# Some test names correspond with openjpeg tests. Long names are ok in this +# case. +# pylint: disable=C0103 + +# unittest fools pylint with "too many public methods" +# pylint: disable=R0904 + +# asserWarns introduced in python 3.2 (python2.7/pylint issue) +# pylint: disable=E1101 + import os -import platform import re import sys -from xml.etree import cElementTree as ET if sys.hexversion < 0x02070000: import unittest2 as unittest @@ -18,13 +24,6 @@ else: import warnings -if sys.hexversion <= 0x03030000: - from mock import patch - from StringIO import StringIO -else: - from unittest.mock import patch - from io import StringIO - import numpy as np from glymur import Jp2k @@ -33,7 +32,6 @@ import glymur from .fixtures import OPENJPEG_VERSION from .fixtures import OPENJP2_IS_V2_OFFICIAL -from .fixtures import * try: data_root = os.environ['OPJ_DATA_ROOT'] @@ -7762,30 +7760,35 @@ class TestSuite15(unittest.TestCase): self.assertEqual(jpdata.shape, (512, 768)) def test_ETS_JP2_file5(self): + """ETS_JP2_file5""" jfile = os.path.join(data_root, 'input/conformance/file5.jp2') jp2k = Jp2k(jfile) - jpdata = jp2k.read() + jp2k.read() self.assertEqual(jpdata.shape, (512, 768, 3)) def test_ETS_JP2_file6(self): + """ETS_JP2_file6""" jfile = os.path.join(data_root, 'input/conformance/file6.jp2') jp2k = Jp2k(jfile) - jpdata = jp2k.read() + jp2k.read() self.assertEqual(jpdata.shape, (512, 768)) def test_ETS_JP2_file7(self): + """ETS_JP2_file7""" jfile = os.path.join(data_root, 'input/conformance/file7.jp2') jp2k = Jp2k(jfile) - jpdata = jp2k.read() + jp2k.read() self.assertEqual(jpdata.shape, (640, 480, 3)) def test_ETS_JP2_file8(self): + """ETS_JP2_file8""" jfile = os.path.join(data_root, 'input/conformance/file8.jp2') jp2k = Jp2k(jfile) - jpdata = jp2k.read() + jp2k.read() self.assertEqual(jpdata.shape, (400, 700)) def test_ETS_JP2_file9(self): + """ETS_JP2_file9""" jfile = os.path.join(data_root, 'input/conformance/file9.jp2') jp2k = Jp2k(jfile) jpdata = jp2k.read() @@ -7796,214 +7799,231 @@ class TestSuite15(unittest.TestCase): self.assertEqual(jpdata.shape, (512, 768, 3)) def test_NR_DEC_Bretagne2_j2k_1_decode(self): - jfile = os.path.join(data_root, - 'input/nonregression/Bretagne2.j2k') + """test_NR_DEC_Bretagne2_j2k_1_decode""" + jfile = os.path.join(data_root, 'input/nonregression/Bretagne2.j2k') jp2 = Jp2k(jfile) - data = jp2.read() + jp2.read() self.assertTrue(True) def test_NR_DEC__00042_j2k_2_decode(self): - jfile = os.path.join(data_root, - 'input/nonregression/_00042.j2k') + """NR_DEC__00042_j2k_2_decode""" + jfile = os.path.join(data_root, 'input/nonregression/_00042.j2k') jp2 = Jp2k(jfile) - data = jp2.read() + jp2.read() self.assertTrue(True) @unittest.skip("fprintf stderr output in r2343.") def test_NR_DEC_123_j2c_3_decode(self): - jfile = os.path.join(data_root, - 'input/nonregression/123.j2c') + """NR_DEC_123_j2c_3_decode""" + jfile = os.path.join(data_root, 'input/nonregression/123.j2c') jp2 = Jp2k(jfile) - data = jp2.read() + jp2.read() self.assertTrue(True) @unittest.skipIf(sys.hexversion < 0x03020000, "Uses features introduced in 3.2.") def test_NR_DEC_broken_jp2_4_decode(self): - jfile = os.path.join(data_root, - 'input/nonregression/broken.jp2') - with self.assertWarns(UserWarning) as cw: + """NR_DEC_broken_jp2_4_decode""" + jfile = os.path.join(data_root, 'input/nonregression/broken.jp2') + with self.assertWarns(UserWarning): # colr box has bad length. jp2 = Jp2k(jfile) with self.assertRaises(ValueError): - data = jp2.read() + jp2.read() self.assertTrue(True) @unittest.skipIf(re.match('[01]\.[34]', OPENJPEG_VERSION), "Segfaults openjpeg 1.4 and earlier.") def test_NR_DEC_broken2_jp2_5_decode(self): + """NR_DEC_broken2_jp2_5_decode""" # Null pointer access jfile = os.path.join(data_root, 'input/nonregression/broken2.jp2') with self.assertRaises(ValueError): with warnings.catch_warnings(): # Library warning, invalid number of subbands. warnings.simplefilter("ignore") - data = Jp2k(jfile).read() + Jp2k(jfile).read() self.assertTrue(True) @unittest.skipIf(sys.hexversion < 0x03020000, "Uses features introduced in 3.2.") def test_NR_DEC_broken3_jp2_6_decode(self): + """NR_DEC_broken3_jp2_6_decode""" jfile = os.path.join(data_root, 'input/nonregression/broken3.jp2') - with self.assertWarns(UserWarning) as cw: + with self.assertWarns(UserWarning): # colr box has bad length. j = Jp2k(jfile) - with self.assertRaises(ValueError) as ce: - d = j.read() + with self.assertRaises(ValueError): + j.read() @unittest.skipIf(re.match('[01]\.[34]', OPENJPEG_VERSION), "Segfaults openjpeg 1.4 and earlier.") def test_NR_DEC_broken4_jp2_7_decode(self): + """NR_DEC_broken4_jp2_7_decode""" # Null pointer access jfile = os.path.join(data_root, 'input/nonregression/broken4.jp2') with self.assertRaises(ValueError): with warnings.catch_warnings(): # Library warning, invalid number of subbands. warnings.simplefilter("ignore") - data = Jp2k(jfile).read() + Jp2k(jfile).read() self.assertTrue(True) @unittest.skip("fprintf stderr output in r2343.") def test_NR_DEC_bug_j2c_8_decode(self): - jfile = os.path.join(data_root, - 'input/nonregression/bug.j2c') - data = Jp2k(jfile).read() + """NR_DEC_bug_j2c_8_decode""" + jfile = os.path.join(data_root, 'input/nonregression/bug.j2c') + Jp2k(jfile).read() self.assertTrue(True) def test_NR_DEC_buxI_j2k_9_decode(self): - jfile = os.path.join(data_root, - 'input/nonregression/buxI.j2k') - data = Jp2k(jfile).read() + """NR_DEC_buxI_j2k_9_decode""" + jfile = os.path.join(data_root, 'input/nonregression/buxI.j2k') + Jp2k(jfile).read() self.assertTrue(True) def test_NR_DEC_buxR_j2k_10_decode(self): - jfile = os.path.join(data_root, - 'input/nonregression/buxR.j2k') - data = Jp2k(jfile).read() + """NR_DEC_buxR_j2k_10_decode""" + jfile = os.path.join(data_root, 'input/nonregression/buxR.j2k') + Jp2k(jfile).read() self.assertTrue(True) def test_NR_DEC_Cannotreaddatawithnosizeknown_j2k_11_decode(self): + """NR_DEC_Cannotreaddatawithnosizeknown_j2k_11_decode""" relpath = 'input/nonregression/Cannotreaddatawithnosizeknown.j2k' jfile = os.path.join(data_root, relpath) - data = Jp2k(jfile).read() + Jp2k(jfile).read() self.assertTrue(True) def test_NR_DEC_cthead1_j2k_12_decode(self): - jfile = os.path.join(data_root, - 'input/nonregression/cthead1.j2k') - data = Jp2k(jfile).read() + """NR_DEC_cthead1_j2k_12_decode""" + jfile = os.path.join(data_root, 'input/nonregression/cthead1.j2k') + Jp2k(jfile).read() self.assertTrue(True) def test_NR_DEC_CT_Phillips_JPEG2K_Decompr_Problem_j2k_13_decode(self): + """NR_DEC_CT_Phillips_JPEG2K_Decompr_Problem_j2k_13_decode""" relpath = 'input/nonregression/CT_Phillips_JPEG2K_Decompr_Problem.j2k' jfile = os.path.join(data_root, relpath) - data = Jp2k(jfile).read() + Jp2k(jfile).read() self.assertTrue(True) @unittest.skip("fprintf stderr output in r2343.") def test_NR_DEC_illegalcolortransform_j2k_14_decode(self): - # Stream too short, expected SOT. + """Stream too short, expected SOT.""" jfile = os.path.join(data_root, 'input/nonregression/illegalcolortransform.j2k') - data = Jp2k(jfile).read() + Jp2k(jfile).read() self.assertTrue(True) def test_NR_DEC_j2k32_j2k_15_decode(self): - jfile = os.path.join(data_root, - 'input/nonregression/j2k32.j2k') - data = Jp2k(jfile).read() + """NR_DEC_j2k32_j2k_15_decode""" + jfile = os.path.join(data_root, 'input/nonregression/j2k32.j2k') + Jp2k(jfile).read() self.assertTrue(True) def test_NR_DEC_kakadu_v4_4_openjpegv2_broken_j2k_16_decode(self): + """NR_DEC_kakadu_v4_4_openjpegv2_broken_j2k_16_decode""" relpath = 'input/nonregression/kakadu_v4-4_openjpegv2_broken.j2k' jfile = os.path.join(data_root, relpath) with warnings.catch_warnings(): # This file has an invalid ICC profile warnings.simplefilter("ignore") - data = Jp2k(jfile).read() + Jp2k(jfile).read() self.assertTrue(True) def test_NR_DEC_MarkerIsNotCompliant_j2k_17_decode(self): + """NR_DEC_MarkerIsNotCompliant_j2k_17_decode""" jfile = os.path.join(data_root, 'input/nonregression/MarkerIsNotCompliant.j2k') - data = Jp2k(jfile).read() + Jp2k(jfile).read() self.assertTrue(True) def test_NR_DEC_Marrin_jp2_18_decode(self): - jfile = os.path.join(data_root, - 'input/nonregression/Marrin.jp2') - data = Jp2k(jfile).read() + """NR_DEC_Marrin_jp2_18_decode""" + jfile = os.path.join(data_root, 'input/nonregression/Marrin.jp2') + Jp2k(jfile).read() self.assertTrue(True) def test_NR_DEC_movie_00000_j2k_20_decode(self): + """test_NR_DEC_movie_00000_j2k_20_decode""" jfile = os.path.join(data_root, 'input/nonregression/movie_00000.j2k') - data = Jp2k(jfile).read() + Jp2k(jfile).read() self.assertTrue(True) def test_NR_DEC_movie_00001_j2k_21_decode(self): + """NR_DEC_movie_00001_j2k_21_decode""" jfile = os.path.join(data_root, 'input/nonregression/movie_00001.j2k') - data = Jp2k(jfile).read() + Jp2k(jfile).read() self.assertTrue(True) def test_NR_DEC_movie_00002_j2k_22_decode(self): - jfile = os.path.join(data_root, - 'input/nonregression/movie_00002.j2k') - data = Jp2k(jfile).read() + """NR_DEC_movie_00002_j2k_22_decode""" + jfile = os.path.join(data_root, 'input/nonregression/movie_00002.j2k') + Jp2k(jfile).read() self.assertTrue(True) def test_NR_DEC_orb_blue_lin_j2k_j2k_23_decode(self): + """NR_DEC_orb_blue_lin_j2k_j2k_23_decode""" jfile = os.path.join(data_root, 'input/nonregression/orb-blue10-lin-j2k.j2k') - data = Jp2k(jfile).read() + Jp2k(jfile).read() self.assertTrue(True) def test_NR_DEC_orb_blue_win_j2k_j2k_24_decode(self): + """NR_DEC_orb_blue_win_j2k_j2k_24_decode""" jfile = os.path.join(data_root, 'input/nonregression/orb-blue10-win-j2k.j2k') - data = Jp2k(jfile).read() + Jp2k(jfile).read() self.assertTrue(True) - def test_NR_DEC_orb_blue_lin_jp2_25_decode(self): + def test_nc_dec_orb_blue_lin_jp2_25_decode(self): + """NR-DEC-orb-blue-lin.jp2-25-decode""" jfile = os.path.join(data_root, 'input/nonregression/orb-blue10-lin-jp2.jp2') with warnings.catch_warnings(): # This file has an invalid ICC profile warnings.simplefilter("ignore") - data = Jp2k(jfile).read() + Jp2k(jfile).read() self.assertTrue(True) - def test_NR_DEC_orb_blue_win_jp2_26_decode(self): + def test_nr_dec_orb_blue_win_jp2_26_decode(self): + """NR-DEC-orb-blue-win.jp2-26-decode""" jfile = os.path.join(data_root, 'input/nonregression/orb-blue10-win-jp2.jp2') - data = Jp2k(jfile).read() + Jp2k(jfile).read() self.assertTrue(True) - def test_NR_DEC_relax_jp2_27_decode(self): + def test_nr_dec_relax_jp2_27_decode(self): + """NR-DEC-relax.jp2-27-decode""" jfile = os.path.join(data_root, 'input/nonregression/relax.jp2') - data = Jp2k(jfile).read() + Jp2k(jfile).read() self.assertTrue(True) - def test_NR_DEC_test_lossless_j2k_28_decode(self): + def test_nr_dec_test_lossless_j2k_28_decode(self): + """NR-DEC-test-lossless.j2k-28-decode""" jfile = os.path.join(data_root, 'input/nonregression/test_lossless.j2k') - data = Jp2k(jfile).read() + Jp2k(jfile).read() self.assertTrue(True) - def test_NR_DEC_issue104_jpxstream_jp2_33_decode(self): + def test_nr_dec_issue104_jpxstream_jp2_33_decode(self): + """NR-DEC-issue104-jpxstream.jp2-33-decode""" jfile = os.path.join(data_root, 'input/nonregression/issue104_jpxstream.jp2') - data = Jp2k(jfile).read() + Jp2k(jfile).read() self.assertTrue(True) - def test_NR_DEC_file_409752_jp2_40_decode(self): + def test_nr_dec_file_409752_jp2_40_decode(self): + """NR-DEC-file-409752.jp2-40-decode""" jfile = os.path.join(data_root, 'input/nonregression/file409752.jp2') j = Jp2k(jfile) - with self.assertRaises(RuntimeError) as ce: - data = j.read() + with self.assertRaises(RuntimeError): + j.read() if __name__ == "__main__": unittest.main() From f55963db81d3164d569b107a20c8292fbc46e013 Mon Sep 17 00:00:00 2001 From: jevans Date: Mon, 12 Aug 2013 19:22:13 -0400 Subject: [PATCH 16/20] pylint work, exposed mantissa, exponent, guard bits in QCC, QCD issue #99 --- CHANGES.txt | 3 + glymur/codestream.py | 18 +- glymur/test/test_opj_suite.py | 643 +++++++++++++++++----------------- 3 files changed, 336 insertions(+), 328 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 42b5b4b..7283bfb 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,3 +1,6 @@ +Aug 11, 2013 - v0.3.1 Exposed mantissa, exponent, and guard_bits fields in QCC + and QCD segments. + Jul 31, 2013 - v0.3.0 Added support for official 2.0.0. Jul 27, 2013 - v0.2.8 Fixed inconsistency regarding configuration diff --git a/glymur/codestream.py b/glymur/codestream.py index bb3caf6..c60bc1b 100644 --- a/glymur/codestream.py +++ b/glymur/codestream.py @@ -1291,18 +1291,18 @@ class QCCsegment(Segment): self.length = length self.offset = offset - self._mantissa, self._exponent = parse_quantization(self.spqcc, + self.mantissa, self.exponent = parse_quantization(self.spqcc, self.sqcc) - self._guard_bits = (self.sqcc & 0xe0) >> 5 + self.guard_bits = (self.sqcc & 0xe0) >> 5 def __str__(self): msg = Segment.__str__(self) msg += '\n Associated Component: {0}'.format(self.cqcc) msg += _print_quantization_style(self.sqcc) - msg += '{0} guard bits'.format(self._guard_bits) + msg += '{0} guard bits'.format(self.guard_bits) - step_size = zip(self._mantissa, self._exponent) + step_size = zip(self.mantissa, self.exponent) msg += '\n Step size: ' + str(list(step_size)) return msg @@ -1339,18 +1339,18 @@ class QCDsegment(Segment): self.offset = offset mantissa, exponent = parse_quantization(self.spqcd, self.sqcd) - self._mantissa = mantissa - self._exponent = exponent - self._guard_bits = (self.sqcd & 0xe0) >> 5 + self.mantissa = mantissa + self.exponent = exponent + self.guard_bits = (self.sqcd & 0xe0) >> 5 def __str__(self): msg = Segment.__str__(self) msg += _print_quantization_style(self.sqcd) - msg += '{0} guard bits'.format(self._guard_bits) + msg += '{0} guard bits'.format(self.guard_bits) - step_size = zip(self._mantissa, self._exponent) + step_size = zip(self.mantissa, self.exponent) msg += '\n Step size: ' + str(list(step_size)) return msg diff --git a/glymur/test/test_opj_suite.py b/glymur/test/test_opj_suite.py index 4106e94..bfefbc6 100644 --- a/glymur/test/test_opj_suite.py +++ b/glymur/test/test_opj_suite.py @@ -7,9 +7,23 @@ suite. # case. # pylint: disable=C0103 +# All of these tests correspond to tests in openjpeg, so no docstring is really +# needed. +# pylint: disable=C0111 + +# This module is very long, cannot be helped. +# pylint: disable=C0302 + # unittest fools pylint with "too many public methods" # pylint: disable=R0904 +# Some tests use numpy test infrastructure, which means the tests never +# reference "self", so pylint claims it should be a function. No, no, no. +# pylint: disable=R0201 + +# Many tests are pretty long and that can't be helped. +# pylint: disable=R0915 + # asserWarns introduced in python 3.2 (python2.7/pylint issue) # pylint: disable=E1101 @@ -31,6 +45,7 @@ import glymur from .fixtures import OPENJPEG_VERSION from .fixtures import OPENJP2_IS_V2_OFFICIAL +from .fixtures import mse, peak_tolerance, read_pgx try: @@ -788,14 +803,14 @@ class TestSuite(unittest.TestCase): jfile = os.path.join(data_root, 'input/nonregression/Bretagne2.j2k') jp2 = Jp2k(jfile) - data = jp2.read() + jp2.read() self.assertTrue(True) def test_NR_DEC__00042_j2k_2_decode(self): jfile = os.path.join(data_root, 'input/nonregression/_00042.j2k') jp2 = Jp2k(jfile) - data = jp2.read() + jp2.read() self.assertTrue(True) @unittest.skip("fprintf stderr output in r2343.") @@ -803,7 +818,7 @@ class TestSuite(unittest.TestCase): jfile = os.path.join(data_root, 'input/nonregression/123.j2c') jp2 = Jp2k(jfile) - data = jp2.read() + jp2.read() self.assertTrue(True) @unittest.skipIf(sys.hexversion < 0x03020000, @@ -811,11 +826,11 @@ class TestSuite(unittest.TestCase): def test_NR_DEC_broken_jp2_4_decode(self): jfile = os.path.join(data_root, 'input/nonregression/broken.jp2') - with self.assertWarns(UserWarning) as cw: + with self.assertWarns(UserWarning): # colr box has bad length. jp2 = Jp2k(jfile) with self.assertRaises(IOError): - data = jp2.read() + jp2.read() self.assertTrue(True) def test_NR_DEC_broken2_jp2_5_decode(self): @@ -825,66 +840,60 @@ class TestSuite(unittest.TestCase): with warnings.catch_warnings(): # Invalid marker ID. warnings.simplefilter("ignore") - data = Jp2k(jfile).read() + Jp2k(jfile).read() self.assertTrue(True) @unittest.skipIf(sys.hexversion < 0x03020000, "Uses features introduced in 3.2.") def test_NR_DEC_broken3_jp2_6_decode(self): - jfile = os.path.join(data_root, - 'input/nonregression/broken3.jp2') - with self.assertWarns(UserWarning) as cw: + jfile = os.path.join(data_root, 'input/nonregression/broken3.jp2') + with self.assertWarns(UserWarning): # colr box has bad length. j = Jp2k(jfile) - with self.assertRaises(IOError) as ce: - d = j.read() + with self.assertRaises(IOError): + j.read() def test_NR_DEC_broken4_jp2_7_decode(self): - jfile = os.path.join(data_root, - 'input/nonregression/broken4.jp2') + jfile = os.path.join(data_root, 'input/nonregression/broken4.jp2') with self.assertRaises(IOError): with warnings.catch_warnings(): # invalid number of subbands, bad marker ID warnings.simplefilter("ignore") - data = Jp2k(jfile).read() + Jp2k(jfile).read() self.assertTrue(True) @unittest.skip("fprintf stderr output in r2343.") def test_NR_DEC_bug_j2c_8_decode(self): - jfile = os.path.join(data_root, - 'input/nonregression/bug.j2c') - data = Jp2k(jfile).read() + jfile = os.path.join(data_root, 'input/nonregression/bug.j2c') + Jp2k(jfile).read() self.assertTrue(True) def test_NR_DEC_buxI_j2k_9_decode(self): - jfile = os.path.join(data_root, - 'input/nonregression/buxI.j2k') - data = Jp2k(jfile).read() + jfile = os.path.join(data_root, 'input/nonregression/buxI.j2k') + Jp2k(jfile).read() self.assertTrue(True) def test_NR_DEC_buxR_j2k_10_decode(self): - jfile = os.path.join(data_root, - 'input/nonregression/buxR.j2k') - data = Jp2k(jfile).read() + jfile = os.path.join(data_root, 'input/nonregression/buxR.j2k') + Jp2k(jfile).read() self.assertTrue(True) def test_NR_DEC_Cannotreaddatawithnosizeknown_j2k_11_decode(self): relpath = 'input/nonregression/Cannotreaddatawithnosizeknown.j2k' jfile = os.path.join(data_root, relpath) - data = Jp2k(jfile).read() + Jp2k(jfile).read() self.assertTrue(True) def test_NR_DEC_cthead1_j2k_12_decode(self): - jfile = os.path.join(data_root, - 'input/nonregression/cthead1.j2k') - data = Jp2k(jfile).read() + jfile = os.path.join(data_root, 'input/nonregression/cthead1.j2k') + Jp2k(jfile).read() self.assertTrue(True) def test_NR_DEC_CT_Phillips_JPEG2K_Decompr_Problem_j2k_13_decode(self): relpath = 'input/nonregression/CT_Phillips_JPEG2K_Decompr_Problem.j2k' jfile = os.path.join(data_root, relpath) - data = Jp2k(jfile).read() + Jp2k(jfile).read() self.assertTrue(True) @unittest.skip("fprintf stderr output in r2343.") @@ -892,67 +901,64 @@ class TestSuite(unittest.TestCase): # Stream too short, expected SOT. jfile = os.path.join(data_root, 'input/nonregression/illegalcolortransform.j2k') - data = Jp2k(jfile).read() + Jp2k(jfile).read() self.assertTrue(True) def test_NR_DEC_j2k32_j2k_15_decode(self): - jfile = os.path.join(data_root, - 'input/nonregression/j2k32.j2k') - data = Jp2k(jfile).read() + jfile = os.path.join(data_root, 'input/nonregression/j2k32.j2k') + Jp2k(jfile).read() self.assertTrue(True) def test_NR_DEC_kakadu_v4_4_openjpegv2_broken_j2k_16_decode(self): relpath = 'input/nonregression/kakadu_v4-4_openjpegv2_broken.j2k' jfile = os.path.join(data_root, relpath) - data = Jp2k(jfile).read() + Jp2k(jfile).read() self.assertTrue(True) def test_NR_DEC_MarkerIsNotCompliant_j2k_17_decode(self): jfile = os.path.join(data_root, 'input/nonregression/MarkerIsNotCompliant.j2k') - data = Jp2k(jfile).read() + Jp2k(jfile).read() self.assertTrue(True) def test_NR_DEC_Marrin_jp2_18_decode(self): jfile = os.path.join(data_root, 'input/nonregression/Marrin.jp2') - data = Jp2k(jfile).read() + Jp2k(jfile).read() self.assertTrue(True) def test_NR_DEC_merged_jp2_19_decode(self): jfile = os.path.join(data_root, 'input/nonregression/merged.jp2') - data = Jp2k(jfile).read_bands() + Jp2k(jfile).read_bands() self.assertTrue(True) def test_NR_DEC_movie_00000_j2k_20_decode(self): jfile = os.path.join(data_root, 'input/nonregression/movie_00000.j2k') - data = Jp2k(jfile).read() + Jp2k(jfile).read() self.assertTrue(True) def test_NR_DEC_movie_00001_j2k_21_decode(self): - jfile = os.path.join(data_root, - 'input/nonregression/movie_00001.j2k') - data = Jp2k(jfile).read() + jfile = os.path.join(data_root, 'input/nonregression/movie_00001.j2k') + Jp2k(jfile).read() self.assertTrue(True) def test_NR_DEC_movie_00002_j2k_22_decode(self): - jfile = os.path.join(data_root, - 'input/nonregression/movie_00002.j2k') - data = Jp2k(jfile).read() + jfile = os.path.join(data_root, 'input/nonregression/movie_00002.j2k') + Jp2k(jfile).read() self.assertTrue(True) def test_NR_DEC_orb_blue_lin_j2k_j2k_23_decode(self): jfile = os.path.join(data_root, 'input/nonregression/orb-blue10-lin-j2k.j2k') - data = Jp2k(jfile).read() + Jp2k(jfile).read() self.assertTrue(True) def test_NR_DEC_orb_blue_win_j2k_j2k_24_decode(self): jfile = os.path.join(data_root, 'input/nonregression/orb-blue10-win-j2k.j2k') - data = Jp2k(jfile).read() + Jp2k(jfile).read() self.assertTrue(True) def test_NR_DEC_orb_blue_lin_jp2_25_decode(self): @@ -961,25 +967,25 @@ class TestSuite(unittest.TestCase): with warnings.catch_warnings(): # This file has an invalid ICC profile warnings.simplefilter("ignore") - data = Jp2k(jfile).read() + Jp2k(jfile).read() self.assertTrue(True) def test_NR_DEC_orb_blue_win_jp2_26_decode(self): jfile = os.path.join(data_root, 'input/nonregression/orb-blue10-win-jp2.jp2') - data = Jp2k(jfile).read() + Jp2k(jfile).read() self.assertTrue(True) def test_NR_DEC_relax_jp2_27_decode(self): jfile = os.path.join(data_root, 'input/nonregression/relax.jp2') - data = Jp2k(jfile).read() + Jp2k(jfile).read() self.assertTrue(True) def test_NR_DEC_test_lossless_j2k_28_decode(self): jfile = os.path.join(data_root, 'input/nonregression/test_lossless.j2k') - data = Jp2k(jfile).read() + Jp2k(jfile).read() self.assertTrue(True) @unittest.skipIf(OPENJP2_IS_V2_OFFICIAL, @@ -991,13 +997,13 @@ class TestSuite(unittest.TestCase): # brand is 'jp2 ', but has any icc profile. warnings.simplefilter("ignore") jp2 = Jp2k(jfile) - data = jp2.read() + jp2.read() self.assertTrue(True) def test_NR_DEC_pacs_ge_j2k_30_decode(self): jfile = os.path.join(data_root, 'input/nonregression/pacs.ge.j2k') - data = Jp2k(jfile).read() + Jp2k(jfile).read() self.assertTrue(True) @unittest.skipIf(OPENJP2_IS_V2_OFFICIAL, @@ -1005,7 +1011,7 @@ class TestSuite(unittest.TestCase): def test_NR_DEC_kodak_2layers_lrcp_j2c_31_decode(self): jfile = os.path.join(data_root, 'input/nonregression/kodak_2layers_lrcp.j2c') - data = Jp2k(jfile).read() + Jp2k(jfile).read() self.assertTrue(True) @unittest.skipIf(OPENJP2_IS_V2_OFFICIAL, @@ -1013,13 +1019,13 @@ class TestSuite(unittest.TestCase): def test_NR_DEC_kodak_2layers_lrcp_j2c_32_decode(self): jfile = os.path.join(data_root, 'input/nonregression/kodak_2layers_lrcp.j2c') - data = Jp2k(jfile).read(layer=2) + Jp2k(jfile).read(layer=2) self.assertTrue(True) def test_NR_DEC_issue104_jpxstream_jp2_33_decode(self): jfile = os.path.join(data_root, 'input/nonregression/issue104_jpxstream.jp2') - data = Jp2k(jfile).read() + Jp2k(jfile).read() self.assertTrue(True) @unittest.skipIf(OPENJP2_IS_V2_OFFICIAL, @@ -1031,7 +1037,7 @@ class TestSuite(unittest.TestCase): # This file has a bad pclr box, we test for this elsewhere. warnings.simplefilter("ignore") j = Jp2k(jfile) - data = j.read() + j.read() self.assertTrue(True) @unittest.skipIf(OPENJP2_IS_V2_OFFICIAL, @@ -1039,7 +1045,7 @@ class TestSuite(unittest.TestCase): def test_NR_DEC_mem_b2b86b74_2753_jp2_35_decode(self): jfile = os.path.join(data_root, 'input/nonregression/mem-b2b86b74-2753.jp2') - data = Jp2k(jfile).read() + Jp2k(jfile).read() self.assertTrue(True) def test_NR_DEC_gdal_fuzzer_unchecked_num_resolutions_jp2_36_decode(self): @@ -1050,7 +1056,7 @@ class TestSuite(unittest.TestCase): warnings.simplefilter("ignore") j = Jp2k(jfile) with self.assertRaises(IOError): - data = j.read() + j.read() @unittest.skipIf(OPENJP2_IS_V2_OFFICIAL, "Test not in done in v2.0.0 official") @@ -1064,7 +1070,7 @@ class TestSuite(unittest.TestCase): warnings.simplefilter("ignore") j = Jp2k(jfile) with self.assertRaises(IOError): - data = j.read() + j.read() @unittest.skipIf(OPENJP2_IS_V2_OFFICIAL, "Test not in done in v2.0.0 official") @@ -1076,7 +1082,7 @@ class TestSuite(unittest.TestCase): warnings.simplefilter("ignore") j = Jp2k(jfile) with self.assertRaises(IOError): - data = j.read() + j.read() @unittest.skipIf(OPENJP2_IS_V2_OFFICIAL, "Test not in done in v2.0.0 official") @@ -1087,13 +1093,12 @@ class TestSuite(unittest.TestCase): # Invalid subsampling value warnings.simplefilter("ignore") with self.assertRaises(IOError): - j = Jp2k(jfile).read() + Jp2k(jfile).read() def test_NR_DEC_file_409752_jp2_40_decode(self): - jfile = os.path.join(data_root, - 'input/nonregression/file409752.jp2') + jfile = os.path.join(data_root, 'input/nonregression/file409752.jp2') with self.assertRaises(RuntimeError): - data = Jp2k(jfile).read() + Jp2k(jfile).read() @unittest.skipIf(OPENJP2_IS_V2_OFFICIAL, "Test not in done in v2.0.0 official") @@ -1104,15 +1109,15 @@ class TestSuite(unittest.TestCase): # really does deserve a warning. relpath = 'input/nonregression/issue188_beach_64bitsbox.jp2' jfile = os.path.join(data_root, relpath) - with self.assertWarns(UserWarning) as cw: - data = Jp2k(jfile).read() + with self.assertWarns(UserWarning): + Jp2k(jfile).read() @unittest.skipIf(OPENJP2_IS_V2_OFFICIAL, "Test not in done in v2.0.0 official") def test_NR_DEC_issue206_image_000_jp2_42_decode(self): jfile = os.path.join(data_root, 'input/nonregression/issue206_image-000.jp2') - data = Jp2k(jfile).read() + Jp2k(jfile).read() self.assertTrue(True) def test_NR_DEC_p1_04_j2k_43_decode(self): @@ -1347,8 +1352,8 @@ class TestSuite(unittest.TestCase): # Image size would be 0 x 0. jfile = os.path.join(data_root, 'input/conformance/p1_06.j2k') jp2k = Jp2k(jfile) - with self.assertRaises((IOError, OSError)) as ce: - ssdata = jp2k.read(area=(9, 9, 12, 12), rlevel=2) + with self.assertRaises((IOError, OSError)): + jp2k.read(area=(9, 9, 12, 12), rlevel=2) @unittest.skip("fprintf stderr output in r2343.") def test_NR_DEC_p1_06_j2k_76_decode(self): @@ -1393,7 +1398,7 @@ class TestSuite(unittest.TestCase): jp2k = Jp2k(jfile) with warnings.catch_warnings(): warnings.simplefilter("ignore") - tiledata = jp2k.read(tile=0, rlevel=2) + jp2k.read(tile=0, rlevel=2) @unittest.skip("fprintf stderr output in r2343.") def test_NR_DEC_p1_06_j2k_81_decode(self): @@ -1402,7 +1407,7 @@ class TestSuite(unittest.TestCase): jp2k = Jp2k(jfile) with warnings.catch_warnings(): warnings.simplefilter("ignore") - tiledata = jp2k.read(tile=5, rlevel=2) + jp2k.read(tile=5, rlevel=2) @unittest.skip("fprintf stderr output in r2343.") def test_NR_DEC_p1_06_j2k_82_decode(self): @@ -1411,7 +1416,7 @@ class TestSuite(unittest.TestCase): jp2k = Jp2k(jfile) with warnings.catch_warnings(): warnings.simplefilter("ignore") - tiledata = jp2k.read(tile=9, rlevel=2) + jp2k.read(tile=9, rlevel=2) @unittest.skip("fprintf stderr output in r2343.") def test_NR_DEC_p1_06_j2k_83_decode(self): @@ -1420,15 +1425,15 @@ class TestSuite(unittest.TestCase): jp2k = Jp2k(jfile) with warnings.catch_warnings(): warnings.simplefilter("ignore") - with self.assertRaises((IOError, OSError)) as ce: - tiledata = jp2k.read(tile=15, rlevel=2) + with self.assertRaises((IOError, OSError)): + jp2k.read(tile=15, rlevel=2) @unittest.skip("fprintf stderr output in r2343.") def test_NR_DEC_p1_06_j2k_84_decode(self): # Just read the data, don't bother verifying. jfile = os.path.join(data_root, 'input/conformance/p1_06.j2k') jp2k = Jp2k(jfile) - data = jp2k.read(rlevel=4) + jp2k.read(rlevel=4) def test_NR_DEC_p0_04_j2k_85_decode(self): jfile = os.path.join(data_root, 'input/conformance/p0_04.j2k') @@ -1556,10 +1561,10 @@ class TestSuiteDump(unittest.TestCase): # QCD: Quantization default self.assertEqual(c.segment[2].sqcd & 0x1f, 0) - self.assertEqual(c.segment[2]._guard_bits, 2) - self.assertEqual(c.segment[2]._exponent, + self.assertEqual(c.segment[2].guard_bits, 2) + self.assertEqual(c.segment[2].exponent, [8, 9, 9, 10, 9, 9, 10, 9, 9, 10]) - self.assertEqual(c.segment[2]._mantissa, + self.assertEqual(c.segment[2].mantissa, [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) # COD: Coding style default @@ -1663,10 +1668,10 @@ class TestSuiteDump(unittest.TestCase): # QCD: Quantization default # quantization type self.assertEqual(c.segment[4].sqcd & 0x1f, 0) # none - self.assertEqual(c.segment[4]._guard_bits, 3) - self.assertEqual(c.segment[4]._exponent, + self.assertEqual(c.segment[4].guard_bits, 3) + self.assertEqual(c.segment[4].exponent, [8, 9, 9, 10, 9, 9, 10, 9, 9, 10]) - self.assertEqual(c.segment[4]._mantissa, + self.assertEqual(c.segment[4].mantissa, [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) # COM: comment @@ -1749,18 +1754,18 @@ class TestSuiteDump(unittest.TestCase): # QCD: Quantization default # quantization type self.assertEqual(c.segment[3].sqcd & 0x1f, 1) # scalar implicit - self.assertEqual(c.segment[3]._guard_bits, 2) - self.assertEqual(c.segment[3]._exponent, [0]) - self.assertEqual(c.segment[3]._mantissa, [0]) + self.assertEqual(c.segment[3].guard_bits, 2) + self.assertEqual(c.segment[3].exponent, [0]) + self.assertEqual(c.segment[3].mantissa, [0]) # QCC: Quantization component # associated component self.assertEqual(c.segment[4].cqcc, 0) - self.assertEqual(c.segment[4]._guard_bits, 2) + self.assertEqual(c.segment[4].guard_bits, 2) # quantization type self.assertEqual(c.segment[4].sqcc & 0x1f, 0) # none - self.assertEqual(c.segment[4]._exponent, [4, 5, 5, 6]) - self.assertEqual(c.segment[4]._mantissa, [0, 0, 0, 0]) + self.assertEqual(c.segment[4].exponent, [4, 5, 5, 6]) + self.assertEqual(c.segment[4].mantissa, [0, 0, 0, 0]) # POD: progression order change self.assertEqual(c.segment[5].rspod, (0,)) @@ -1869,11 +1874,11 @@ class TestSuiteDump(unittest.TestCase): # QCD: Quantization default # quantization type self.assertEqual(c.segment[3].sqcd & 0x1f, 2) # scalar expounded - self.assertEqual(c.segment[3]._guard_bits, 3) - self.assertEqual(c.segment[3]._exponent, + self.assertEqual(c.segment[3].guard_bits, 3) + self.assertEqual(c.segment[3].exponent, [16, 16, 16, 16, 15, 15, 15, 14, 14, 14, 13, 13, 13, 11, 11, 11, 11, 11, 11]) - self.assertEqual(c.segment[3]._mantissa, + self.assertEqual(c.segment[3].mantissa, [1814, 1815, 1815, 1817, 1821, 1821, 1827, 1845, 1845, 1868, 1925, 1925, 2007, 32, 32, 131, 2002, 2002, 1888]) @@ -1883,11 +1888,11 @@ class TestSuiteDump(unittest.TestCase): self.assertEqual(c.segment[4].cqcc, 1) # quantization type self.assertEqual(c.segment[4].sqcc & 0x1f, 2) # none - self.assertEqual(c.segment[4]._guard_bits, 3) - self.assertEqual(c.segment[4]._exponent, + self.assertEqual(c.segment[4].guard_bits, 3) + self.assertEqual(c.segment[4].exponent, [14, 14, 14, 14, 13, 13, 13, 12, 12, 12, 11, 11, 11, 9, 9, 9, 9, 9, 9]) - self.assertEqual(c.segment[4]._mantissa, + self.assertEqual(c.segment[4].mantissa, [1814, 1815, 1815, 1817, 1821, 1821, 1827, 1845, 1845, 1868, 1925, 1925, 2007, 32, 32, 131, 2002, 2002, 1888]) @@ -1897,11 +1902,11 @@ class TestSuiteDump(unittest.TestCase): self.assertEqual(c.segment[5].cqcc, 2) # quantization type self.assertEqual(c.segment[5].sqcc & 0x1f, 2) # none - self.assertEqual(c.segment[5]._guard_bits, 3) - self.assertEqual(c.segment[5]._exponent, + self.assertEqual(c.segment[5].guard_bits, 3) + self.assertEqual(c.segment[5].exponent, [14, 14, 14, 14, 13, 13, 13, 12, 12, 12, 11, 11, 11, 9, 9, 9, 9, 9, 9]) - self.assertEqual(c.segment[5]._mantissa, + self.assertEqual(c.segment[5].mantissa, [1814, 1815, 1815, 1817, 1821, 1821, 1827, 1845, 1845, 1868, 1925, 1925, 2007, 32, 32, 131, 2002, 2002, 1888]) @@ -2016,11 +2021,11 @@ class TestSuiteDump(unittest.TestCase): # QCD: Quantization default # quantization type self.assertEqual(c.segment[5].sqcd & 0x1f, 2) # scalar expounded - self.assertEqual(c.segment[5]._guard_bits, 3) - self.assertEqual(c.segment[5]._exponent, + self.assertEqual(c.segment[5].guard_bits, 3) + self.assertEqual(c.segment[5].exponent, [16, 16, 16, 16, 15, 15, 15, 14, 14, 14, 13, 13, 13, 11, 11, 11, 11, 11, 11]) - self.assertEqual(c.segment[5]._mantissa, + self.assertEqual(c.segment[5].mantissa, [1814, 1815, 1815, 1817, 1821, 1821, 1827, 1845, 1845, 1868, 1925, 1925, 2007, 32, 32, 131, 2002, 2002, 1888]) @@ -2030,20 +2035,20 @@ class TestSuiteDump(unittest.TestCase): self.assertEqual(c.segment[6].cqcc, 0) # quantization type self.assertEqual(c.segment[6].sqcc & 0x1f, 1) # scalar derived - self.assertEqual(c.segment[6]._guard_bits, 3) - self.assertEqual(c.segment[6]._exponent, [14]) - self.assertEqual(c.segment[6]._mantissa, [0]) + self.assertEqual(c.segment[6].guard_bits, 3) + self.assertEqual(c.segment[6].exponent, [14]) + self.assertEqual(c.segment[6].mantissa, [0]) # QCC: Quantization component # associated component self.assertEqual(c.segment[7].cqcc, 3) # quantization type self.assertEqual(c.segment[7].sqcc & 0x1f, 0) # none - self.assertEqual(c.segment[7]._guard_bits, 3) - self.assertEqual(c.segment[7]._exponent, + self.assertEqual(c.segment[7].guard_bits, 3) + self.assertEqual(c.segment[7].exponent, [8, 9, 9, 10, 9, 9, 10, 9, 9, 10, 9, 9, 10, 9, 9, 10, 9, 9, 10]) - self.assertEqual(c.segment[7]._mantissa, [0] * 19) + self.assertEqual(c.segment[7].mantissa, [0] * 19) # COM: comment # Registration @@ -2119,11 +2124,11 @@ class TestSuiteDump(unittest.TestCase): # QCD: Quantization default # quantization type self.assertEqual(c.segment[3].sqcd & 0x1f, 2) # scalar expounded - self.assertEqual(c.segment[3]._guard_bits, 3) - self.assertEqual(c.segment[3]._mantissa, + self.assertEqual(c.segment[3].guard_bits, 3) + self.assertEqual(c.segment[3].mantissa, [512, 518, 522, 524, 516, 524, 522, 527, 523, 549, 557, 561, 853, 852, 700, 163, 78, 1508, 1831]) - self.assertEqual(c.segment[3]._exponent, + self.assertEqual(c.segment[3].exponent, [7, 7, 7, 7, 6, 6, 6, 5, 5, 5, 4, 4, 4, 3, 3, 2, 1, 2, 1]) @@ -2132,11 +2137,11 @@ class TestSuiteDump(unittest.TestCase): self.assertEqual(c.segment[4].cqcc, 1) # quantization type self.assertEqual(c.segment[4].sqcc & 0x1f, 2) # scalar derived - self.assertEqual(c.segment[4]._guard_bits, 4) - self.assertEqual(c.segment[4]._mantissa, + self.assertEqual(c.segment[4].guard_bits, 4) + self.assertEqual(c.segment[4].mantissa, [1527, 489, 665, 506, 487, 502, 493, 493, 500, 485, 505, 491, 490, 491, 499, 509, 503, 496, 558]) - self.assertEqual(c.segment[4]._exponent, + self.assertEqual(c.segment[4].exponent, [10, 10, 10, 10, 9, 9, 9, 8, 8, 8, 7, 7, 7, 6, 6, 6, 5, 5, 5]) @@ -2145,11 +2150,11 @@ class TestSuiteDump(unittest.TestCase): self.assertEqual(c.segment[5].cqcc, 2) # quantization type self.assertEqual(c.segment[5].sqcc & 0x1f, 2) # scalar derived - self.assertEqual(c.segment[5]._guard_bits, 5) - self.assertEqual(c.segment[5]._mantissa, + self.assertEqual(c.segment[5].guard_bits, 5) + self.assertEqual(c.segment[5].mantissa, [1337, 728, 890, 719, 716, 726, 700, 718, 704, 704, 712, 712, 717, 719, 701, 749, 753, 718, 841]) - self.assertEqual(c.segment[5]._exponent, + self.assertEqual(c.segment[5].exponent, [10, 10, 10, 10, 9, 9, 9, 8, 8, 8, 7, 7, 7, 6, 6, 6, 5, 5, 5]) @@ -2158,9 +2163,9 @@ class TestSuiteDump(unittest.TestCase): self.assertEqual(c.segment[6].cqcc, 3) # quantization type self.assertEqual(c.segment[6].sqcc & 0x1f, 0) # none - self.assertEqual(c.segment[6]._guard_bits, 6) - self.assertEqual(c.segment[6]._mantissa, [0] * 19) - self.assertEqual(c.segment[6]._exponent, + self.assertEqual(c.segment[6].guard_bits, 6) + self.assertEqual(c.segment[6].mantissa, [0] * 19) + self.assertEqual(c.segment[6].exponent, [12, 13, 13, 14, 13, 13, 14, 13, 13, 14, 13, 13, 14, 13, 13, 14, 13, 13, 14]) @@ -2256,9 +2261,9 @@ class TestSuiteDump(unittest.TestCase): # QCD: Quantization default # quantization type self.assertEqual(c.segment[3].sqcd & 0x1f, 0) # none - self.assertEqual(c.segment[3]._guard_bits, 1) - self.assertEqual(c.segment[3]._mantissa, [0] * 10) - self.assertEqual(c.segment[3]._exponent, + self.assertEqual(c.segment[3].guard_bits, 1) + self.assertEqual(c.segment[3].mantissa, [0] * 10) + self.assertEqual(c.segment[3].exponent, [14, 15, 15, 16, 15, 15, 16, 15, 15, 16]) # COM: comment @@ -2401,9 +2406,9 @@ class TestSuiteDump(unittest.TestCase): # QCD: Quantization default # quantization type self.assertEqual(c.segment[6].sqcd & 0x1f, 0) # none - self.assertEqual(c.segment[6]._guard_bits, 4) - self.assertEqual(c.segment[6]._mantissa, [0] * 22) - self.assertEqual(c.segment[6]._exponent, + self.assertEqual(c.segment[6].guard_bits, 4) + self.assertEqual(c.segment[6].mantissa, [0] * 22) + self.assertEqual(c.segment[6].exponent, [11, 12, 12, 13, 12, 12, 13, 12, 12, 13, 12, 12, 13, 12, 12, 13, 12, 12, 13, 12, 12, 13]) @@ -2412,9 +2417,9 @@ class TestSuiteDump(unittest.TestCase): self.assertEqual(c.segment[7].cqcc, 0) # quantization type self.assertEqual(c.segment[7].sqcc & 0x1f, 0) # none - self.assertEqual(c.segment[7]._guard_bits, 4) - self.assertEqual(c.segment[7]._mantissa, [0] * 19) - self.assertEqual(c.segment[7]._exponent, + self.assertEqual(c.segment[7].guard_bits, 4) + self.assertEqual(c.segment[7].mantissa, [0] * 19) + self.assertEqual(c.segment[7].exponent, [11, 12, 12, 13, 12, 12, 13, 12, 12, 13, 12, 12, 13, 12, 12, 13, 12, 12, 13]) @@ -2423,9 +2428,9 @@ class TestSuiteDump(unittest.TestCase): self.assertEqual(c.segment[8].cqcc, 2) # quantization type self.assertEqual(c.segment[8].sqcc & 0x1f, 0) # none - self.assertEqual(c.segment[8]._guard_bits, 4) - self.assertEqual(c.segment[8]._mantissa, [0] * 25) - self.assertEqual(c.segment[8]._exponent, + self.assertEqual(c.segment[8].guard_bits, 4) + self.assertEqual(c.segment[8].mantissa, [0] * 25) + self.assertEqual(c.segment[8].exponent, [11, 12, 12, 13, 12, 12, 13, 12, 12, 13, 12, 12, 13, 12, 12, 13, 12, 12, 13, 12, 12, 13, 12, 12, 13]) @@ -2494,11 +2499,11 @@ class TestSuiteDump(unittest.TestCase): # QCD: Quantization default # quantization type self.assertEqual(c.segment[3].sqcd & 0x1f, 2) # scalar expounded - self.assertEqual(c.segment[3]._guard_bits, 1) - self.assertEqual(c.segment[3]._mantissa, + self.assertEqual(c.segment[3].guard_bits, 1) + self.assertEqual(c.segment[3].mantissa, [1915, 1884, 1884, 1853, 1884, 1884, 1853, 1962, 1962, 1986, 53, 53, 120, 26, 26, 1983]) - self.assertEqual(c.segment[3]._exponent, + self.assertEqual(c.segment[3].exponent, [16, 16, 16, 16, 15, 15, 15, 14, 14, 14, 12, 12, 12, 11, 11, 12]) @@ -2574,9 +2579,9 @@ class TestSuiteDump(unittest.TestCase): # QCD: Quantization default # quantization type self.assertEqual(c.segment[3].sqcd & 0x1f, 0) # none - self.assertEqual(c.segment[3]._guard_bits, 0) - self.assertEqual(c.segment[3]._mantissa, [0] * 10) - self.assertEqual(c.segment[3]._exponent, + self.assertEqual(c.segment[3].guard_bits, 0) + self.assertEqual(c.segment[3].mantissa, [0] * 10) + self.assertEqual(c.segment[3].exponent, [11, 12, 12, 13, 12, 12, 13, 12, 12, 13]) # SOT: start of tile part @@ -2715,9 +2720,9 @@ class TestSuiteDump(unittest.TestCase): # QCD: Quantization default # quantization type self.assertEqual(c.segment[3].sqcd & 0x1f, 0) # none - self.assertEqual(c.segment[3]._guard_bits, 3) - self.assertEqual(c.segment[3]._mantissa, [0]) - self.assertEqual(c.segment[3]._exponent, [8]) + self.assertEqual(c.segment[3].guard_bits, 3) + self.assertEqual(c.segment[3].mantissa, [0]) + self.assertEqual(c.segment[3].exponent, [8]) # COM: comment # Registration @@ -2796,9 +2801,9 @@ class TestSuiteDump(unittest.TestCase): # QCD: Quantization default # quantization type self.assertEqual(c.segment[3].sqcd & 0x1f, 0) # none - self.assertEqual(c.segment[3]._guard_bits, 3) - self.assertEqual(c.segment[3]._mantissa, [0] * 10) - self.assertEqual(c.segment[3]._exponent, + self.assertEqual(c.segment[3].guard_bits, 3) + self.assertEqual(c.segment[3].mantissa, [0] * 10) + self.assertEqual(c.segment[3].exponent, [8, 9, 9, 10, 9, 9, 10, 9, 9, 10]) # COM: comment @@ -2896,28 +2901,28 @@ class TestSuiteDump(unittest.TestCase): # QCD: Quantization default # quantization type self.assertEqual(c.segment[4].sqcd & 0x1f, 0) # none - self.assertEqual(c.segment[4]._guard_bits, 2) - self.assertEqual(c.segment[4]._mantissa, [0] * 4) - self.assertEqual(c.segment[4]._exponent, + self.assertEqual(c.segment[4].guard_bits, 2) + self.assertEqual(c.segment[4].mantissa, [0] * 4) + self.assertEqual(c.segment[4].exponent, [8, 9, 9, 10]) # QCC: Quantization component # associated component self.assertEqual(c.segment[5].cqcc, 1) - self.assertEqual(c.segment[5]._guard_bits, 3) + self.assertEqual(c.segment[5].guard_bits, 3) # quantization type self.assertEqual(c.segment[5].sqcc & 0x1f, 0) # none - self.assertEqual(c.segment[5]._exponent, [9, 10, 10, 11]) - self.assertEqual(c.segment[5]._mantissa, [0, 0, 0, 0]) + self.assertEqual(c.segment[5].exponent, [9, 10, 10, 11]) + self.assertEqual(c.segment[5].mantissa, [0, 0, 0, 0]) # QCC: Quantization component # associated component self.assertEqual(c.segment[6].cqcc, 2) - self.assertEqual(c.segment[6]._guard_bits, 2) + self.assertEqual(c.segment[6].guard_bits, 2) # quantization type self.assertEqual(c.segment[6].sqcc & 0x1f, 0) # none - self.assertEqual(c.segment[6]._exponent, [9, 10, 10, 11]) - self.assertEqual(c.segment[6]._mantissa, [0, 0, 0, 0]) + self.assertEqual(c.segment[6].exponent, [9, 10, 10, 11]) + self.assertEqual(c.segment[6].mantissa, [0, 0, 0, 0]) # RGN: region of interest self.assertEqual(c.segment[7].crgn, 3) @@ -3003,9 +3008,9 @@ class TestSuiteDump(unittest.TestCase): # QCD: Quantization default # quantization type self.assertEqual(c.segment[3].sqcd & 0x1f, 0) # none - self.assertEqual(c.segment[3]._guard_bits, 1) - self.assertEqual(c.segment[3]._mantissa, [0] * 16) - self.assertEqual(c.segment[3]._exponent, + self.assertEqual(c.segment[3].guard_bits, 1) + self.assertEqual(c.segment[3].mantissa, [0] * 16) + self.assertEqual(c.segment[3].exponent, [10, 11, 11, 12, 11, 11, 12, 11, 11, 12, 11, 11, 12, 11, 11, 12]) @@ -3079,18 +3084,18 @@ class TestSuiteDump(unittest.TestCase): # QCD: Quantization default # quantization type self.assertEqual(c.segment[3].sqcd & 0x1f, 1) # derived - self.assertEqual(c.segment[3]._guard_bits, 2) - self.assertEqual(c.segment[3]._mantissa, [0]) - self.assertEqual(c.segment[3]._exponent, [0]) + self.assertEqual(c.segment[3].guard_bits, 2) + self.assertEqual(c.segment[3].mantissa, [0]) + self.assertEqual(c.segment[3].exponent, [0]) # QCC: Quantization component # associated component self.assertEqual(c.segment[4].cqcc, 0) - self.assertEqual(c.segment[4]._guard_bits, 2) + self.assertEqual(c.segment[4].guard_bits, 2) # quantization type self.assertEqual(c.segment[4].sqcc & 0x1f, 0) # none - self.assertEqual(c.segment[4]._mantissa, [0] * 4) - self.assertEqual(c.segment[4]._exponent, [4, 5, 5, 6]) + self.assertEqual(c.segment[4].mantissa, [0] * 4) + self.assertEqual(c.segment[4].exponent, [4, 5, 5, 6]) # POD: progression order change self.assertEqual(c.segment[5].rspod, (0,)) @@ -3233,9 +3238,9 @@ class TestSuiteDump(unittest.TestCase): # QCD: Quantization default # quantization type self.assertEqual(c.segment[3].sqcd & 0x1f, 0) # none - self.assertEqual(c.segment[3]._guard_bits, 2) - self.assertEqual(c.segment[3]._mantissa, [0] * 10) - self.assertEqual(c.segment[3]._exponent, + self.assertEqual(c.segment[3].guard_bits, 2) + self.assertEqual(c.segment[3].mantissa, [0] * 10) + self.assertEqual(c.segment[3].exponent, [8, 9, 9, 10, 9, 9, 10, 9, 9, 10]) # SOT: start of tile part @@ -3320,9 +3325,9 @@ class TestSuiteDump(unittest.TestCase): # QCD: Quantization default # quantization type self.assertEqual(c.segment[4].sqcd & 0x1f, 0) # none - self.assertEqual(c.segment[4]._guard_bits, 3) - self.assertEqual(c.segment[4]._mantissa, [0] * 10) - self.assertEqual(c.segment[4]._exponent, + self.assertEqual(c.segment[4].guard_bits, 3) + self.assertEqual(c.segment[4].mantissa, [0] * 10) + self.assertEqual(c.segment[4].exponent, [8, 9, 9, 10, 9, 9, 10, 9, 9, 10]) # COM: comment @@ -3404,40 +3409,40 @@ class TestSuiteDump(unittest.TestCase): # QCD: Quantization default # quantization type self.assertEqual(c.segment[3].sqcd & 0x1f, 2) # expounded - self.assertEqual(c.segment[3]._guard_bits, 3) - self.assertEqual(c.segment[3]._mantissa, + self.assertEqual(c.segment[3].guard_bits, 3) + self.assertEqual(c.segment[3].mantissa, [1814, 1815, 1815, 1817, 1821, 1821, 1827, 1845, 1845, 1868, 1925, 1925, 2007, 32, 32, 131, 2002, 2002, 1888]) - self.assertEqual(c.segment[3]._exponent, + self.assertEqual(c.segment[3].exponent, [16, 16, 16, 16, 15, 15, 15, 14, 14, 14, 13, 13, 13, 11, 11, 11, 11, 11, 11]) # QCC: Quantization component # associated component self.assertEqual(c.segment[4].cqcc, 1) - self.assertEqual(c.segment[4]._guard_bits, 3) + self.assertEqual(c.segment[4].guard_bits, 3) # quantization type self.assertEqual(c.segment[4].sqcc & 0x1f, 2) # expounded - self.assertEqual(c.segment[4]._mantissa, + self.assertEqual(c.segment[4].mantissa, [1814, 1815, 1815, 1817, 1821, 1821, 1827, 1845, 1845, 1868, 1925, 1925, 2007, 32, 32, 131, 2002, 2002, 1888]) - self.assertEqual(c.segment[4]._exponent, + self.assertEqual(c.segment[4].exponent, [14, 14, 14, 14, 13, 13, 13, 12, 12, 12, 11, 11, 11, 9, 9, 9, 9, 9, 9]) # QCC: Quantization component # associated component self.assertEqual(c.segment[5].cqcc, 2) - self.assertEqual(c.segment[5]._guard_bits, 3) + self.assertEqual(c.segment[5].guard_bits, 3) # quantization type self.assertEqual(c.segment[5].sqcc & 0x1f, 2) # expounded - self.assertEqual(c.segment[5]._mantissa, + self.assertEqual(c.segment[5].mantissa, [1814, 1815, 1815, 1817, 1821, 1821, 1827, 1845, 1845, 1868, 1925, 1925, 2007, 32, 32, 131, 2002, 2002, 1888]) - self.assertEqual(c.segment[5]._exponent, + self.assertEqual(c.segment[5].exponent, [14, 14, 14, 14, 13, 13, 13, 12, 12, 12, 11, 11, 11, 9, 9, 9, 9, 9, 9]) @@ -3554,32 +3559,32 @@ class TestSuiteDump(unittest.TestCase): # QCD: Quantization default # quantization type self.assertEqual(c.segment[5].sqcd & 0x1f, 2) # expounded - self.assertEqual(c.segment[5]._guard_bits, 3) - self.assertEqual(c.segment[5]._mantissa, + self.assertEqual(c.segment[5].guard_bits, 3) + self.assertEqual(c.segment[5].mantissa, [1814, 1815, 1815, 1817, 1821, 1821, 1827, 1845, 1845, 1868, 1925, 1925, 2007, 32, 32, 131, 2002, 2002, 1888]) - self.assertEqual(c.segment[5]._exponent, + self.assertEqual(c.segment[5].exponent, [16, 16, 16, 16, 15, 15, 15, 14, 14, 14, 13, 13, 13, 11, 11, 11, 11, 11, 11]) # QCC: Quantization component # associated component self.assertEqual(c.segment[6].cqcc, 0) - self.assertEqual(c.segment[6]._guard_bits, 3) + self.assertEqual(c.segment[6].guard_bits, 3) # quantization type self.assertEqual(c.segment[6].sqcc & 0x1f, 1) # derived - self.assertEqual(c.segment[6]._mantissa, [0]) - self.assertEqual(c.segment[6]._exponent, [14]) + self.assertEqual(c.segment[6].mantissa, [0]) + self.assertEqual(c.segment[6].exponent, [14]) # QCC: Quantization component # associated component self.assertEqual(c.segment[7].cqcc, 3) - self.assertEqual(c.segment[7]._guard_bits, 3) + self.assertEqual(c.segment[7].guard_bits, 3) # quantization type self.assertEqual(c.segment[7].sqcc & 0x1f, 0) # none - self.assertEqual(c.segment[7]._mantissa, [0] * 19) - self.assertEqual(c.segment[7]._exponent, + self.assertEqual(c.segment[7].mantissa, [0] * 19) + self.assertEqual(c.segment[7].exponent, [8, 9, 9, 10, 9, 9, 10, 9, 9, 10, 9, 9, 10, 9, 9, 10, 9, 9, 10]) @@ -3662,10 +3667,10 @@ class TestSuiteDump(unittest.TestCase): # QCD: Quantization default # quantization type self.assertEqual(c.segment[3].sqcd & 0x1f, 2) # expounded - self.assertEqual(c.segment[3]._guard_bits, 2) - self.assertEqual(c.segment[3]._mantissa, + self.assertEqual(c.segment[3].guard_bits, 2) + self.assertEqual(c.segment[3].mantissa, [84, 423, 408, 435, 450, 435, 470, 549, 520, 618]) - self.assertEqual(c.segment[3]._exponent, + self.assertEqual(c.segment[3].exponent, [8, 10, 10, 10, 9, 9, 9, 8, 8, 8]) # TLM (tile-part length) @@ -3705,11 +3710,11 @@ class TestSuiteDump(unittest.TestCase): # QCD: Quantization default # quantization type self.assertEqual(c.segment[9].sqcd & 0x1f, 2) # expounded - self.assertEqual(c.segment[9]._guard_bits, 2) - self.assertEqual(c.segment[9]._mantissa, + self.assertEqual(c.segment[9].guard_bits, 2) + self.assertEqual(c.segment[9].mantissa, [75, 1093, 1098, 1115, 1157, 1134, 1186, 1217, 1245, 1248]) - self.assertEqual(c.segment[9]._exponent, + self.assertEqual(c.segment[9].exponent, [8, 10, 10, 10, 9, 9, 9, 8, 8, 8]) # SOD: start of data @@ -3787,12 +3792,12 @@ class TestSuiteDump(unittest.TestCase): self.assertEqual(c.segment[2].precinct_size, [(16, 16)] * 8) self.assertEqual(c.segment[3].sqcd & 0x1f, 2) # expounded - self.assertEqual(c.segment[3]._guard_bits, 3) - self.assertEqual(c.segment[3]._mantissa, + self.assertEqual(c.segment[3].guard_bits, 3) + self.assertEqual(c.segment[3].mantissa, [1813, 1814, 1814, 1814, 1815, 1815, 1817, 1821, 1821, 1827, 1845, 1845, 1868, 1925, 1925, 2007, 32, 32, 131, 2002, 2002, 1888]) - self.assertEqual(c.segment[3]._exponent, + self.assertEqual(c.segment[3].exponent, [17, 17, 17, 17, 16, 16, 16, 15, 15, 15, 14, 14, 14, 13, 13, 13, 11, 11, 11, 11, 11, 11]) @@ -3877,11 +3882,11 @@ class TestSuiteDump(unittest.TestCase): # QCD: Quantization default # quantization type self.assertEqual(c.segment[3].sqcd & 0x1f, 2) # expounded - self.assertEqual(c.segment[3]._guard_bits, 3) - self.assertEqual(c.segment[3]._mantissa, + self.assertEqual(c.segment[3].guard_bits, 3) + self.assertEqual(c.segment[3].mantissa, [1821, 1845, 1845, 1868, 1925, 1925, 2007, 32, 32, 131, 2002, 2002, 1888]) - self.assertEqual(c.segment[3]._exponent, + self.assertEqual(c.segment[3].exponent, [14, 14, 14, 14, 13, 13, 13, 11, 11, 11, 11, 11, 11]) @@ -3990,9 +3995,9 @@ class TestSuiteDump(unittest.TestCase): # QCD: Quantization default # quantization type self.assertEqual(c.segment[4].sqcd & 0x1f, 0) # none - self.assertEqual(c.segment[4]._guard_bits, 2) - self.assertEqual(c.segment[4]._mantissa, [0] * 4) - self.assertEqual(c.segment[4]._exponent, [8, 9, 9, 10]) + self.assertEqual(c.segment[4].guard_bits, 2) + self.assertEqual(c.segment[4].mantissa, [0] * 4) + self.assertEqual(c.segment[4].exponent, [8, 9, 9, 10]) # COM: comment # Registration @@ -4514,11 +4519,11 @@ class TestSuiteDump(unittest.TestCase): # QCD: Quantization default # quantization type self.assertEqual(c.segment[3].sqcd & 0x1f, 2) - self.assertEqual(c.segment[3]._guard_bits, 2) - self.assertEqual(c.segment[3]._mantissa, + self.assertEqual(c.segment[3].guard_bits, 2) + self.assertEqual(c.segment[3].mantissa, [1824, 1776, 1776, 1728, 1792, 1792, 1760, 1872, 1872, 1896, 5, 5, 71, 2003, 2003, 1890]) - self.assertEqual(c.segment[3]._exponent, + self.assertEqual(c.segment[3].exponent, [18, 18, 18, 18, 17, 17, 17, 16, 16, 16, 14, 14, 14, 14, 14, 14]) @@ -4544,13 +4549,13 @@ class TestSuiteDump(unittest.TestCase): # QCC: Quantization component # associated component self.assertEqual(c.segment[5].cqcc, 1) - self.assertEqual(c.segment[5]._guard_bits, 2) + self.assertEqual(c.segment[5].guard_bits, 2) # quantization type self.assertEqual(c.segment[5].sqcc & 0x1f, 2) - self.assertEqual(c.segment[5]._mantissa, + self.assertEqual(c.segment[5].mantissa, [1824, 1776, 1776, 1728, 1792, 1792, 1760, 1872, 1872, 1896, 5, 5, 71, 2003, 2003, 1890]) - self.assertEqual(c.segment[5]._exponent, + self.assertEqual(c.segment[5].exponent, [18, 18, 18, 18, 17, 17, 17, 16, 16, 16, 14, 14, 14, 14, 14, 14]) @@ -4576,13 +4581,13 @@ class TestSuiteDump(unittest.TestCase): # QCC: Quantization component # associated component self.assertEqual(c.segment[7].cqcc, 2) - self.assertEqual(c.segment[7]._guard_bits, 2) + self.assertEqual(c.segment[7].guard_bits, 2) # quantization type self.assertEqual(c.segment[7].sqcc & 0x1f, 2) # none - self.assertEqual(c.segment[7]._mantissa, + self.assertEqual(c.segment[7].mantissa, [1824, 1776, 1776, 1728, 1792, 1792, 1760, 1872, 1872, 1896, 5, 5, 71, 2003, 2003, 1890]) - self.assertEqual(c.segment[7]._exponent, + self.assertEqual(c.segment[7].exponent, [18, 18, 18, 18, 17, 17, 17, 16, 16, 16, 14, 14, 14, 14, 14, 14]) @@ -4837,9 +4842,9 @@ class TestSuiteDump(unittest.TestCase): # QCD: Quantization default # quantization type self.assertEqual(c.segment[3].sqcd & 0x1f, 0) - self.assertEqual(c.segment[3]._guard_bits, 4) - self.assertEqual(c.segment[3]._mantissa, [0] * 34) - self.assertEqual(c.segment[3]._exponent, [16] + [17, 17, 18] * 11) + self.assertEqual(c.segment[3].guard_bits, 4) + self.assertEqual(c.segment[3].mantissa, [0] * 34) + self.assertEqual(c.segment[3].exponent, [16] + [17, 17, 18] * 11) def test_NR_CT_Phillips_JPEG2K_Decompr_Problem_dump(self): jfile = os.path.join(data_root, @@ -4899,11 +4904,11 @@ class TestSuiteDump(unittest.TestCase): # QCD: Quantization default # quantization type self.assertEqual(c.segment[3].sqcd & 0x1f, 2) - self.assertEqual(c.segment[3]._guard_bits, 1) - self.assertEqual(c.segment[3]._mantissa, + self.assertEqual(c.segment[3].guard_bits, 1) + self.assertEqual(c.segment[3].mantissa, [442, 422, 422, 403, 422, 422, 403, 472, 472, 487, 591, 591, 676, 558, 558, 485]) - self.assertEqual(c.segment[3]._exponent, + self.assertEqual(c.segment[3].exponent, [22, 22, 22, 22, 21, 21, 21, 20, 20, 20, 19, 19, 19, 18, 18, 18]) @@ -4970,9 +4975,9 @@ class TestSuiteDump(unittest.TestCase): # QCD: Quantization default # quantization type self.assertEqual(c.segment[3].sqcd & 0x1f, 0) - self.assertEqual(c.segment[3]._guard_bits, 1) - self.assertEqual(c.segment[3]._mantissa, [0] * 16) - self.assertEqual(c.segment[3]._exponent, + self.assertEqual(c.segment[3].guard_bits, 1) + self.assertEqual(c.segment[3].mantissa, [0] * 16) + self.assertEqual(c.segment[3].exponent, [9, 10, 10, 11, 10, 10, 11, 10, 10, 11, 10, 10, 10, 9, 9, 10]) @@ -5047,9 +5052,9 @@ class TestSuiteDump(unittest.TestCase): # QCD: Quantization default # quantization type self.assertEqual(c.segment[3].sqcd & 0x1f, 0) - self.assertEqual(c.segment[3]._guard_bits, 4) - self.assertEqual(c.segment[3]._mantissa, [0] * 34) - self.assertEqual(c.segment[3]._exponent, [16] + [17, 17, 18] * 11) + self.assertEqual(c.segment[3].guard_bits, 4) + self.assertEqual(c.segment[3].mantissa, [0] * 34) + self.assertEqual(c.segment[3].exponent, [16] + [17, 17, 18] * 11) def test_NR_j2k32_dump(self): jfile = os.path.join(data_root, 'input/nonregression/j2k32.j2k') @@ -5107,9 +5112,9 @@ class TestSuiteDump(unittest.TestCase): # QCD: Quantization default # quantization type self.assertEqual(c.segment[3].sqcd & 0x1f, 0) - self.assertEqual(c.segment[3]._guard_bits, 2) - self.assertEqual(c.segment[3]._mantissa, [0] * 16) - self.assertEqual(c.segment[3]._exponent, [8, 9, 9, 10, 9, 9, 10, 9, 9, + self.assertEqual(c.segment[3].guard_bits, 2) + self.assertEqual(c.segment[3].mantissa, [0] * 16) + self.assertEqual(c.segment[3].exponent, [8, 9, 9, 10, 9, 9, 10, 9, 9, 10, 9, 9, 10, 9, 9, 10]) # COM: comment @@ -5172,9 +5177,9 @@ class TestSuiteDump(unittest.TestCase): # QCD: Quantization default self.assertEqual(c.segment[3].sqcd & 0x1f, 0) - self.assertEqual(c.segment[3]._guard_bits, 1) - self.assertEqual(c.segment[3]._mantissa, [0] * 25) - self.assertEqual(c.segment[3]._exponent, + self.assertEqual(c.segment[3].guard_bits, 1) + self.assertEqual(c.segment[3].mantissa, [0] * 25) + self.assertEqual(c.segment[3].exponent, [17, 18, 18, 19, 18, 18, 19, 18, 18, 19, 18, 18, 19, 18, 18, 19, 18, 18, 19, 18, 18, 19, 18, 18, 19]) @@ -5257,9 +5262,9 @@ class TestSuiteDump(unittest.TestCase): # QCD: Quantization default self.assertEqual(c.segment[3].sqcd & 0x1f, 0) - self.assertEqual(c.segment[3]._guard_bits, 4) - self.assertEqual(c.segment[3]._mantissa, [0] * 34) - self.assertEqual(c.segment[3]._exponent, + self.assertEqual(c.segment[3].guard_bits, 4) + self.assertEqual(c.segment[3].mantissa, [0] * 34) + self.assertEqual(c.segment[3].exponent, [16, 17, 17, 18, 17, 17, 18, 17, 17, 18, 17, 17, 18, 17, 17, 18, 17, 17, 18, 17, 17, 18, 17, 17, 18, 17, 17, 18, 17, 17, 18, 17, 17, 18]) @@ -5317,9 +5322,9 @@ class TestSuiteDump(unittest.TestCase): # QCD: Quantization default self.assertEqual(c.segment[3].sqcd & 0x1f, 0) - self.assertEqual(c.segment[3]._guard_bits, 2) - self.assertEqual(c.segment[3]._mantissa, [0] * 16) - self.assertEqual(c.segment[3]._exponent, + self.assertEqual(c.segment[3].guard_bits, 2) + self.assertEqual(c.segment[3].mantissa, [0] * 16) + self.assertEqual(c.segment[3].exponent, [8, 9, 9, 10, 9, 9, 10, 9, 9, 10, 9, 9, 10, 9, 9, 10]) def test_NR_movie_00001(self): @@ -5375,9 +5380,9 @@ class TestSuiteDump(unittest.TestCase): # QCD: Quantization default self.assertEqual(c.segment[3].sqcd & 0x1f, 0) - self.assertEqual(c.segment[3]._guard_bits, 2) - self.assertEqual(c.segment[3]._mantissa, [0] * 16) - self.assertEqual(c.segment[3]._exponent, + self.assertEqual(c.segment[3].guard_bits, 2) + self.assertEqual(c.segment[3].mantissa, [0] * 16) + self.assertEqual(c.segment[3].exponent, [8, 9, 9, 10, 9, 9, 10, 9, 9, 10, 9, 9, 10, 9, 9, 10]) def test_NR_movie_00002(self): @@ -5433,9 +5438,9 @@ class TestSuiteDump(unittest.TestCase): # QCD: Quantization default self.assertEqual(c.segment[3].sqcd & 0x1f, 0) - self.assertEqual(c.segment[3]._guard_bits, 2) - self.assertEqual(c.segment[3]._mantissa, [0] * 16) - self.assertEqual(c.segment[3]._exponent, + self.assertEqual(c.segment[3].guard_bits, 2) + self.assertEqual(c.segment[3].mantissa, [0] * 16) + self.assertEqual(c.segment[3].exponent, [8, 9, 9, 10, 9, 9, 10, 9, 9, 10, 9, 9, 10, 9, 9, 10]) def test_NR_orb_blue10_lin_j2k_dump(self): @@ -5494,9 +5499,9 @@ class TestSuiteDump(unittest.TestCase): # QCD: Quantization default self.assertEqual(c.segment[3].sqcd & 0x1f, 0) - self.assertEqual(c.segment[3]._guard_bits, 2) - self.assertEqual(c.segment[3]._mantissa, [0] * 16) - self.assertEqual(c.segment[3]._exponent, + self.assertEqual(c.segment[3].guard_bits, 2) + self.assertEqual(c.segment[3].mantissa, [0] * 16) + self.assertEqual(c.segment[3].exponent, [8, 9, 9, 10, 9, 9, 10, 9, 9, 10, 9, 9, 10, 9, 9, 10]) def test_NR_orb_blue10_win_j2k_dump(self): @@ -5555,9 +5560,9 @@ class TestSuiteDump(unittest.TestCase): # QCD: Quantization default self.assertEqual(c.segment[3].sqcd & 0x1f, 0) - self.assertEqual(c.segment[3]._guard_bits, 2) - self.assertEqual(c.segment[3]._mantissa, [0] * 16) - self.assertEqual(c.segment[3]._exponent, + self.assertEqual(c.segment[3].guard_bits, 2) + self.assertEqual(c.segment[3].mantissa, [0] * 16) + self.assertEqual(c.segment[3].exponent, [8, 9, 9, 10, 9, 9, 10, 9, 9, 10, 9, 9, 10, 9, 9, 10]) def test_NR_pacs_ge_j2k_dump(self): @@ -5615,9 +5620,9 @@ class TestSuiteDump(unittest.TestCase): # QCD: Quantization default self.assertEqual(c.segment[3].sqcd & 0x1f, 0) - self.assertEqual(c.segment[3]._guard_bits, 1) - self.assertEqual(c.segment[3]._mantissa, [0] * 16) - self.assertEqual(c.segment[3]._exponent, + self.assertEqual(c.segment[3].guard_bits, 1) + self.assertEqual(c.segment[3].mantissa, [0] * 16) + self.assertEqual(c.segment[3].exponent, [18, 19, 19, 20, 19, 19, 20, 19, 19, 20, 19, 19, 20, 19, 19, 20]) @@ -5685,9 +5690,9 @@ class TestSuiteDump(unittest.TestCase): # QCD: Quantization default self.assertEqual(c.segment[3].sqcd & 0x1f, 0) - self.assertEqual(c.segment[3]._guard_bits, 2) - self.assertEqual(c.segment[3]._mantissa, [0] * 16) - self.assertEqual(c.segment[3]._exponent, + self.assertEqual(c.segment[3].guard_bits, 2) + self.assertEqual(c.segment[3].mantissa, [0] * 16) + self.assertEqual(c.segment[3].exponent, [12, 13, 13, 14, 13, 13, 14, 13, 13, 14, 13, 13, 14, 13, 13, 14]) @@ -5755,9 +5760,9 @@ class TestSuiteDump(unittest.TestCase): # QCD: Quantization default self.assertEqual(c.segment[3].sqcd & 0x1f, 0) - self.assertEqual(c.segment[3]._guard_bits, 4) - self.assertEqual(c.segment[3]._mantissa, [0] * 34) - self.assertEqual(c.segment[3]._exponent, + self.assertEqual(c.segment[3].guard_bits, 4) + self.assertEqual(c.segment[3].mantissa, [0] * 34) + self.assertEqual(c.segment[3].exponent, [16] + [17, 17, 18] * 11) def test_NR_bug_j2c_dump(self): @@ -5817,9 +5822,9 @@ class TestSuiteDump(unittest.TestCase): # QCD: Quantization default self.assertEqual(c.segment[3].sqcd & 0x1f, 0) - self.assertEqual(c.segment[3]._guard_bits, 4) - self.assertEqual(c.segment[3]._mantissa, [0] * 34) - self.assertEqual(c.segment[3]._exponent, + self.assertEqual(c.segment[3].guard_bits, 4) + self.assertEqual(c.segment[3].mantissa, [0] * 34) + self.assertEqual(c.segment[3].exponent, [16] + [17, 17, 18] * 11) def test_NR_kodak_2layers_lrcp_j2c_dump(self): @@ -5881,9 +5886,9 @@ class TestSuiteDump(unittest.TestCase): # QCD: Quantization default self.assertEqual(c.segment[3].sqcd & 0x1f, 2) - self.assertEqual(c.segment[3]._guard_bits, 2) - self.assertEqual(c.segment[3]._mantissa, [0] * 16) - self.assertEqual(c.segment[3]._exponent, + self.assertEqual(c.segment[3].guard_bits, 2) + self.assertEqual(c.segment[3].mantissa, [0] * 16) + self.assertEqual(c.segment[3].exponent, [13, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13]) @@ -5899,7 +5904,7 @@ class TestSuiteDump(unittest.TestCase): def test_NR_broken_jp2_dump(self): jfile = os.path.join(data_root, 'input/nonregression/broken.jp2') - with self.assertWarns(UserWarning) as cw: + with self.assertWarns(UserWarning): # colr box has bad length. jp2 = Jp2k(jfile) @@ -5996,29 +6001,29 @@ class TestSuiteDump(unittest.TestCase): # QCD: Quantization default self.assertEqual(c.segment[4].sqcd & 0x1f, 0) - self.assertEqual(c.segment[4]._guard_bits, 2) - self.assertEqual(c.segment[4]._mantissa, [0] * 16) - self.assertEqual(c.segment[4]._exponent, + self.assertEqual(c.segment[4].guard_bits, 2) + self.assertEqual(c.segment[4].mantissa, [0] * 16) + self.assertEqual(c.segment[4].exponent, [8] + [9, 9, 10] * 5) # QCC: Quantization component # associated component self.assertEqual(c.segment[5].cqcc, 1) - self.assertEqual(c.segment[5]._guard_bits, 2) + self.assertEqual(c.segment[5].guard_bits, 2) # quantization type self.assertEqual(c.segment[5].sqcc & 0x1f, 0) # none - self.assertEqual(c.segment[5]._mantissa, [0] * 16) - self.assertEqual(c.segment[5]._exponent, + self.assertEqual(c.segment[5].mantissa, [0] * 16) + self.assertEqual(c.segment[5].exponent, [8] + [9, 9, 10] * 5) # QCC: Quantization component # associated component self.assertEqual(c.segment[6].cqcc, 2) - self.assertEqual(c.segment[6]._guard_bits, 2) + self.assertEqual(c.segment[6].guard_bits, 2) # quantization type self.assertEqual(c.segment[6].sqcc & 0x1f, 0) # none - self.assertEqual(c.segment[6]._mantissa, [0] * 16) - self.assertEqual(c.segment[6]._exponent, + self.assertEqual(c.segment[6].mantissa, [0] * 16) + self.assertEqual(c.segment[6].exponent, [8] + [9, 9, 10] * 5) @unittest.skipIf(sys.hexversion < 0x03020000, @@ -6036,7 +6041,7 @@ class TestSuiteDump(unittest.TestCase): def test_NR_broken3_jp2_dump(self): jfile = os.path.join(data_root, 'input/nonregression/broken3.jp2') - with self.assertWarns(UserWarning) as cw: + with self.assertWarns(UserWarning): # colr box has bad length. jp2 = Jp2k(jfile) @@ -6133,29 +6138,29 @@ class TestSuiteDump(unittest.TestCase): # QCD: Quantization default self.assertEqual(c.segment[4].sqcd & 0x1f, 0) - self.assertEqual(c.segment[4]._guard_bits, 2) - self.assertEqual(c.segment[4]._mantissa, [0] * 16) - self.assertEqual(c.segment[4]._exponent, + self.assertEqual(c.segment[4].guard_bits, 2) + self.assertEqual(c.segment[4].mantissa, [0] * 16) + self.assertEqual(c.segment[4].exponent, [8] + [9, 9, 10] * 5) # QCC: Quantization component # associated component self.assertEqual(c.segment[5].cqcc, 1) - self.assertEqual(c.segment[5]._guard_bits, 2) + self.assertEqual(c.segment[5].guard_bits, 2) # quantization type self.assertEqual(c.segment[5].sqcc & 0x1f, 0) # none - self.assertEqual(c.segment[5]._mantissa, [0] * 16) - self.assertEqual(c.segment[5]._exponent, + self.assertEqual(c.segment[5].mantissa, [0] * 16) + self.assertEqual(c.segment[5].exponent, [8] + [9, 9, 10] * 5) # QCC: Quantization component # associated component self.assertEqual(c.segment[6].cqcc, 2) - self.assertEqual(c.segment[6]._guard_bits, 2) + self.assertEqual(c.segment[6].guard_bits, 2) # quantization type self.assertEqual(c.segment[6].sqcc & 0x1f, 0) # none - self.assertEqual(c.segment[6]._mantissa, [0] * 16) - self.assertEqual(c.segment[6]._exponent, + self.assertEqual(c.segment[6].mantissa, [0] * 16) + self.assertEqual(c.segment[6].exponent, [8] + [9, 9, 10] * 5) @unittest.skipIf(sys.hexversion < 0x03020000, @@ -6259,11 +6264,11 @@ class TestSuiteDump(unittest.TestCase): # QCD: Quantization default self.assertEqual(c.segment[3].sqcd & 0x1f, 2) - self.assertEqual(c.segment[3]._guard_bits, 1) - self.assertEqual(c.segment[3]._mantissa, + self.assertEqual(c.segment[3].guard_bits, 1) + self.assertEqual(c.segment[3].mantissa, [1816, 1792, 1792, 1724, 1770, 1770, 1724, 1868, 1868, 1892, 3, 3, 69, 2002, 2002, 1889]) - self.assertEqual(c.segment[3]._exponent, + self.assertEqual(c.segment[3].exponent, [13] * 4 + [12] * 3 + [11] * 3 + [9] * 6) @unittest.skipIf(sys.hexversion < 0x03020000, @@ -6273,7 +6278,7 @@ class TestSuiteDump(unittest.TestCase): 'gdal_fuzzer_assert_in_opj_j2k_read_SQcd_SQcc.patch.jp2'] jfile = os.path.join(data_root, '/'.join(lst)) with self.assertWarns(UserWarning): - jp2 = Jp2k(jfile) + Jp2k(jfile) @unittest.skipIf(sys.hexversion < 0x03020000, "Uses features introduced in 3.2.") @@ -6281,7 +6286,7 @@ class TestSuiteDump(unittest.TestCase): lst = ['input', 'nonregression', 'gdal_fuzzer_check_comp_dx_dy.jp2'] jfile = os.path.join(data_root, '/'.join(lst)) with self.assertWarns(UserWarning): - jp2 = Jp2k(jfile) + Jp2k(jfile) @unittest.skipIf(sys.hexversion < 0x03020000, "Uses features introduced in 3.2.") @@ -6291,7 +6296,7 @@ class TestSuiteDump(unittest.TestCase): 'gdal_fuzzer_check_number_of_tiles.jp2'] jfile = os.path.join(data_root, '/'.join(lst)) with self.assertWarns(UserWarning): - jp2 = Jp2k(jfile) + Jp2k(jfile) @unittest.skipIf(sys.hexversion < 0x03020000, "Uses features introduced in 3.2.") @@ -6301,7 +6306,7 @@ class TestSuiteDump(unittest.TestCase): 'gdal_fuzzer_unchecked_numresolutions.jp2'] jfile = os.path.join(data_root, '/'.join(lst)) with self.assertWarns(UserWarning): - jp2 = Jp2k(jfile) + Jp2k(jfile) def test_NR_issue104_jpxstream_dump(self): jfile = os.path.join(data_root, @@ -6413,9 +6418,9 @@ class TestSuiteDump(unittest.TestCase): # QCD: Quantization default self.assertEqual(c.segment[3].sqcd & 0x1f, 0) - self.assertEqual(c.segment[3]._guard_bits, 2) - self.assertEqual(c.segment[3]._mantissa, [0] * 16) - self.assertEqual(c.segment[3]._exponent, [8] + [9, 9, 10] * 5) + self.assertEqual(c.segment[3].guard_bits, 2) + self.assertEqual(c.segment[3].mantissa, [0] * 16) + self.assertEqual(c.segment[3].exponent, [8] + [9, 9, 10] * 5) def test_NR_issue188_beach_64bitsbox(self): lst = ['input', 'nonregression', 'issue188_beach_64bitsbox.jp2'] @@ -6514,7 +6519,7 @@ class TestSuiteDump(unittest.TestCase): # QCD: Quantization default self.assertEqual(c.segment[3].sqcd & 0x1f, 2) - self.assertEqual(c.segment[3]._guard_bits, 1) + self.assertEqual(c.segment[3].guard_bits, 1) def test_NR_issue206_image_000_dump(self): jfile = os.path.join(data_root, @@ -6613,9 +6618,9 @@ class TestSuiteDump(unittest.TestCase): # QCD: Quantization default self.assertEqual(c.segment[3].sqcd & 0x1f, 2) - self.assertEqual(c.segment[3]._guard_bits, 2) - self.assertEqual(c.segment[3]._mantissa, [0] * 16) - self.assertEqual(c.segment[3]._exponent, [8] + [9, 9, 10] * 5) + self.assertEqual(c.segment[3].guard_bits, 2) + self.assertEqual(c.segment[3].mantissa, [0] * 16) + self.assertEqual(c.segment[3].exponent, [8] + [9, 9, 10] * 5) def test_NR_Marrin_jp2_dump(self): jfile = os.path.join(data_root, @@ -6717,11 +6722,11 @@ class TestSuiteDump(unittest.TestCase): # QCD: Quantization default self.assertEqual(c.segment[3].sqcd & 0x1f, 2) - self.assertEqual(c.segment[3]._guard_bits, 1) - self.assertEqual(c.segment[3]._mantissa, + self.assertEqual(c.segment[3].guard_bits, 1) + self.assertEqual(c.segment[3].mantissa, [1822, 1770, 1770, 1724, 1792, 1792, 1762, 1868, 1868, 1892, 3, 3, 69, 2002, 2002, 1889]) - self.assertEqual(c.segment[3]._exponent, + self.assertEqual(c.segment[3].exponent, [14] * 4 + [13] * 3 + [12] * 3 + [10] * 6) # COM: comment @@ -6845,9 +6850,9 @@ class TestSuiteDump(unittest.TestCase): # QCD: Quantization default self.assertEqual(c.segment[3].sqcd & 0x1f, 0) - self.assertEqual(c.segment[3]._guard_bits, 3) - self.assertEqual(c.segment[3]._mantissa, [0] * 16) - self.assertEqual(c.segment[3]._exponent, [1] + [2, 2, 3] * 5) + self.assertEqual(c.segment[3].guard_bits, 3) + self.assertEqual(c.segment[3].mantissa, [0] * 16) + self.assertEqual(c.segment[3].exponent, [1] + [2, 2, 3] * 5) def test_NR_mem_b2b86b74_2753_dump(self): jfile = os.path.join(data_root, @@ -6960,9 +6965,9 @@ class TestSuiteDump(unittest.TestCase): # QCD: Quantization default self.assertEqual(c.segment[3].sqcd & 0x1f, 0) - self.assertEqual(c.segment[3]._guard_bits, 2) - self.assertEqual(c.segment[3]._mantissa, [0] * 16) - self.assertEqual(c.segment[3]._exponent, [4] + [5, 5, 6] * 5) + self.assertEqual(c.segment[3].guard_bits, 2) + self.assertEqual(c.segment[3].mantissa, [0] * 16) + self.assertEqual(c.segment[3].exponent, [4] + [5, 5, 6] * 5) def test_NR_merged_dump(self): jfile = os.path.join(data_root, 'input/nonregression/merged.jp2') @@ -7054,9 +7059,9 @@ class TestSuiteDump(unittest.TestCase): # QCD: Quantization default self.assertEqual(c.segment[3].sqcd & 0x1f, 0) - self.assertEqual(c.segment[3]._guard_bits, 1) - self.assertEqual(c.segment[3]._mantissa, [0] * 16) - self.assertEqual(c.segment[3]._exponent, [8] + [9, 9, 10] * 5) + self.assertEqual(c.segment[3].guard_bits, 1) + self.assertEqual(c.segment[3].mantissa, [0] * 16) + self.assertEqual(c.segment[3].exponent, [8] + [9, 9, 10] * 5) # POD: progression order change self.assertEqual(c.segment[4].rspod, (0, 0)) @@ -7163,9 +7168,9 @@ class TestSuiteDump(unittest.TestCase): # QCD: Quantization default self.assertEqual(c.segment[3].sqcd & 0x1f, 0) - self.assertEqual(c.segment[3]._guard_bits, 2) - self.assertEqual(c.segment[3]._mantissa, [0] * 16) - self.assertEqual(c.segment[3]._exponent, + self.assertEqual(c.segment[3].guard_bits, 2) + self.assertEqual(c.segment[3].mantissa, [0] * 16) + self.assertEqual(c.segment[3].exponent, [8, 9, 9, 10, 9, 9, 10, 9, 9, 10, 9, 9, 10, 9, 9, 10]) def test_NR_orb_blue10_win_jp2_dump(self): @@ -7263,9 +7268,9 @@ class TestSuiteDump(unittest.TestCase): # QCD: Quantization default self.assertEqual(c.segment[3].sqcd & 0x1f, 0) - self.assertEqual(c.segment[3]._guard_bits, 2) - self.assertEqual(c.segment[3]._mantissa, [0] * 16) - self.assertEqual(c.segment[3]._exponent, + self.assertEqual(c.segment[3].guard_bits, 2) + self.assertEqual(c.segment[3].mantissa, [0] * 16) + self.assertEqual(c.segment[3].exponent, [8, 9, 9, 10, 9, 9, 10, 9, 9, 10, 9, 9, 10, 9, 9, 10]) def test_NR_text_GBR_dump(self): @@ -7375,9 +7380,9 @@ class TestSuiteDump(unittest.TestCase): # QCD: Quantization default self.assertEqual(c.segment[3].sqcd & 0x1f, 0) - self.assertEqual(c.segment[3]._guard_bits, 2) - self.assertEqual(c.segment[3]._mantissa, [0] * 16) - self.assertEqual(c.segment[3]._exponent, + self.assertEqual(c.segment[3].guard_bits, 2) + self.assertEqual(c.segment[3].mantissa, [0] * 16) + self.assertEqual(c.segment[3].exponent, [8, 9, 9, 10, 9, 9, 10, 9, 9, 10, 9, 9, 10, 9, 9, 10]) @@ -7763,28 +7768,28 @@ class TestSuite15(unittest.TestCase): """ETS_JP2_file5""" jfile = os.path.join(data_root, 'input/conformance/file5.jp2') jp2k = Jp2k(jfile) - jp2k.read() + jpdata = jp2k.read() self.assertEqual(jpdata.shape, (512, 768, 3)) def test_ETS_JP2_file6(self): """ETS_JP2_file6""" jfile = os.path.join(data_root, 'input/conformance/file6.jp2') jp2k = Jp2k(jfile) - jp2k.read() + jpdata = jp2k.read() self.assertEqual(jpdata.shape, (512, 768)) def test_ETS_JP2_file7(self): """ETS_JP2_file7""" jfile = os.path.join(data_root, 'input/conformance/file7.jp2') jp2k = Jp2k(jfile) - jp2k.read() + jpdata = jp2k.read() self.assertEqual(jpdata.shape, (640, 480, 3)) def test_ETS_JP2_file8(self): """ETS_JP2_file8""" jfile = os.path.join(data_root, 'input/conformance/file8.jp2') jp2k = Jp2k(jfile) - jp2k.read() + jpdata = jp2k.read() self.assertEqual(jpdata.shape, (400, 700)) def test_ETS_JP2_file9(self): @@ -7792,7 +7797,7 @@ class TestSuite15(unittest.TestCase): jfile = os.path.join(data_root, 'input/conformance/file9.jp2') jp2k = Jp2k(jfile) jpdata = jp2k.read() - if re.match('[01]\.3', OPENJPEG_VERSION): + if re.match(r'[01]\.3', OPENJPEG_VERSION): # Version 1.3 reads in the image as the palette indices. self.assertEqual(jpdata.shape, (512, 768)) else: @@ -7832,7 +7837,7 @@ class TestSuite15(unittest.TestCase): jp2.read() self.assertTrue(True) - @unittest.skipIf(re.match('[01]\.[34]', OPENJPEG_VERSION), + @unittest.skipIf(re.match(r'[01]\.[34]', OPENJPEG_VERSION), "Segfaults openjpeg 1.4 and earlier.") def test_NR_DEC_broken2_jp2_5_decode(self): """NR_DEC_broken2_jp2_5_decode""" @@ -7857,7 +7862,7 @@ class TestSuite15(unittest.TestCase): with self.assertRaises(ValueError): j.read() - @unittest.skipIf(re.match('[01]\.[34]', OPENJPEG_VERSION), + @unittest.skipIf(re.match(r'[01]\.[34]', OPENJPEG_VERSION), "Segfaults openjpeg 1.4 and earlier.") def test_NR_DEC_broken4_jp2_7_decode(self): """NR_DEC_broken4_jp2_7_decode""" From 4db8763056989460425b8f1301e0d7123db38b5e Mon Sep 17 00:00:00 2001 From: jevans Date: Mon, 12 Aug 2013 20:12:23 -0400 Subject: [PATCH 17/20] Refactored out read_common, remove ambiguity on return type. It was the case that _read_common could return either a list, a view, or an image cube depending upon the jp2 subsampling or the image dimensions. No more. Closed #100 --- glymur/jp2k.py | 156 +++++++++++++++++++++++++------------------------ 1 file changed, 81 insertions(+), 75 deletions(-) diff --git a/glymur/jp2k.py b/glymur/jp2k.py index 37cad71..ea3c859 100644 --- a/glymur/jp2k.py +++ b/glymur/jp2k.py @@ -686,12 +686,12 @@ class Jp2k(Jp2kBox): if data.shape[2] == 1: # The third dimension has just a single layer. Make the image # data 2D instead of 3D. - data = data.view() data.shape = data.shape[0:2] return data - def _read_openjp2(self, **kwargs): + def _read_openjp2(self, rlevel=0, layer=0, area=None, tile=None, + verbose=False): """Read a JPEG 2000 image using libopenjp2. Parameters @@ -721,10 +721,46 @@ class Jp2k(Jp2kBox): """ self._subsampling_sanity_check() - img_array = self._read_common(as_bands=False, **kwargs) + dparam = self._populate_dparam(layer, rlevel, area, tile) + + with ExitStack() as stack: + if hasattr(opj2.OPENJP2, + 'opj_stream_create_default_file_stream_v3'): + filename = self.filename + stream = opj2.stream_create_default_file_stream_v3(filename, + True) + stack.callback(opj2.stream_destroy_v3, stream) + else: + fptr = libc.fopen(self.filename, 'rb') + stack.callback(libc.fclose, fptr) + stream = opj2.stream_create_default_file_stream(fptr, True) + stack.callback(opj2.stream_destroy, stream) + codec = opj2.create_decompress(self._codec_format) + stack.callback(opj2.destroy_codec, codec) + + opj2.set_error_handler(codec, _ERROR_CALLBACK) + opj2.set_warning_handler(codec, _WARNING_CALLBACK) + if verbose: + opj2.set_info_handler(codec, _INFO_CALLBACK) + else: + opj2.set_info_handler(codec, None) + + opj2.setup_decoder(codec, dparam) + image = opj2.read_header(stream, codec) + stack.callback(opj2.image_destroy, image) + + if dparam.nb_tile_to_decode: + opj2.get_decoded_tile(codec, stream, image, dparam.tile_index) + else: + opj2.set_decode_area(codec, image, + dparam.DA_x0, dparam.DA_y0, + dparam.DA_x1, dparam.DA_y1) + opj2.decode(codec, stream, image) + opj2.end_decompress(codec, stream) + + img_array = extract_image_cube(image) if img_array.shape[2] == 1: - img_array = img_array.view() img_array.shape = img_array.shape[0:2] return img_array @@ -782,76 +818,8 @@ class Jp2k(Jp2kBox): return dparam - def _read_common(self, rlevel=0, layer=0, area=None, tile=None, - verbose=False, as_bands=False): - """Read a JPEG 2000 image. - - Parameters - ---------- - layer : int, optional - Number of quality layer to decode. - rlevel : int, optional - Factor by which to rlevel output resolution. - area : tuple, optional - Specifies decoding image area, - (first_row, first_col, last_row, last_col) - tile : int, optional - Number of tile to decode. - verbose : bool, optional - Print informational messages produced by the OpenJPEG library. - as_bands : bool, optional - If true, return the individual 2D components in a list. - - Returns - ------- - img_array : ndarray - The individual image components or a single array. - """ - dparam = self._populate_dparam(layer, rlevel, area, tile) - - with ExitStack() as stack: - if hasattr(opj2.OPENJP2, - 'opj_stream_create_default_file_stream_v3'): - filename = self.filename - stream = opj2.stream_create_default_file_stream_v3(filename, - True) - stack.callback(opj2.stream_destroy_v3, stream) - else: - fptr = libc.fopen(self.filename, 'rb') - stack.callback(libc.fclose, fptr) - stream = opj2.stream_create_default_file_stream(fptr, True) - stack.callback(opj2.stream_destroy, stream) - codec = opj2.create_decompress(self._codec_format) - stack.callback(opj2.destroy_codec, codec) - - opj2.set_error_handler(codec, _ERROR_CALLBACK) - opj2.set_warning_handler(codec, _WARNING_CALLBACK) - if verbose: - opj2.set_info_handler(codec, _INFO_CALLBACK) - else: - opj2.set_info_handler(codec, None) - - opj2.setup_decoder(codec, dparam) - image = opj2.read_header(stream, codec) - stack.callback(opj2.image_destroy, image) - - if dparam.nb_tile_to_decode: - opj2.get_decoded_tile(codec, stream, image, dparam.tile_index) - else: - opj2.set_decode_area(codec, image, - dparam.DA_x0, dparam.DA_y0, - dparam.DA_x1, dparam.DA_y1) - opj2.decode(codec, stream, image) - opj2.end_decompress(codec, stream) - - if as_bands: - data = extract_image_bands(image) - else: - data = extract_image_cube(image) - - return data - - def read_bands(self, **kwargs): + def read_bands(self, rlevel=0, layer=0, area=None, tile=None, + verbose=False): """Read a JPEG 2000 image. The only time you should use this method is when the image has @@ -898,7 +866,45 @@ class Jp2k(Jp2kBox): "of OpenJP2 installed before using " "this functionality.") - lst = self._read_common(as_bands=True, **kwargs) + dparam = self._populate_dparam(layer, rlevel, area, tile) + + with ExitStack() as stack: + if hasattr(opj2.OPENJP2, + 'opj_stream_create_default_file_stream_v3'): + filename = self.filename + stream = opj2.stream_create_default_file_stream_v3(filename, + True) + stack.callback(opj2.stream_destroy_v3, stream) + else: + fptr = libc.fopen(self.filename, 'rb') + stack.callback(libc.fclose, fptr) + stream = opj2.stream_create_default_file_stream(fptr, True) + stack.callback(opj2.stream_destroy, stream) + codec = opj2.create_decompress(self._codec_format) + stack.callback(opj2.destroy_codec, codec) + + opj2.set_error_handler(codec, _ERROR_CALLBACK) + opj2.set_warning_handler(codec, _WARNING_CALLBACK) + if verbose: + opj2.set_info_handler(codec, _INFO_CALLBACK) + else: + opj2.set_info_handler(codec, None) + + opj2.setup_decoder(codec, dparam) + image = opj2.read_header(stream, codec) + stack.callback(opj2.image_destroy, image) + + if dparam.nb_tile_to_decode: + opj2.get_decoded_tile(codec, stream, image, dparam.tile_index) + else: + opj2.set_decode_area(codec, image, + dparam.DA_x0, dparam.DA_y0, + dparam.DA_x1, dparam.DA_y1) + opj2.decode(codec, stream, image) + opj2.end_decompress(codec, stream) + + lst = extract_image_bands(image) + return lst def get_codestream(self, header_only=True): From 6f964ce1468e25689027f75db9ad5b98d9ce5cdc Mon Sep 17 00:00:00 2001 From: jevans Date: Mon, 12 Aug 2013 20:31:48 -0400 Subject: [PATCH 18/20] Closes #101 --- glymur/jp2k.py | 2 +- glymur/test/test_jp2k.py | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/glymur/jp2k.py b/glymur/jp2k.py index ea3c859..2994742 100644 --- a/glymur/jp2k.py +++ b/glymur/jp2k.py @@ -238,7 +238,7 @@ class Jp2k(Jp2kBox): outfile += b'0' * num_pad_bytes cparams.outfile = outfile - if self.filename[-4:].lower() == '.jp2': + if self.filename[-4:].endswith(('.jp2', '.JP2')): cparams.codec_fmt = opj2.CODEC_JP2 else: cparams.codec_fmt = opj2.CODEC_J2K diff --git a/glymur/test/test_jp2k.py b/glymur/test/test_jp2k.py index 8b04dfa..c018897 100644 --- a/glymur/test/test_jp2k.py +++ b/glymur/test/test_jp2k.py @@ -224,6 +224,17 @@ class TestJp2k(unittest.TestCase): filename = 'this file does not actually exist on the file system.' Jp2k(filename) + @unittest.skipIf(os.name == "nt", "NamedTemporaryFile issue on windows") + def test_write_with_JP2_suffix(self): + """should be able to write with JP2 suffix.""" + j2k = Jp2k(self.j2kfile) + expdata = j2k.read() + with tempfile.NamedTemporaryFile(suffix='.JP2') as tfile: + ofile = Jp2k(tfile.name, 'wb') + ofile.write(expdata) + actdata = ofile.read() + np.testing.assert_array_equal(actdata, expdata) + @unittest.skipIf(os.name == "nt", "NamedTemporaryFile issue on windows") def test_write_srgb_without_mct(self): """should be able to write RGB without specifying mct""" From 3753dc5e60edb99abdc3a54355303aa05588b95e Mon Sep 17 00:00:00 2001 From: John Evans Date: Tue, 13 Aug 2013 06:53:59 -0400 Subject: [PATCH 19/20] pylint work, #99 --- glymur/lib/config.py | 3 +++ glymur/lib/test/test_openjp2.py | 4 ++++ glymur/lib/test/test_openjpeg.py | 7 +++++-- glymur/test/test_codestream.py | 3 +++ glymur/test/test_conformance.py | 2 ++ glymur/test/test_icc.py | 3 +++ glymur/test/test_opj_suite.py | 3 +++ glymur/test/test_opj_suite_neg.py | 3 +++ glymur/test/test_opj_suite_write.py | 4 ++++ 9 files changed, 30 insertions(+), 2 deletions(-) diff --git a/glymur/lib/config.py b/glymur/lib/config.py index e2b780a..e3a5c1d 100644 --- a/glymur/lib/config.py +++ b/glymur/lib/config.py @@ -1,6 +1,9 @@ """ Configure glymur to use installed libraries if possible. """ +# configparser is new in python3 (pylint/python-2.7) +# pylint: disable=F0401 + import ctypes from ctypes.util import find_library import os diff --git a/glymur/lib/test/test_openjp2.py b/glymur/lib/test/test_openjp2.py index 13c5975..54d8254 100644 --- a/glymur/lib/test/test_openjp2.py +++ b/glymur/lib/test/test_openjp2.py @@ -4,6 +4,10 @@ Tests for libopenjp2 wrapping functions. # R0904: Seems like pylint is fooled in this situation # W0142: using kwargs is ok in this context # pylint: disable=R0904,W0142 + +# unittest2 is python-2.6 only (pylint/python-2.7) +# pylint: disable=F0401 + import os import sys import tempfile diff --git a/glymur/lib/test/test_openjpeg.py b/glymur/lib/test/test_openjpeg.py index 5363a1f..91e6d84 100644 --- a/glymur/lib/test/test_openjpeg.py +++ b/glymur/lib/test/test_openjpeg.py @@ -1,6 +1,11 @@ """ Tests for OpenJPEG module. """ +# unittest2 is python2.6 only (pylint/python-2.7) +# pylint: disable=F0401 + +# pylint: disable=E1101,R0904 + import ctypes import re import sys @@ -12,8 +17,6 @@ else: import glymur -# pylint: disable=E1101,R0904 - @unittest.skipIf(glymur.lib.openjpeg.OPENJPEG is None, "Missing openjpeg library.") class TestOpenJPEG(unittest.TestCase): diff --git a/glymur/test/test_codestream.py b/glymur/test/test_codestream.py index 3913d44..f9d4d75 100644 --- a/glymur/test/test_codestream.py +++ b/glymur/test/test_codestream.py @@ -8,6 +8,9 @@ Test suite for codestream parsing. # tempfile.TemporaryDirectory, unittest.assertWarns introduced in 3.2 # pylint: disable=E1101 +# unittest2 is python2.6 only (pylint/python-2.7) +# pylint: disable=F0401 + import os import struct import sys diff --git a/glymur/test/test_conformance.py b/glymur/test/test_conformance.py index 8c022bb..3c7c9c4 100644 --- a/glymur/test/test_conformance.py +++ b/glymur/test/test_conformance.py @@ -7,6 +7,8 @@ These tests deal with JPX/JP2/J2K images in the format-corpus repository. # E1101: assertWarns introduced in python 3.2 # pylint: disable=E1101 +# unittest2 is python2.6 only (pylint/python-2.7) +# pylint: disable=F0401 import os from os.path import join diff --git a/glymur/test/test_icc.py b/glymur/test/test_icc.py index fc2f7c1..bf589a5 100644 --- a/glymur/test/test_icc.py +++ b/glymur/test/test_icc.py @@ -5,6 +5,9 @@ ICC profile tests. # unittest doesn't work well with R0904. # pylint: disable=R0904 +# unittest2 is python2.6 only (pylint/python-2.7) +# pylint: disable=F0401 + import datetime import os import sys diff --git a/glymur/test/test_opj_suite.py b/glymur/test/test_opj_suite.py index bfefbc6..a264019 100644 --- a/glymur/test/test_opj_suite.py +++ b/glymur/test/test_opj_suite.py @@ -27,6 +27,9 @@ suite. # asserWarns introduced in python 3.2 (python2.7/pylint issue) # pylint: disable=E1101 +# unittest2 is python2.6 only (pylint/python-2.7) +# pylint: disable=F0401 + import os import re import sys diff --git a/glymur/test/test_opj_suite_neg.py b/glymur/test/test_opj_suite_neg.py index 2f61675..e8675aa 100644 --- a/glymur/test/test_opj_suite_neg.py +++ b/glymur/test/test_opj_suite_neg.py @@ -8,6 +8,9 @@ seem like logical negative tests to add. # R0904: Not too many methods in unittest. # pylint: disable=R0904 +# unittest2 is python2.6 only (pylint/python-2.7) +# pylint: disable=F0401 + import os import sys import tempfile diff --git a/glymur/test/test_opj_suite_write.py b/glymur/test/test_opj_suite_write.py index 09722dc..6cc37f3 100644 --- a/glymur/test/test_opj_suite_write.py +++ b/glymur/test/test_opj_suite_write.py @@ -5,6 +5,10 @@ suite. # C0103: method names longer that 30 chars are ok in tests, IMHO # R0904: Seems like pylint is fooled in this situation # pylint: disable=R0904,C0103 + +# unittest2 is python2.6 only (pylint/python-2.7) +# pylint: disable=F0401 + import os import sys import tempfile From b8fe75984e3bb618e22afe2f58a3a71a98bd8c02 Mon Sep 17 00:00:00 2001 From: John Evans Date: Tue, 13 Aug 2013 18:46:47 -0400 Subject: [PATCH 20/20] pylint work, closes #99 --- CHANGES.txt | 5 +- glymur/__init__.py | 2 + glymur/codestream.py | 22 +++++++- glymur/jp2k.py | 105 ++++++++++++++++++++------------------- glymur/test/test_jp2k.py | 2 +- 5 files changed, 80 insertions(+), 56 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 7283bfb..1874042 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,5 +1,6 @@ -Aug 11, 2013 - v0.3.1 Exposed mantissa, exponent, and guard_bits fields in QCC - and QCD segments. +Aug 13, 2013 - v0.3.1 Exposed mantissa, exponent, and guard_bits fields in QCC + and QCD segments. Exposed layers and code_block_size in COD segment. + Exposed precinct_size in COC segment. Jul 31, 2013 - v0.3.0 Added support for official 2.0.0. diff --git a/glymur/__init__.py b/glymur/__init__.py index fb1c504..cc80a72 100644 --- a/glymur/__init__.py +++ b/glymur/__init__.py @@ -8,6 +8,8 @@ from .jp2dump import jp2dump from . import data +# unittest2 only in python-2.6 (pylint/python2.7 issue) +# pylint: disable=F0401 def runtests(): """Discover and run all tests for the glymur package. """ diff --git a/glymur/codestream.py b/glymur/codestream.py index c60bc1b..7a32190 100644 --- a/glymur/codestream.py +++ b/glymur/codestream.py @@ -3,7 +3,19 @@ The module contains classes used to store information parsed from JPEG 2000 codestreams. """ -# pylint: disable=C0302,R0902,R0903,R0913 + +# The number of lines in the module is long and that's ok. It would not help +# matters to move anything out to another file. +# pylint: disable=C0302 + +# "Too many instance attributes", "Too many arguments" +# Some segments just have a lot of information. +# It doesn't make sense to subclass just for that. +# pylint: disable=R0902,R0913 + +# "Too few public methods" Some segments don't define any new methods from +# the base Segment class. +# pylint: disable=R0903 import math import struct @@ -1276,6 +1288,10 @@ class QCCsegment(Segment): Quantization style for this component. spqcc : iterable bytes Quantization value for each sub-band. + mantissa, exponent : iterable + Defines quantization factors. + guard_bits : int + Number of guard bits. References ---------- @@ -1323,6 +1339,10 @@ class QCDsegment(Segment): Quantization style for all components. spqcd : iterable bytes Quantization step size values (uninterpreted). + mantissa, exponent : iterable + Defines quantization factors. + guard_bits : int + Number of guard bits. References ---------- diff --git a/glymur/jp2k.py b/glymur/jp2k.py index 2994742..ea8ef5e 100644 --- a/glymur/jp2k.py +++ b/glymur/jp2k.py @@ -4,10 +4,14 @@ License: MIT """ import sys + +# Exitstack not found in contextlib in 2.7 +# pylint: disable=E0611 if sys.hexversion >= 0x03030000: from contextlib import ExitStack else: from contextlib2 import ExitStack + import ctypes import math import os @@ -22,63 +26,13 @@ from .core import GREYSCALE from .core import PROGRESSION_ORDER from .core import ENUMERATED_COLORSPACE, RESTRICTED_ICC_PROFILE from .jp2box import Jp2kBox -from .jp2box import JPEG2000SignatureBox -from .jp2box import FileTypeBox -from .jp2box import JP2HeaderBox -from .jp2box import ContiguousCodestreamBox +from .jp2box import JPEG2000SignatureBox, FileTypeBox, JP2HeaderBox +from .jp2box import ColourSpecificationBox, ContiguousCodestreamBox from .jp2box import ImageHeaderBox -from .jp2box import ColourSpecificationBox from .lib import openjpeg as opj from .lib import openjp2 as opj2 from .lib import c as libc -# Need to known if openjp2 library is the officially release v2.0.0 or not. -_OPENJP2_IS_OFFICIAL_V2 = False -if opj2.OPENJP2 is not None: - if opj2.version() == '2.0.0': - if not hasattr(opj2.OPENJP2, - 'opj_stream_create_default_file_stream_v3'): - _OPENJP2_IS_OFFICIAL_V2 = True - -_COLORSPACE_MAP = {'rgb': opj2.CLRSPC_SRGB, - 'gray': opj2.CLRSPC_GRAY, - 'grey': opj2.CLRSPC_GRAY, - 'ycc': opj2.CLRSPC_YCC} - -# Setup the default callback handlers. See the callback functions subsection -# in the ctypes section of the Python documentation for a solid explanation of -# what's going on here. -_CMPFUNC = ctypes.CFUNCTYPE(ctypes.c_void_p, ctypes.c_char_p, ctypes.c_void_p) - - -def _default_error_handler(msg, _): - """Default error handler callback for openjpeg library.""" - msg = "OpenJPEG library error: {0}".format(msg.decode('utf-8').rstrip()) - opj2.set_error_message(msg) - - -def _default_info_handler(msg, _): - """Default info handler callback for openjpeg library.""" - print("[INFO] {0}".format(msg.decode('utf-8').rstrip())) - - -def _default_warning_handler(library_msg, _): - """Default warning handler callback for openjpeg library.""" - library_msg = library_msg.decode('utf-8').rstrip() - msg = "OpenJPEG library warning: {0}".format(library_msg) - warnings.warn(msg) - -_ERROR_CALLBACK = _CMPFUNC(_default_error_handler) -_INFO_CALLBACK = _CMPFUNC(_default_info_handler) -_WARNING_CALLBACK = _CMPFUNC(_default_warning_handler) - - -class LibraryNotFoundError(IOError): - """Raised if functionality is requested without the necessary library. - """ - def __init__(self, msg): - IOError.__init__(self, msg) - class Jp2k(Jp2kBox): """JPEG 2000 file. @@ -1313,3 +1267,50 @@ def _validate_compression_params(img_array, cparams): msg = "Only uint8 and uint16 images are currently supported." raise RuntimeError(msg) +# Need to known if openjp2 library is the officially release v2.0.0 or not. +_OPENJP2_IS_OFFICIAL_V2 = False +if opj2.OPENJP2 is not None: + if opj2.version() == '2.0.0': + if not hasattr(opj2.OPENJP2, + 'opj_stream_create_default_file_stream_v3'): + _OPENJP2_IS_OFFICIAL_V2 = True + +_COLORSPACE_MAP = {'rgb': opj2.CLRSPC_SRGB, + 'gray': opj2.CLRSPC_GRAY, + 'grey': opj2.CLRSPC_GRAY, + 'ycc': opj2.CLRSPC_YCC} + +# Setup the default callback handlers. See the callback functions subsection +# in the ctypes section of the Python documentation for a solid explanation of +# what's going on here. +_CMPFUNC = ctypes.CFUNCTYPE(ctypes.c_void_p, ctypes.c_char_p, ctypes.c_void_p) + + +def _default_error_handler(msg, _): + """Default error handler callback for openjpeg library.""" + msg = "OpenJPEG library error: {0}".format(msg.decode('utf-8').rstrip()) + opj2.set_error_message(msg) + + +def _default_info_handler(msg, _): + """Default info handler callback for openjpeg library.""" + print("[INFO] {0}".format(msg.decode('utf-8').rstrip())) + + +def _default_warning_handler(library_msg, _): + """Default warning handler callback for openjpeg library.""" + library_msg = library_msg.decode('utf-8').rstrip() + msg = "OpenJPEG library warning: {0}".format(library_msg) + warnings.warn(msg) + +_ERROR_CALLBACK = _CMPFUNC(_default_error_handler) +_INFO_CALLBACK = _CMPFUNC(_default_info_handler) +_WARNING_CALLBACK = _CMPFUNC(_default_warning_handler) + + +class LibraryNotFoundError(IOError): + """Raised if functionality is requested without the necessary library. + """ + def __init__(self, msg): + IOError.__init__(self, msg) + diff --git a/glymur/test/test_jp2k.py b/glymur/test/test_jp2k.py index c018897..747782f 100644 --- a/glymur/test/test_jp2k.py +++ b/glymur/test/test_jp2k.py @@ -225,7 +225,7 @@ class TestJp2k(unittest.TestCase): Jp2k(filename) @unittest.skipIf(os.name == "nt", "NamedTemporaryFile issue on windows") - def test_write_with_JP2_suffix(self): + def test_write_with_jp2_in_caps(self): """should be able to write with JP2 suffix.""" j2k = Jp2k(self.j2kfile) expdata = j2k.read()