Back to index

plone3  3.1.7
Public Member Functions | Public Attributes
exif.EXIF_header Class Reference

List of all members.

Public Member Functions

def __init__
def s2n
def n2s
def first_IFD
def next_IFD
def list_IFDs
def dump_IFD
def decode_maker_note
def canon_decode_tag

Public Attributes

 file
 endian
 offset
 fake_exif
 debug
 tags

Detailed Description

Definition at line 731 of file exif.py.


Constructor & Destructor Documentation

def exif.EXIF_header.__init__ (   self,
  file,
  endian,
  offset,
  fake_exif,
  debug = 0 
)

Definition at line 732 of file exif.py.

00732 
00733     def __init__(self, file, endian, offset, fake_exif, debug=0):
00734         self.file=file
00735         self.endian=endian
00736         self.offset=offset
00737         self.fake_exif=fake_exif
00738         self.debug=debug
00739         self.tags={}


Member Function Documentation

def exif.EXIF_header.canon_decode_tag (   self,
  value,
  dict 
)

Definition at line 966 of file exif.py.

00966 
00967     def canon_decode_tag(self, value, dict):
00968         for i in range(1, len(value)):
00969             x=dict.get(i, ('Unknown', ))
00970             if self.debug:
00971                 print i, x
00972             name=x[0]
00973             if len(x) > 1:
00974                 val=x[1].get(value[i], 'Unknown')
00975             else:
00976                 val=value[i]
00977             # it's not a real IFD Tag but we fake one to make everybody
00978             # happy. this will have a "proprietary" type
00979             self.tags['MakerNote '+name]=str(val)
00980 
00981 # process an image file (expects an open file object)
00982 # this is the function that has to deal with all the arbitrary nasty bits
# of the EXIF standard

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 895 of file exif.py.

00895 
00896     def decode_maker_note(self):
00897         note=self.tags['EXIF MakerNote']
00898         make=self.tags['Image Make'][1]
00899         model=self.tags['Image Model'][1]
00900 
00901         # Nikon
00902         # The maker note usually starts with the word Nikon, followed by the
00903         # type of the makernote (1 or 2, as a short).  If the word Nikon is
00904         # not at the start of the makernote, it's probably type 2, since some
00905         # cameras work that way.
00906         if make in ('NIKON', 'NIKON CORPORATION'):
00907             if note.values[0:7] == [78, 105, 107, 111, 110, 00, 01]:
00908                 if self.debug:
00909                     print "Looks like a type 1 Nikon MakerNote."
00910                 self.dump_IFD(note[2]+8, 'MakerNote',
00911                               dict=MAKERNOTE_NIKON_OLDER_TAGS)
00912             elif note.values[0:7] == [78, 105, 107, 111, 110, 00, 02]:
00913                 if self.debug:
00914                     print "Looks like a labeled type 2 Nikon MakerNote"
00915                 if note[0][12:14] != [0, 42] and note[0][12:14] != [42L, 0L]:
00916                     raise ValueError, "Missing marker tag '42' in MakerNote."
00917                 # skip the Makernote label and the TIFF header
00918                 self.dump_IFD(note[2]+10+8, 'MakerNote',
00919                               dict=MAKERNOTE_NIKON_NEWER_TAGS, relative=1)
00920             else:
00921                 # E99x or D1
00922                 if self.debug:
00923                     print "Looks like an unlabeled type 2 Nikon MakerNote"
00924                 self.dump_IFD(note[2], 'MakerNote',
00925                               dict=MAKERNOTE_NIKON_NEWER_TAGS)
00926             return
00927 
00928         # Olympus
00929         if make[:7] == 'OLYMPUS':
00930             self.dump_IFD(note[2]+8, 'MakerNote',
00931                           dict=MAKERNOTE_OLYMPUS_TAGS)
00932             return
00933 
00934         # Casio
00935         if make == 'Casio':
00936             self.dump_IFD(note[2], 'MakerNote',
00937                           dict=MAKERNOTE_CASIO_TAGS)
00938             return
00939 
00940         # Fujifilm
00941         if make == 'FUJIFILM':
00942             # bug: everything else is "Motorola" endian, but the MakerNote
00943             # is "Intel" endian
00944             endian=self.endian
00945             self.endian='I'
00946             # bug: IFD offsets are from beginning of MakerNote, not
00947             # beginning of file header
00948             offset=self.offset
00949             self.offset+=note[2]
00950             # process note with bogus values (note is actually at offset 12)
00951             self.dump_IFD(12, 'MakerNote', dict=MAKERNOTE_FUJIFILM_TAGS)
00952             # reset to correct values
00953             self.endian=endian
00954             self.offset=offset
00955             return
00956 
00957         # Canon
00958         if make == 'Canon':
00959             self.dump_IFD(note[2], 'MakerNote',dict=MAKERNOTE_CANON_TAGS)
00960             for i in (('MakerNote Tag 0x0001', MAKERNOTE_CANON_TAG_0x001),
00961                       ('MakerNote Tag 0x0004', MAKERNOTE_CANON_TAG_0x004)):
00962                 self.canon_decode_tag(self.tags[i[0]][0], i[1])
00963             return

Here is the call graph for this function:

def exif.EXIF_header.dump_IFD (   self,
  ifd,
  ifd_name,
  dict = EXIF_TAGS,
  relative = 0 
)

Definition at line 788 of file exif.py.

