[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