modify EXIF.py to use mmap in the hope of slightly better improvements with less syscalls
authorTero Marttila <terom@fixme.fi>
Thu, 11 Jun 2009 23:24:48 +0300
changeset 98 d7d98c4479ab
parent 97 92c20f8b297f
child 99 2ea929b45a14
modify EXIF.py to use mmap in the hope of slightly better improvements with less syscalls
degal/lib/EXIF.py
degal/lib/EXIFpy-1.0.8-changes.txt
--- a/degal/lib/EXIF.py	Thu Jun 11 22:50:44 2009 +0300
+++ b/degal/lib/EXIF.py	Thu Jun 11 23:24:48 2009 +0300
@@ -81,7 +81,7 @@
 #
 # ----- See 'changes.txt' file for all contributors and changes ----- #
 #
-
+import mmap
 
 # Don't throw an exception when given an out of range character.
 def make_string(seq):
@@ -1240,20 +1240,27 @@
 class EXIF_header:
     def __init__(self, file, endian, offset, fake_exif, strict, debug=0):
         self.file = file
+        self.mmap = mmap.mmap(file.fileno(), 0, access=mmap.ACCESS_READ)
         self.endian = endian
         self.offset = offset
         self.fake_exif = fake_exif
         self.strict = strict
         self.debug = debug
         self.tags = {}
+    
+    def pread(self, reloffset, length):
+        """Read <length> bytes from self.file at relative offset <offset>"""
+        
+        offset = self.offset + reloffset
+
+        return self.mmap[offset:offset + length]
 
     # convert slice to integer, based on sign and endian flags
     # usually this offset is assumed to be relative to the beginning of the
     # start of the EXIF information.  For some cameras that use relative tags,
     # this offset may be relative to some other starting point.
     def s2n(self, offset, length, signed=0):
-        self.file.seek(self.offset+offset)
-        slice=self.file.read(length)
+        slice=self.pread(offset, length)
         if self.endian == 'I':
             val=s2n_intel(slice)
         else:
@@ -1349,8 +1356,7 @@
                     # XXX investigate
                     # sometimes gets too big to fit in int value
                     if count != 0 and count < (2**31):
-                        self.file.seek(self.offset + offset)
-                        values = self.file.read(count)
+                        values = self.pread(offset, count)
                         #print values
                         # Drop any garbage after a null.
                         values = values.split('\x00', 1)[0]
@@ -1426,8 +1432,7 @@
         else:
             tiff = 'II*\x00\x08\x00\x00\x00'
         # ... plus thumbnail IFD data plus a null "next IFD" pointer
-        self.file.seek(self.offset+thumb_ifd)
-        tiff += self.file.read(entries*12+2)+'\x00\x00\x00\x00'
+        tiff += self.pread(thumb_ifd, entries*12+2)+'\x00\x00\x00\x00'
 
         # fix up large value offset pointers into data area
         for i in range(entries):
@@ -1454,8 +1459,7 @@
                     strip_off = newoff
                     strip_len = 4
                 # get original data and store it
-                self.file.seek(self.offset + oldoff)
-                tiff += self.file.read(count * typelen)
+                tiff += self.pread(oldoff, count * typelen)
 
         # add pixel strips and update strip offset info
         old_offsets = self.tags['Thumbnail StripOffsets'].values
@@ -1466,8 +1470,7 @@
             tiff = tiff[:strip_off] + offset + tiff[strip_off + strip_len:]
             strip_off += strip_len
             # add pixel strip to end