00788 
00789     def dump_IFD(self, ifd, ifd_name, dict=EXIF_TAGS, relative=0):
00790         entries=self.s2n(ifd, 2)
00791         for i in range(entries):
00792             # entry is index of start of this IFD in the file
00793             entry=ifd+2+12*i
00794             tag=self.s2n(entry, 2)
00795             # get tag name.  We do it early to make debugging easier
00796             tag_entry=dict.get(tag)
00797             if tag_entry:
00798                 tag_name=tag_entry[0]
00799             else:
00800                 tag_name='Tag 0x%04X' % tag
00801             field_type=self.s2n(entry+2, 2)
00802             if not 0 < field_type < len(FIELD_TYPES):
00803                 # unknown field type
00804                 raise ValueError, \
00805                       'unknown type %d in tag 0x%04X' % (field_type, tag)
00806 
00807             typelen=FIELD_TYPES[field_type][0]
00808             count=self.s2n(entry+4, 4)
00809             offset=entry+8
00810             if count*typelen > 4:
00811                 # offset is not the value; it's a pointer to the value
00812                 # if relative we set things up so s2n will seek to the right
00813                 # place when it adds self.offset.  Note that this 'relative'
00814                 # is for the Nikon type 3 makernote.  Other cameras may use
00815                 # other relative offsets, which would have to be computed here
00816                 # slightly differently.
00817                 if relative:
00818                     tmp_offset=self.s2n(offset, 4)
00819                     offset=tmp_offset+ifd-self.offset+4
00820                     if self.fake_exif:
00821                         offset=offset+18
00822                 else:
00823                     offset=self.s2n(offset, 4)
00824             field_offset=offset
00825             if field_type == 2:
00826                 # special case: null-terminated ASCII string
00827                 if count != 0:
00828                     self.file.seek(self.offset+offset)
00829                     values=self.file.read(count)
00830                     values=values.strip().replace('\x00','')
00831                 else:
00832                     values=''
00833             else:
00834                 values=[]
00835                 signed=(field_type in [6, 8, 9, 10])
00836                 for j in range(count):
00837                     if field_type in (5, 10):
00838                         # a ratio => reduce it if possible
00839                         num = self.s2n(offset,   4, signed)
00840                         den = self.s2n(offset+4, 4, signed)
00841                         div=gcd(num, den)
00842                         if div > 1:
00843                           num=num/div
00844                           den=den/div
00845                         if(den==1):
00846                           value_j = str(num)
00847                         else:
00848                           value_j = "%d/%d" % (num, den)
00849                     else:
00850                         value_j=self.s2n(offset, typelen, signed)
00851                     values.append(value_j)
00852                     offset=offset+typelen
00853             # now "values" is either a string or an array
00854             if count == 1 and field_type != 2:
00855                 printable=str(values[0])
00856             else:
00857                 printable=str(values)
00858             # compute printable version of values
00859             if tag_entry:
00860                 if len(tag_entry) != 1:
00861                     # optional 2nd tag element is present
00862                     if callable(tag_entry[1]):
00863                         # call mapping function
00864                         printable=tag_entry[1](values)
00865                     else:
00866                         printable=''
00867                         for i in values:
00868                             # use lookup table for this tag
00869                             printable+=tag_entry[1].get(i, repr(i))
00870             printable=printable.strip().replace('\x00','')
00871             if(values):
00872                 self.tags[ifd_name+' '+tag_name] = (values[0],printable,field_offset)
00873             if self.debug:
00874                 print ' debug:   %s: %s' % (tag_name,
00875                                             repr(self.tags[ifd_name+' '+tag_name]))

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 770 of file exif.py.

00770 
00771     def first_IFD(self):
00772         return self.s2n(4, 4)

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 779 of file exif.py.

00779 
00780     def list_IFDs(self):
00781         i=self.first_IFD()
00782         a=[]
00783         while i:
00784             a.append(i)
00785             i=self.next_IFD(i)
00786         return a

Here is the call graph for this function:

def exif.EXIF_header.n2s (   self,
  offset,
  length 
)

Definition at line 759 of file exif.py.

00759 
00760     def n2s(self, offset, length):
00761         s=''
00762         for i in range(length):
00763             if self.endian == 'I':
00764                 s=s+chr(offset & 0xFF)
00765             else:
00766                 s=chr(offset & 0xFF)+s
00767             offset=offset >> 8
00768         return s

def exif.EXIF_header.next_IFD (   self,
  ifd 
)

Definition at line 774 of file exif.py.

00774 
00775     def next_IFD(self, ifd):
00776         entries=self.s2n(ifd, 2)
00777         return self.s2n(ifd+2+12*entries, 4)

Here is the call graph for this function:

Here is the caller graph for this function:

def exif.EXIF_header.s2n (   self,
  offset,
  length,
  signed = 0 
)

Definition at line 744 of file exif.py.

00744 
00745     def s2n(self, offset, length, signed=0):
00746         self.file.seek(self.offset+offset)
00747         slice=self.file.read(length)
00748         if self.endian == 'I':
00749             val=s2n_intel(slice)
00750         else:
00751             val=s2n_motorola(slice)
00752         # Sign extension ?
00753         if signed:
00754             msb=1L << (8*length-1)
00755             if val & msb:
00756                 val=val-(msb << 1)
00757         return val

Here is the call graph for this function:

Here is the caller graph for this function:


Member Data Documentation

Definition at line 737 of file exif.py.

Definition at line 734 of file exif.py.

Definition at line 736 of file exif.py.

Definition at line 733 of file exif.py.

Definition at line 735 of file exif.py.

Definition at line 738 of file exif.py.


The documentation for this class was generated from the following file: