All parsing routines have the same signature now. #94
This commit is contained in:
parent
40e91dae7f
commit
2b5b1d081d
1 changed files with 81 additions and 69 deletions
|
|
@ -103,7 +103,7 @@ class Codestream(object):
|
|||
|
||||
read_buffer = fptr.read(2)
|
||||
try:
|
||||
marker_id, = struct.unpack('>H', read_buffer)
|
||||
self._marker_id, = struct.unpack('>H', read_buffer)
|
||||
except struct.error:
|
||||
# Treat this as a warning.
|
||||
msg = "Marker had length {0} instead of expected length of 2 "
|
||||
|
|
@ -111,13 +111,15 @@ class Codestream(object):
|
|||
warnings.warn(msg.format(len(read_buffer)))
|
||||
break
|
||||
|
||||
if marker_id == 0xff90 and header_only:
|
||||
self._offset = fptr.tell() - 2
|
||||
|
||||
if self._marker_id == 0xff90 and header_only:
|
||||
# Start-of-tile (SOT) means that we are out of the main header
|
||||
# and there is no need to go further.
|
||||
break
|
||||
|
||||
try:
|
||||
segment = self._process_marker_segment(fptr, marker_id)
|
||||
segment = self._process_marker_segment(fptr)
|
||||
except Exception as error:
|
||||
# Treat this as a warning.
|
||||
msg = str(error)
|
||||
|
|
@ -126,11 +128,11 @@ class Codestream(object):
|
|||
|
||||
self.segment.append(segment)
|
||||
|
||||
if marker_id == 0xffd9:
|
||||
if self._marker_id == 0xffd9:
|
||||
# end of codestream, should break.
|
||||
break
|
||||
|
||||
if marker_id == 0xff93:
|
||||
if self._marker_id == 0xff93:
|
||||
# If SOD, then we need to seek past the tile part bit stream.
|
||||
if self._parse_tpart_flag and not header_only:
|
||||
# But first parse the tile part bit stream for SOP and
|
||||
|
|
@ -140,93 +142,126 @@ class Codestream(object):
|
|||
|
||||
fptr.seek(self._tile_offset[-1] + self._tile_length[-1])
|
||||
|
||||
def _process_marker_segment(self, fptr, marker_id):
|
||||
def _process_marker_segment(self, fptr):
|
||||
"""Process and return a segment from the codestream.
|
||||
"""
|
||||
offset = fptr.tell() - 2
|
||||
if self._marker_id >= 0xff30 and self._marker_id <= 0xff3f:
|
||||
segment = self._parse_reserved_marker(fptr)
|
||||
|
||||
if marker_id >= 0xff30 and marker_id <= 0xff3f:
|
||||
the_id = '0x{0:x}'.format(marker_id)
|
||||
segment = Segment(marker_id=the_id, offset=offset, length=0)
|
||||
|
||||
elif marker_id == 0xff51:
|
||||
elif self._marker_id == 0xff51:
|
||||
segment = self._parse_siz_segment(fptr)
|
||||
|
||||
elif marker_id == 0xff52:
|
||||
elif self._marker_id == 0xff52:
|
||||
segment = self._parse_cod_segment(fptr)
|
||||
|
||||
elif marker_id == 0xff53:
|
||||
elif self._marker_id == 0xff53:
|
||||
segment = self._parse_coc_segment(fptr)
|
||||
|
||||
elif marker_id == 0xff55:
|
||||
elif self._marker_id == 0xff55:
|
||||
segment = self._parse_tlm_segment(fptr)
|
||||
|
||||
elif marker_id == 0xff58:
|
||||
elif self._marker_id == 0xff58:
|
||||
segment = self._parse_plt_segment(fptr)
|
||||
|
||||
elif marker_id == 0xff5c:
|
||||
elif self._marker_id == 0xff5c:
|
||||
segment = self._parse_qcd_segment(fptr)
|
||||
|
||||
elif marker_id == 0xff5d:
|
||||
elif self._marker_id == 0xff5d:
|
||||
segment = self._parse_qcc_segment(fptr)
|
||||
|
||||
elif marker_id == 0xff5e:
|
||||
elif self._marker_id == 0xff5e:
|
||||
segment = self._parse_rgn_segment(fptr)
|
||||
|
||||
elif marker_id == 0xff5f:
|
||||
elif self._marker_id == 0xff5f:
|
||||
segment = self._parse_pod_segment(fptr)
|
||||
|
||||
elif marker_id == 0xff60:
|
||||
elif self._marker_id == 0xff60:
|
||||
segment = self._parse_ppm_segment(fptr)
|
||||
|
||||
elif marker_id == 0xff61:
|
||||
elif self._marker_id == 0xff61:
|
||||
segment = self._parse_ppt_segment(fptr)
|
||||
|
||||
elif marker_id == 0xff63:
|
||||
elif self._marker_id == 0xff63:
|
||||
segment = self._parse_crg_segment(fptr)
|
||||
|
||||
elif marker_id == 0xff64:
|
||||
elif self._marker_id == 0xff64:
|
||||
segment = self._parse_cme_segment(fptr)
|
||||
|
||||
elif marker_id == 0xff90:
|
||||
elif self._marker_id == 0xff90:
|
||||
segment = self._parse_sot_segment(fptr)
|
||||
|
||||
elif marker_id == 0xff93:
|
||||
elif self._marker_id == 0xff93:
|
||||
segment = self._parse_sod_segment(fptr)
|
||||
|
||||
elif marker_id == 0xffd9:
|
||||
elif self._marker_id == 0xffd9:
|
||||
segment = self._parse_eoc_segment(fptr)
|
||||
|
||||
elif marker_id in _VALID_MARKERS:
|
||||
elif self._marker_id in _VALID_MARKERS:
|
||||
# It's a reserved marker that I don't know anything about.
|
||||
# See table A-1 in ISO/IEC FCD15444-1.
|
||||
segment = _parse_generic_segment(fptr, marker_id)
|
||||
segment = self._parse_reserved_segment(fptr)
|
||||
|
||||
elif ((marker_id & 0xff00) >> 8) == 255:
|
||||
# Peek ahead to see if the next two bytes are a marker or not.
|
||||
# Then seek back.
|
||||
msg = "Unrecognized marker id: 0x{0:x}".format(marker_id)
|
||||
warnings.warn(msg)
|
||||
cpos = fptr.tell()
|
||||
read_buffer = fptr.read(2)
|
||||
next_item, = struct.unpack('>H', read_buffer)
|
||||
fptr.seek(cpos)
|
||||
if ((next_item & 0xff00) >> 8) == 255:
|
||||
# No segment associated with this marker, so reset
|
||||
# to two bytes after it.
|
||||
segment = Segment(id='0x{0:x}'.format(marker_id),
|
||||
offset=offset, length=0)
|
||||
else:
|
||||
segment = _parse_generic_segment(fptr, marker_id)
|
||||
elif self._marker_id == 0xff79:
|
||||
segment = self._parse_unrecognized_segment(fptr)
|
||||
|
||||
else:
|
||||
msg = 'Invalid marker id encountered at byte {0:d} '
|
||||
msg += 'in codestream: "0x{1:x}"'
|
||||
msg = msg.format(offset, marker_id)
|
||||
msg = msg.format(self._offset, self._marker_id)
|
||||
raise IOError(msg)
|
||||
|
||||
return segment
|
||||
|
||||
def _parse_unrecognized_segment(self, fptr):
|
||||
"""Looks like a marker, but not sure what it is.
|
||||
"""
|
||||
msg = "Unrecognized marker id: 0x{0:x}".format(self._marker_id)
|
||||
warnings.warn(msg)
|
||||
cpos = fptr.tell()
|
||||
read_buffer = fptr.read(2)
|
||||
next_item, = struct.unpack('>H', read_buffer)
|
||||
fptr.seek(cpos)
|
||||
if ((next_item & 0xff00) >> 8) == 255:
|
||||
# No segment associated with this marker, so reset
|
||||
# to two bytes after it.
|
||||
segment = Segment(id='0x{0:x}'.format(self._marker_id),
|
||||
offset=self._offset, length=0)
|
||||
else:
|
||||
segment = self._parse_reserved_segment(fptr)
|
||||
return segment
|
||||
|
||||
|
||||
def _parse_reserved_marker(self, fptr):
|
||||
"""Marker range between 0xff30 and 0xff39.
|
||||
"""
|
||||
the_id = '0x{0:x}'.format(self._marker_id)
|
||||
segment = Segment(marker_id=the_id, offset=self._offset, length=0)
|
||||
return segment
|
||||
|
||||
|
||||
def _parse_reserved_segment(self, fptr):
|
||||
"""Parse a marker segment for which we know nothing of the segment itself.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
fptr : file
|
||||
Open file object.
|
||||
|
||||
Returns
|
||||
-------
|
||||
Segment instance.
|
||||
"""
|
||||
offset = fptr.tell() - 2
|
||||
|
||||
read_buffer = fptr.read(2)
|
||||
length, = struct.unpack('>H', read_buffer)
|
||||
data = fptr.read(length-2)
|
||||
|
||||
segment = Segment(marker_id='0x{0:x}'.format(self._marker_id),
|
||||
offset=offset, length=length, data=data)
|
||||
return segment
|
||||
|
||||
|
||||
def _parse_tile_part_bit_stream(self, fptr, sod_marker, tile_length):
|
||||
"""Parse the tile part bit stream for SOP, EPH marker segments."""
|
||||
read_buffer = fptr.read(tile_length)
|
||||
|
|
@ -1763,26 +1798,3 @@ def _print_quantization_style(sqcc):
|
|||
elif sqcc & 0x1f == 2:
|
||||
msg += 'scalar explicit, '
|
||||
return msg
|
||||
|
||||
|
||||
def _parse_generic_segment(fptr, marker_id):
|
||||
"""Parse a generic marker segment.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
fptr : file
|
||||
Open file object.
|
||||
|
||||
Returns
|
||||
-------
|
||||
Segment instance.
|
||||
"""
|
||||
offset = fptr.tell() - 2
|
||||
|
||||
read_buffer = fptr.read(2)
|
||||
length, = struct.unpack('>H', read_buffer)
|
||||
data = fptr.read(length-2)
|
||||
|
||||
segment = Segment(marker_id='0x{0:x}'.format(marker_id), offset=offset,
|
||||
length=length, data=data)
|
||||
return segment
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue