summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Tardon <dtardon@redhat.com>2016-12-12 15:23:55 +0100
committerDavid Tardon <dtardon@redhat.com>2016-12-12 15:23:55 +0100
commit2e5496881e0b14da3a8c0acf5de6be0f49f80350 (patch)
tree04cf1aace5759b9ec065a54282ca8fea3ebccc9c
parent079034b8aa1d4b7bd07a81ef46059cdb6b2f4b38 (diff)
emit bmps with color palette correctly
Change-Id: I731ab9629fdc08c54b43cdcb21a81633bd89f569
-rw-r--r--src/lib/VSDContentCollector.cpp47
-rw-r--r--src/lib/libvisio_utils.h2
2 files changed, 45 insertions, 4 deletions
diff --git a/src/lib/VSDContentCollector.cpp b/src/lib/VSDContentCollector.cpp
index 3178937..eb9a366 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>
@@ -68,6 +69,43 @@ void computeRounding(double &prevX, double &prevY, double x0, double y0, double
prevY = y0;
}
+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(
@@ -1402,10 +1440,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
{