-            self.file.seek(self.offset + old_offsets[i])
-            tiff += self.file.read(old_counts[i])
+            tiff += self.pread(old_offsets[i], old_counts[i])
 
         self.tags['TIFFThumbnail'] = tiff
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/degal/lib/EXIFpy-1.0.8-changes.txt	Thu Jun 11 23:24:48 2009 +0300
@@ -0,0 +1,114 @@
+~ EXIF.py Changelog ~
+
+2009-06-11 - Tero Marttila <terom@fixme.fi>
+Replace file.seek/file.read calls with direct mmap access
+
+2008-07-31 - Ianaré Sévi
+Wikipedia Commons hunt for suitable test case images,
+testing new code additions.
+
+2008-07-09 - Stephen H. Olson
+Fix a problem with reading MakerNotes out of NEF files.
+Add some more Nikon MakerNote tags.
+
+2008-07-08 - Stephen H. Olson
+An error check for large tags totally borked MakerNotes.
+  With Nikon anyway, valid MakerNotes can be pretty big.
+Add error check for a crash caused by nikon_ev_bias being 
+  called with the wrong args.
+Drop any garbage after a null character in string
+  (patch from Andrew McNabb <amcnabb@google.com>).
+
+2008-02-12 - Ianaré Sévi
+Fix crash on invalid MakerNote
+Fix crash on huge Makernote (temp fix)
+Add printIM tag 0xC4A5, needs decoding info
+Add 0x9C9B-F range of tags
+Add a bunch of tag definitions from:
+ http://owl.phy.queensu.ca/~phil/exiftool/TagNames/EXIF.html
+Add 'strict' variable and command line option
+
+2008-01-18 - Gunter Ohrner
+Add 'GPSDate' tag
+
+2007-12-12 - Ianaré Sévi
+Fix quick option on certain image types
+Add note on tag naming in documentation
+
+2007-11-30 - Ianaré Sévi
+Changed -s option to -t
+Put changelog into separate file
+
+2007-10-28 - Ianaré Sévi
+Merged changes from MoinMoin:ReimarBauer
+Added command line option for debug, stop
+processing on tag.
+
+2007-09-27 - Ianaré Sévi
+Add some Olympus Makernote tags.
+
+2007-09-26 - Stephen H. Olson
+Don't error out on invalid Olympus 'SpecialMode'.
+Add a few more Olympus/Minolta tags.
+
+2007-09-22 - Stephen H. Olson
+Don't error on invalid string
+Improved Nikon MakerNote support
+
+2007-05-03 - Martin Stone <mj_stone@users.sourceforge.net>
+Fix for inverted detailed flag and Photoshop header
+
+2007-03-24 - Ianaré Sévi
+Can now ignore MakerNotes Tags for faster processing.
+
+2007-01-18 - Ianaré Sévi <ianare@gmail.com>
+Fixed a couple errors and assuming maintenance of the library.
+
+2006-08-04 MoinMoin:ReimarBauer
+Added an optional parameter name to process_file and dump_IFD. Using this parameter the
+loop is breaked after that tag_name is processed.
+some PEP8 changes
+
+---------------------------- original notices -------------------------
+
+Contains code from "exifdump.py" originally written by Thierry Bousch
+<bousch@topo.math.u-psud.fr> and released into the public domain.
+
+Updated and turned into general-purpose library by Gene Cash
+
+Patch Contributors:
+* Simon J. Gerraty <sjg@crufty.net>
+s2n fix & orientation decode
+* John T. Riedl <riedl@cs.umn.edu>
+Added support for newer Nikon type 3 Makernote format for D70 and some
+other Nikon cameras.
+* Joerg Schaefer <schaeferj@gmx.net>
+Fixed subtle bug when faking an EXIF header, which affected maker notes
+using relative offsets, and a fix for Nikon D100.
+
+1999-08-21 TB  Last update by Thierry Bousch to his code.
+2002-01-17 CEC Discovered code on web.
+            Commented everything.
+            Made small code improvements.
+            Reformatted for readability.
+2002-01-19 CEC Added ability to read TIFFs and JFIF-format JPEGs.
+            Added ability to extract JPEG formatted thumbnail.
+            Added ability to read GPS IFD (not tested).
+            Converted IFD data structure to dictionaries indexed by
+            tag name.
+            Factored into library returning dictionary of IFDs plus
+            thumbnail, if any.
+2002-01-20 CEC Added MakerNote processing logic.
+            Added Olympus MakerNote.
+            Converted data structure to single-level dictionary, avoiding
+            tag name collisions by prefixing with IFD name.  This makes
+            it much easier to use.
+2002-01-23 CEC Trimmed nulls from end of string values.
+2002-01-25 CEC Discovered JPEG thumbnail in Olympus TIFF MakerNote.
+2002-01-26 CEC Added ability to extract TIFF thumbnails.
+            Added Nikon, Fujifilm, Casio MakerNotes.
+2003-11-30 CEC Fixed problem with canon_decode_tag() not creating an
+            IFD_Tag() object.
+2004-02-15 CEC Finally fixed bit shift warning by converting Y to 0L.
+
+~ EOF ~