summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFridrich Štrba <fridrich.strba@bluewin.ch>2012-11-09 17:30:21 +0100
committerFridrich Štrba <fridrich.strba@bluewin.ch>2012-11-09 17:47:30 +0100
commit6e226afc3fa3d8470f4f9731b6b17c4f8d99d44f (patch)
treea7cb2a781301472b633233b39cdaa31d5ba7d176
parentfb1a3735e95f11166d0adc823ecca05caab9cd23 (diff)
Some more work on VSD5 parser
-rw-r--r--src/lib/VSD11Parser.h2
-rw-r--r--src/lib/VSD5Parser.cpp64
-rw-r--r--src/lib/VSD5Parser.h2
-rw-r--r--src/lib/VSD6Parser.h3
-rw-r--r--src/lib/VSDDocumentStructure.h1
-rw-r--r--src/lib/VSDParser.cpp53
-rw-r--r--src/lib/VSDParser.h5
7 files changed, 105 insertions, 25 deletions
diff --git a/src/lib/VSD11Parser.h b/src/lib/VSD11Parser.h
index 3557af9..bf9155a 100644
--- a/src/lib/VSD11Parser.h
+++ b/src/lib/VSD11Parser.h
@@ -47,7 +47,7 @@ public:
explicit VSD11Parser(WPXInputStream *input, libwpg::WPGPaintInterface *painter);
~VSD11Parser();
private:
- bool getChunkHeader(WPXInputStream *input);
+ virtual bool getChunkHeader(WPXInputStream *input);
void readText(WPXInputStream *input);
void readCharIX(WPXInputStream *input);
void readParaIX(WPXInputStream *input);
diff --git a/src/lib/VSD5Parser.cpp b/src/lib/VSD5Parser.cpp
index a29834a..1662e85 100644
--- a/src/lib/VSD5Parser.cpp
+++ b/src/lib/VSD5Parser.cpp
@@ -55,5 +55,69 @@ void libvisio::VSD5Parser::readPointer(WPXInputStream *input, Pointer &ptr)
ptr.Length = readU32(input);
}
+void libvisio::VSD5Parser::readPointerInfo(WPXInputStream *input, unsigned ptrType, unsigned shift, unsigned &listSize, unsigned &pointerCount)
+{
+ VSD_DEBUG_MSG(("VSD5Parser::readPointerInfo\n"));
+ input->seek(shift+0x6, WPX_SEEK_SET);
+ listSize = readU16(input);
+ switch (ptrType)
+ {
+ case VSD_TRAILER_STREAM:
+ input->seek(shift+0x82, WPX_SEEK_SET);
+ break;
+ case VSD_STENCILS:
+ input->seek(shift+0x1e, WPX_SEEK_SET);
+ break;
+ case VSD_STENCIL_PAGE:
+ input->seek(shift+0x36, WPX_SEEK_SET);
+ break;
+ default:
+ input->seek(shift+0xa, WPX_SEEK_SET);
+ break;
+ }
+ pointerCount = readU16(input);
+ VSD_DEBUG_MSG(("VSD5Parser::readPointerInfo ptrType %u shift %u listSize 0x%x pointerCount 0x%x\n", ptrType, shift, listSize, pointerCount));
+}
+
+bool libvisio::VSD5Parser::getChunkHeader(WPXInputStream *input)
+{
+ unsigned char tmpChar = 0;
+ while (!input->atEOS() && !tmpChar)
+ tmpChar = readU8(input);
+
+ if (input->atEOS())
+ return false;
+ else
+ input->seek(-1, WPX_SEEK_CUR);
+
+ m_header.chunkType = readU16(input);
+ m_header.id = readU16(input);
+ m_header.level = readU8(input);
+ m_header.unknown = readU8(input);
+
+ m_header.list = readU16(input);
+
+ // Certain chunk types seem to always have a trailer
+ m_header.trailer = 0;
+ if (m_header.list != 0 || m_header.chunkType == 0x76 || m_header.chunkType == 0x73 ||
+ m_header.chunkType == 0x72 || m_header.chunkType == 0x71 || m_header.chunkType == 0x70 ||
+ m_header.chunkType == 0x6f || m_header.chunkType == 0x6e || m_header.chunkType == 0x6d ||
+ m_header.chunkType == 0x6c || m_header.chunkType == 0x6b || m_header.chunkType == 0x6a ||
+ m_header.chunkType == 0x69 || m_header.chunkType == 0x68 || m_header.chunkType == 0x67 ||
+ m_header.chunkType == 0x66 || m_header.chunkType == 0x65 || m_header.chunkType == 0x64 ||
+ m_header.chunkType == 0x2c || m_header.chunkType == 0xd)
+ m_header.trailer += 8; // 8 byte trailer
+
+ m_header.dataLength = readU32(input);
+
+ // 0x1f (OLE data) and 0xc9 (Name ID) never have trailer
+ if (m_header.chunkType == 0x1f || m_header.chunkType == 0xc9)
+ {
+ m_header.trailer = 0;
+ }
+ return true;
+}
+
+
/* vim:set shiftwidth=2 softtabstop=2 expandtab: */
diff --git a/src/lib/VSD5Parser.h b/src/lib/VSD5Parser.h
index e3caeb2..2eff54d 100644
--- a/src/lib/VSD5Parser.h
+++ b/src/lib/VSD5Parser.h
@@ -49,6 +49,8 @@ public:
protected:
virtual void readPointer(WPXInputStream *input, Pointer &ptr);
+ virtual bool getChunkHeader(WPXInputStream *input);
+ virtual void readPointerInfo(WPXInputStream *input, unsigned ptrType, unsigned shift, unsigned &listSize, unsigned &pointerCount);
private:
VSD5Parser();
diff --git a/src/lib/VSD6Parser.h b/src/lib/VSD6Parser.h
index 6c403b5..2615abe 100644
--- a/src/lib/VSD6Parser.h
+++ b/src/lib/VSD6Parser.h
@@ -46,8 +46,9 @@ class VSD6Parser : public VSDParser
public:
explicit VSD6Parser(WPXInputStream *input, libwpg::WPGPaintInterface *painter);
~VSD6Parser();
+protected:
+ virtual bool getChunkHeader(WPXInputStream *input);
private:
- bool getChunkHeader(WPXInputStream *input);
void readText(WPXInputStream *input);
void readCharIX(WPXInputStream *input);
void readParaIX(WPXInputStream *input);
diff --git a/src/lib/VSDDocumentStructure.h b/src/lib/VSDDocumentStructure.h
index 774fe29..77eba00 100644
--- a/src/lib/VSDDocumentStructure.h
+++ b/src/lib/VSDDocumentStructure.h
@@ -35,6 +35,7 @@
#define VSD_OLE_LIST 0x0d
#define VSD_TEXT 0x0e
+#define VSD_TRAILER_STREAM 0x14
#define VSD_PAGE 0x15
#define VSD_COLORS 0x16
#define VSD_FONT_LIST 0x18
diff --git a/src/lib/VSDParser.cpp b/src/lib/VSDParser.cpp
index 99f8860..971777a 100644
--- a/src/lib/VSDParser.cpp
+++ b/src/lib/VSDParser.cpp
@@ -62,14 +62,15 @@ bool libvisio::VSDParser::parseMain()
// Seek to trailer stream pointer
m_input->seek(0x24, WPX_SEEK_SET);
- m_input->seek(8, WPX_SEEK_CUR);
- unsigned offset = readU32(m_input);
- unsigned length = readU32(m_input);
- unsigned short format = readU16(m_input);
- bool compressed = ((format & 2) == 2);
+ Pointer trailerPointer;
+ readPointer(m_input, trailerPointer);
+ bool compressed = ((trailerPointer.Format & 2) == 2);
+ unsigned shift = 0;
+ if (compressed)
+ shift = 4;
- m_input->seek(offset, WPX_SEEK_SET);
- VSDInternalStream trailerStream(m_input, length, compressed);
+ m_input->seek(trailerPointer.Offset, WPX_SEEK_SET);
+ VSDInternalStream trailerStream(m_input, trailerPointer.Length, compressed);
std::vector<std::map<unsigned, XForm> > groupXFormsSequence;
std::vector<std::map<unsigned, unsigned> > groupMembershipsSequence;
@@ -78,7 +79,7 @@ bool libvisio::VSDParser::parseMain()
VSDStylesCollector stylesCollector(groupXFormsSequence, groupMembershipsSequence, documentPageShapeOrders);
m_collector = &stylesCollector;
VSD_DEBUG_MSG(("VSDParser::parseMain 1st pass\n"));
- if (!parseDocument(&trailerStream))
+ if (!parseDocument(&trailerStream, shift))
return false;
_handleLevelChange(0);
@@ -88,17 +89,17 @@ bool libvisio::VSDParser::parseMain()
VSDContentCollector contentCollector(m_painter, groupXFormsSequence, groupMembershipsSequence, documentPageShapeOrders, styles, m_stencils);
m_collector = &contentCollector;
VSD_DEBUG_MSG(("VSDParser::parseMain 2nd pass\n"));
- if (!parseDocument(&trailerStream))
+ if (!parseDocument(&trailerStream, shift))
return false;
return true;
}
-bool libvisio::VSDParser::parseDocument(WPXInputStream *input)
+bool libvisio::VSDParser::parseDocument(WPXInputStream *input, unsigned shift)
{
try
{
- handleStreams(input, 4, 0);
+ handleStreams(input, VSD_TRAILER_STREAM, shift, 0);
return true;
}
catch (...)
@@ -122,8 +123,20 @@ void libvisio::VSDParser::readPointer(WPXInputStream *input, Pointer &ptr)
ptr.Format = readU16(input);
}
-void libvisio::VSDParser::handleStreams(WPXInputStream *input, unsigned shift, unsigned level)
+void libvisio::VSDParser::readPointerInfo(WPXInputStream *input, unsigned /* ptrType */, unsigned shift, unsigned &listSize, unsigned &pointerCount)
{
+ VSD_DEBUG_MSG(("VSDParser::readPointerInfo\n"));
+ input->seek(shift, WPX_SEEK_SET);
+ unsigned offset = readU32(input);
+ input->seek(offset+shift-4, WPX_SEEK_SET);
+ listSize = readU32(input);
+ pointerCount = readU32(input);
+ input->seek(4, WPX_SEEK_CUR);
+}
+
+void libvisio::VSDParser::handleStreams(WPXInputStream *input, unsigned ptrType, unsigned shift, unsigned level)
+{
+ VSD_DEBUG_MSG(("VSDParser::HandleStreams\n"));
std::vector<unsigned> pointerOrder;
std::map<unsigned, libvisio::Pointer> PtrList;
std::map<unsigned, libvisio::Pointer> FontFaces;
@@ -132,20 +145,18 @@ void libvisio::VSDParser::handleStreams(WPXInputStream *input, unsigned shift, u
try
{
// Parse out pointers to streams
- input->seek(shift, WPX_SEEK_SET);
- unsigned offset = readU32(input);
- input->seek(offset+shift-4, WPX_SEEK_SET);
- unsigned listSize = readU32(input);
- unsigned pointerCount = readU32(input);
- input->seek(4, WPX_SEEK_CUR);
+ unsigned listSize = 0;
+ unsigned pointerCount = 0;
+ readPointerInfo(input, ptrType, shift, listSize, pointerCount);
for (i = 0; i < pointerCount; i++)
{
Pointer ptr;
- readPointer(input, ptr);
+ readPointer(input, ptr);
if (ptr.Type == VSD_FONTFACES)
FontFaces[i] = ptr;
else if (ptr.Type != 0)
PtrList[i] = ptr;
+ VSD_DEBUG_MSG(("--> Pointer #%u\n", i));
}
for (i = 0; i < listSize; ++i)
pointerOrder.push_back(readU32(input));
@@ -178,9 +189,9 @@ void libvisio::VSDParser::handleStreams(WPXInputStream *input, unsigned shift, u
}
-
void libvisio::VSDParser::handleStream(const Pointer &ptr, unsigned idx, unsigned level)
{
+ VSD_DEBUG_MSG(("VSDParser::HandleStream\n"));
m_header.level = level;
m_header.id = idx;
m_header.chunkType = ptr.Type;
@@ -248,7 +259,7 @@ void libvisio::VSDParser::handleStream(const Pointer &ptr, unsigned idx, unsigne
if (ptr.Length > 4)
handleBlob(&tmpInput, level+1);
if ((ptr.Format >> 4) == 0x5 && ptr.Type != VSD_COLORS)
- handleStreams(&tmpInput, shift, level+1);
+ handleStreams(&tmpInput, ptr.Type, shift, level+1);
}
else if ((ptr.Format >> 4) == 0xd || (ptr.Format >> 4) == 0x8)
handleChunks(&tmpInput, level+1);
diff --git a/src/lib/VSDParser.h b/src/lib/VSDParser.h
index f6ddd49..a4594e9 100644
--- a/src/lib/VSDParser.h
+++ b/src/lib/VSDParser.h
@@ -124,16 +124,17 @@ protected:
void readOLEData(WPXInputStream *input);
// parser of one pass
- bool parseDocument(WPXInputStream *input);
+ bool parseDocument(WPXInputStream *input, unsigned shift);
// Stream handlers
- void handleStreams(WPXInputStream *input, unsigned shift, unsigned level);
+ void handleStreams(WPXInputStream *input, unsigned ptrType, unsigned shift, unsigned level);
void handleStream(const Pointer &ptr, unsigned idx, unsigned level);
void handleChunks(WPXInputStream *input, unsigned level);
void handleChunk(WPXInputStream *input);
void handleBlob(WPXInputStream *input, unsigned level);
virtual void readPointer(WPXInputStream *input, Pointer &ptr);
+ virtual void readPointerInfo(WPXInputStream *input, unsigned ptrType, unsigned shift, unsigned &listSize, unsigned &pointerCount);
virtual bool getChunkHeader(WPXInputStream *input) = 0;
void _handleLevelChange(unsigned level);
Colour _colourFromIndex(unsigned idx);