diff options
author | Tibby Lickle <tibbylickle@gmail.com> | 2012-02-15 18:19:04 +0000 |
---|---|---|
committer | Tibby Lickle <tibbylickle@gmail.com> | 2012-02-15 18:29:06 +0000 |
commit | a7eb7bd1e836e4646f0e5f047d386ccd5f5146e5 (patch) | |
tree | 99f5c4e347e32cf46a5601743fa8d0cff4123a44 | |
parent | fcee6785ee8cf688d0e6c55658906b7a033e8868 (diff) |
Added OLE stencil support
-rw-r--r-- | src/lib/VSDXContentCollector.cpp | 2 | ||||
-rw-r--r-- | src/lib/VSDXParser.cpp | 52 | ||||
-rw-r--r-- | src/lib/VSDXParser.h | 1 |
3 files changed, 54 insertions, 1 deletions
diff --git a/src/lib/VSDXContentCollector.cpp b/src/lib/VSDXContentCollector.cpp index ee0fff0..9996da6 100644 --- a/src/lib/VSDXContentCollector.cpp +++ b/src/lib/VSDXContentCollector.cpp @@ -1203,6 +1203,7 @@ void libvisio::VSDXContentCollector::_handleForeignData(const WPXBinaryData &bin else if (m_foreignType == 2) { m_currentForeignProps.insert("libwpg:mime-type", "object/ole"); + m_currentForeignData.append(binaryData); } } @@ -1759,6 +1760,7 @@ void libvisio::VSDXContentCollector::collectShape(unsigned id, unsigned level, u m_foreignOffsetY = m_stencilShape->m_foreign->offsetY; m_foreignWidth = m_stencilShape->m_foreign->width; m_foreignHeight = m_stencilShape->m_foreign->height; + m_currentForeignData.clear(); _handleForeignData(m_stencilShape->m_foreign->data); } diff --git a/src/lib/VSDXParser.cpp b/src/lib/VSDXParser.cpp index f53847a..5adf909 100644 --- a/src/lib/VSDXParser.cpp +++ b/src/lib/VSDXParser.cpp @@ -386,7 +386,7 @@ void libvisio::VSDXParser::handleStencilForeign(WPXInputStream *input, unsigned m_input->seek(ptrOffset, WPX_SEEK_SET); VSDInternalStream tmpInput(m_input, ptrLength, compressed); - VSD_DEBUG_MSG(("Stencil foreign stream %x\n", ptrType)); + shift = compressed ? 4 : 0; if (ptrType == VSD_PROP_LIST) { @@ -433,6 +433,56 @@ void libvisio::VSDXParser::handleStencilForeign(WPXInputStream *input, unsigned m_stencilShape.m_foreign->data = binaryData; } } + else if (ptrType == VSD_OLE_LIST) + { + m_stencilShape.m_foreign->dataId = m_header.id; + handleStencilOle(&tmpInput, shift); + } + } +} + +void libvisio::VSDXParser::handleStencilOle(WPXInputStream *input, unsigned shift) +{ + unsigned ptrType; + unsigned ptrOffset; + unsigned ptrLength; + unsigned ptrFormat; + + input->seek(shift, WPX_SEEK_CUR); + unsigned offset = readU32(input); + input->seek(offset+shift, WPX_SEEK_SET); + unsigned pointerCount = readU32(input); + input->seek(4, WPX_SEEK_CUR); // Ignore 0x0 dword + + for (unsigned i = 0; i < pointerCount; i++) + { + ptrType = readU32(input); + input->seek(4, WPX_SEEK_CUR); // Skip dword + ptrOffset = readU32(input); + ptrLength = readU32(input); + ptrFormat = readU16(input); + + bool compressed = ((ptrFormat & 2) == 2); + m_input->seek(ptrOffset, WPX_SEEK_SET); + VSDInternalStream tmpInput(m_input, ptrLength, compressed); + + shift = compressed ? 4 : 0; + tmpInput.seek(shift, WPX_SEEK_CUR); + + if (ptrType == VSD_OLE_DATA) + { + // Be sure to use internal stream size to get decompressed size + unsigned foreignLength = tmpInput.getSize() - shift; + unsigned long tmpBytesRead = 0; + const unsigned char *buffer = tmpInput.read(foreignLength, tmpBytesRead); + + if (foreignLength == tmpBytesRead) + { + // Append data instead of setting it - allows multi-stream OLE objects + m_stencilShape.m_foreign->data.append(buffer, tmpBytesRead); + m_stencilShape.m_foreign->dataLevel = m_header.level; + } + } } } diff --git a/src/lib/VSDXParser.h b/src/lib/VSDXParser.h index 04d8f54..d6edcc4 100644 --- a/src/lib/VSDXParser.h +++ b/src/lib/VSDXParser.h @@ -118,6 +118,7 @@ protected: void handleStencils(WPXInputStream *input, unsigned shift); void handleStencilPage(WPXInputStream *input, unsigned shift); void handleStencilForeign(WPXInputStream *input, unsigned shift); + void handleStencilOle(WPXInputStream *input, unsigned shift); void handleStencilShape(WPXInputStream *input); virtual bool getChunkHeader(WPXInputStream *input) = 0; |