def __parseIFDs(self, base, start, end, IFD=""): assert IFD != "" log("Enter", "[%s]"%(IFD), "add") if not self._file: assert False entries = getBytes2(self._file, self._orderAPP1) log("Number of entries = %d"%(entries)) for idx in xrange(entries): tag = getBytes2(self._file, self._orderAPP1) dataFormat = getBytes2(self._file, self._orderAPP1) numOfComps = getBytes4(self._file, self._orderAPP1) posBeforeDataOffset = nowAt(self._file) dataOffset = getBytes4(self._file, self._orderAPP1) posAfterDataOffset = nowAt(self._file) if 0 == dataFormat or dataFormat >= len(EXIF_TIFF_DATAFORMAT_LIST): assert False, "dataformat incorrect = %d"%(dataFormat) continue bytesPerComp = EXIF_TIFF_DATAFORMAT_LIST[dataFormat] dataSize = bytesPerComp * numOfComps if dataSize > 4: targetOffset = base + dataOffset if targetOffset <= start or targetOffset >= end: continue else: seekTo(self._file, targetOffset) else: seekTo(self._file, posBeforeDataOffset) entry = self.__getDataFromFormat(tag, dataFormat, dataSize) seekTo(self._file, posAfterDataOffset) log("Leave", "[%s]"%(IFD), "remove")
def __parseIFDs(self, base, start, end, IFD=""): assert IFD != "" log("Enter", "[%s]" % (IFD), "add") if not self._file: assert False entries = getBytes2(self._file, self._orderAPP1) log("Number of entries = %d" % (entries)) for idx in xrange(entries): tag = getBytes2(self._file, self._orderAPP1) dataFormat = getBytes2(self._file, self._orderAPP1) numOfComps = getBytes4(self._file, self._orderAPP1) posBeforeDataOffset = nowAt(self._file) dataOffset = getBytes4(self._file, self._orderAPP1) posAfterDataOffset = nowAt(self._file) if 0 == dataFormat or dataFormat >= len(EXIF_TIFF_DATAFORMAT_LIST): assert False, "dataformat incorrect = %d" % (dataFormat) continue bytesPerComp = EXIF_TIFF_DATAFORMAT_LIST[dataFormat] dataSize = bytesPerComp * numOfComps if dataSize > 4: targetOffset = base + dataOffset if targetOffset <= start or targetOffset >= end: continue else: seekTo(self._file, targetOffset) else: seekTo(self._file, posBeforeDataOffset) entry = self.__getDataFromFormat(tag, dataFormat, dataSize) seekTo(self._file, posAfterDataOffset) log("Leave", "[%s]" % (IFD), "remove")
def GetCurveHelper(_fd, sig): reserved = getBytes4(_fd) assert reserved == 0 count = getBytes4(_fd) exp = None tblLookUp = [] if count in [0, 1]: first = 1.0 if count == 0 else getCharToOrd(_fd) second = 0.0 if count == 0 else getCharToOrd(_fd) exp = first + float(second/256.0) log(" count = %d / exp(%f)"%(count, exp)) else: for _ in xrange(count): first, second = getCharToOrd(_fd), getCharToOrd(_fd) v = first + float(second/256.0) tblLookUp.append(v) log(" count = %d "%(count)) sigDescObj = Curve(sig, exp, tblLookUp) return sigDescObj
def parseTagTable(): log("Enter", "[ICCProfileTagTable]", "add") tagCount = getBytes4(self._fd) log("Tag count = %d"%(tagCount)) for idx in xrange(tagCount): tagStartPos = nowAt(self._fd) sig = ''.join(getChar(self._fd) for _ in xrange(4)) offset = getBytes4(self._fd) size = getBytes4(self._fd) seekTo(self._fd, basePos+offset) log("Tag sig(%s) / offset(%d) / size(%d) / basePos(%d) / tagSigPos(%d) / tagTypePos(%d) "%(sig, offset, size, basePos, tagStartPos, basePos+offset)) typeDesc = ''.join(getChar(self._fd) for _ in xrange(4)) log("Type Desc(%s)"%(typeDesc)) sigDescObj = GetSigObject(sig, typeDesc, self._fd, size, basePos+offset) assert sig not in self.__dicSig2TagInfo, "Check this file, two same sig !" self.__dicSig2TagInfo[sig] = sigDescObj seekTo(self._fd, tagStartPos+12) log("Leave", "[ICCProfileTagTable]", "remove") pprint.pprint(self.__dicSig2TagInfo) pass
def __parseAPP1(self, base, start, end): if not self._file: assert False seekTo(self._file, base) self._orderAPP1 = getBytes2(self._file) log("order = %s" % (hex(self._orderAPP1))) if self._orderAPP1 not in [BYTE_ALIGN_MOTOROLA, BYTE_ALIGN_INTEL]: log("order incorrect") assert False check = getBytes2(self._file, self._orderAPP1) if check != 0x002a: assert False offsetToNextIFD = getBytes4(self._file, self._orderAPP1) log("offsetToNextIFD = %s" % (hex(offsetToNextIFD))) while offsetToNextIFD: seekTo(self._file, base + offsetToNextIFD) self.__parseBasicIFD(base, start, end) offsetToNextIFD = getBytes4(self._file, self._orderAPP1) log("offsetToNextIFD = %s" % (hex(offsetToNextIFD)))
def __parseAPP1(self, base, start, end): if not self._file: assert False seekTo(self._file, base) self._orderAPP1 = getBytes2(self._file) log("order = %s"%(hex(self._orderAPP1))) if self._orderAPP1 not in [BYTE_ALIGN_MOTOROLA, BYTE_ALIGN_INTEL]: log("order incorrect") assert False check = getBytes2(self._file, self._orderAPP1) if check != 0x002a: assert False offsetToNextIFD = getBytes4(self._file, self._orderAPP1) log("offsetToNextIFD = %s"%(hex(offsetToNextIFD))) while offsetToNextIFD: seekTo(self._file, base+offsetToNextIFD) self.__parseBasicIFD(base, start, end) offsetToNextIFD = getBytes4(self._file, self._orderAPP1) log("offsetToNextIFD = %s"%(hex(offsetToNextIFD)))
def GetMlucHelper(_fd, sig, tagStartPos): reserved = getBytes4(_fd) assert reserved == 0 numOfRecords = getBytes4(_fd) recordSize = getBytes4(_fd) log(" numOfRecords = %d / recordSize = %s"%(numOfRecords, recordSize)) sigDescObj = MultiLocalizedUnicode(sig) for _ in xrange(numOfRecords): langCode = ''.join(getChar(_fd) for i in xrange(2)) langCountryCode = ''.join(getChar(_fd) for i in xrange(2)) lenRecordString = getBytes4(_fd) offsetRecordString = getBytes4(_fd) here = nowAt(_fd) seekTo(_fd, tagStartPos + offsetRecordString) uniBytes = getChar(_fd, lenRecordString) # TODO : Think a better way to store these special unicode glyph uniChar = unicode(uniBytes, errors='replace') log(" uniChar = %s"%(uniChar)) sigDescObj.add(langCode, langCountryCode, uniChar) seekTo(_fd, here) return sigDescObj
def GetMultiFunctionTableHelper(_fd, sig, tagStartPos): reserved = getBytes4(_fd) assert reserved == 0 numOfInputChannel = getCharToOrd(_fd) numOfOutputChannel = getCharToOrd(_fd) numOfCLUTGridPoints = getCharToOrd(_fd) padding = getCharToOrd(_fd) assert padding == 0 encodedParas = [] for _ in xrange(9): encodedParas.append(GetS15Fixed16Number(_fd)) numOfInputTableEntries = getBytes2(_fd) numOfOutputTableEntries = getBytes2(_fd) log(" InChannels(%d) / OutChannels(%d) / GridPts(%d) / EncodedPars(%s)"\ %(numOfInputChannel, numOfOutputChannel, numOfCLUTGridPoints,\ str(encodedParas))) log(" InTableEntries(%d) / OutTableEntries(%d)"\ %(numOfInputTableEntries, numOfOutputTableEntries)) inputTables = [] for _ in xrange(numOfInputChannel): tmp = [] for __ in xrange(numOfInputTableEntries): tmp.append(getBytes2(_fd)) inputTables.append(tmp) clut = [] for _ in xrange(numOfCLUTGridPoints ** numOfInputChannel): tmp = [] for __ in xrange(numOfOutputChannel): tmp.append(getBytes2(_fd)) clut.append(tmp) outputTables = [] for _ in xrange(numOfOutputChannel): tmp = [] for __ in xrange(numOfOutputTableEntries): tmp.append(getBytes2(_fd)) outputTables.append(tmp) return Lut16(sig, encodedParas, inputTables, clut, outputTables)
def GetParaCurveHelper(_fd, sig): reserved = getBytes4(_fd) assert reserved == 0 funcType = getBytes2(_fd) reserved2 = getBytes2(_fd) assert reserved2 == 0 para_g = para_a = para_b = para_c = para_d = para_e = para_f = None if funcType == 0: para_g = GetS15Fixed16Number(_fd) elif funcType == 1: para_g = GetS15Fixed16Number(_fd) para_a = GetS15Fixed16Number(_fd) para_b = GetS15Fixed16Number(_fd) elif funcType == 2: para_g = GetS15Fixed16Number(_fd) para_a = GetS15Fixed16Number(_fd) para_b = GetS15Fixed16Number(_fd) para_c = GetS15Fixed16Number(_fd) elif funcType == 3: para_g = GetS15Fixed16Number(_fd) para_a = GetS15Fixed16Number(_fd) para_b = GetS15Fixed16Number(_fd) para_c = GetS15Fixed16Number(_fd) para_d = GetS15Fixed16Number(_fd) elif funcType == 4: para_g = GetS15Fixed16Number(_fd) para_a = GetS15Fixed16Number(_fd) para_b = GetS15Fixed16Number(_fd) para_c = GetS15Fixed16Number(_fd) para_d = GetS15Fixed16Number(_fd) para_e = GetS15Fixed16Number(_fd) para_f = GetS15Fixed16Number(_fd) sigDescObj = ParaCurve(sig, para_g, para_a, para_b, para_c, para_d,\ para_e, para_f) log(" ParaCurve - g(%s), a(%s), b(%s), c(%s), d(%s), e(%s), f(%s)"%(\ str(para_g), str(para_a), str(para_b), str(para_c), str(para_d),\ str(para_e), str(para_f))) return sigDescObj
def __parseBasicIFD(self, base, start, end): log("Enter", "[BasicIFD]", "add") if not self._file: assert False entries = getBytes2(self._file, self._orderAPP1) log("Number of entries = %d" % (entries)) for idx in xrange(entries): tag = getBytes2(self._file, self._orderAPP1) dataFormat = getBytes2(self._file, self._orderAPP1) numOfComps = getBytes4(self._file, self._orderAPP1) posBeforeDataOffset = nowAt(self._file) dataOffset = getBytes4(self._file, self._orderAPP1) posAfterDataOffset = nowAt(self._file) if 0 == dataFormat or dataFormat >= len(EXIF_TIFF_DATAFORMAT_LIST): assert False, "dataformat incorrect = %d" % (dataFormat) continue bytesPerComp = EXIF_TIFF_DATAFORMAT_LIST[dataFormat] dataSize = bytesPerComp * numOfComps if dataSize > 4: targetOffset = base + dataOffset if targetOffset <= start or targetOffset >= end: continue else: seekTo(self._file, targetOffset) else: seekTo(self._file, posBeforeDataOffset) entry = self.__getDataFromFormat(tag, dataFormat, dataSize) if entry.getTag() == TAGID_ExifIFD: ifdOffset = entry.getValue() seekTo(self._file, base + ifdOffset) self.__parseIFDs(base, start, end, "ExifIFD") elif entry.getTag() == TAGID_SubIFDs: log("SubIFDs") elif entry.getTag() == TAGID_GPSIFD: ifdOffset = entry.getValue() seekTo(self._file, base + ifdOffset) self.__parseIFDs(base, start, end, IFD="GPSIFD") pass elif entry.getTag() == TAGID_IPTC: log("IPTC") pass elif entry.getTag() == TAGID_XMP: log("XMP") pass elif entry.getTag() == TAGID_Photoshop: log("Photoshop") pass elif entry.getTag() == TAGID_ICCProfile: log("ICCProfile") pass elif entry.getTag() == TAGID_DNGPrivateData: log("DNGPrivateData") pass seekTo(self._file, posAfterDataOffset) log("Leave", "[BasicIFD]", "remove")
def __getDataFromFormat(self, tag, format, size): from array import array bytesPerComp = EXIF_TIFF_DATAFORMAT_LIST[format] entry = IFDEntry(tag, bytesPerComp) #print 'format(%d)/Size(%d)'%(format, size) lstValue = [] if format in [1, 6, 7]: # unsigned byte / # signed byte / # undefined data = array('b', getChar(self._file, size)) pass elif format == 2: # ascii string data = array('c', getChar(self._file, size)) pass elif format in [3, 8]: # unsigned short / # signed short while size > 0: v = getBytes2(self._file, self._orderAPP1) lstValue.append(v) size -= 2 encode = 'H' if format == 3 else 'h' data = array('H', lstValue) pass elif format in [4, 9]: # unsigned long / # signed long while size > 0: v = getBytes4(self._file, self._orderAPP1) lstValue.append(v) size -= 4 encode = 'L' if format == 4 else 'l' data = array('L', lstValue) pass elif format in [5, 10]: # unsigned rational / # signed rational while size > 0: numerator = getBytes4(self._file, self._orderAPP1) denominator = getBytes4(self._file, self._orderAPP1) size -= 8 lstValue.append(float(numerator) / float(denominator)) data = array('d', lstValue) pass elif format == 11: # signed float while size > 0: v = getBytes4(self._file, self._orderAPP1) lstValue.append(v) size -= 4 data = array('f', lstValue) pass elif format == 12: # double float while size > 0: numerator = getBytes4(self._file, self._orderAPP1) denominator = getBytes4(self._file, self._orderAPP1) size -= 8 lstValue.append(float(numerator) / float(denominator)) data = array('d', lstValue) pass entry.setData(data) log(" --- tag(%s), %s" % (getTagStringByValue(tag), str(data))) return entry
def __parseBasicIFD(self, base, start, end): log("Enter", "[BasicIFD]", "add") if not self._file: assert False entries = getBytes2(self._file, self._orderAPP1) log("Number of entries = %d"%(entries)) for idx in xrange(entries): tag = getBytes2(self._file, self._orderAPP1) dataFormat = getBytes2(self._file, self._orderAPP1) numOfComps = getBytes4(self._file, self._orderAPP1) posBeforeDataOffset = nowAt(self._file) dataOffset = getBytes4(self._file, self._orderAPP1) posAfterDataOffset = nowAt(self._file) if 0 == dataFormat or dataFormat >= len(EXIF_TIFF_DATAFORMAT_LIST): assert False, "dataformat incorrect = %d"%(dataFormat) continue bytesPerComp = EXIF_TIFF_DATAFORMAT_LIST[dataFormat] dataSize = bytesPerComp * numOfComps if dataSize > 4: targetOffset = base + dataOffset if targetOffset <= start or targetOffset >= end: continue else: seekTo(self._file, targetOffset) else: seekTo(self._file, posBeforeDataOffset) entry = self.__getDataFromFormat(tag, dataFormat, dataSize) if entry.getTag() == TAGID_ExifIFD: ifdOffset = entry.getValue() seekTo(self._file, base+ifdOffset) self.__parseIFDs(base, start, end, "ExifIFD") elif entry.getTag() == TAGID_SubIFDs: log("SubIFDs") elif entry.getTag() == TAGID_GPSIFD: ifdOffset = entry.getValue() seekTo(self._file, base+ifdOffset) self.__parseIFDs(base, start, end, IFD="GPSIFD") pass elif entry.getTag() == TAGID_IPTC: log("IPTC") pass elif entry.getTag() == TAGID_XMP: log("XMP") pass elif entry.getTag() == TAGID_Photoshop: log("Photoshop") pass elif entry.getTag() == TAGID_ICCProfile: log("ICCProfile") pass elif entry.getTag() == TAGID_DNGPrivateData: log("DNGPrivateData") pass seekTo(self._file, posAfterDataOffset) log("Leave", "[BasicIFD]", "remove")
def __getDataFromFormat(self, tag, format, size): from array import array bytesPerComp = EXIF_TIFF_DATAFORMAT_LIST[format] entry = IFDEntry(tag, bytesPerComp) #print 'format(%d)/Size(%d)'%(format, size) lstValue = [] if format in [1, 6, 7]: # unsigned byte / # signed byte / # undefined data = array('b', getChar(self._file, size)) pass elif format == 2: # ascii string data = array('c', getChar(self._file, size)) pass elif format in [3, 8]: # unsigned short / # signed short while size > 0: v = getBytes2(self._file, self._orderAPP1) lstValue.append(v) size -= 2 encode = 'H' if format == 3 else 'h' data = array('H', lstValue) pass elif format in [4, 9]: # unsigned long / # signed long while size > 0: v = getBytes4(self._file, self._orderAPP1) lstValue.append(v) size -= 4 encode = 'L' if format == 4 else 'l' data = array('L', lstValue) pass elif format in [5, 10]: # unsigned rational / # signed rational while size > 0: numerator = getBytes4(self._file, self._orderAPP1) denominator = getBytes4(self._file, self._orderAPP1) size -= 8 lstValue.append(float(numerator) / float(denominator)) data = array('d', lstValue) pass elif format == 11: # signed float while size > 0: v = getBytes4(self._file, self._orderAPP1) lstValue.append(v) size -= 4 data = array('f', lstValue) pass elif format == 12: # double float while size > 0: numerator = getBytes4(self._file, self._orderAPP1) denominator = getBytes4(self._file, self._orderAPP1) size -= 8 lstValue.append(float(numerator) / float(denominator)) data = array('d', lstValue) pass entry.setData(data) log(" --- tag(%s), %s"%(getTagStringByValue(tag), str(data))) return entry
def parseHeader(): log("Enter", "[ICCProfileHeader]", "add") profileSize = getBytes4(self._fd) cmmType = ''.join(getChar(self._fd) for _ in xrange(4)) lstVer = [str(getCharToOrd(self._fd)) for _ in xrange(4)] self.__dicHeaderInfo[H_CMM_TYPE] = cmmType self.__dicHeaderInfo[H_VERSION] = lstVer[0] + "." + lstVer[1] deviceClass = ''.join(getChar(self._fd) for _ in xrange(4)) colorSpaceOfData = ''.join(getChar(self._fd) for _ in xrange(4)) pcs = ''.join(getChar(self._fd) for _ in xrange(4)) self.__dicHeaderInfo[H_DEVICE_CLASS] = dicDevCls2Name.get(deviceClass, "Not found") self.__dicHeaderInfo[H_COLOR_SPACE] = colorSpaceOfData.strip() self.__dicHeaderInfo[H_PROFILE_CONNECTION_SPACE] = pcs.strip() lstDatetime = [getBytes2(self._fd) for _ in xrange(6)] signature = ''.join(getChar(self._fd) for _ in xrange(4)) assert signature == "acsp", "Not a standard ICC Profile !!" primaryPlatform = ''.join(getChar(self._fd) for _ in xrange(4)) def getBitsList(numBytes): lstBits = [] for _ in xrange(numBytes): bits_short = bin(getCharToOrd(self._fd))[2:] bits_full = '00000000'[len(bits_short):] + bits_short lstBits.extend([int(b) for b in bits_full]) return lstBits lstProfileFlags = getBitsList(4) self.__dicHeaderInfo[H_CREATE_DATETIME] = "Datatime = %d/%d/%d-%d:%d:%d"%tuple(lstDatetime) self.__dicHeaderInfo[H_SIGNATURE] = signature self.__dicHeaderInfo[H_PLATFORM] = dicPlatformSig2Desc.get(primaryPlatform, "Not found") self.__dicHeaderInfo[H_IS_EMBEDED] = True if lstProfileFlags[0] == 1 else False self.__dicHeaderInfo[H_USED_INDENDENTLY] = False if lstProfileFlags[1] == 1 else True deviceManufacturer = ''.join(getChar(self._fd) for _ in xrange(4)) deviceModel = ''.join(getChar(self._fd) for _ in xrange(4)) lstDeviceAttributes = getBitsList(8) renderingIntent, zeroPadding = getBytes2(self._fd), getBytes2(self._fd) self.__dicHeaderInfo[H_DEVICE_MANUFACTURER] = deviceManufacturer self.__dicHeaderInfo[H_DEVICE_MODEL] = deviceModel self.__dicHeaderInfo[H_ATTR_T_R] = "Transparency" if lstDeviceAttributes[0] == 1 else "Reflective" self.__dicHeaderInfo[H_ATTR_M_G] = "Matte" if lstDeviceAttributes[1] == 1 else "Glossy" self.__dicHeaderInfo[H_RENDERING_INTENT] = dicRenderingIntent2Desc.get(renderingIntent, "Not found") intX, intY, intZ = getBytes4(self._fd), getBytes4(self._fd), getBytes4(self._fd) X = struct.unpack('f', struct.pack('i', intX)) Y = struct.unpack('f', struct.pack('i', intY)) Z = struct.unpack('f', struct.pack('i', intZ)) CIEXYZ_X = X[0] / Y[0] CIEXYZ_Y = Y[0] / Y[0] CIEXYZ_Z = Z[0] / Y[0] profileCreator = ''.join(getChar(self._fd) for _ in xrange(4)) profileID = [hex(getCharToOrd(self._fd)) for _ in xrange(16)] reserved = [hex(getCharToOrd(self._fd)) for _ in xrange(28)] self.__dicHeaderInfo[H_PROFILE_CREATOR] = profileCreator self.__dicHeaderInfo[H_PROFILE_D50_XYZ] = "(%f, %f, %f)"%(CIEXYZ_X, CIEXYZ_Y, CIEXYZ_Z) log("Header Information : \n%s "%(pprint.pformat(self.__dicHeaderInfo, indent=2))) log("Leave", "[ICCProfileHeader]", "remove")
def GetSigObject(sig, type, _fd, size, tagStartPos=None): # _fd is already seeked to starting point of data # 4bytes type(description) is included in size sigDescObj = None if sig == "A2B0": if type == "mAB ": sigDescObj = GetAToBHelper(_fd, sig, tagStartPos) elif type == "mft2": sigDescObj = GetMultiFunctionTableHelper(_fd, sig, tagStartPos) pass elif sig == "A2B1": if type == "mAB ": sigDescObj = GetAToBHelper(_fd, sig, tagStartPos) elif type == "mft2": sigDescObj = GetMultiFunctionTableHelper(_fd, sig, tagStartPos) pass elif sig == "A2B2": if type == "mAB ": sigDescObj = GetAToBHelper(_fd, sig, tagStartPos) elif type == "mft2": sigDescObj = GetMultiFunctionTableHelper(_fd, sig, tagStartPos) pass elif sig in ["bXYZ", "gXYZ", "rXYZ", "bkpt", "wtpt", "lumi"]: reserved = getBytes4(_fd) assert reserved == 0 assert size == 20 X, Y, Z = GetXYZHelper(_fd) log(" XYZ = (%f, %f, %f)"%(X, Y, Z)) sigDescObj = XYZ(sig, X, Y, Z) elif sig == "B2A0": if type == "mBA ": sigDescObj = GetBToAHelper(_fd, sig, tagStartPos) elif type == "mft2": sigDescObj = GetMultiFunctionTableHelper(_fd, sig, tagStartPos) elif sig == "B2A1": if type == "mBA ": sigDescObj = GetBToAHelper(_fd, sig, tagStartPos) elif type == "mft2": sigDescObj = GetMultiFunctionTableHelper(_fd, sig, tagStartPos) elif sig == "B2A2": if type == "mBA ": sigDescObj = GetBToAHelper(_fd, sig, tagStartPos) elif type == "mft2": sigDescObj = GetMultiFunctionTableHelper(_fd, sig, tagStartPos) elif sig == "calt": pass elif sig == "ciis": content = ''.join(getChar(_fd) for _ in xrange(size-4)).strip('\0x00') log(" ciis content = %s "%(dicColorimetricIntentImageState2Desc.get(content, "Unknown"))) sigDescObj = Signature(sig, content) elif sig == "targ": pass elif sig == "cprt": if type == "mluc": sigDescObj = GetMlucHelper(_fd, sig, tagStartPos) else: content = ''.join(getChar(_fd) for _ in xrange(size-4)) log(" cpry content = %s"%(content)) sigDescObj = Text(sig, content) pass elif sig == "chad": reserved = getBytes4(_fd) assert reserved == 0 assert size == 44 mat = [] for _ in xrange(9): intUnsigned = getBytes2(_fd) intSigned = intUnsigned - 65536 if intUnsigned >= 32768 else intUnsigned fracPart = getBytes2(_fd) v = intSigned + float(fracPart) / 65536 mat.append(v) log(" chad = %s"%(str(mat))) sigDescObj = S15Fixed16Array(sig, mat) pass elif sig == "gamt": pass elif sig == "kTRC": pass elif sig == "meas": reserved = getBytes4(_fd) assert reserved == 0 assert size == 36 obs = dicStdObserver2Desc.get(hex(getBytes4(_fd)), dicStdObserver2Desc[hex(0)]) tristimulusXYZ = GetXYZHelper(_fd) geo = dicGeometry2Desc.get(hex(getBytes4(_fd)), dicGeometry2Desc[hex(0)]) flareInt, flareFractional = getBytes2(_fd), getBytes2(_fd) flare = flareInt + float(flareFractional) / 65536 illuminantType = dicIlluminantType2Desc.get(hex(getBytes4(_fd)), dicIlluminantType2Desc[hex(0)]) log(" obs(%s) / triXYZ(%s) / geo(%s) / flare(%f) / illu(%s)"%(obs, str(tristimulusXYZ),\ geo, flare, illuminantType)) sigDescObj = Measurement(sig, obs, tristimulusXYZ, geo, flare, illuminantType) elif sig == "ncol": pass elif sig == "ncl2": pass elif sig == "pre0": pass elif sig == "pre1": pass elif sig == "pre2": pass elif sig in ["dscm"]: if type == "mluc": sigDescObj = GetMlucHelper(_fd, sig, tagStartPos) elif sig in ["desc", "dmdd", "dmnd", "scrd", "vued"]: if type == "mluc": sigDescObj = GetMlucHelper(_fd, sig, tagStartPos) else: reserved = getBytes4(_fd) assert reserved == 0 asciiCount = getBytes4(_fd) log(" asciiCount = %d"%(asciiCount)) asciiInvariantDesc = getChar(_fd, asciiCount) log(" asciiInvariantDesc = %s"%(asciiInvariantDesc)) uniLangCode = getBytes4(_fd) uniCount = getBytes4(_fd) log(" uniLangCode, uniCount = %d, %d"%(uniLangCode, uniCount)) uniLocalizableDesc = None if uniCount != 0: uniLocalizableDesc = u"" for _ in xrange(uniCount): uniLocalizableDesc.join(getBytes2(_fd).decode("utf-8", "ignore")) log(" uniLocalizableDesc = %s"%(uniLocalizableDesc)) scriptCode = getBytes2(_fd) scriptCount = getCharToOrd(_fd) log(" scriptCode, scriptCount = %d, %d"%(scriptCode, scriptCount)) localMacintoshDesc = None if scriptCount != 0: localMacintoshDesc = getChar(_fd, min(67,scriptCount)) log(" localMacintoshDesc = %s"%(localMacintoshDesc)) sigDescObj = TextDescription(sig, asciiInvariantDesc,\ uniLocalizableDesc, localMacintoshDesc) pass elif sig == "pseq": pass elif sig == "psd0": pass elif sig == "psd1": pass elif sig == "psd2": pass elif sig == "psd3": pass elif sig == "ps2s": pass elif sig == "ps2i": pass elif sig == "rig0": content = ''.join(getChar(_fd) for _ in xrange(size-4)).strip('\0x00') log(" rig0 content = %s "%(content)) sigDescObj = Signature(sig, content) elif sig in ["rTRC", "gTRC", "bTRC"]: sigDescObj = GetCurveHelper(_fd, sig) elif sig == "scrn": pass elif sig == "tech": content = ''.join(getChar(_fd) for _ in xrange(size-4)).strip('\0x00') log(" tech content = %s "%(dicTechType2Desc.get(content, 'None'))) sigDescObj = Signature(sig, content) pass elif sig == "bfd ": pass elif sig == "vued": pass elif sig == "view": reserved = getBytes4(_fd) assert reserved == 0 illuminantXYZ = GetXYZHelper(_fd) surroundXYZ = GetXYZHelper(_fd) log(" illXYZ = (%f, %f, %f)"%(illuminantXYZ)) log(" surXYZ = (%f, %f, %f)"%(surroundXYZ)) illuminantType = dicIlluminantType2Desc.get(hex(getBytes4(_fd)), dicIlluminantType2Desc[hex(0)]) sigDescObj = ViewingConditions(sig, illuminantXYZ, surroundXYZ, illuminantType) log(" illuminantType = %s"%illuminantType) return sigDescObj
def GetAToBHelper(_fd, sig, tagStartPos, reverse=False): reserved = getBytes4(_fd) assert reserved == 0 numOfInputChannel = getCharToOrd(_fd) numOfOutputChannel = getCharToOrd(_fd) padding = getBytes2(_fd) log(" Input(%d) , Output(%d), padding(%d)"%(numOfInputChannel, numOfOutputChannel, padding)) assert padding == 0 sigDescObj = None lstBCurve = [] mMat = None lstMCurve = [] clut = [] lstACurve = [] offset2BCurve = getBytes4(_fd) if offset2BCurve != 0: here = nowAt(_fd) seekTo(_fd, tagStartPos + offset2BCurve) for _ in xrange(numOfOutputChannel): subType = getChar(_fd, 4) log(" B Curve subtype = %s"%(subType)) if subType == "para": sigSubDescObj = GetParaCurveHelper(_fd, sig) lstBCurve.append(sigSubDescObj) elif subType == "curv": sigSubDescObj = GetCurveHelper(_fd, sig) lstBCurve.append(sigSubDescObj) seekTo(_fd, here) assert len(lstBCurve) == numOfOutputChannel offset2Matrix = getBytes4(_fd) if offset2Matrix != 0: here = nowAt(_fd) seekTo(_fd, tagStartPos + offset2Matrix) mat = [] for _ in xrange(12): intUnsigned = getBytes2(_fd) intSigned = intUnsigned - 65536 if intUnsigned >= 32768 else intUnsigned fracPart = getBytes2(_fd) v = intSigned + float(fracPart) / 65536 mat.append(v) log(" Matrix = %s"%(str(mat))) mMat = S15Fixed16Array(sig, mat) seekTo(_fd, here) offset2MCurve = getBytes4(_fd) if offset2MCurve != 0: here = nowAt(_fd) seekTo(_fd, tagStartPos + offset2MCurve) for _ in xrange(numOfOutputChannel): subType = getChar(_fd, 4) log(" M Curve subtype = %s"%(subType)) if subType == "para": sigSubDescObj = GetParaCurveHelper(_fd, sig) lstMCurve.append(sigSubDescObj) elif subType == "curv": sigSubDescObj = GetCurveHelper(_fd, sig) lstMCurve.append(sigSubDescObj) seekTo(_fd, here) assert len(lstMCurve) == numOfOutputChannel offset2CLUT = getBytes4(_fd) if offset2CLUT != 0: # TODO : Check the implementation correctness here = nowAt(_fd) seekTo(_fd, tagStartPos + offset2CLUT) lstGridPoints = [] for _ in xrange(16): gridPts = getCharToOrd(_fd) if _ >= numOfInputChannel: assert gridPts == 0 lstGridPoints.append(gridPts) precision = getCharToOrd(_fd) padding = getBytes3(_fd) log(" >>> lstGridPoints : %s"%(str(lstGridPoints))) log(" >>> precision : %s / padding %s "%(str(precision), str(padding))) assert padding == 0 getDataPoint = getBytes2 if precision == 2 else getCharToOrd def fn(x, y): return x * y if y != 0 else x totalCLUTPts = reduce(fn, lstGridPoints) for _ in xrange(totalCLUTPts): tmp = [] for __ in xrange(numOfOutputChannel): tmp.append(getDataPoint(_fd)) clut.append(tmp) seekTo(_fd, here) offset2ACurve = getBytes4(_fd) if offset2ACurve != 0: here = nowAt(_fd) seekTo(_fd, tagStartPos + offset2ACurve) for _ in xrange(numOfOutputChannel): subType = getChar(_fd, 4) log(" A Curve subtype = %s"%(subType)) if subType == "para": sigSubDescObj = GetParaCurveHelper(_fd, sig) lstACurve.append(sigSubDescObj) elif subType == "curv": sigSubDescObj = GetCurveHelper(_fd, sig) lstACurve.append(sigSubDescObj) seekTo(_fd, here) assert len(lstACurve) == numOfOutputChannel log(" O2B(%d) / O2mat(%d) / O2M(%d) / O2CLUT(%d) / O2A(%d)"%(offset2BCurve,\ offset2Matrix, offset2MCurve, offset2CLUT, offset2ACurve)) if reverse: sigDescObj = LutBToA(sig, lstBCurve, mMat, lstMCurve, clut, lstACurve) else: sigDescObj = LutAToB(sig, lstBCurve, mMat, lstMCurve, clut, lstACurve) return sigDescObj