diff options
author | David Tardon <dtardon@redhat.com> | 2016-12-12 15:23:55 +0100 |
---|---|---|
committer | David Tardon <dtardon@redhat.com> | 2016-12-12 15:23:55 +0100 |
commit | 2e5496881e0b14da3a8c0acf5de6be0f49f80350 (patch) | |
tree | 04cf1aace5759b9ec065a54282ca8fea3ebccc9c | |
parent | 079034b8aa1d4b7bd07a81ef46059cdb6b2f4b38 (diff) |
emit bmps with color palette correctly
Change-Id: I731ab9629fdc08c54b43cdcb21a81633bd89f569
-rw-r--r-- | src/lib/VSDContentCollector.cpp | 47 | ||||
-rw-r--r-- | src/lib/libvisio_utils.h | 2 |
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 { |