[Libreoffice-commits] mso-dumper.git: 11 commits - src/docrecord.py src/msodraw.py test/doc
Miklos Vajna
vmiklos at kemper.freedesktop.org
Fri Jul 19 04:12:08 PDT 2013
src/docrecord.py | 139 ++++++++++++++++++++++++++++++++++++++++++++++-----
src/msodraw.py | 113 ++++++++++++++++++++++++++++++++++++++++-
test/doc/picture.doc |binary
test/doc/test.py | 11 ++++
4 files changed, 250 insertions(+), 13 deletions(-)
New commits:
commit 791c8e3aefaf5ea4c15900bc2724564b8e616d0d
Author: Miklos Vajna <vmiklos at suse.cz>
Date: Fri Jul 19 12:58:07 2013 +0200
msodraw: dump BlipPng
diff --git a/src/msodraw.py b/src/msodraw.py
index 5e84489..8126ab9 100644
--- a/src/msodraw.py
+++ b/src/msodraw.py
@@ -73,6 +73,7 @@ class RecordHeader:
FClientAnchor = 0xF010
FClientData = 0xF011
FConnectorRule = 0xF012
+ BlipPNG = 0xF01E
FDGSL = 0xF119
SplitMenuColorContainer = 0xF11E
TertiaryFOPT = 0xF122
@@ -94,6 +95,7 @@ class RecordHeader:
Type.FSP: 'OfficeArtFSP',
Type.FSPGR: 'OfficeArtFSPGR',
Type.FConnectorRule: 'OfficeArtFConnectorRule',
+ Type.BlipPNG: 'OfficeArtBlipPng',
Type.FDGSL: 'OfficeArtFDGSL',
Type.SplitMenuColorContainer: 'OfficeArtSplitMenuColorContainer'
}
@@ -304,6 +306,34 @@ class FDGSL:
for shape in self.shapesSelected:
recHdl.appendLine(" ID of shape selected: %d"%shape)
+class BlipPNG:
+ def __init__(self, strm):
+ self.strm = strm
+
+ def __parseBytes(self, rh):
+ pos = self.strm.pos
+ self.rgbUid1 = self.strm.readBytes(16)
+ if rh.recInstance == 0x06E1:
+ self.rgbUid2 = self.strm.readBytes(16)
+ else:
+ self.rgbUid2 = None
+ self.tag = self.strm.readUnsignedInt(1)
+ header = self.strm.pos - pos
+ data = rh.recLen - header
+ self.BLIPFileData = self.strm.readBytes(data)
+
+ def appendLines(self, recHdl, rh):
+ pass
+
+ def dumpXml(self, recHdl, model, rh):
+ recHdl.appendLine('<blipPng type="OfficeArtBlipPng">')
+ self.__parseBytes(rh)
+ recHdl.appendLine('<rgbUid1 value="%s"/>' % hexdump(self.rgbUid1))
+ if self.rgbUid2:
+ recHdl.appendLine('<rgbUid2 value="%s"/>' % hexdump(self.rgbUid2))
+ recHdl.appendLine('<tag value="%s"/>' % self.tag)
+ recHdl.appendLine('<BLIPFileData value="%s"/>' % hexdump(self.BLIPFileData))
+ recHdl.appendLine('</blipPng>')
class FOPT:
"""property table for a shape instance"""
@@ -1227,6 +1257,7 @@ recData = {
RecordHeader.Type.FDGGBlock: FDGGBlock,
RecordHeader.Type.FConnectorRule: FConnectorRule,
RecordHeader.Type.FDGSL: FDGSL,
+ RecordHeader.Type.BlipPNG: BlipPNG,
RecordHeader.Type.FClientAnchor: FClientAnchorSheet,
RecordHeader.Type.FClientData: FClientData,
RecordHeader.Type.FClientTextbox: FClientTextbox,
diff --git a/test/doc/picture.doc b/test/doc/picture.doc
new file mode 100644
index 0000000..78c8aa7
Binary files /dev/null and b/test/doc/picture.doc differ
diff --git a/test/doc/test.py b/test/doc/test.py
index 97951cb..da0de0a 100755
--- a/test/doc/test.py
+++ b/test/doc/test.py
@@ -185,6 +185,17 @@ class Test(unittest.TestCase):
def test_abi1157(self):
self.dump('abi1157-1')
+ def test_picture(self):
+ self.dump('picture')
+
+ runs = self.getRuns()
+ self.assertEqual(3, len(runs))
+
+ # make sure the correct PNG data is dumped
+ expected = "89504e470d0a1a0a0000000d4948445200000010000000100802000000909168360000015049444154789c9592c14a02511486bf99714ccb322d7521140541cb6a11448b164150fb8a363d41f4083d40cba0655044d0a637a837682fd1a6a2488b10b23475bcb77b671c491dc1cee23077e67cf7fcff39139252f29f08b59e3e1dae8b4c45998ff501a82e070f5cbd3366733acb5c6fa609fc0872651236df0deeca7d002a6cc33d1b941a146ab49ca937e37610e0c590c5c92b67f926a07243b293613f8b1108a8a84aadb01575c9799edd0c895010a0ae71048e77b99b6a92e53861a387a48a6033c5d208c297a43ca8a3697601d217b010632dd9a9f34be09968021698bea4c76ab72f5dd0d6216c3211e1bec2a0c5e59bce9303baa770c7bd38aca7d729692bcd4d512b53bb3b7cc2f45dd604ab098e67b499366025ce5e96a317fd2162e2d76bbbb725bdcd80b12a603aca4581e7aade97e14ec2916ca719ed96e4c54692f5241f755de7019641eacfaff10b469261dc6a800dd30000000049454e44ae426082"
+ actual = runs[1].findall('chpx/prl[@index="0"]/sprm/PICFAndOfficeArtData/inlineSpContainer/fbse/blipPng/BLIPFileData')[0].attrib['value']
+ self.assertEqual(expected, actual)
+
if __name__ == '__main__':
unittest.main()
commit 787b518be36118741204d89905c0d61719f7ced9
Author: Miklos Vajna <vmiklos at suse.cz>
Date: Fri Jul 19 13:06:33 2013 +0200
add index to Prl dumper
diff --git a/src/docrecord.py b/src/docrecord.py
index 9d0d027..b73fba4 100644
--- a/src/docrecord.py
+++ b/src/docrecord.py
@@ -978,15 +978,19 @@ class Sprm(DOCDirStream):
class Prl(DOCDirStream):
"""The Prl structure is a Sprm that is followed by an operand."""
- def __init__(self, bytes, offset, mainStream = None, transformed = None):
+ def __init__(self, bytes, offset, mainStream = None, transformed = None, index = None):
DOCDirStream.__init__(self, bytes)
self.pos = offset
self.posOrig = self.pos
self.sprm = Sprm(self.bytes, self.pos, mainStream, transformed)
self.pos += 2
+ self.index = index
def dump(self):
- print '<prl type="Prl" offset="%d">' % self.posOrig
+ indexstr = ""
+ if self.index != None:
+ indexstr = ' index="%d"' % self.index
+ print '<prl type="Prl" offset="%d"%s>' % (self.posOrig, indexstr)
self.sprm.dump()
print '</prl>'
@@ -1022,10 +1026,12 @@ class Chpx(DOCDirStream):
print '<chpx type="Chpx" offset="%d">' % self.pos
self.printAndSet("cb", self.readuInt8())
pos = self.pos
+ index = 0
while (self.cb - (pos - self.pos)) > 0:
- prl = Prl(self.bytes, pos, self.mainStream, self.transformed)
+ prl = Prl(self.bytes, pos, self.mainStream, self.transformed, index)
prl.dump()
pos += prl.getSize()
+ index += 1
print '</chpx>'
class PapxInFkp(DOCDirStream):
commit 566624c10883396e239a20ac87e5f3ac5b5ce8a4
Author: Miklos Vajna <vmiklos at suse.cz>
Date: Fri Jul 19 12:38:07 2013 +0200
FBSE: handle non-empty embeddedBlip
diff --git a/src/msodraw.py b/src/msodraw.py
index 0badb4f..5e84489 100644
--- a/src/msodraw.py
+++ b/src/msodraw.py
@@ -1049,7 +1049,14 @@ class FBSE:
if self.cbName != 0:
recHdl.appendLine('<todo what="FBSE::dumpXml(): cbName != 0"/>')
if self.strm.pos < self.posOrig + rh.recLen:
- recHdl.appendLine('<todo what="FBSE::dumpXml(): non-empty embeddedBlip"/>')
+ rh = RecordHeader(self.strm)
+ rh.dumpXml(recHdl)
+ if rh.recType in recData:
+ child = recData[rh.recType](self.strm)
+ child.dumpXml(self.strm, model, rh)
+ else:
+ recHdl.appendLine('<todo what="FBSE::dumpXml(): recType = %s unhandled (size: %d bytes)"/>' % (hex(rh.recType), rh.recLen))
+ self.strm.pos += rh.recLen
recHdl.appendLine('</fbse>')
class FClientAnchorSheet:
commit 0f002aabf189d479bf62bec803175342ee45ad73
Author: Miklos Vajna <vmiklos at suse.cz>
Date: Fri Jul 19 11:46:18 2013 +0200
msodraw: dump InlineSpContainer
diff --git a/src/docrecord.py b/src/docrecord.py
index 93e46ac..9d0d027 100644
--- a/src/docrecord.py
+++ b/src/docrecord.py
@@ -753,7 +753,8 @@ class PICFAndOfficeArtData(DOCDirStream):
assert self.pos == pos + 68
if picf.mfpf.mm == 0x0066:
print '<todo what="PICFAndOfficeArtData::dump(): picf.mfpf.mm == MM_SHAPEFILE is unhandled"/>'
- # TODO dump OfficeArtInlineSpContainer
+ remaining = picf.lcb - (self.pos - pos)
+ msodraw.InlineSpContainer(self, remaining).dumpXml(self, globals.ModelBase(globals.ModelBase.HostAppType.Word))
print '</PICFAndOfficeArtData>'
# The TextFlow enumeration specifies the rotation settings for a block of text and for the individual
diff --git a/src/msodraw.py b/src/msodraw.py
index 6b46aa3..0badb4f 100644
--- a/src/msodraw.py
+++ b/src/msodraw.py
@@ -963,6 +963,7 @@ class BStoreContainerFileBlock:
child.dumpXml(self.strm, model, rh)
else:
recHdl.appendLine('<todo what="BStoreContainerFileBlock: recType = %s unhandled (size: %d bytes)"/>' % (hex(rh.recType), rh.recLen))
+ self.strm.pos += rh.recLen
class BStoreContainer:
def __init__ (self, strm):
@@ -1181,6 +1182,21 @@ class DgContainer(MSODrawHandler):
def __init__(self, officeArtContent, name):
MSODrawHandler.__init__(self, officeArtContent.bytes, officeArtContent, name, "OfficeArtDgContainer")
+class InlineSpContainer:
+ """The OfficeArtInlineSpContainer record specifies a container for inline shapes."""
+ def __init__(self, officeArtContent, size):
+ self.strm = officeArtContent
+ self.size = size
+
+ def dumpXml (self, recHdl, model):
+ recHdl.appendLine('<inlineSpContainer>')
+ pos = self.strm.pos
+ shape = SpContainer(self.strm)
+ shape.dumpXml(recHdl, model)
+ while self.size > self.strm.pos - pos:
+ bStoreContainerFileBlock = BStoreContainerFileBlock(self)
+ bStoreContainerFileBlock.dumpXml(recHdl, model)
+ recHdl.appendLine('</inlineSpContainer>')
class SpContainer(MSODrawHandler):
"""The OfficeArtSpContainer record specifies a shape container."""
commit 50e25edf526e921951c5d48dc1115fc0964f93d0
Author: Miklos Vajna <vmiklos at suse.cz>
Date: Fri Jul 19 11:23:22 2013 +0200
finish dumping PICFAndOfficeArtData
diff --git a/src/docrecord.py b/src/docrecord.py
index 03be1e5..93e46ac 100644
--- a/src/docrecord.py
+++ b/src/docrecord.py
@@ -729,7 +729,8 @@ class PICF(DOCDirStream):
self.printAndSet("lcb", self.readInt32())
self.printAndSet("cbHeader", self.readInt16())
assert self.cbHeader == 0x44
- MFPF(self).dump()
+ self.mfpf = MFPF(self)
+ self.mfpf.dump()
PICF_Shape(self, "innerHeader").dump()
PICMID(self).dump()
self.printAndSet("cProps", self.readuInt16())
@@ -747,9 +748,12 @@ class PICFAndOfficeArtData(DOCDirStream):
def dump(self):
print '<PICFAndOfficeArtData>'
pos = self.pos
- PICF(self).dump()
+ picf = PICF(self)
+ picf.dump()
assert self.pos == pos + 68
- # TODO cchPicName and others
+ if picf.mfpf.mm == 0x0066:
+ print '<todo what="PICFAndOfficeArtData::dump(): picf.mfpf.mm == MM_SHAPEFILE is unhandled"/>'
+ # TODO dump OfficeArtInlineSpContainer
print '</PICFAndOfficeArtData>'
# The TextFlow enumeration specifies the rotation settings for a block of text and for the individual
commit f49c8d611f1bd86b8bff634d6f55c759cae7e2ae
Author: Miklos Vajna <vmiklos at suse.cz>
Date: Fri Jul 19 11:18:27 2013 +0200
dump PICMID
diff --git a/src/docrecord.py b/src/docrecord.py
index 3e3960f..03be1e5 100644
--- a/src/docrecord.py
+++ b/src/docrecord.py
@@ -688,6 +688,33 @@ class PICF_Shape(DOCDirStream):
self.parent.pos = self.pos
print '</%s>' % self.name
+class PICMID(DOCDirStream):
+ """The PICMID structure specifies the size and border information for a picture."""
+ def __init__(self, parent):
+ DOCDirStream.__init__(self, parent.bytes)
+ self.pos = parent.pos
+ self.parent = parent
+
+ def dump(self):
+ print '<picmid type="PICMID" offset="%d">' % self.pos
+ self.printAndSet("dxaGoal", self.readuInt16())
+ self.printAndSet("dyaGoal", self.readuInt16())
+ self.printAndSet("mx", self.readuInt16())
+ self.printAndSet("my", self.readuInt16())
+ self.printAndSet("dxaReserved1", self.readuInt16())
+ self.printAndSet("dyaReserved1", self.readuInt16())
+ self.printAndSet("dxaReserved2", self.readuInt16())
+ self.printAndSet("dyaReserved2", self.readuInt16())
+ self.printAndSet("fReserved", self.readuInt8())
+ self.printAndSet("bpp", self.readuInt8())
+ self.printAndSet("brcTop80", self.readuInt32()) # TODO dump Brc80
+ self.printAndSet("brcLeft80", self.readuInt32())
+ self.printAndSet("brcBottom80", self.readuInt32())
+ self.printAndSet("brcRight80", self.readuInt32())
+ self.printAndSet("dxaReserved3", self.readuInt16())
+ self.printAndSet("dyaReserved3", self.readuInt16())
+ self.parent.pos = self.pos
+ print '</picmid>'
class PICF(DOCDirStream):
"""The PICF structure specifies the type of a picture, as well as the size
@@ -704,8 +731,7 @@ class PICF(DOCDirStream):
assert self.cbHeader == 0x44
MFPF(self).dump()
PICF_Shape(self, "innerHeader").dump()
- # TODO PICMID
- self.pos += 38
+ PICMID(self).dump()
self.printAndSet("cProps", self.readuInt16())
self.parent.pos = self.pos
print '</picf>'
commit a6416f7c4dc0b9ad3cef17b4ceb16f9f7d142146
Author: Miklos Vajna <vmiklos at suse.cz>
Date: Fri Jul 19 11:10:15 2013 +0200
dump PICF_Shape
This is probably the most useless structure I've seen so far: all of its
fields must be ignored...
diff --git a/src/docrecord.py b/src/docrecord.py
index 59bdd39..3e3960f 100644
--- a/src/docrecord.py
+++ b/src/docrecord.py
@@ -670,6 +670,25 @@ class MFPF(DOCDirStream):
self.parent.pos = self.pos
print '</mfpf>'
+class PICF_Shape(DOCDirStream):
+ """The PICF_Shape structure specifies additional header information for
+ pictures of type MM_SHAPE or MM_SHAPEFILE."""
+ def __init__(self, parent, name):
+ DOCDirStream.__init__(self, parent.bytes)
+ self.pos = parent.pos
+ self.parent = parent
+ self.name = name
+
+ def dump(self):
+ print '<%s type="PICF_Shape" offset="%d">' % (self.name, self.pos)
+ self.printAndSet("grf", self.readuInt32())
+ self.printAndSet("padding1", self.readuInt32())
+ self.printAndSet("mmpm", self.readuInt16())
+ self.printAndSet("padding2", self.readuInt32())
+ self.parent.pos = self.pos
+ print '</%s>' % self.name
+
+
class PICF(DOCDirStream):
"""The PICF structure specifies the type of a picture, as well as the size
of the picture and information about its border."""
@@ -684,8 +703,7 @@ class PICF(DOCDirStream):
self.printAndSet("cbHeader", self.readInt16())
assert self.cbHeader == 0x44
MFPF(self).dump()
- # TODO PICF_Shape
- self.pos += 14
+ PICF_Shape(self, "innerHeader").dump()
# TODO PICMID
self.pos += 38
self.printAndSet("cProps", self.readuInt16())
commit f1cd0863861573b37ca1432ef7cf87865b40e166
Author: Miklos Vajna <vmiklos at suse.cz>
Date: Fri Jul 19 11:05:17 2013 +0200
dump MFPF
diff --git a/src/docrecord.py b/src/docrecord.py
index 4f8dd1e..59bdd39 100644
--- a/src/docrecord.py
+++ b/src/docrecord.py
@@ -650,6 +650,26 @@ class SPgbPropOperand(DOCDirStream):
self.printAndSet("reserved", self.readuInt8())
print '</sPgbPropOperand>'
+class MFPF(DOCDirStream):
+ """The MFPF structure specifies the type of picture data that is stored."""
+ def __init__(self, parent):
+ DOCDirStream.__init__(self, parent.bytes)
+ self.pos = parent.pos
+ self.parent = parent
+
+ def dump(self):
+ mmDict = {
+ 0x0064: "MM_SHAPE",
+ 0x0066: "MM_SHAPEFILE",
+ }
+ print '<mfpf type="MFPF" offset="%d">' % self.pos
+ self.printAndSet("mm", self.readInt16(), dict = mmDict)
+ self.printAndSet("xExt", self.readuInt16())
+ self.printAndSet("yExt", self.readuInt16())
+ self.printAndSet("swHMF", self.readuInt16())
+ self.parent.pos = self.pos
+ print '</mfpf>'
+
class PICF(DOCDirStream):
"""The PICF structure specifies the type of a picture, as well as the size
of the picture and information about its border."""
@@ -663,8 +683,7 @@ class PICF(DOCDirStream):
self.printAndSet("lcb", self.readInt32())
self.printAndSet("cbHeader", self.readInt16())
assert self.cbHeader == 0x44
- # TODO MFPF
- self.pos += 8
+ MFPF(self).dump()
# TODO PICF_Shape
self.pos += 14
# TODO PICMID
commit cc3d2bd28f0274ab0d9a653fb18ca615af5ae190
Author: Miklos Vajna <vmiklos at suse.cz>
Date: Fri Jul 19 10:59:22 2013 +0200
initial PICF
diff --git a/src/docrecord.py b/src/docrecord.py
index d4584ea..4f8dd1e 100644
--- a/src/docrecord.py
+++ b/src/docrecord.py
@@ -650,6 +650,29 @@ class SPgbPropOperand(DOCDirStream):
self.printAndSet("reserved", self.readuInt8())
print '</sPgbPropOperand>'
+class PICF(DOCDirStream):
+ """The PICF structure specifies the type of a picture, as well as the size
+ of the picture and information about its border."""
+ def __init__(self, parent):
+ DOCDirStream.__init__(self, parent.bytes)
+ self.pos = parent.pos
+ self.parent = parent
+
+ def dump(self):
+ print '<picf type="PICF" offset="%d">' % self.pos
+ self.printAndSet("lcb", self.readInt32())
+ self.printAndSet("cbHeader", self.readInt16())
+ assert self.cbHeader == 0x44
+ # TODO MFPF
+ self.pos += 8
+ # TODO PICF_Shape
+ self.pos += 14
+ # TODO PICMID
+ self.pos += 38
+ self.printAndSet("cProps", self.readuInt16())
+ self.parent.pos = self.pos
+ print '</picf>'
+
class PICFAndOfficeArtData(DOCDirStream):
"""The PICFAndOfficeArtData structure specifies header information and
binary data for a picture."""
@@ -660,7 +683,10 @@ class PICFAndOfficeArtData(DOCDirStream):
def dump(self):
print '<PICFAndOfficeArtData>'
- # TODO PICF and others
+ pos = self.pos
+ PICF(self).dump()
+ assert self.pos == pos + 68
+ # TODO cchPicName and others
print '</PICFAndOfficeArtData>'
# The TextFlow enumeration specifies the rotation settings for a block of text and for the individual
commit 84a4e7458d322a5202a0f976c9ee63fd19d3bc49
Author: Miklos Vajna <vmiklos at suse.cz>
Date: Fri Jul 19 10:50:56 2013 +0200
initial PICFAndOfficeArtData
diff --git a/src/docrecord.py b/src/docrecord.py
index 87ece9d..d4584ea 100644
--- a/src/docrecord.py
+++ b/src/docrecord.py
@@ -650,6 +650,19 @@ class SPgbPropOperand(DOCDirStream):
self.printAndSet("reserved", self.readuInt8())
print '</sPgbPropOperand>'
+class PICFAndOfficeArtData(DOCDirStream):
+ """The PICFAndOfficeArtData structure specifies header information and
+ binary data for a picture."""
+ def __init__(self, parent):
+ dataStream = parent.mainStream.doc.getDirectoryStreamByName("Data")
+ DOCDirStream.__init__(self, dataStream.bytes)
+ self.pos = parent.operand
+
+ def dump(self):
+ print '<PICFAndOfficeArtData>'
+ # TODO PICF and others
+ print '</PICFAndOfficeArtData>'
+
# The TextFlow enumeration specifies the rotation settings for a block of text and for the individual
# East Asian characters in each line of the block.
TextFlow = {
@@ -763,8 +776,8 @@ class BrcOperand(DOCDirStream):
class Sprm(DOCDirStream):
"""The Sprm structure specifies a modification to a property of a character, paragraph, table, or section."""
- def __init__(self, bytes, offset):
- DOCDirStream.__init__(self, bytes)
+ def __init__(self, bytes, offset, mainStream = None, transformed = None):
+ DOCDirStream.__init__(self, bytes, mainStream = mainStream)
self.pos = offset
self.operandSizeMap = {
0: 1,
@@ -795,6 +808,8 @@ class Sprm(DOCDirStream):
self.operand = self.getuInt24()
elif self.getOperandSize() == 4:
self.operand = self.getuInt32()
+ if self.sprm == 0x6a03 and transformed == r"\x01":
+ self.ct = PICFAndOfficeArtData(self)
elif self.getOperandSize() == 7:
self.operand = self.getuInt64() & 0x0fffffff
elif self.getOperandSize() == 9:
@@ -869,11 +884,11 @@ class Sprm(DOCDirStream):
class Prl(DOCDirStream):
"""The Prl structure is a Sprm that is followed by an operand."""
- def __init__(self, bytes, offset):
+ def __init__(self, bytes, offset, mainStream = None, transformed = None):
DOCDirStream.__init__(self, bytes)
self.pos = offset
self.posOrig = self.pos
- self.sprm = Sprm(self.bytes, self.pos)
+ self.sprm = Sprm(self.bytes, self.pos, mainStream, transformed)
self.pos += 2
def dump(self):
@@ -904,16 +919,17 @@ class GrpPrlAndIstd(DOCDirStream):
class Chpx(DOCDirStream):
"""The Chpx structure specifies a set of properties for text."""
- def __init__(self, bytes, mainStream, offset):
- DOCDirStream.__init__(self, bytes)
+ def __init__(self, bytes, mainStream, offset, transformed = None):
+ DOCDirStream.__init__(self, bytes, mainStream = mainStream)
self.pos = offset
+ self.transformed = transformed
def dump(self):
print '<chpx type="Chpx" offset="%d">' % self.pos
self.printAndSet("cb", self.readuInt8())
pos = self.pos
while (self.cb - (pos - self.pos)) > 0:
- prl = Prl(self.bytes, pos)
+ prl = Prl(self.bytes, pos, self.mainStream, self.transformed)
prl.dump()
pos += prl.getSize()
print '</chpx>'
@@ -953,7 +969,7 @@ class BxPap(DOCDirStream):
class ChpxFkp(DOCDirStream):
"""The ChpxFkp structure maps text to its character properties."""
def __init__(self, pnFkpChpx, offset, size):
- DOCDirStream.__init__(self, pnFkpChpx.mainStream.bytes)
+ DOCDirStream.__init__(self, pnFkpChpx.mainStream.bytes, mainStream = pnFkpChpx.mainStream)
self.pos = offset
self.size = size
self.pnFkpChpx = pnFkpChpx
@@ -967,13 +983,14 @@ class ChpxFkp(DOCDirStream):
start = self.getuInt32(pos = pos)
end = self.getuInt32(pos = pos + 4)
print '<rgfc index="%d" start="%d" end="%d">' % (i, start, end)
- print '<transformed value="%s"/>' % self.quoteAttr(self.pnFkpChpx.mainStream.retrieveOffset(start, end))
+ self.transformed = self.quoteAttr(self.pnFkpChpx.mainStream.retrieveOffset(start, end))
+ print '<transformed value="%s"/>' % self.transformed
pos += 4
# rgbx
offset = PLC.getPLCOffset(self.pos, self.crun, 1, i)
chpxOffset = self.getuInt8(pos = offset) * 2
- chpx = Chpx(self.bytes, self.mainStream, self.pos + chpxOffset)
+ chpx = Chpx(self.bytes, self.mainStream, self.pos + chpxOffset, self.transformed)
chpx.dump()
print '</rgfc>'
commit 0056eeede3735b8360338f4cf6f2fbb517ebd4ef
Author: Miklos Vajna <vmiklos at suse.cz>
Date: Fri Jul 19 09:59:22 2013 +0200
dump FBSE
diff --git a/src/msodraw.py b/src/msodraw.py
index fb8cd24..6b46aa3 100644
--- a/src/msodraw.py
+++ b/src/msodraw.py
@@ -64,6 +64,7 @@ class RecordHeader:
spContainer = 0xF004
solverContainer = 0xF005
FDGGBlock = 0xF006
+ FBSE = 0xF007
FDG = 0xF008
FSPGR = 0xF009
FSP = 0xF00A
@@ -85,6 +86,7 @@ class RecordHeader:
Type.solverContainer: 'OfficeArtSolverContainer',
Type.FDG: 'OfficeArtFDG',
Type.FDGGBlock: 'OfficeArtFDGGBlock',
+ Type.FBSE: 'OfficeArtFBSE',
Type.FOPT: 'OfficeArtFOPT',
Type.FClientTextbox: 'OfficeArtClientTextbox',
Type.FClientAnchor: 'OfficeArtClientAnchor',
@@ -957,8 +959,8 @@ class BStoreContainerFileBlock:
rh = RecordHeader(self.strm)
rh.dumpXml(recHdl)
if rh.recType in recData:
- child = recData[rh.recType](self)
- child.dumpXml(self, model, rh)
+ child = recData[rh.recType](self.strm)
+ child.dumpXml(self.strm, model, rh)
else:
recHdl.appendLine('<todo what="BStoreContainerFileBlock: recType = %s unhandled (size: %d bytes)"/>' % (hex(rh.recType), rh.recLen))
@@ -996,6 +998,58 @@ class SplitMenuColorContainer:
recHdl.appendLine('</smca>')
recHdl.appendLine('</splitColors>')
+MSOBLIPTYPE = {
+ 0x00: 'msoblipERROR',
+ 0x01: 'msoblipUNKNOWN',
+ 0x02: 'msoblipEMF',
+ 0x03: 'msoblipWMF',
+ 0x04: 'msoblipPICT',
+ 0x05: 'msoblipJPEG',
+ 0x06: 'msoblipPNG',
+ 0x07: 'msoblipDIB',
+ 0x11: 'msoblipTIFF',
+ 0x12: 'msoblipCMYKJPEG',
+ }
+
+class FBSE:
+ """2.2.32 The OfficeArtFBSE record specifies a File BLIP Store Entry (FBSE)
+ that contains information about the BLIP."""
+ def __init__(self, strm):
+ self.strm = strm
+ self.posOrig = strm.pos
+ self.btWin32 = strm.readUnsignedInt(1)
+ self.btMacOS = strm.readUnsignedInt(1)
+ self.rgbUid = strm.readBytes(16)
+ self.tag = strm.readUnsignedInt(2)
+ self.size = strm.readUnsignedInt(4)
+ self.cRef = strm.readUnsignedInt(4)
+ self.foDelay = strm.readUnsignedInt(4)
+ self.unused1 = strm.readUnsignedInt(1)
+ self.cbName = strm.readUnsignedInt(1)
+ self.unused2 = strm.readUnsignedInt(1)
+ self.unused3 = strm.readUnsignedInt(1)
+
+ def appendLines (self, recHdl, rh):
+ pass
+
+ def dumpXml(self, recHdl, model, rh):
+ recHdl.appendLine('<fbse>')
+ recHdl.appendLine('<btWin32 value="%s" name="%s"/>' % (self.btWin32, globals.getValueOrUnknown(MSOBLIPTYPE, self.btWin32, "todo")))
+ recHdl.appendLine('<btMacOS value="%s" name="%s"/>' % (self.btMacOS, globals.getValueOrUnknown(MSOBLIPTYPE, self.btMacOS, "todo")))
+ recHdl.appendLine('<rgbUid value="%s"/>' % hexdump(self.rgbUid))
+ recHdl.appendLine('<tag value="%s"/>' % self.tag)
+ recHdl.appendLine('<size value="%s"/>' % self.size)
+ recHdl.appendLine('<cRef value="%s"/>' % self.cRef)
+ recHdl.appendLine('<foDelay value="%s"/>' % hex(self.foDelay))
+ recHdl.appendLine('<unused1 value="%s"/>' % self.unused1)
+ recHdl.appendLine('<cbName value="%s"/>' % self.cbName)
+ recHdl.appendLine('<unused2 value="%s"/>' % self.unused2)
+ recHdl.appendLine('<unused3 value="%s"/>' % self.unused3)
+ if self.cbName != 0:
+ recHdl.appendLine('<todo what="FBSE::dumpXml(): cbName != 0"/>')
+ if self.strm.pos < self.posOrig + rh.recLen:
+ recHdl.appendLine('<todo what="FBSE::dumpXml(): non-empty embeddedBlip"/>')
+ recHdl.appendLine('</fbse>')
class FClientAnchorSheet:
"""Excel-specific anchor data (OfficeArtClientAnchorSheet)"""
@@ -1156,6 +1210,7 @@ recData = {
RecordHeader.Type.SplitMenuColorContainer: SplitMenuColorContainer,
RecordHeader.Type.TertiaryFOPT: TertiaryFOPT,
RecordHeader.Type.BStoreContainer: BStoreContainer,
+ RecordHeader.Type.FBSE: FBSE,
}
# vim:set filetype=python shiftwidth=4 softtabstop=4 expandtab:
More information about the Libreoffice-commits
mailing list