summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTibby Lickle <tibbylickle@gmail.com>2012-02-15 18:19:04 +0000
committerTibby Lickle <tibbylickle@gmail.com>2012-02-15 18:29:06 +0000
commita7eb7bd1e836e4646f0e5f047d386ccd5f5146e5 (patch)
tree99f5c4e347e32cf46a5601743fa8d0cff4123a44
parentfcee6785ee8cf688d0e6c55658906b7a033e8868 (diff)
Added OLE stencil support
-rw-r--r--src/lib/VSDXContentCollector.cpp2
-rw-r--r--src/lib/VSDXParser.cpp52
-rw-r--r--src/lib/VSDXParser.h1
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;