def parse_Precinct(self, file, px, py): self._print_indent("%-8s: Precinct (%s,%s)" % (self.offset, px, py)) self.indent += 1 bytesize = (24 + 8 + 8 + 2 * self.bandcount + 7) >> 3 header = file.read(bytesize) self.offset = self.offset + bytesize psize = (ord(header[0:1]) << 16) + (ord(header[1:2]) << 8) + (ord(header[2:3]) << 0) qp = ord(header[3:4]) rp = ord(header[4:5]) self._print_indent("Data length : %s bytes" % psize) self._print_indent("Quantization : %s" % qp) self._print_indent("Refinement : %s" % rp) for b in range(self.bandcount): mode = (ordb(header[(b >> 2) + 5]) >> (6 - ((b & 0x03) << 1))) & 0x03 if mode == 0: modestr = "no prediction, no sigflags" elif mode == 1: modestr = "vertical prediction, no sigflags" elif mode == 2: modestr = "no prediction, sigflags" else: # elif mode == 3: modestr = "vertical prediction, sigflags" self._print_indent("Band %3s mode : %s" % (b, modestr)) file.read(psize) print("") self.offset += psize self.datacount += psize self.bytecount += psize + bytesize self._indent -= 1
def read_QCC(self): self._new_marker("QCC", "Quantization component") if self.size < 4: raise InvalidSizedMarker("QCC") if self.csiz <= 256: index = ordb(self.buffer[self.pos + 2]) self.pos += 3 else: index = ordw(self.buffer[self.pos + 2:self.pos + 4]) self.pos += 4 self.print_header("Index", str(index)) sqcc = ordb(self.buffer[self.pos + 0]) self.pos += 1 if sqcc & 0x1f == 0: s = "none" elif sqcc & 0x1f == 1: s = "scalar derived" elif sqcc & 0x1f == 2: s = "scalar expounded" else: s = "unknown" self.print_header("Quantization Type", s) self.print_header("Guard Bits", str(sqcc >> 5)) if self.csiz <= 256: subbands = self.size - 4 else: subbands = self.size - 5 if sqcc & 0x1f == 1 or sqcc & 0x1f == 2: if subbands % 2 != 0: raise InvalidSizedMarker("QCC") subbands = int(subbands / 2) for i in range(subbands): mantissa = 1.0 if sqcc & 0x1f == 1 or sqcc & 0x1f == 2: spqcd = ordw(self.buffer[self.pos + 0:self.pos + 2]) self.pos += 2 mantissa = 1.0 + ((spqcd & 0x7ff) / 2048.0) self.print_header("Mantissa #%d" % i, str(spqcd & 0x7ff)) exponent = spqcd >> 11 else: spqcd = ordb(self.buffer[self.pos + 0]) self.pos += 1 exponent = spqcd >> 3 self.print_header("Exponent #%d" % i, str(exponent)) self.print_header("Delta #%d" % i, mantissa * pow(2.0, -exponent)) self._end_marker()
def read_PPM(self): self._new_marker("PPM", "Packed packet headers, main header") if self.size < 3: raise InvalidSizedMarker("PPM") self.print_header("Index Zppm", str(ordb(self.buffer[self.pos + 2]))) self.print_header("Marker Length Lppm", str(self.size)) self._end_marker() self.pos += self.size
def read_QCD(self): self._new_marker("QCD", "Quantization default") if self.size < 4: raise InvalidSizedMarker("QCD") sqcd = ordb(self.buffer[self.pos + 2]) if sqcd & 0x1f == 0: s = "none" elif sqcd & 0x1f == 1: s = "scalar derived" elif sqcd & 0x1f == 2: s = "scalar expounded" elif sqcd & 0x1f == 3: s = "variable deadzone scalar derived" elif sqcd & 0x1f == 4: s = "variable deadzone scalar expounded" elif sqcd & 0x1f == 5: s = "variable deadzone scalar expounded" elif sqcd & 0x1f == 9: s = "trellis quantization derived" elif sqcd & 0x1f == 10: s = "trellis quantization expounded" else: s = "unknown" self.print_header("Quantization Type", s) self.print_header("Guard Bits", str(sqcd >> 5)) subbands = self.size - 3 if sqcd & 0x1f == 1 or sqcd & 0x1f == 2: if subbands % 2 != 0: raise InvalidSizedMarker("QCD") subbands = int(subbands / 2) for i in range(subbands): mantissa = 1.0 if sqcd & 0x1f == 1 or sqcd & 0x1f == 2: spqcd = ordw(self.buffer[self.pos + i * 2 + 3:self.pos + i * 2 + 5]) mantissa = 1.0 + ((spqcd & 0x7ff) / 2048.0) self.print_header("Mantissa #%d" % i, str(spqcd & 0x7ff)) exponent = spqcd >> 11 else: spqcd = ordb(self.buffer[self.pos + i + 3]) exponent = spqcd >> 3 self.print_header("Exponent #%d" % i, str(exponent)) self.print_header("Delta #%d" % i, str(mantissa * pow(2.0, -exponent))) self._end_marker() self.pos += self.size
def read_PLT(self): self._new_marker("PLT", "Packet length, tile-part header") if self.size < 3: raise InvalidSizedMarker("PLT") self.print_header("Index Zplt", str(ordb(self.buffer[self.pos + 2]))) self.print_header("Marker size Lplt", "%d bytes" % self.size) self._end_marker() self.pos += self.size
def parse_CTS(self): self._new_marker("CTS", "Colour Transformation Specification Marker") if len(self.buffer) != 2 + 4: raise InvalidSizedMarker("Size of the CTS marker shall be 4 bytes") cf = ordb(self.buffer[4]) ex = ordb(self.buffer[5]) if cf == 0: xfo = "full" elif cf == 3: xfo = "in-line" else: xfo = "invalid (%d)" % cf self.extent = xfo self._print_indent("Transformation type : %s" % xfo) self._print_indent("Red exponent : %s" % (ex >> 4)) self._print_indent("Blue exponent : %s" % (ex & 0x0f)) self._end_marker()
def read_marker(self): if len(self.buffer) - self.pos < 2: raise UnexpectedEOC() if ordb(self.buffer[self.pos + 0]) != 0xff: raise MisplacedData() self.marker = ordb(self.buffer[self.pos + 1]) self.pos += 2 if 0x30 <= self.marker <= 0x3f or \ self.marker == 0x4f or self.marker == 0x93 or \ self.marker == 0x92 or self.marker == 0xd9: self.size = None else: if len(self.buffer) - self.pos < 2: raise UnexpectedEOC() self.size = (ordb(self.buffer[self.pos + 0]) << 8) + \ (ordb(self.buffer[self.pos + 1]) << 0)
def load_marker(self, file, marker): mrk = ordw(marker[0:2]) if 0xff30 <= mrk <= 0xff3f: self.buffer = marker elif mrk in [0xff93, 0xff4f, 0xffd9, 0xff92]: self.buffer = marker elif 0xff4f <= mrk <= 0xff93: size = file.read(2) ln = ((ordb(size[0]) << 8) + (ordb(size[1]) << 0)) if ln < 2: raise InvalidSizedMarker("Marker too short") self.buffer = marker + size + file.read(ln - 2) if len(self.buffer) != ln + 2: raise UnexpectedEOC() else: raise MisplacedData() self.bytecount += len(self.buffer) self.pos = 0
def parse_frame(self, file, process): if ordw(self.buffer[0:2]) == 0xffde: self._new_marker("DHP", "Define hierarchical process") else: self._new_marker("SOF", "Start of frame, type: %s" % process) prec = ordb(self.buffer[4]) self._print_indent("Frame bit precision : %d" % prec) hei = ordw(self.buffer[5:7]) wid = ordw(self.buffer[7:9]) self._print_indent("Frame width : %d" % wid) self._print_indent("Frame height : %d" % hei) dep = ordb(self.buffer[9]) self._print_indent("Depth : %d" % dep) self.pos = 10 for i in range(dep): ci = ordb(self.buffer[self.pos]) self._print_indent("Component Id : %d" % ci) mcu = ordb(self.buffer[self.pos + 1]) self._print_indent("MCU Width : %d" % (mcu & 0x0f)) self._print_indent("MCU Height : %d" % (mcu >> 4)) qnt = ordb(self.buffer[self.pos + 2]) self._print_indent("Quantization Table : %d" % qnt) self.pos += 3 if ordw(self.buffer[0:2]) != 0xffde: print("") self.frametype = ordw(self.buffer[0:2]) self.load_buffer(file) marker = ordw(self.buffer[0:2]) while marker == 0xffc4 or marker == 0xffcc or marker >= 0xffd0: if marker == 0xffda: marker = self.parse_scan(file) if marker == 0xffdc: self.load_buffer(file) self.parse_DNL() marker = ordw(file.read(2)) file.seek(self.offset) if marker == 0xffdf or marker == 0xffd9: break else: self.parse_table() self.load_buffer(file) marker = ordw(self.buffer[0:2]) self._end_marker()
def read_PLM(self): self._new_marker("PLM", "Packet length, main header") if self.size < 3: raise InvalidSizedMarker("PLM") self.print_header("Index", str(ordb(self.buffer[self.pos + 2]))) self.pos += 3 self.size -= 3 self.print_header("Length", str(self.size)) self._end_marker() self.pos += self.size
def read_SOT(self): self._new_marker("SOT", "Start of tile-part") if len(self.buffer) - self.pos < 10: raise InvalidSizedMarker("SOT") size = ordw(self.buffer[self.pos + 0:self.pos + 2]) if size != 10: raise InvalidSizedMarker("SOT") self.print_header("Tile", str(ordw(self.buffer[self.pos + 2:self.pos + 4]))) length = ordl(self.buffer[self.pos + 4:self.pos + 8]) self.print_header("Length", str(length)) self.print_header("Index", str(ordb(self.buffer[self.pos + 8]))) if ordb(self.buffer[self.pos + 9]) == 0: s = "unknown" else: s = str(ordb(self.buffer[self.pos + 9])) self.print_header("Tile-Parts", s) self._end_marker() self.pos += 10
def stream_data(self, file): count = 0 while True: byte = file.read(1) if len(byte) != 1: raise UnexpectedEOC() count += 1 if ordb(byte[0]) == 0xff: marker = file.read(1) if len(marker) == 1: count += 1 if ordb(marker[0]) >= 0x90: self.offset += count - 2 self.print_data(count - 2) self.load_marker(file, byte + marker) if self.read_data_marker(): break self.offset += len(self.buffer) count = 0
def read_POC(self): self._new_marker("POC", "Progression order change") if self.size < 9: raise InvalidSizedMarker("POC") if self.csiz <= 256: if (self.size - 2) % 7 != 0: raise InvalidSizedMarker("POC") num = (self.size - 2) / 7 else: if (self.size - 2) % 9 != 0: raise InvalidSizedMarker("POC") num = (self.size - 2) / 9 self.pos += 2 for i in range(num): self.print_header("Resolution Level Index #%d (Start)" % i, str(ordb(self.buffer[self.pos]))) if self.csiz <= 256: rspoc = ordb(self.buffer[self.pos + 1]) self.pos += 2 else: rspoc = ordw(self.buffer[self.pos + 1:self.pos + 3]) self.pos += 3 self.print_header("Component Index #%d (Start)" % i, str(rspoc)) lyepoc = ordw(self.buffer[self.pos + 0:self.pos + 2]) self.print_header("Layer Index #%d (End)" % i, str(lyepoc)) self.print_header("Resolution Level Index #%d (End)" % i, str(ordb(self.buffer[self.pos + 2]))) if self.csiz <= 256: cepoc = ordb(self.buffer[self.pos + 3]) if cepoc == 0: cepoc = 256 self.pos += 4 else: cepoc = ordw(self.buffer[self.pos + 3:self.pos + 5]) if cepoc == 0: cepoc = 16384 self.pos += 5 self.print_header("Component Index #%d (End)" % i, str(cepoc)) po = self.progression_order(ordb(self.buffer[self.pos])) self.print_header("Progression Order #%d" % i, po) self.pos += 1 self._end_marker()
def read_NSI(self): self._new_marker("NSI", "Additional Dimension Image and Tile Size") size = ordw(self.buffer[self.pos + 0:self.pos + 2]) if size < 20 or size > 16403: raise InvalidSizedMarker("NSI") ndim = ordb(self.buffer[self.pos + 2]) zsiz = ordl(self.buffer[self.pos + 3:self.pos + 7]) osiz = ordl(self.buffer[self.pos + 7:self.pos + 11]) tsiz = ordl(self.buffer[self.pos + 11:self.pos + 15]) tosz = ordl(self.buffer[self.pos + 15:self.pos + 19]) self.print_header("Dimensionality", "%d" % ndim) self.print_header("Image Depth", "%d" % zsiz) self.print_header("Image Depth Offset", "%d" % osiz) self.print_header("Tile Depth", "%d" % tsiz) self.print_header("Tile Depth Offset", "%d" % tosz) for i in range(size - 19): self.print_header("Z Sample Separation for component %d" % i, "%d" % ordb(self.buffer[self.pos + 19 + i])) self.pos += size self._end_marker()
def print_lut8(buf, indent): print_lutheader(buf, indent) ic = ordb(buf[0]) oc = ordb(buf[1]) g = ordb(buf[2]) n = 256 m = 256 print_indent("Input entries : %d" % 256, indent) print_indent("Output entries : %d" % 256, indent) of = 40 for i in range(ic): print_indent("Input table %d :" % i, indent) print_hex(buf[of:of + n], indent + 1) of += n print_indent("CLUT table :", indent) print_hex(buf[of:of + pow(g, ic) * oc], indent + 1) of += pow(g, ic) * oc for i in range(oc): print_indent("Output table %d :" % i, indent) print_hex(buf[of:of + m], indent + 1) of += m
def print_lut16(buf, indent): print_lutheader(buf, indent) ic = ordb(buf[0]) oc = ordb(buf[1]) g = ordb(buf[2]) n = ordw(buf[40:42]) m = ordw(buf[42:44]) print_indent("Input entries : %d" % ordw(buf[40:42]), indent) print_indent("Output entries : %d" % ordw(buf[42:44]), indent) of = 44 for i in range(ic): print_indent("Input table %d :" % i, indent) print_hex(buf[of:of + 2 * n], indent + 1) of += 2 * n print_indent("CLUT table %d :" % ic, indent) print_hex(buf[of:of + 2 * pow(g, ic) * oc], indent + 1) of += 2 * pow(g, ic) * oc for i in range(oc): print_indent("Output table %d :" % i, indent) print_hex(buf[of:of + 2 * m], indent + 1) of += 2 * m
def print_lutheader(buf, indent): print_indent("Input channels : %d" % ordb(buf[0]), indent) print_indent("Output channels : %d" % ordb(buf[1]), indent) print_indent("Grid points : %d" % ordb(buf[2]), indent) e00 = ordl(buf[4:8]) e01 = ordl(buf[8:12]) e02 = ordl(buf[12:16]) e10 = ordl(buf[16:20]) e11 = ordl(buf[20:24]) e12 = ordl(buf[24:28]) e20 = ordl(buf[28:32]) e21 = ordl(buf[32:36]) e22 = ordl(buf[36:40]) print_indent( "Matrix : 0x%08x 0x%08x 0x%08x\t%8g\t%8g\t%8g" % (e00, e01, e02, s15d(e00), s15d(e01), s15d(e02)), indent) print_indent( " 0x%08x 0x%08x 0x%08x\t%8g\t%8g\t%8g" % (e10, e11, e12, s15d(e10), s15d(e11), s15d(e01)), indent) print_indent( " 0x%08x 0x%08x 0x%08x\t%8g\t%8g\t%8g" % (e20, e21, e22, s15d(e20), s15d(e21), s15d(e22)), indent)
def parse_CAP(self): self._new_marker("CAP", "Capabilities Marker") self.pos = 4 while self.pos < len(self.buffer): for bit in range(8): cap = ((ordb(self.buffer[self.pos])) >> (7 - bit)) & 1 if cap == 0: required = "not required" else: required = "is required" self._print_indent("Capability %3s : %s" % ((self.pos << 3) + bit - 32, required)) self.pos += 1 self._end_marker()
def parse_NLT(self): self._new_marker("NLT", "Nonlinearity Marker") tnlt = ordb(self.buffer[4]) if tnlt == 1: self.nlt = "quadratic" self._print_indent("NLT Type : quadratic") if len(self.buffer) != 2 + 2 + 1 + 2: raise InvalidSizedMarker("Size of the NLT marker shall be 5 bytes") t1 = ordw(self.buffer[5:7]) self._print_indent("DC Offset : %s" % t1) elif tnlt == 2: self.nlt = "extended" self._print_indent("NLT Type : extended") if len(self.buffer) != 2 + 12: raise InvalidSizedMarker("Size of NLT marker shall be 12 bytes") t1 = ordl(self.buffer[5:9]) t2 = ordl(self.buffer[9:13]) e = ordb(self.buffer[13]) self._print_indent("Threshold t1 : %s" % t1) self._print_indent("Threshold t2 : %s" % t2) self._print_indent("Slope exponent : %s" % e) self._end_marker()
def parse_DQT(self): self._new_marker("DQT", "Define quantization table") self.pos = 4 while self.pos < len(self.buffer): tq = ordb(self.buffer[self.pos]) self.pos += 1 pq = tq >> 4 tq &= 15 if pq == 0: ntry = "byte" elif pq == 1: ntry = "word" else: ntry = "invalid" self._print_indent("Entry size : %s" % ntry) self._print_indent("Table destination : %d" % tq) q = [] for i in range(64): if pq == 0: q = q + [ordb(self.buffer[self.pos])] self.pos += 1 elif pq == 1: q = q + [ordw(self.buffer[self.pos:self.pos + 2])] self.pos += 2 else: q += [0] scanorder = [ 0, 1, 5, 6, 14, 15, 27, 28, 2, 4, 7, 13, 16, 26, 29, 42, 3, 8, 12, 17, 25, 30, 41, 43, 9, 11, 18, 24, 31, 40, 44, 53, 10, 19, 23, 32, 39, 45, 52, 54, 20, 22, 33, 38, 46, 51, 55, 60, 21, 34, 37, 47, 50, 56, 59, 61, 35, 36, 48, 49, 57, 58, 62, 63 ] self._print_indent("Quantization Matrix : ") for y in range(8): line = "" for x in range(8): line = "%s %5d" % (line, q[scanorder[x + y * 8]]) self._print_indent(line) self._end_marker()
def read_COC(self): self._new_marker("COC", "Coding style component") if self.csiz <= 256 and self.size < 9 or \ self.csiz > 256 and self.size < 10: raise InvalidSizedMarker("COC") self.pos += 2 # Print Ccoc if self.csiz <= 256: component = ordb(self.buffer[self.pos + 0]) self.pos += 1 else: component = ordw(self.buffer[self.pos + 0:self.pos + 2]) self.pos += 2 self.print_header("Component", str(component)) # Print Scoc prec = ordb(self.buffer[self.pos + 0]) self.pos += 1 if prec == 0: s = "default" elif prec == 1: s = "custom" else: s = "unknown" self.print_header("Precincts", s) # Print SPcoc if prec == 0: if self.csiz <= 256 and self.size != 9 or \ self.csiz > 256 and self.size != 10: raise InvalidSizedMarker("COC") precincts = self.size - 9 if self.csiz > 256: precincts -= 1 self.read_SPco(precincts) self._end_marker()
def read_PPT(self): self._new_marker("PPT", "Packed packet headers, tile-part header") if self.size < 3: raise InvalidSizedMarker("PPT") self.print_header("Index", str(ordb(self.buffer[self.pos + 2]))) self.print_header("Contents", "") self._flush_marker() restlen = self.size - 3 self.pos += 3 cs = JP2Codestream(self._indent + 1) cs.parse_data(self.buffer[self.pos:self.pos + restlen]) self.datacount = self.datacount + cs.datacount self._end_marker() self.pos += restlen
def read_SGco(self): if len(self.buffer) - self.pos < 4: raise InvalidSizedMarker("SGco") self.print_header( "Progression Order", self.progression_order(ordb(self.buffer[self.pos + 0]))) self.print_header("Layers", str(ordw(self.buffer[self.pos + 1:self.pos + 3]))) trafo = ordb(self.buffer[self.pos + 3]) if trafo == 0: s = "none" elif trafo == 1: s = "components 0,1,2" elif trafo == 2: s = "generic array based transform" elif trafo == 4: s = "wavelet based transform" elif trafo == 6: s = "array and wavelet based transform" else: s = str(ordb(self.buffer[self.pos + 3])) self.print_header("Multiple Component Transformation", s) self.pos += 4
def parse_DAC(self): self._new_marker("DAC", "Define arithmetic coding conditioning") self.pos = 4 while self.pos < len(self.buffer): tc = ordb(self.buffer[self.pos]) if (tc >> 4) == 0: hclass = "dc" elif (tc >> 4) == 1: hclass = "ac" else: hclass = "invalid" self._print_indent("AC coding table class : %s" % hclass) self._print_indent("AC coding destination : %d" % (tc & 0x0f)) self.pos += 1 cond = ordb(self.buffer[self.pos]) self.pos += 1 if (tc >> 4) == 0: self._print_indent(" Lower Amplitude DC : %d" % (cond & 0x0f)) self._print_indent(" Upper Amplitude DC : %d" % (cond >> 4)) elif (tc >> 4) == 1: self._print_indent(" Block End AC : %d" % cond) self._end_marker()
def read_CBD(self): self._new_marker("CBD", "Component bit depth definition") if self.size < 5: raise InvalidSizedMarker("CBD") nbcd = ordw(self.buffer[self.pos + 2:self.pos + 4]) if nbcd & (1 << 15): nbcd -= 1 << 15 self.print_header("Definition style", "Identical depth and signs") count = 1 else: self.print_header("Definition style", "Individual depths and signs") count = nbcd self.print_header("Number of generated components", str(nbcd)) self.pos += 4 for i in range(count): if ordb(self.buffer[self.pos]) & (1 << 7): self.print_header("Component %d sign" % i, "signed") else: self.print_header("Component %d sign" % i, "unsigned") self.print_header("Component %d Bit Depth" % i, str(1 + (ordb(self.buffer[self.pos]) & 0x7f))) self.pos += 1 self._end_marker()
def read_COD(self): self._new_marker("COD", "Coding style default") if self.size < 3: raise InvalidSizedMarker("COD") cod = ordb(self.buffer[self.pos + 2]) self.print_header("Default Precincts of 2^15x2^15", "no" if cod & 0x01 else "yes") self.print_header("SOP Marker Segments", "yes" if cod & 0x02 else "no") self.print_header("EPH Marker Segments", "yes" if cod & 0x04 else "no") self.print_header("Codeblock X offset", "1" if cod & 0x08 else "0") self.print_header("Codeblock Y offset", "1" if cod & 0x10 else "0") self.print_header("All Flags", "%08x" % cod) self.pos += 3 self.read_SGco() self.read_SPco(self.size - 12) self._end_marker()
def parse_scan(self, file): self._new_marker("SOS", "Start of Scan") if len(self.buffer) < 2 + 2 + 1 + 1: raise InvalidSizedMarker("SOS") ns = ordb(self.buffer[4]) if len(self.buffer) != 2 + 6 + 2 * ns: raise InvalidSizedMarker("SOS") self._print_indent("Number of Components : %d" % ns) self.pos = 5 for i in range(ns): self._print_indent("Component % d : %d" % (i, ordb(self.buffer[self.pos]))) self.pos = self.pos + 1 table = ordb(self.buffer[self.pos]) if self.frametype == 0xfff7: self._print_indent("Mapping %d : %d" % (i, table)) else: dc = table >> 4 ac = table & 0x0f self._print_indent("DC table %d : %d" % (i, dc)) if self.frametype in [0xffc3, 0xffc7, 0xffcb, 0xffcf]: self._print_indent("Reserved %d : %d" % (i, ac)) else: self._print_indent("AC table %d : %d" % (i, ac)) self.pos += 1 sstart = ordb(self.buffer[self.pos]) sstop = ordb(self.buffer[self.pos + 1]) self.pos += 2 if self.frametype == 0xfff7: self._print_indent("Near : %d" % sstart) if sstop == 0: scantype = "plane interleaved" elif sstop == 1: scantype = "line interleaved" elif sstop == 2: scantype = "sample interleaved" else: scantype = "invalid, type %d" % sstop self._print_indent("Scan type : %s" % scantype) elif self.frametype in [0xffc3, 0xffc7, 0xffcb, 0xffcf]: self._print_indent("Predictor : %d" % sstart) self._print_indent("Reserved : %d" % sstop) else: self._print_indent("Scan start : %d" % sstart) self._print_indent("Scan stop : %d" % sstop) ah = ordb(self.buffer[self.pos]) al = ah & 0x0f ah >>= 4 self._print_indent("Shift high : %d" % ah) self._print_indent("Shift low : %d" % al) marker = self.parse_data(file, self.frametype == 0xfff7) self._end_marker() return marker
def read_SPco(self, precincts): if len(self.buffer) - self.pos < 5 + precincts: raise InvalidSizedMarker("SPco") levels = ordb(self.buffer[self.pos + 0]) if levels <= 32: self.print_header("Decomposition Levels", str(levels)) else: self.print_header("Downsampling factor style", str(levels)) self.print_header("Code-block size", "%dx%d" % \ (1 << (ordb(self.buffer[self.pos + 1]) + 2), 1 << (ordb(self.buffer[self.pos + 2]) + 2))) x = ordb(self.buffer[self.pos + 3]) self.print_header("Selective Arithmetic Coding Bypass", "yes" if x & 0x01 else "no") self.print_header("Reset Context Probabilities", "yes" if x & 0x02 else "no") self.print_header("Termination on Each Coding Pass", "yes" if x & 0x04 else "no") self.print_header("Vertically Causal Context", "yes" if x & 0x08 else "no") self.print_header("Predictable Termination", "yes" if x & 0x10 else "no") self.print_header("Segmentation Symbols", "yes" if x & 0x20 else "no") self.print_header("Entropy Coding", "FBCOT (Part 15)" if x & 0x40 else "EBCOT") if x & 0x40: self.print_header("Mixing of FBCOT and EBCOT", "yes" if x & 0x80 else "no") if ordb(self.buffer[self.pos + 4]) == 0x00: s = "9-7 irreversible" elif ordb(self.buffer[self.pos + 4]) == 0x01: s = "5-3 reversible" else: s = "arbitrary ATK specified transform" self.print_header("Wavelet Transformation", s) for i in range(precincts): x = ordb(self.buffer[self.pos + i + 5]) self.print_header("Precinct #%d Size Exponents" % i, "%dx%d" % (x & 0x0f, x >> 4)) self.pos += 5 + precincts
def parse_data(self, file, bitstuff): byte = 0 cnt = 0 while 1: last_byte = byte dta = file.read(1) if len(dta) != 1: raise UnexpectedEOC() self.offset += 1 self.datacount += 1 self.bytecount += 1 cnt += 1 byte = ordb(dta[0]) if last_byte == 0xff: if (byte > 0x00 and not bitstuff) or (byte >= 0x80 and bitstuff): marker = (last_byte << 8) | byte if 0xffd0 <= marker <= 0xffd7: self._markerpos = self.offset - 2 self.datacount = self.datacount - 2 self._new_marker( "RST", "Restart marker #%d" % (marker - 0xffd0)) self._end_marker() elif marker != 0xffff: # Skip filler bytes. print("") self._print_indent("%d bytes of entropy coded data" % (cnt - 2)) self.offset = self.offset - 2 file.seek(self.offset) return marker else: self.update_checksum(0xff) self.update_checksum(byte) elif byte != 0xff: self.update_checksum(byte)
def parse_PIH(self): self._new_marker("PIH", "Picture header") self.pos = 4 if len(self.buffer) != 2 + 26: raise InvalidSizedMarker("Size of the PIH marker shall be 26 bytes") lcod = ordl(self.buffer[self.pos + 0:self.pos + 4]) ppih = ordw(self.buffer[self.pos + 4:self.pos + 6]) plev = ordw(self.buffer[self.pos + 6:self.pos + 8]) wf = ordw(self.buffer[self.pos + 8:self.pos + 10]) hf = ordw(self.buffer[self.pos + 10:self.pos + 12]) cw = ordw(self.buffer[self.pos + 12:self.pos + 14]) hsl = ordw(self.buffer[self.pos + 14:self.pos + 16]) nc = ordb(self.buffer[self.pos + 16]) ng = ordb(self.buffer[self.pos + 17]) ss = ordb(self.buffer[self.pos + 18]) bw = ordb(self.buffer[self.pos + 19]) fqbr = ordb(self.buffer[self.pos + 20]) fq = fqbr >> 4 br = fqbr & 15 misc = ordb(self.buffer[self.pos + 21]) fslc = misc >> 7 ppoc = (misc >> 4) & 7 cpih = misc & 15 wavl = ordb(self.buffer[self.pos + 22]) nlx = wavl >> 4 nly = wavl & 15 cod = ordb(self.buffer[self.pos + 23]) lhdr = (cod >> 7) & 1 lraw = (cod >> 6) & 1 qpih = (cod >> 4) & 3 fs = (cod >> 2) & 2 rm = cod & 3 self.sliceheight = hsl self.precheight = 1 << nly self.width = wf self.height = hf self.depth = nc self.columnsize = cw self.hlevels = nlx self.vlevels = nly self.profile = ppih self.level = plev self.longhdr = lhdr self.rawbyline = lraw self.fractional = fq self.colortrafo = self.decode_cpih(cpih) if cw == 0: pwidthstr = "full width" else: pwidthstr = "%s 8*LL samples of max(sx)" % cw if fslc == 0: slicemode = "regular (in the DWT domain)" else: slicemode = "invalid (%s)" % fslc if ppoc == 0: progression = "resolution-line-band-component" else: progression = "invalid (%s)" % ppoc self._print_indent("Size of the codestream : %s" % lcod) self._print_indent("Profile : %s" % decode_Profile(ppih)) self._print_indent("Level : %s" % decode_Level(plev)) self._print_indent("Width of the frame : %s" % wf) self._print_indent("Height of the frame : %s" % hf) self._print_indent("Precinct width : %s " % pwidthstr) self._print_indent("Slice height : %s lines" % (hsl << nly)) self._print_indent("Number of components : %s" % nc) self._print_indent("Code group size : %s" % ng) self._print_indent("Significance group size : %s code groups" % ss) self._print_indent("Wavelet bit precision : %s bits" % bw) self._print_indent("Fractional bits : %s bits" % fq) self._print_indent("Raw bits per code group : %s bits" % br) self._print_indent("Slice coding mode : %s" % slicemode) self._print_indent("Progression mode : %s" % progression) self._print_indent("Colour decorrelation : %s" % self.colortrafo) self._print_indent("Horizontal wavelet levels : %s" % nlx) self._print_indent("Vertical wavelet levels : %s" % nly) self._print_indent("Forced long headers : %s" % lhdr) self._print_indent("Raw mode switch per line : %s" % lraw) self._print_indent("Quantizer type : %s" % self.decode_qpih(qpih)) self._print_indent("Sign handling : %s" % self.decode_fs(fs)) self._print_indent("Run mode : %s" % self.decode_rm(rm)) self._end_marker()