示例#1
0
 def setValue(self, val):    #from python to binary
     #we support writing unsigned (short, long, rational), ascii
     self.value = val
     if self.type in [3,4]: #short, long
         if type(val) not in [[], ()]: 
             val = [val]
         self.valueFlat = ''.join([util.setNr(n, self.bytes, self.endian) for n in val])
         self.count = len(val)
     elif self.type == 5: #rational
         self.valueFlat = ''.join([util.setNr(n, 4, self.endian) + util.setNr(d, 4, self.endian) for n,d in self.value])
         self.count = 1
     else:
         if self.type == 2:  #ascii
             self.valueFlat = self.value + "\x00"   #must be NULL terminated string
             self.count = len(self.value) + 1
             if self.count < 4:
                 self.valueFlat = self.valueFlat.rjust(4)    #self.valueFlat + ("\x00" * (4-len(self.valueFlat)))
                 self.count = 4
         else:
             self.valueFlat = self.value
             self.count = len(self.value)
             if self.count < 4:
                 self.valueFlat = self.valueFlat + ("\x00" * (4-len(self.valueFlat)))
                 self.count = 4
     self.len = self.bytes * self.count
示例#2
0
文件: iptc.py 项目: imclab/filtr
    def binary(self):
        #http://www.iptc.org/std/IIM/4.1/specification/IIMV4.1.pdf  (pag 15)
        res = self.marker + self.type

        val = self.value
        #only parse it this way but not write this way
        #if len(val) % 2 != 0:  #Pad with a NULL if not even size but let length be as it was
        #    val += "\x00"

        if len(self.value) < 32767:
            res += util.setNr(len(self.value), 2) + val
        else:
            #lengthOfValueLength + valueLength + value  (4 should be enough for lengthOfValueLength)
            res += util.setNr(4, 2) + util.setNr(len(self.value), 4) + val
        return res
示例#3
0
    def binary(self):
        #http://www.iptc.org/std/IIM/4.1/specification/IIMV4.1.pdf  (pag 15)
        res = self.marker + self.type

        val = self.value
        #only parse it this way but not write this way
        #if len(val) % 2 != 0:  #Pad with a NULL if not even size but let length be as it was
        #    val += "\x00"

        if len(self.value) < 32767:
            res += util.setNr(len(self.value), 2) + val
        else:
            #lengthOfValueLength + valueLength + value  (4 should be enough for lengthOfValueLength)
            res += util.setNr(4, 2) + util.setNr(len(self.value), 4) + val
        return res
示例#4
0
def _write(value, file, marker):
    """-Overwrights <marker> segment with given <value>
       -if <marker> segment does not already exist then it will write it 
        right before the image segment (SOF - FFC0)
    """
    markerSeg, sof, length, im = _process(file, marker)
    if markerSeg or sof:
        lenHex = util.setNr(len(value) + 2, "short")  #the length on 2 bytes
        segment = "\xFF" + marker + lenHex + value  #segment = marker + value length + value

        pos = im.tell() - 4
        im.seek(0)
        before = im.read(pos)
        if markerSeg:
            im.seek(util.getNr(length) + 2,
                    1)  #skip over existing segment, including marker
        after = im.read()
        im.reset()
        im.write(before)
        im.write(segment)
        im.write(after)
        im.close()
        return im
    else:
        im.close()
        raise NoImageFound, "There is no image in this image file ?"
示例#5
0
def _write(value, file, marker):
    """-Overwrights <marker> segment with given <value>
       -if <marker> segment does not already exist then it will write it 
        right before the image segment (SOF - FFC0)
    """
    markerSeg, sof, length, im = _process(file, marker)
    if markerSeg or sof:
        lenHex = util.setNr(len(value)+2, "short")  #the length on 2 bytes
        segment = "\xFF" + marker + lenHex + value  #segment = marker + value length + value
        
        pos = im.tell() - 4 
        im.seek(0)
        before = im.read(pos)
        if markerSeg: 
            im.seek(util.getNr(length) + 2, 1)      #skip over existing segment, including marker
        after = im.read()
        im.reset()
        im.write(before)
        im.write(segment)
        im.write(after)
        im.close()
        return im
    else:
        im.close()
        raise NoImageFound, "There is no image in this image file ?"
