[ooo-build-commit] 3 commits - scratch/mso-dumper

Thorsten Behrens thorsten at kemper.freedesktop.org
Wed Sep 23 00:55:18 PDT 2009


 scratch/mso-dumper/src/pptrecord.py |   72 ++++++
 scratch/mso-dumper/src/pptstream.py |  374 ++++++++++++++++++++----------------
 2 files changed, 282 insertions(+), 164 deletions(-)

New commits:
commit 4a23865f9b9263c9113cac3467fe551c6683f3ea
Author: Thorsten Behrens <tbehrens at novell.com>
Date:   Wed Sep 23 09:50:30 2009 +0200

    Ugh, special magic required to look into DFF_PST_ProgBinaryTag
    
    * scratch/mso-dumper/src/pptrecord.py: added CString prop name
    * scratch/mso-dumper/src/pptstream.py: recursing into
      DFF_PST_ProgBinaryTag when special magic version was seen

diff --git a/scratch/mso-dumper/src/pptrecord.py b/scratch/mso-dumper/src/pptrecord.py
index 7c593f0..0abd53a 100644
--- a/scratch/mso-dumper/src/pptrecord.py
+++ b/scratch/mso-dumper/src/pptrecord.py
@@ -122,6 +122,10 @@ def ShapeUniString (*args):
     args += "ShapeText",
     return UniString(*args)
 
+def CString (*args):
+    args += "CString",
+    return UniString(*args)
+
 class ZipRecord(BaseRecordHandler):
     """Zipped content."""
 
diff --git a/scratch/mso-dumper/src/pptstream.py b/scratch/mso-dumper/src/pptstream.py
index 0738a65..46a42a1 100644
--- a/scratch/mso-dumper/src/pptstream.py
+++ b/scratch/mso-dumper/src/pptstream.py
@@ -18,6 +18,180 @@ from globals import output
 
 class EndOfStream(Exception): pass
 
