diff options
author | Fridrich Štrba <fridrich.strba@bluewin.ch> | 2012-11-09 17:30:21 +0100 |
---|---|---|
committer | Fridrich Štrba <fridrich.strba@bluewin.ch> | 2012-11-09 17:47:30 +0100 |
commit | 6e226afc3fa3d8470f4f9731b6b17c4f8d99d44f (patch) | |
tree | a7cb2a781301472b633233b39cdaa31d5ba7d176 | |
parent | fb1a3735e95f11166d0adc823ecca05caab9cd23 (diff) |
Some more work on VSD5 parser
-rw-r--r-- | src/lib/VSD11Parser.h | 2 | ||||
-rw-r--r-- | src/lib/VSD5Parser.cpp | 64 | ||||
-rw-r--r-- | src/lib/VSD5Parser.h | 2 | ||||
-rw-r--r-- | src/lib/VSD6Parser.h | 3 | ||||
-rw-r--r-- | src/lib/VSDDocumentStructure.h | 1 | ||||
-rw-r--r-- | src/lib/VSDParser.cpp | 53 | ||||
-rw-r--r-- | src/lib/VSDParser.h | 5 |
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); |