示例#6
0
文件: iptc.py 项目: imclab/filtr
 def binary(self):
     res = ""
     for ds in self.datasets:
         res += ds.binary()
     length = util.setNr(len(res), 2)
     if len(res) % 2 != 0:
         # Pad with a blank if not even size but let length be as it was
         res += "\x00"
     return self.marker + self.type + self.padding + length + res
示例#7
0
 def binary(self):
     res = ""
     for ds in self.datasets:
         res += ds.binary()
     length = util.setNr(len(res), 2)
     if len(res) % 2 != 0:
         # Pad with a blank if not even size but let length be as it was
         res += "\x00"
     return self.marker + self.type + self.padding + length + res
示例#8
0
 def create(self, name, value):
     if name in txt_datasets:
         ds = DataSet('\x1c\x02', util.setNr(txt_datasets[name], 1), value, self)
         self.datasets.append(ds)
         return ds
     else:
         s = ["Only the following are supported:"]
         for k in txt_datasets.keys():
             s.append(k)
         raise NotImplementedError("\n".join(s))
示例#9
0
文件: iptc.py 项目: imclab/filtr
 def create(self, name, value):
     if name in txt_datasets:
         ds = DataSet('\x1c\x02', util.setNr(txt_datasets[name], 1), value,
                      self)
         self.datasets.append(ds)
         return ds
     else:
         s = ["Only the following are supported:"]
         for k in txt_datasets.keys():
             s.append(k)
         raise NotImplementedError("\n".join(s))
示例#10
0
 def set(self, tag, value, targetIfd, type_):
     """ - Overwrite <tagID> tag with <value>.
         - If tag does not already exist, build it in the specified <targetIfd>.
         - The type (short, long, ascii, etc. as 3,4,2 etc.) need to be specified since this program will 
           probably never be aware of all posible tags and their specification. You may need to do some
           research with exif.org to find the right type
     """
     tagID = type(tag)==type(1) and util.setNr(tag)[2:] or tag   #nr to str
     for ifd in self.ifds:
         for tag in ifd:
             if tag.id == tagID or (self.endian == "II" and tag.id == util.reverse(tagID)):
                 tag.setValue(value)
                 return True
     
     tag = FirstTag(tagID, value, type_, self)    #don't have it yet, so create one
     targetIfd.append(tag)
示例#11
0
 def get(self, tags, value=True, parse_value=True):
     "return value for given <tags> (1 tag or a list of tags as number or string hex value in big endian)"
     if type(tags) in (type(""), type(1)):
         tags = [tags] #allow searching multiple tags at once
     tags = [type(t)==type(1) and util.setNr(t)[2:] or t for t in tags]  #nr to str for each tag
     if self.endian == "II":
         tags = [t[1]+t[0] for t in tags]
     res = []
     
     for ifd in self.ifds:
         for tag in ifd:
             if tag.id in tags:
                 if value:
                     res.append(tag.getValue(parse_value))
                 else:
                     res.append(tag)
                 if len(res) == len(tags):
                     break
     
     if len(res) == 1: return res[0]
     if len(res) == 0: return None
     return res
