You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
libvisio/0001-emit-bmps-with-color-p...

105 lines
3.4 KiB

From a4ab4fdafc33088429a6c6bcdcf3c072b3a834a9 Mon Sep 17 00:00:00 2001
From: David Tardon <dtardon@redhat.com>
Date: Mon, 12 Dec 2016 15:23:55 +0100
Subject: [PATCH 2/2] emit bmps with color palette correctly
Change-Id: I731ab9629fdc08c54b43cdcb21a81633bd89f569
---
src/lib/VSDContentCollector.cpp | 52 +++++++++++++++++++++++++++++++++++++----
src/lib/libvisio_utils.h | 2 ++
2 files changed, 50 insertions(+), 4 deletions(-)
diff --git a/src/lib/VSDContentCollector.cpp b/src/lib/VSDContentCollector.cpp
index c20e626..229120f 100644
--- a/src/lib/VSDContentCollector.cpp
+++ b/src/lib/VSDContentCollector.cpp
@@ -7,6 +7,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
+#include <cassert>
#include <string.h> // for memcpy
#include <set>
#include <stack>
@@ -33,6 +34,48 @@ static unsigned bitmapId = 0;
#define SURROGATE_VALUE(h,l) (((h) - 0xd800) * 0x400 + (l) - 0xdc00 + 0x10000)
+namespace
+{
+
+unsigned computeBMPDataOffset(librevenge::RVNGInputStream *const input, const unsigned long maxLength)
+{
+ assert(input);
+
+ using namespace libvisio;
+
+ // determine header size
+ unsigned headerSize = readU32(input);
+ if (headerSize > maxLength)
+ headerSize = 40; // assume v.3 bitmap header size
+ unsigned off = headerSize;
+
+ // determine palette size
+ input->seek(10, librevenge::RVNG_SEEK_CUR);
+ unsigned bpp = readU16(input);
+ // sanitize bpp
+ if (bpp > 32)
+ bpp = 32;
+ const unsigned allowedBpp[] = {1, 4, 8, 16, 24, 32};
+ size_t bppIdx = 0;
+ while (bppIdx < VSD_NUM_ELEMENTS(allowedBpp) && bpp < allowedBpp[bppIdx])
+ ++bppIdx;
+ if (bpp < allowedBpp[bppIdx])
+ bpp = allowedBpp[bppIdx];
+ input->seek(16, librevenge::RVNG_SEEK_CUR);
+ unsigned paletteColors = readU32(input);
+ if (bpp < 16 && paletteColors == 0)
+ paletteColors = 1 << bpp;
+ assert(maxLength >= off);
+ if (paletteColors > 0 && (paletteColors < (maxLength - off) / 4))
+ off += 4 * paletteColors;
+
+ off += 14; // file header size
+
+ return off;
+}
+
+} // anonymous namespace
+
libvisio::VSDContentCollector::VSDContentCollector(
librevenge::RVNGDrawingInterface *painter,
std::vector<std::map<unsigned, XForm> > &groupXFormsSequence,
@@ -1359,10 +1402,11 @@ void libvisio::VSDContentCollector::_handleForeignData(const librevenge::RVNGBin
m_currentForeignData.append((unsigned char)0x00);
m_currentForeignData.append((unsigned char)0x00);
- m_currentForeignData.append((unsigned char)0x36);
- m_currentForeignData.append((unsigned char)0x00);
- m_currentForeignData.append((unsigned char)0x00);
- m_currentForeignData.append((unsigned char)0x00);
+ const unsigned dataOff = computeBMPDataOffset(binaryData.getDataStream(), binaryData.size());
+ m_currentForeignData.append((unsigned char)(dataOff & 0xff));
+ m_currentForeignData.append((unsigned char)((dataOff >> 8) & 0xff));
+ m_currentForeignData.append((unsigned char)((dataOff >> 16) & 0xff));
+ m_currentForeignData.append((unsigned char)((dataOff >> 24) & 0xff));
}
m_currentForeignData.append(binaryData);
diff --git a/src/lib/libvisio_utils.h b/src/lib/libvisio_utils.h
index c6c3a03..2a4880e 100644
--- a/src/lib/libvisio_utils.h
+++ b/src/lib/libvisio_utils.h
@@ -70,6 +70,8 @@ typedef unsigned __int64 uint64_t;
#define VSD_DEBUG(M)
#endif
+#define VSD_NUM_ELEMENTS(array) (sizeof(array)/sizeof((array)[0]))
+
namespace libvisio
{
--
2.9.3