+class PPTFile(object):
+    """Represents the whole powerpoint file - feed will all bytes."""
+    def __init__ (self, chars, params):
+        self.chars = chars
+        self.size = len(self.chars)
+        self.version = None
+        self.params = params
+
+        self.header = ole.Header(self.chars, self.params)
+        self.pos = self.header.parse()
+
+
+    def __printSep (self, c='-', w=68, prefix=''):
+        print(prefix + c*w)
+
+
+    def printStreamInfo (self):
+        self.__printSep('=', 68)
+        print("PPT File Format Dumper by Kohei Yoshida & Thorsten Behrens")
+        print("  total stream size: %d bytes"%self.size)
+        self.__printSep('=', 68)
+        print('')
+
+
+    def printHeader (self):
+        self.header.output()
+
+
+    def __getDirectoryObj (self):
+        obj = self.header.getDirectory()
+        if obj is None:
+            return None
+        obj.parseDirEntries()
+        return obj
+
+
+    def printDirectory (self):
+        obj = self.__getDirectoryObj()
+        if obj is None:
+            return
+        obj.output()
+
+
+    def getDirectoryNames (self):
+        obj = self.__getDirectoryObj()
+        if obj is None:
+            return
+        return obj.getDirectoryNames()
+
+
+    def getDirectoryStreamByName (self, name):
+        obj = self.__getDirectoryObj()
+        bytes = []
+        if obj is not None:
+            bytes = obj.getRawStreamByName(name)
+        strm = PPTDirStream(bytes, self.params)
+        return strm
+
+
+class PPTDirStream(object):
+    """Represents one single powerpoint file subdirectory, like e.g. \"PowerPoint Document\"."""
+    def __init__ (self, bytes, params, prefix='', recordInfo=None):
+        self.bytes = bytes
+        self.size = len(self.bytes)
+        self.pos = 0
+        self.prefix = prefix
+        self.params = params
+        self.properties = {"recordInfo": recordInfo}
+
+
+    def readBytes (self, size=1):
+        if self.size - self.pos < size:
+            raise EndOfStream
+        bytes = self.bytes[self.pos:self.pos+size]
+        self.pos += size
+        return bytes
+
+
+    def readUnsignedInt (self, size=1):
+        return globals.getUnsignedInt(self.readBytes(size))
+
+
+    def __print (self, text):
+        print(self.prefix + text)
+
+
+    def __printSep (self, c='-', w=68, prefix=''):
+        self.__print(prefix + c*w)
+
+
+    def readRecords (self):
+        try:
+            # read until data is exhausted (min record size: 8 bytes)
+            while self.pos+8 < self.size:
+                print("")
+                self.readRecord()
+            return True
+        except EndOfStream:
+            return False
+
+
+    def printRecordHeader (self, startPos, recordInstance, recordVersion, recordType, size):
+        self.__printSep('=')
+        if recordType in recData:
+            self.__print("[%s]"%recData[recordType][0])
+        else:
+            self.__print("[anon record]")
+        self.__print("(type: %4.4Xh inst: %4.4Xh, vers: %4.4Xh, start: %d, size: %d)"%
+              (recordType, recordInstance, recordVersion, startPos, size))
+        self.__printSep('=')
+
+
+    def printRecordDump (self, bytes, recordType):
+        size = len(bytes)
+        self.__printSep('-', 61, "%4.4Xh: "%recordType)
+        for i in xrange(0, size):
+            if (i+1) % 16 == 1:
+                output(self.prefix + "%4.4Xh: "%recordType)
+            output("%2.2X "%ord(bytes[i]))
+            if (i+1) % 16 == 0 and i != size-1:
+                print("")
+        if size > 0:
+            print("")
+            self.__printSep('-', 61, "%4.4Xh: "%recordType)
+
+
+    def readRecord (self):
+        startPos = self.pos
+        recordInstance = self.readUnsignedInt(2)
+        recordVersion = (recordInstance & 0x000F)
+        recordInstance = recordInstance // 16
+        recordType = self.readUnsignedInt(2)
+        size = self.readUnsignedInt(4)
+
+        self.printRecordHeader(startPos, recordInstance, recordVersion, recordType, size)
+        bytes = self.readBytes(size)
+
+        recordInfo = None
+        if recordType in recData and len(recData[recordType]) >= 2:
+            recordInfo = recData[recordType]
+
+        if recordVersion == 0x0F:
+            # substream? recurse into that
+            subSubStrm = PPTDirStream(bytes, self.params, self.prefix+" ", recordInfo)
+            subSubStrm.readRecords()
+        elif (recordInfo is not None
+              and recordInfo[1] == "magic"
+              and self.isPPT10SpecialData()):
+            # what a mess. PPT10 binary data is just another embedded
+            # stream
+            self.handlePPT10BinaryTags(bytes,recordInfo)
+        elif recordInfo is not None:
+            handler = recordInfo[1](recordType, recordInstance, size, bytes, self.properties, self.prefix)
+            print("")
+            # call special record handler, if any
+            if handler is not None:
+                handler.output()
+            self.printRecordDump(bytes, recordType)
+        elif size > 0:
+            print("")
+            self.printRecordDump(bytes, recordType)
+
+    def checkPPT10BinaryTag (recordType, recordInstance, size, bytes, properties, prefix):
+        # waiting for magic '___PPT10' string, clear any incidental
+        # prior occurrence
+        properties["CString"] = ''
+
+    def isPPT10SpecialData (self):
+        return "CString" in self.properties and self.properties["CString"] == "___PPT10"
+
+    def handlePPT10BinaryTags (self, bytes, recordInfo):
+        subSubStrm = PPTDirStream(bytes, self.params, self.prefix+" ", recordInfo)
+        subSubStrm.readRecords()
+
 # IDs from OOo's svx/inc/svx/msdffdef.hxx (slightly adapted)
 #
 # opcode: [canonical name, handler (optional)]
