def print_lutmAB(buf, indent): ic = ordb(buf[0]) oc = ordb(buf[1]) boffs = ordl(buf[4:8]) mtffs = ordl(buf[8:12]) moffs = ordl(buf[12:16]) coffs = ordl(buf[16:20]) aoffs = ordl(buf[20:24]) print_indent("Input channels : %d" % ic, indent) print_indent("Output channels : %d" % oc, indent) if aoffs != 0: print_indent("A curve :", indent) print_tag(buf[aoffs - 8:], len(buf[aoffs - 8:]), indent + 2) if boffs != 0: print_indent("B curve :", indent) print_tag(buf[boffs - 8:], len(buf[boffs - 8:]), indent + 2) if moffs != 0: print_indent("M curve :", indent) print_tag(buf[moffs - 8:], len(buf[moffs - 8:]), indent + 2) if coffs != 0: print_indent("Color Lookup Table:", indent) print_clut(buf[coffs - 8:], ic, oc, indent + 2) if mtffs != 0: print_indent("Affine Trafo :", indent) print_matrix(buf[mtffs - 8:], indent + 2)
def print_xyz(buffer, indent): x = ordl(buffer[0:4]) y = ordl(buffer[4:8]) z = ordl(buffer[8:12]) print_indent("X : 0x%08x = %g" % (x, s15d(x)), indent) print_indent("Y : 0x%08x = %g" % (y, s15d(y)), indent) print_indent("Z : 0x%08x = %g" % (z, s15d(z)), indent)
def print_mluc(buf, indent): count = ordl(buf[0:4]) recs = ordl(buf[4:8]) offs = 8 for i in range(count): code = ordw(buf[offs:offs + 2]) cntr = ordw(buf[offs + 2:offs + 4]) lnth = ordl(buf[offs + 4:offs + 8]) disp = ordl(buf[offs + 8:offs + 12]) offs = offs + recs print_indent( "Entry %d for language %c%c, country %c%c :" % (i, code >> 8, code & 0xff, cntr >> 8, cntr & 0xff), indent) print_hex(buf[disp - 8:disp - 8 + lnth], indent + 2)
def __init__(self, buf, offset): self.offset = offset self.en = ordw(buf[6:8]) self.seq = ordl(buf[8:12]) self.lbox = ordl(buf[12:16]) if self.lbox != 1 and self.lbox < 8: raise InvalidBoxSize() self.type = buf[16:20] if self.lbox == 1: self.lbox = ordq(buf[20:28]) self.buffer = buf[28:] self.body = self.lbox - 4 - 4 - 8 else: self.buffer = buf[20:] self.body = self.lbox - 4 - 4
def print_meas(buffer, indent): obs = ordl(buffer[0:4]) if obs == 0: observer = "unknown" elif obs == 1: observer = "CIE 1931" elif obs == 2: observer = "CIE 1964" else: observer = "invalid" print_indent("Observer : %s" % observer, indent) print_indent("Backing :", indent) print_xyz(buffer[4:], indent + 1) geom = ordl(buffer[16:20]) if geom == 0: geometry = "unknown" elif geom == 1: geometry = "0/45 or 45/0" elif geom == 2: geometry = "0/d or d/0" else: geometry = "invalid" print_indent("Geometry : %s" % geometry, indent) flare = ordl(buffer[20:24]) print_indent( "Flare : 0x%08x = %g%%" % (flare, flare * 100.0 / 65536.0), indent) ilm = ordl(buffer[24:38]) if ilm == 0: illum = "unknown" elif ilm == 1: illum = "D50" elif ilm == 2: illum = "D65" elif ilm == 3: illum = "D93" elif ilm == 4: illum = "F2" elif ilm == 5: illum = "D55" elif ilm == 6: illum = "A" elif ilm == 7: illum = "E" elif ilm == 8: illum = "F8" else: illum = "invalid" print_indent("Illuminant: %s" % illum, indent)
def print_view(buffer, indent): print_indent("Illuminant:", indent) print_xyz(buffer, indent + 1) print_indent("Surround :", indent) print_xyz(buffer[12:], indent + 1) ilm = ordl(buffer[24:38]) if ilm == 0: illum = "unknown" elif ilm == 1: illum = "D50" elif ilm == 2: illum = "D65" elif ilm == 3: illum = "D93" elif ilm == 4: illum = "F2" elif ilm == 5: illum = "D55" elif ilm == 6: illum = "A" elif ilm == 7: illum = "E" elif ilm == 8: illum = "F8" else: illum = "invalid" print_indent("Illuminant: %s" % illum, indent)
def read_TLM(self): self._new_marker("TLM", "Tile-part length") if self.size < 4: raise InvalidSizedMarker("TLM") self.print_header("Index", str(ordb(self.buffer[self.pos + 2]))) stlm = ordb(self.buffer[self.pos + 3]) >> 4 st = stlm & 0x03 sp = (stlm >> 2) & 0x1 if st == 3: raise InvalidMarkerField("TLM", "Stlm") if st == 0: if sp == 0: if (self.size - 4) % 2 != 0: raise InvalidSizedMarker("TLM") tileparts = (self.size - 4) / 2 else: if (self.size - 4) % 4 != 0: raise InvalidSizedMarker("TLM") tileparts = (self.size - 4) / 4 elif st == 1: if sp == 0: if (self.size - 4) % 3 != 0: raise InvalidSizedMarker("TLM") tileparts = (self.size - 4) / 3 else: if (self.size - 4) % 5 != 0: raise InvalidSizedMarker("TLM") tileparts = (self.size - 4) / 5 else: if sp == 0: if (self.size - 4) % 4 != 0: raise InvalidSizedMarker("TLM") tileparts = (self.size - 4) / 4 else: if (self.size - 4) % 6 != 0: raise InvalidSizedMarker("TLM") tileparts = (self.size - 4) / 6 self.pos += 4 ttlm = "" for i in range(tileparts): if st == 0: ttlm = "in order" if st == 1: ttlm = str(ordb(self.buffer[self.pos + 0])) self.pos += 1 elif st == 2: ttlm = str(ordw(self.buffer[self.pos + 0:self.pos + 2])) self.pos += 2 self.print_header("Tile index #%d" % i, ttlm) if sp == 0: length = ordw(self.buffer[self.pos + 0:self.pos + 2]) self.pos += 2 else: length = ordl(self.buffer[self.pos + 0:self.pos + 4]) self.pos += 4 self.print_header("Length #%d" % i, str(length)) self._end_marker()
def print_tag(buf, size, indent): sign = buf[0:4] print_indent("Tag type: %s" % sign.decode('ascii'), indent) print_indent("Reserved: %d" % ordl(buf[4:8]), indent) if sign == "desc": size = ordl(buf[8:12]) print_indent( "Profile description: %s" % buf[12:12 + size - 1].decode('ascii'), indent) elif sign == "text": print_indent("Text: %s" % buf[8:len(buf) - 1].decode('ascii'), indent) elif sign == "XYZ ": count = (len(buf) - 8) // 12 off = 8 for i in range(count): print_xyz(buf[off:off + 12], indent) off += 12 elif sign == "curv": print_curve(buf[8:8 + size], indent) elif sign == "dtim": print_datetime(buf[8:8 + size], indent) elif sign == "view": print_view(buf[8:8 + size], indent) elif sign == "meas": print_meas(buf[8:8 + size], indent) elif sign == "sig ": print_indent("Signature : %s " % readsignature(buf[8:8 + size]), indent) elif sign == "mft1": print_lut8(buf[8:8 + size], indent) elif sign == "mft2": print_lut16(buf[8:8 + size], indent) elif sign == "mAB ": print_lutmAB(buf[8:8 + size], indent) elif sign == "mBA ": print_lutmAB(buf[8:8 + size], indent) elif sign == "para": print_para(buf[8:8 + size], indent) elif sign == "mluc": print_mluc(buf[8:8 + size], indent) elif sign == "sf32": print_sf32(buf[8:8 + size], indent) else: print_hex(buf[8:8 + size], indent)
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 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 read_CAP(self): self._new_marker("CAP", "Extended Capabilities Marker") pcap = ordl(self.buffer[self.pos + 2:self.pos + 6]) offs = self.pos + 6 for i in range(32): if pcap & (1 << (32 - i)): if offs >= self.pos + self.size: raise InvalidSizedMarker("CAP") self.print_header("Extended capabilities for part %d" % i, "0x%x" % (ordw(self.buffer[offs:offs + 2]))) offs += 2 self._end_marker() self.pos += self.size
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 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 print_curve(buffer, indent): count = ordl(buffer[0:4]) if count == 0: print_indent("Identity mapping", indent) elif count == 1: gamma = ordw(buffer[4:6]) print_indent( "Gamma mapping, gamma : 0x%04x = %g" % (gamma, gamma * 1.0 / 256.0), indent) else: off = 4 for i in range(count): value = ordw(buffer[off:off + 2]) if i % 4 == 0: if i != 0: print("") for j in range(indent): print(" ", end=' ') print("0x%04x = %g " % (value, value * 1.0 / 65535), end=' ') off += 2 print("")
def parse_header(self): if self.end > 0: if self.infile.tell() == self.end: return [] elif self.infile.tell() > self.end: raise InvalidBoxLength("unknown box") length = self.infile.read(4) if len(length) == 0: return [] elif len(length) < 4: raise UnexpectedEOF() length = ordl(length) id = self.infile.read(4).decode('ascii') if len(id) < 4: raise UnexpectedEOF self.offset += 8 self.hdrsize = 8 # Read XLBox (extra box length, if any) if length == 1: xlength = self.infile.read(8) self.offset += 8 self.hdrsize = 16 if len(xlength) < 8: raise UnexpectedEOF length = ordq(xlength) if length < 16: raise InvalidBoxLength(self.boxname(id)) else: length -= 16 elif 0 < length < 8: raise InvalidBoxLength(self.boxname(id)) elif length > 0: length -= 8 elif length == 0: return id, self.boxsize = length return length, id
def parse_string_header(self, buf): length = ordl(buf) id = buf[4:8] buf = buf[8:len(buf)] # Read XLBox (extra box length, if any) if length == 1: xlength = buf[0:8] buf = buf[8:len(buf)] if len(xlength) < 8: raise UnexpectedEOF length = ordq(xlength) if length < 16: raise InvalidBoxLength(self.boxname(id)) else: length -= 16 elif 0 < length < 8: raise InvalidBoxLength(self.boxname(id)) elif length > 0: length -= 8 return buf, length, id
def readsignature(buf): signature = ordl(buf[0:4]) return "0 (undefined)" if signature == 0 else buf[0:4]
def print_matrix(buf, indent): e1 = ordl(buf[0:4]) e2 = ordl(buf[4:8]) e3 = ordl(buf[8:12]) e4 = ordl(buf[12:16]) e5 = ordl(buf[16:20]) e6 = ordl(buf[20:24]) e7 = ordl(buf[24:28]) e8 = ordl(buf[28:32]) e9 = ordl(buf[32:36]) e10 = ordl(buf[36:40]) e11 = ordl(buf[40:44]) e12 = ordl(buf[44:48]) print_indent( "Matrix : 0x%08x 0x%08x 0x%08x\t%8g\t%8g\t%8g" % (e1, e2, e3, s15d(e1), s15d(e2), s15d(e3)), indent) print_indent( " 0x%08x 0x%08x 0x%08x\t%8g\t%8g\t%8g" % (e4, e5, e6, s15d(e4), s15d(e5), s15d(e6)), indent) print_indent( " 0x%08x 0x%08x 0x%08x\t%8g\t%8g\t%8g" % (e7, e8, e9, s15d(e7), s15d(e8), s15d(e9)), indent) print_indent( "Offset : 0x%08x 0x%08x 0x%08x\t%8g\t%8g\t%8g" % (e10, e11, e12, s15d(e10), s15d(e11), s15d(e11)), indent)
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()
def print_para(buf, indent): curv = ordw(buf[0:2]) if curv == 0: print_indent("Gamma mapping", indent) gamma = s15d(ordl(buf[4:8])) print_indent("Gamma : %g" % gamma, indent) elif curv == 1: print_indent("CIE 122-1966", indent) gamma = s15d(ordl(buf[4:8])) a = s15d(ordl(buf[8:12])) b = s15d(ordl(buf[12:16])) print_indent("Gamma : %g" % gamma, indent) print_indent("A : %g" % a, indent) print_indent("B : %g" % b, indent) elif curv == 2: print_indent("IEC 61996-3", indent) gamma = s15d(ordl(buf[4:8])) a = s15d(ordl(buf[8:12])) b = s15d(ordl(buf[12:16])) c = s15d(ordl(buf[16:20])) print_indent("Gamma : %g" % gamma, indent) print_indent("A : %g" % a, indent) print_indent("B : %g" % b, indent) print_indent("C : %g" % c, indent) elif curv == 3: gamma = s15d(ordl(buf[4:8])) a = s15d(ordl(buf[8:12])) b = s15d(ordl(buf[12:16])) c = s15d(ordl(buf[16:20])) d = s15d(ordl(buf[20:24])) print_indent("IEC 61966-2.1 (sRGB)", indent) print_indent("Gamma : %g" % gamma, indent) print_indent("A : %g" % a, indent) print_indent("B : %g" % b, indent) print_indent("C : %g" % c, indent) print_indent("D : %g" % d, indent) elif curv == 4: print_indent("Affine Gamma with Toe", indent) gamma = s15d(ordl(buf[4:8])) a = s15d(ordl(buf[8:12])) b = s15d(ordl(buf[12:16])) c = s15d(ordl(buf[16:20])) d = s15d(ordl(buf[20:24])) e = s15d(ordl(buf[24:28])) print_indent("Gamma : %g" % gamma, indent) print_indent("A : %g" % a, indent) print_indent("B : %g" % b, indent) print_indent("C : %g" % c, indent) print_indent("D : %g" % d, indent) print_indent("E : %g" % e, indent)
def read_MCC(self): self._new_marker("MCC", "Multiple component collection") if self.size < 5: raise InvalidSizedMarker("MCC") zmcc = ordw(self.buffer[self.pos + 2:self.pos + 4]) self.print_header("Concatenation index", str(zmcc)) imcc = ordb(self.buffer[self.pos + 4]) self.print_header("Reference index", str(imcc)) self.pos += 5 qmcc = 0 if zmcc == 0: ymcc = ordw(self.buffer[self.pos + 0:self.pos + 2]) self.print_header("Last concatenation index", str(ymcc)) qmcc = ordw(self.buffer[self.pos + 2:self.pos + 4]) self.print_header("Number of collections", str(qmcc)) self.pos += 4 for i in range(qmcc): ctp = ordb(self.buffer[self.pos]) if ctp & 3 == 0: s = "array based dependency transformation" elif ctp & 3 == 1: s = "array based decorrelation transformation" elif ctp & 3 == 3: s = "wavelet based transformation" else: s = "invalid type" self.print_header("Transformation type", s) self.pos += 1 nmcc = ordw(self.buffer[self.pos + 0:self.pos + 2]) if nmcc & (1 << 15): self.print_header("Collection %d input index size" % i, "16 bit") intype = 2 nmcc -= 1 << 15 else: self.print_header("Collection %d input index size" % i, "8 bit") intype = 1 self.print_header("Collection %d # of input components" % i, nmcc) self.pos += 2 for j in range(nmcc): if intype == 2: incom = ordw(self.buffer[self.pos + 0:self.pos + 2]) self.pos += 2 else: incom = ordb(self.buffer[self.pos]) self.pos += 1 self.print_header("Collection %d input component %d" % (i, j), str(incom)) mmcc = ordw(self.buffer[self.pos + 0:self.pos + 2]) if mmcc & (1 << 15): self.print_header("Collection %d output index size" % i, "16 bit") outtype = 2 mmcc -= 1 << 15 else: self.print_header("Collection %d output index size" % i, "8 bit") outtype = 1 self.print_header("Collection %d # of output components" % i, mmcc) self.pos += 2 for j in range(mmcc): if outtype == 2: outcom = ordw(self.buffer[self.pos + 0:self.pos + 2]) self.pos += 2 else: outcom = ordb(self.buffer[self.pos]) self.pos += 1 self.print_header("Collection %d output component %d" % (i, j), str(outcom)) if ctp & 3 == 3: self.print_header("Number of decomposition levels", ordb(self.buffer[self.pos])) if ordb(self.buffer[self.pos + 1]) == 0: s = "null" else: s = "in MCT marker %d" % ordb(self.buffer[self.pos + 1]) self.print_header("Collection %d offset vector" % i, s) if ordb(self.buffer[self.pos + 2]) == 0: s = "9-7 irreversible" elif ordb(self.buffer[self.pos + 2]) == 1: s = "5-3 reversible" else: s = "defined in ATK segment %d " % ordb( self.buffer[self.pos + 2]) self.print_header("Wavelet filter used", s) self.pos += 3 self.print_header("Collection %d reference grid offset" % i, ordl(self.buffer[self.pos + 0:self.pos + 4])) self.pos += 4 else: if ordb(self.buffer[self.pos]) & 1: s = "reversible" else: s = "irreversible" self.print_header("Collection %d transformation is" % i, s) if ordb(self.buffer[self.pos + 1]) == 0: s = "null" else: s = "in MCT marker %d" % ordb(self.buffer[self.pos + 1]) self.print_header("Collection %d offset vector" % i, s) if ordb(self.buffer[self.pos + 2]) == 0: s = "identity" else: s = "in MCT marker %d" % ordb(self.buffer[self.pos + 2]) self.print_header("Collection %d matrix" % i, s) self.pos += 3 self._end_marker()
def read_MCT(self): self._new_marker("MCT", "Multiple component transformation") len = self.size - 6 if len < 0: raise InvalidSizedMarker("MCT") zmct = ordw(self.buffer[self.pos + 2:self.pos + 4]) self.print_header("Concatenation index", str(zmct)) imct = ordb(self.buffer[self.pos + 5]) self.print_header("Reference index", str(imct)) type = ordb(self.buffer[self.pos + 4]) if type & 3 == 0: s = "Dependency transform" elif type & 3 == 1: s = "Decorrelation matrix" elif type & 3 == 2: s = "Offset vector" else: s = "Unknown" self.print_header("Transform type", s) if type & 12 == 0: s = "16 bit integer" l = 2 elif type & 12 == 4: s = "32 bit integer" l = 4 elif type & 12 == 8: s = "32 bit IEEE float" l = 4 else: # elif type & 12 == 12: s = "64 bit IEEE float" l = 8 self.print_header("Data type", s) self.pos += 6 if zmct == 0: ymct = ordw(self.buffer[self.pos + 0:self.pos + 2]) self.print_header("Last concatenation index", str(ymct)) self.pos += 2 len -= 2 if len % l != 0: raise InvalidSizedMarker("MCT") count = int(len / l) self.print_header("Number of entries", str(count)) for i in range(count): if type & 12 == 0: dt = ordw(self.buffer[self.pos + 0:self.pos + 2]) if dt >= (1 << 15): dt -= 1 << 16 s = str(dt) self.pos += 2 elif type & 12 == 4: dt = ordl(self.buffer[self.pos + 0:self.pos + 4]) if dt >= (1 << 31): dt -= 1 << 32 s = str(dt) self.pos += 4 elif type & 12 == 8: dt = ordl(self.buffer[self.pos + 0:self.pos + 4]) s = str(ieee_float_to_float(dt)) self.pos += 4 elif type & 12 == 12: dtl = ordq(self.buffer[self.pos + 0:self.pos + 8]) s = str(ieee_double_to_float(dtl)) self.pos += 8 self.print_header("Data entry %d" % i, s) self._end_marker()
def print_sf32(buf, indent): off = 0 for i in range(len(buf) // 4): v = ordl(buf[off:off + 4]) off = off + 4 print_indent("Entry %d : 0x%08x = %g" % (i, v, s15d(v)), indent + 2)
def print_desctag(buf, indent): size = ordl(buf[8:12]) print_indent("Profile description: %s" % buf[12:12 + size].decode('ascii'))
def read_SIZ(self): self._new_marker("SIZ", "Image and tile size") size = ordw(self.buffer[self.pos + 0:self.pos + 2]) if size < 41: raise InvalidSizedMarker("SIZ") if (size - 38) % 3 != 0: raise InvalidSizedMarker("SIZ") # Read Csiz components = (size - 38) // 3 self.csiz = ordw(self.buffer[self.pos + 36:self.pos + 38]) if self.csiz != components: raise InvalidSizedMarker("SIZ") # Read Rsiz rsiz = ordw(self.buffer[self.pos + 2:self.pos + 4]) if rsiz == 0: s = "JPEG2000 full standard" elif rsiz == 1: s = "JPEG2000 profile 0" elif rsiz == 2: s = "JPEG2000 profile 1" elif rsiz == 3: s = "DCI 2K profile" elif rsiz == 4: s = "DCI 4K profile" elif rsiz == 5: s = "DCI long term storage profile" elif rsiz == 6: s = "DCI 2K scalable profile" elif rsiz & (1 << 14): s = "JPEG2000 part 15" elif rsiz & (1 << 15): s = "JPEG2000 part 2" if rsiz & (1 << 11): s += " Precinct dependent QNT" if rsiz & (1 << 10): s += " Arbitrary ROIs" if rsiz & (1 << 9): s += " NLT transform" if rsiz & (1 << 8): s += " Multi-component transform" if rsiz & (1 << 7): s += " WSS transformation kernel" if rsiz & (1 << 6): s += " Arbitrary kernel" if rsiz & (1 << 5): s += " Arbitrary decomposition" if rsiz & (1 << 4): s += " Single sample overlap" if rsiz & (1 << 3): s += " Visual masking" if rsiz & (1 << 2): s += " Trellis quantization" if rsiz & (1 << 1): s += " Variable scalar quantization" if rsiz & (1 << 0): s += " Variable DC offset" else: s = "unknown" self.print_header("Required Capabilities", s) # Read Xsiz and Ysiz xsiz = ordl(self.buffer[self.pos + 4:self.pos + 8]) ysiz = ordl(self.buffer[self.pos + 8:self.pos + 12]) self.print_header("Reference Grid Size", "%dx%d" % (xsiz, ysiz)) # Read XOsiz and YOsiz xosiz = ordl(self.buffer[self.pos + 12:self.pos + 16]) yosiz = ordl(self.buffer[self.pos + 16:self.pos + 20]) self.print_header("Image Offset", "%dx%d" % (xosiz, yosiz)) # Read XTsiz and YTsiz xtsiz = ordl(self.buffer[self.pos + 20:self.pos + 24]) ytsiz = ordl(self.buffer[self.pos + 24:self.pos + 28]) self.print_header("Reference Tile Size", "%dx%d" % (xtsiz, ytsiz)) # Read XTOsiz and YTOsiz xtosiz = ordl(self.buffer[self.pos + 28:self.pos + 32]) ytosiz = ordl(self.buffer[self.pos + 32:self.pos + 36]) self.print_header("Reference Tile Offset", "%dx%d" % (xtosiz, ytosiz)) # Csiz (already read) self.print_header("Components", str(components)) # Read Components for i in range(0, components): ssiz = ordb(self.buffer[self.pos + 38 + i * 3]) xrsiz = ordb(self.buffer[self.pos + 39 + i * 3]) yrsiz = ordb(self.buffer[self.pos + 40 + i * 3]) self.print_header("Component #%d Depth" % i, "%d" % ((ssiz & 0x7f) + 1)) self.print_header("Component #%d Signed" % i, "yes" if ssiz & 0x80 else "no") self.print_header("Component #%d Sample Separation" % i, "%dx%d" % (xrsiz, yrsiz)) self._end_marker() self.pos += size
def parse_icc(indent, buf): indent += 1 print_indent("ICC profile size : %d bytes" % ordl(buf[0:4]), indent) print_indent("Preferred CMM type : %d" % ordl(buf[4:8]), indent) print_indent("ICC major version : %d" % ordb(buf[8]), indent) print_indent("ICC minor version : %d" % ordb(buf[9]), indent) print_indent("Profile class : %s" % buf[12:16].decode('ascii'), indent) print_indent("Canonical input space : %s" % buf[16:20].decode('ascii'), indent) print_indent("Profile connection space: %s" % buf[20:24].decode('ascii'), indent) print_indent("Creation date :", indent) print_datetime(buf[24:36], indent + 1) print_indent("Profile signature : %s" % buf[36:40].decode('ascii'), indent) print_indent("Platform singature : %s" % readsignature(buf[40:44]), indent) print_indent("Profile flags : 0x%08x" % ordl(buf[44:48]), indent) print_indent("Device manufacturer : %s" % readsignature(buf[48:52]), indent) print_indent("Device model : %s" % readsignature(buf[52:56]), indent) print_indent( "Device attributes : 0x%08x%08x" % (ordl(buf[56:60]), ordl(buf[60:64])), indent) intent = ordl(buf[64:68]) if intent == 0: rendering = "perceptual" elif intent == 1: rendering = "media-relative colorimetric" elif intent == 2: rendering = "saturation" elif intent == 3: rendering = "icc absolute colorimetric" else: rendering = "undefined intent %d" % intent print_indent("Rendering intent : %s" % rendering, indent) print_indent("PCS illuminant :", indent) print_xyz(buf[68:80], indent + 1) print_indent("Profile creator : %s" % readsignature(buf[80:84]), indent) print_indent( "Profile MD5 sum : %08lx%08lx%08x%08lx" % (ordl(buf[84:88]), ordl(buf[88:92]), ordl(buf[92:96]), ordl( buf[96:100])), indent) count = ordl(buf[128:132]) print_indent("Number of ICC tags : %d" % count, indent) off = 128 + 4 for i in range(count): offset = ordl(buf[off + 4:off + 8]) size = ordl(buf[off + 8:off + 12]) print_indent( "ICC tag %s at offset %d size %d:" % (buf[off:off + 4].decode('ascii'), offset, size), indent + 1) print_tag(buf[offset:offset + size], size, indent + 2) off += 12
def read_NLT(self): self._new_marker("NLT", "Nonlinearity transformation") if self.size < 6: raise InvalidSizedMarker("NLT") cnlt = ordw(self.buffer[self.pos + 2:self.pos + 4]) if cnlt == 0xffff: s = "for all components" else: s = "for component %d" % cnlt self.print_header("Non-Linearity defined", s) bdnlt = ordb(self.buffer[self.pos + 4]) if bdnlt & 0x80: s = "signed" bdnlt -= 0x80 else: s = "unsigned" self.print_header("Output sign", s) self.print_header("Output bit depth", str(bdnlt + 1)) tnlt = ordb(self.buffer[self.pos + 5]) if tnlt == 0: s = "none" elif tnlt == 1: s = "Gamma transformation" elif tnlt == 2: s = "Table lookup" elif tnlt == 3: s = "Two's completement to sign-magnitude conversion" else: s = "unknown" self.print_header("Non-Linearity type", s) self.pos += 6 if tnlt == 1: e = (ordb(self.buffer[self.pos + 0]) << 16) + \ (ordb(self.buffer[self.pos + 1]) << 8) + \ (ordb(self.buffer[self.pos + 2]) << 0) l = (ordb(self.buffer[self.pos + 3]) << 16) + \ (ordb(self.buffer[self.pos + 4]) << 8) + \ (ordb(self.buffer[self.pos + 5]) << 0) t = (ordb(self.buffer[self.pos + 6]) << 16) + \ (ordb(self.buffer[self.pos + 7]) << 8) + \ (ordb(self.buffer[self.pos + 8]) << 0) a = (ordb(self.buffer[self.pos + 9]) << 16) + \ (ordb(self.buffer[self.pos + 10]) << 8) + \ (ordb(self.buffer[self.pos + 11]) << 0) b = (ordb(self.buffer[self.pos + 12]) << 16) + \ (ordb(self.buffer[self.pos + 13]) << 8) + \ (ordb(self.buffer[self.pos + 14]) << 0) if e == 0: s = "ill-defined" else: s = str(1.0 / (e / 65536.0)) self.print_header("Gamma exponent", s) if l == 0: s = "ill-defined" else: s = str(1.0 / (l / 65536.0)) self.print_header("Linear slope", s) self.print_header("Threshold", str(t / 65536.0)) if a == 0: s = "ill-defined" else: s = str(1.0 / (a / 65536.0)) self.print_header("Nonlinear slope", s) self.print_header("Offset", str(b / 65536.0)) self.pos += 15 elif tnlt == 2: npts = ordw(self.buffer[self.pos + 0:self.pos + 2]) dmin = ordl(self.buffer[self.pos + 2:self.pos + 6]) dmax = ordl(self.buffer[self.pos + 6:self.pos + 10]) prec = ordb(self.buffer[self.pos + 10]) self.print_header("Number of points", npts) self.print_header("Range minimum", dmin / ((1 << 32) - 1.0)) self.print_header("Range maximum", dmax / ((1 << 32) - 1.0)) self.print_header("Data precision", "%d bits" % prec) self.pos += 11 for i in range(npts): if prec <= 8: dt = ordb(self.buffer[self.pos]) + 0 s = str(dt / ((1 << prec) - 1.0)) self.pos += 1 elif prec <= 16: dt = ordw(self.buffer[self.pos + 0:self.pos + 2]) s = str(dt / ((1 << prec) - 1.0)) self.pos += 2 elif prec <= 32: dt = ordl(self.buffer[self.pos + 0:self.pos + 4]) s = str(dt / ((1 << prec) - 1.0)) self.pos += 4 else: s = "ill-defined" self.print_header("Data entry %d" % i, s) self._end_marker()