--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/tools/py2sis/ensymble/decodemif.py Tue Feb 16 10:07:05 2010 +0530
@@ -0,0 +1,229 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+##############################################################################
+# decodemif.py - Decodes a Symbian OS v9.x multi-image file (MIF)
+# Copyright 2006, 2007 Jussi Ylänen
+#
+# This program is part of Ensymble developer utilities for Symbian OS(TM).
+#
+# Ensymble is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# Ensymble is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Ensymble; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+#
+#
+# Version history
+# ---------------
+#
+# v0.03 2006-09-22
+# Replaced every possible range(...) with xrange(...) for efficiency
+#
+# v0.02 2006-08-22
+# Added file type recognition (SVG, binary SVG or other)
+#
+# v0.01 2006-08-14
+# Added support for strange index entries (length 0)
+#
+# v0.00 2006-08-13
+# Work started
+##############################################################################
+
+VERSION = "v0.02 2006-09-22"
+
+import sys
+import os
+import struct
+import getopt
+import random
+import tempfile
+
+# Parameters
+MAXMIFFILESIZE = 1024 * 1024 # Arbitrary maximum size of MIF file
+
+tempdir = None
+dumpcounter = 0
+
+def mkdtemp(template):
+ '''
+ Create a unique temporary directory.
+
+ tempfile.mkdtemp() was introduced in Python v2.3. This is for
+ backward compatibility.
+ '''
+
+ # Cross-platform way to determine a suitable location for temporary files.
+ systemp = tempfile.gettempdir()
+
+ if not template.endswith("XXXXXX"):
+ raise ValueError("invalid template for mkdtemp(): %s" % template)
+
+ for n in xrange(10000):
+ randchars = []
+ for m in xrange(6):
+ randchars.append(random.choice("abcdefghijklmnopqrstuvwxyz"))
+
+ tempdir = os.path.join(systemp, template[: -6]) + "".join(randchars)
+
+ try:
+ os.mkdir(tempdir, 0700)
+ return tempdir
+ except OSError:
+ pass
+
+def dumpdata(data):
+ '''Dumps data to a file in a temporary directory.'''
+
+ global tempdir, dumpcounter
+
+ if tempdir == None:
+ # Create temporary directory for dumped files.
+ tempdir = mkdtemp("decodemif-XXXXXX")
+ dumpcounter = 0
+
+ # Determine file type.
+ if data[0:5] == "<?xml":
+ ext = "svg"
+ elif data[0:4] == '\xcc\x56\xfa\x03':
+ ext = "svgb"
+ else:
+ ext = "dat"
+
+ filename = os.path.join(tempdir, "dump%04d.%s" % (dumpcounter, ext))
+ dumpcounter += 1
+ f = file(filename, "wb")
+ f.write(data)
+ f.close()
+ print "%s written" % filename
+
+def main():
+ global tempdir, dumpcounter
+
+ pgmname = os.path.basename(sys.argv[0])
+ pgmversion = VERSION
+
+ try:
+ try:
+ gopt = getopt.gnu_getopt
+ except:
+ # Python <v2.3, GNU-style parameter ordering not supported.
+ gopt = getopt.getopt
+
+ # Parse command line using getopt.
+ short_opts = "t:h"
+ long_opts = [
+ "dumpdir", "help"
+ ]
+ args = gopt(sys.argv[1:], short_opts, long_opts)
+
+ opts = dict(args[0])
+ pargs = args[1]
+
+ if "--help" in opts.keys() or "-h" in opts.keys():
+ # Help requested.
+ print (
+'''
+DecodeMIF - Symbian OS v9.x MIF file decoder %(pgmversion)s
+
+usage: %(pgmname)s [--dumpdir=DIR] [miffiles...]
+
+ -t, --dumpdir - Directory to use for dumped files (or automatic)
+ miffiles - MIF files to decode (stdin if not given or -)
+
+''' % locals())
+ return 0
+
+ # A temporary directory is generated by default.
+ tempdir = opts.get("--dumpdir", opts.get("-t", None))
+
+ if len(pargs) == 0:
+ miffilenames = ["-"]
+ else:
+ miffilenames = pargs
+
+ for miffilename in miffilenames:
+ if miffilename == '-':
+ miffile = sys.stdin
+ else:
+ miffile = file(miffilename, "rb")
+
+ try:
+ # Load the whole MIF file as a string.
+ mifdata = miffile.read(MAXMIFFILESIZE)
+ if len(mifdata) == MAXMIFFILESIZE:
+ raise IOError("%s: file too large" % miffilename)
+ finally:
+ if miffile != sys.stdin:
+ miffile.close()
+
+ # Verify MIF signature.
+ if mifdata[:4] != "B##4":
+ raise ValueError("%s: not a MIF file" % miffilename)
+
+ if len(mifdata) < 16:
+ raise ValueError("%s: file too short" % miffilename)
+
+ entries = struct.unpack("<L", mifdata[12:16])[0] / 2
+
+ # Verify header length:
+ # 16-byte header, 16 bytes per index entry
+ if len(mifdata) < (16 + 16 * entries):
+ raise ValueError("%s: file too short" % miffilename)
+
+ # Read index.
+ index = []
+ for n in xrange(entries):
+ hdroff = 16 + n * 16
+ a = struct.unpack("<L", mifdata[hdroff + 0:hdroff + 4])[0]
+ b = struct.unpack("<L", mifdata[hdroff + 4:hdroff + 8])[0]
+ c = struct.unpack("<L", mifdata[hdroff + 8:hdroff + 12])[0]
+ d = struct.unpack("<L", mifdata[hdroff + 12:hdroff + 16])[0]
+
+ if b == 0 and d == 0:
+ # Unknown index entry type, skip it.
+ continue
+
+ if a != c or b != d:
+ raise ValueError("%s: invalid index entry %d" %
+ (miffilename, n))
+
+ # Check total length of file.
+ if a + b > len(mifdata):
+ raise ValueError("%s: index %d out of range" %
+ (miffilename, n))
+
+ index.append((a, b))
+
+ n = len(index)
+ print "%s: %s %s inside" % (miffilename, n or "no",
+ ((n == 1) and "file") or "files")
+
+ # Extract contents.
+ for i in index:
+ offset = i[0]
+ length = i[1]
+ if mifdata[offset:offset + 4] != "C##4":
+ raise ValueError("%s: invalid file header %d" %
+ (miffilename, n))
+
+ print "0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x" % (
+ tuple(struct.unpack("<LLLLLLL", mifdata[(offset + 4):
+ (offset + 32)])))
+ dumpdata(mifdata[offset + 32:offset + length + 32])
+ except (TypeError, ValueError, IOError, OSError), e:
+ return "%s: %s" % (pgmname, str(e))
+ except KeyboardInterrupt:
+ return ""
+
+# Call main if run as stand-alone executable.
+if __name__ == '__main__':
+ sys.exit(main())