@@ -121,7 +295,7 @@ recData = {
  4023:  ["DFF_PST_FontEntityAtom", pptrecord.FontEntity],
  4024:  ["DFF_PST_FontEmbedData"],
  4025:  ["DFF_PST_TypeFace"],
- 4026:  ["DFF_PST_CString", pptrecord.UniString],
+ 4026:  ["DFF_PST_CString", pptrecord.CString],
  4027:  ["DFF_PST_ExternalObject"],
  4033:  ["DFF_PST_MetaFile"],
  4034:  ["DFF_PST_ExOleObj"],
@@ -186,8 +360,8 @@ recData = {
  4117:  ["DFF_PST_RTFDateTimeMCAtom"],
  5000:  ["DFF_PST_ProgTags"],
  5001:  ["DFF_PST_ProgStringTag"],
- 5002:  ["DFF_PST_ProgBinaryTag"],
- 5003:  ["DFF_PST_BinaryTagData"],
+ 5002:  ["DFF_PST_ProgBinaryTag", PPTDirStream.checkPPT10BinaryTag],
+ 5003:  ["DFF_PST_BinaryTagData", "magic"],
  6000:  ["DFF_PST_PrintOptions"],
  6001:  ["DFF_PST_PersistPtrFullBlock"],
  6002:  ["DFF_PST_PersistPtrIncrementalBlock"],
@@ -271,159 +445,3 @@ recData = {
 0xF119: ["DFF_msofbtSelection"]
 
 }
-
-class PPTFile(object):
-    """Represents the whole powerpoint file - feed will all bytes."""
-    def __init__ (self, chars, params):
-        self.chars = chars
-        self.size = len(self.chars)
-        self.version = None
-        self.params = params
-
-        self.header = ole.Header(self.chars, self.params)
-        self.pos = self.header.parse()
-
-
-    def __printSep (self, c='-', w=68, prefix=''):
-        print(prefix + c*w)
-
-
-    def printStreamInfo (self):
-        self.__printSep('=', 68)
-        print("PPT File Format Dumper by Kohei Yoshida & Thorsten Behrens")
-        print("  total stream size: %d bytes"%self.size)
-        self.__printSep('=', 68)
-        print('')
-
-
-    def printHeader (self):
-        self.header.output()
-
-
-    def __getDirectoryObj (self):
-        obj = self.header.getDirectory()
-        if obj is None:
-            return None
-        obj.parseDirEntries()
-        return obj
-
-
-    def printDirectory (self):
-        obj = self.__getDirectoryObj()
-        if obj is None:
-            return
-        obj.output()
-
-
-    def getDirectoryNames (self):
-        obj = self.__getDirectoryObj()
-        if obj is None:
-            return
-        return obj.getDirectoryNames()
-
-
-    def getDirectoryStreamByName (self, name):
-        obj = self.__getDirectoryObj()
-        bytes = []
-        if obj is not None:
-            bytes = obj.getRawStreamByName(name)
-        strm = PPTDirStream(bytes, self.params)
-        return strm
-
-
-class PPTDirStream(object):
-    """Represents one single powerpoint file subdirectory, like e.g. \"PowerPoint Document\"."""
-    def __init__ (self, bytes, params, prefix='', recordInfo=None):
-        self.bytes = bytes
-        self.size = len(self.bytes)
-        self.pos = 0
-        self.prefix = prefix
-        self.params = params
-        self.properties = {"recordInfo": recordInfo}
-
-
-    def readBytes (self, size=1):
-        if self.size - self.pos < size:
-            raise EndOfStream
-        bytes = self.bytes[self.pos:self.pos+size]
-        self.pos += size
-        return bytes
-
-
-    def readUnsignedInt (self, size=1):
-        return globals.getUnsignedInt(self.readBytes(size))
-
-
-    def __print (self, text):
-        print(self.prefix + text)
-
-
-    def __printSep (self, c='-', w=68, prefix=''):
-        self.__print(prefix + c*w)
-
-
-    def readRecords (self):
-        try:
-            # read until data is exhausted (min record size: 8 bytes)
-            while self.pos+8 < self.size:
-                print("")
-                self.readRecord()
-            return True
-        except EndOfStream:
-            return False
-
-
-    def printRecordHeader (self, startPos, recordInstance, recordVersion, recordType, size):
-        self.__printSep('=')
-        if recordType in recData:
-            self.__print("[%s]"%recData[recordType][0])
-        else:
-            self.__print("[anon record]")
-        self.__print("(type: %4.4Xh inst: %4.4Xh, vers: %4.4Xh, start: %d, size: %d)"%
-              (recordType, recordInstance, recordVersion, startPos, size))
-        self.__printSep('=')
-
-
-    def printRecordDump (self, bytes, recordType):
-        size = len(bytes)
-        self.__printSep('-', 61, "%4.4Xh: "%recordType)
-        for i in xrange(0, size):
-            if (i+1) % 16 == 1:
-                output(self.prefix + "%4.4Xh: "%recordType)
-            output("%2.2X "%ord(bytes[i]))
-            if (i+1) % 16 == 0 and i != size-1:
-                print("")
-        if size > 0:
-            print("")
-            self.__printSep('-', 61, "%4.4Xh: "%recordType)
-
-
-    def readRecord (self):
-        startPos = self.pos
-        recordInstance = self.readUnsignedInt(2)
-        recordVersion = (recordInstance & 0x000F)
-        recordInstance = recordInstance // 16
-        recordType = self.readUnsignedInt(2)
-        size = self.readUnsignedInt(4)
-
-        self.printRecordHeader(startPos, recordInstance, recordVersion, recordType, size)
-        bytes = self.readBytes(size)
-
-        recordInfo = None
-        if recordType in recData and len(recData[recordType]) >= 2:
-            recordInfo = recData[recordType]
-
-        if recordVersion == 0x0F:
-            # substream? recurse into that
-            subSubStrm = PPTDirStream(bytes, self.params, self.prefix+" ", recordInfo)
-            subSubStrm.readRecords()
-        elif recordInfo is not None:
-            handler = recordInfo[1](recordType, recordInstance, size, bytes, self.properties, self.prefix)
-            print("")
-            # call special record handler, if any
-            if handler is not None:
-                handler.output()
-            self.printRecordDump(bytes, recordType)
-        elif size > 0:
-            print("")
-            self.printRecordDump(bytes, recordType)
commit 2e917dfa677574c7bef717e5bbc4b2fd3cf38fe3
Author: Thorsten Behrens <tbehrens at novell.com>
Date:   Wed Sep 23 00:22:04 2009 +0200

    Added the post-97 SMIL-like anim atoms
    
    * scratch/mso-dumper/src/pptstream.py:

diff --git a/scratch/mso-dumper/src/pptstream.py b/scratch/mso-dumper/src/pptstream.py
index b134311..0738a65 100644
--- a/scratch/mso-dumper/src/pptstream.py
+++ b/scratch/mso-dumper/src/pptstream.py
@@ -81,7 +81,7 @@ recData = {
  1059:  ["DFF_PST_RoundTripOArtTextStyles", pptrecord.ZipRecord],
  1064:  ["DFF_PST_RoundTripCustomTableStyles"],
  2000:  ["DFF_PST_List"],
- 2005:  ["DFF_PST_FontCollection"], 
+ 2005:  ["DFF_PST_FontCollection"],
  2017:  ["DFF_PST_ListPlaceholder"],
  2019:  ["DFF_PST_BookmarkCollection"],
  2020:  ["DFF_PST_SoundCollection"],
@@ -234,6 +234,40 @@ recData = {
 0xF015: ["DFF_msofbtClientRule"],
 0xF017: ["DFF_msofbtCalloutRule"],
 
+0x2AFB: ["DFF_msofbtAnimReference"],
+0xF125: ["DFF_msofbtAnimEvent"],
+0xF127: ["DFF_msofbtAnimNode"],
+0xF128: ["DFF_msofbtAnimTrigger"],
+0xF129: ["DFF_msofbtAnimValue"],
+0xF12A: ["DFF_msofbtAnimateTarget"],
+0xF12B: ["DFF_msofbtAnimate"],
+0xF12C: ["DFF_msofbtAnimateColor"],
+0xF12D: ["DFF_msofbtAnimateFilter"],
+0xF12E: ["DFF_msofbtAnimateMotion"],
+0xF12F: ["DFF_msofbtAnimateRotation"],
+0xF130: ["DFF_msofbtAnimateScale"],
+0xF131: ["DFF_msofbtAnimateSet"],
+0xF132: ["DFF_msofbtAnimCommand"],
+0xF133: ["DFF_msofbtAnimateTargetSettings"],
+0xF134: ["DFF_msofbtAnimateData"],
+0xF135: ["DFF_msofbtAnimateColorData"],
+0xF136: ["DFF_msofbtAnimateFilterData"],
+0xF137: ["DFF_msofbtAnimateMotionData"],
+0xF139: ["DFF_msofbtAnimateScaleData"],
+0xF13A: ["DFF_msofbtAnimateSetData"],
+0xF13B: ["DFF_msofbtCommandData"],
+0xF13C: ["DFF_msofbtAnimateTargetElement"],
+0xF13D: ["DFF_msofbtAnimPropertySet"],
+0xF13E: ["DFF_msofbtAnimateAttributeNames"],
+0xF13F: ["DFF_msofbtAnimKeyPoints"],
+0xF140: ["DFF_msofbtAnimIteration"],
+0xF141: ["DFF_msofbtAnimActions"],
+0xF142: ["DFF_msofbtAnimAttributeValue"],
+0xF143: ["DFF_msofbtAnimKeyTime"],
+0xF144: ["DFF_msofbtAnimGroup"],
+0xF145: ["DFF_msofbtAnimSubGoup"],
+0xF138: ["DFF_msofbtAnimateRotationData"],
+
 0xF119: ["DFF_msofbtSelection"]
 
 }
commit e0d40901973bfe42690c2e9d21ed2bab14381dad
Author: Thorsten Behrens <tbehrens at novell.com>
Date:   Tue Sep 22 23:43:55 2009 +0200

    Added handling of legacy animation info to pptdumper
    
    * scratch/mso-dumper/src/pptrecord.py:
    * scratch/mso-dumper/src/pptstream.py:

diff --git a/scratch/mso-dumper/src/pptrecord.py b/scratch/mso-dumper/src/pptrecord.py
index ba4c1c0..7c593f0 100644
--- a/scratch/mso-dumper/src/pptrecord.py
+++ b/scratch/mso-dumper/src/pptrecord.py
@@ -329,6 +329,71 @@ class ColorScheme(BaseRecordHandler):
 # -------------------------------------------------------------------
 # special record handlers: text style properties
 
+class AnimationInfo(BaseRecordHandler):
+    """Animation properties."""
+
+    def parseBytes (self):
+        self.appendLine(globals.stringizeColorRef(self.readUnsignedInt(4),
+                                                  "DimColor"))
+        flags = self.readUnsignedInt(4)
+        self.appendLine("reverse: %d"%((flags & 0x00000001)!=0))
+        self.appendLine("automatic: %d"%((flags & 0x00000002)!=0))
+        self.appendLine("sound: %d"%((flags & 0x00000004)!=0))
+        self.appendLine("stopsound: %d"%((flags & 0x00000008)!=0))
+        self.appendLine("play: %d"%((flags & 0x00000010)!=0))
+        self.appendLine("synchronous: %d"%((flags & 0x00000020)!=0))
+        self.appendLine("hide: %d"%((flags & 0x00000040)!=0))
+        self.appendLine("animateBackground: %d"%((flags & 0x00000080)!=0))
+
+        self.appendLine("sound reference ID: %Xh"%self.readUnsignedInt(4))
+        self.appendLine("delay time: %d"%self.readUnsignedInt(4))
+        orderID = self.readSignedInt(2)
+        if orderID == -2:
+            self.appendLine("order: follow master slide")
+        else:    
+            self.appendLine("order: ID %4.4Xh"%orderID)
+
+        self.appendLine("num slides to play object: %d"%self.readUnsignedInt(2))
+
+        buildDesc = ["no build","all at once","by text level 1","by text level 2",
+                     "by text level 3","by text level 4","by text level 5",
+                     "graph by series","graph by category","element in series",
+                     "element in category"]
+        buildType = self.readUnsignedInt(1)
+        self.appendLine("build type: %s"%buildDesc[buildType])
+
+        flyDesc = ["none","random","blinds","checker","cover","dissolve",
+                   "fade","pull","random bar","strips","wipe","zoom","fly",
+                   "split","flash","(unused)","(unused)","diamond","plus",
+                   "wedge","push","comb","newsflash","alphafade","blur",
+                   "pushelem","wheel","circle"]
+        flyMethod = self.readUnsignedInt(1)
+        self.appendLine("fly method: %s"%flyDesc[flyMethod])
+
+        flyDirectionDesc = ["left","up","right","down","leftUp","rightUp",
+                            "leftDown","rightDown","fromLeftEdge","fromBottomEdge",
+                            "fromRightEdge","fromTopEdge","leftSlow","upSlow",
+                            "rightSlow","downSlow","zoomIn","zoomInSlightly",
+                            "zoomOut","zoomOutSlightly","zoomCenter","zoomBottom",
+                            "stretchAcross","stretchLeft","stretchUp","stretchRight",
+                            "stretchDown","rotate","spiral"]
+        flyDirection = self.readUnsignedInt(1)
+        self.appendLine("fly direction: %s"%flyDirectionDesc[flyDirection])
+
+        afterEffectDesc = ["none","dim","hide","hideImmediately"]
+        afterEffect = self.readUnsignedInt(1)
+        self.appendLine("after effect: %s"%afterEffectDesc[afterEffect])
+
+        subEffectDesc = ["none","build by word","build by letter"]
+        subEffect = self.readUnsignedInt(1)
+        self.appendLine("sub effect: %s"%subEffectDesc[subEffect])
+
+        self.appendLine("OLE verb: %4.4Xh"%self.readUnsignedInt(1))
+
+
+# -------------------------------------------------------------------
+# special record handlers: text style properties
+
 class TextStyles(BaseRecordHandler):
     """Text style properties."""
 
@@ -600,9 +665,6 @@ class FixedPointHandler(BasePropertyHandler):
 class ColorPropertyHandler(BasePropertyHandler):
     """Color property."""
 
-    def split (self, packedColor):
-        return ((packedColor & 0xFF0000) // 0x10000, (packedColor & 0xFF00) / 0x100, (packedColor & 0xFF))
-
     def output (self):
         propEntry = ["<color atom>", None, "undocumented color property"]
         if self.propType in propData:
diff --git a/scratch/mso-dumper/src/pptstream.py b/scratch/mso-dumper/src/pptstream.py
index 270836c..b134311 100644
--- a/scratch/mso-dumper/src/pptstream.py
+++ b/scratch/mso-dumper/src/pptstream.py
@@ -161,7 +161,7 @@ recData = {
  4078:  ["DFF_PST_ExControl"],
  4091:  ["DFF_PST_ExControlAtom"],
  4080:  ["DFF_PST_SlideListWithText"],
- 4081:  ["DFF_PST_AnimationInfoAtom"],
+ 4081:  ["DFF_PST_AnimationInfoAtom", pptrecord.AnimationInfo],
  4082:  ["DFF_PST_InteractiveInfo"],
  4083:  ["DFF_PST_InteractiveInfoAtom"],
  4084:  ["DFF_PST_SlideList"],


More information about the ooo-build-commit mailing list