示例#12
0
 def binary(self):
     """ return Exif as is needed to be written into the jpeg file
     """
     exifPointer = interopPointer = gpsPointer= None
     
     #endian + fixed number 42 + 8 (ifd0 starts right after tiff header)
     fixed42 = self.endian == "MM" and "\x00\x2A" or "\x2A\x00"
     ifd0offset = self.endian == "MM" and "\x00\x00\x00\x08" or "\x08\x00\x00\x00"
     res = self.endian + fixed42 + ifd0offset
     
     offset = 8 #total bytes for endian, fixed, ifd0 offset
     for ifd in self.ifds:
         #this is a come back later to fill in a gap with offsets to ifd, when we know the offset
         if ifd is self.exif and self.exif:
             res = res[:exifPointer] + util.setNr(len(res), 4, self.endian) + res[exifPointer+4:]
         if ifd is self.interop and self.interop:
             res = res[:interopPointer] + util.setNr(len(res), 4, self.endian) + res[interopPointer+4:]
         if ifd is self.gps and self.gps:
             res = res[:gpsPointer] + util.setNr(len(res), 4, self.endian) + res[gpsPointer+4:]
         
         headLen = 2  #nr of tags
         nrTags = len(ifd)
         headLen += nrTags * 12  #all tags
         if ifd is self.ifd0:
             headLen += 4  #pointer to ifd1
         
         valOffset = offset + headLen
         
         res += util.setNr(nrTags, 2, self.endian)
         tagValOffset = 0
         for tag in ifd:
             res +=  tag.id                               #2 bytes
             res += util.setNr(tag.type, 2, self.endian)      #4
             res += util.setNr(tag.count, 4, self.endian)     #8 
             
             if tag.id == "\x87\x69" or (self.endian=="II" and tag.id == "\x69\x87"): #exif
                 exifPointer = len(res)
                 res += util.setNr(0, 4, self.endian) #will set later, now just to have correct length
             elif tag.id == "\xA0\x05" or (self.endian=="II" and tag.id == "\x05\xA0"): #interopelability
                 interopPointer = len(res)
                 res += util.setNr(0, 4, self.endian)
             elif tag.id == "\x88\x25" or (self.endian=="II" and tag.id == "\x25\x88"):   #gps
                 gpsPointer = len(res)
                 res += util.setNr(0, 4, self.endian)
             elif len(tag.valueFlat) <= 4:
                 res += tag.valueFlat                     #12
             else:
                 res += util.setNr(valOffset + tagValOffset, 4, self.endian)                  #12
                 tagValOffset += tag.len
         if ifd is self.ifd0:
             ifd1Pointer = len(res)  #pointer to ifd1
             res += util.setNr(0, 4, self.endian)
             
         for tag in ifd:
             if len(tag.valueFlat) > 4:
                 res += tag.valueFlat
         
         offset = len(res)
         
     res = res[:ifd1Pointer] + util.setNr(len(res), 4, self.endian) + res[ifd1Pointer+4:]
     res += self.ifd1
     return "Exif\x00\x00" + res
示例#13
0
            'SubsecTimeDigitized':          0x9292, 
            'TimeZoneOffset':               0x882A,  # TODO: I hope TimeZoneOffset is not a pointer to yet another ifd
            'Copyright':                    0x8298,
            'Exif version':                 0x9000,
            'Exif IFD Pointer':             0x8769,
            'GPS IFD Pointer':              0x8825,
            'Interoperability IFD':         0xA005, 
            'FlashPixVersion':              0xA000, 
            'FNumber':                      0x829D, 
            'CompressedBitsPerPixel':       0x9102,
            'ISOSpeedRatings':              0x8827, 
            'InteroperabilityVersion':      0x0002,
            'InteroperabilityIndex':        0x0001,
            'RelatedImageWidth':            0x1001,
            'RelatedImageLength':           0x1002,
            'SensingMethod':                0xA217,
            'FocalPlaneXResolution':        0xA20E,
            'FocalPlaneYResolution':        0xA20F,
            'FocalPlaneResolutionUnit':     0xA210
}
exif_tags_description = {}
for key in exif_tags:
    val = exif_tags[key]
    if type(val) == type(()):
        val = (util.setNr(val[0])[2:], val[1])   #MM int
        exif_tags_description[val[0]] = (key, val[1])
    else:
        val = util.setNr(val, 4)[2:]
        exif_tags_description[val] = key
    exif_tags[key] = val