[Libreoffice-commits] libcdr.git: src/lib

Fridrich Štrba fridrich.strba at bluewin.ch
Wed Jul 13 09:19:21 UTC 2016


 src/lib/CMXParser.cpp |   99 +++++++++++++++++++++++++++-----------------------
 src/lib/CMXParser.h   |    5 +-
 2 files changed, 56 insertions(+), 48 deletions(-)

New commits:
commit 1133f4e3596c8225af6b046385fba0c746774a29
Author: Fridrich Štrba <fridrich.strba at bluewin.ch>
Date:   Wed Jul 13 11:17:31 2016 +0200

    Parse even the pages from the index
    
    Change-Id: I2482141e4c63db6e85d86248a969d332fca12650

diff --git a/src/lib/CMXParser.cpp b/src/lib/CMXParser.cpp
index 276fa15..113352c 100644
--- a/src/lib/CMXParser.cpp
+++ b/src/lib/CMXParser.cpp
@@ -103,11 +103,7 @@ bool libcdr::CMXParser::parseRecord(librevenge::RVNGInputStream *input, unsigned
         return false;
     }
     else
-    {
       readRecord(fourCC, length, input);
-      if (!input->isEnd())
-        _tryToSkipEmbedded(input);
-    }
 
     if (input->tell() < endPosition)
       input->seek(endPosition, librevenge::RVNG_SEEK_SET);
@@ -119,35 +115,6 @@ bool libcdr::CMXParser::parseRecord(librevenge::RVNGInputStream *input, unsigned
   }
 }
 
-void libcdr::CMXParser::_tryToSkipEmbedded(librevenge::RVNGInputStream *input)
-{
-  unsigned long offset = input->tell();
-  unsigned size = readU16(input, m_bigEndian);
-  if (input->isEnd())
-  {
-    input->seek(offset, librevenge::RVNG_SEEK_SET);
-    return;
-  }
-  unsigned code = readU16(input, m_bigEndian);
-  if (input->isEnd())
-  {
-    input->seek(offset, librevenge::RVNG_SEEK_SET);
-    return;
-  }
-  if (22 == code || 23 == code)
-  {
-    if (!input->seek(offset + size, librevenge::RVNG_SEEK_SET))
-    {
-      CDR_DEBUG_MSG(("CMXParser::_tryToSkipEmbedded - skipped %s\n", code == 22 ? "BeginEmbedded" : "EndEmbedded"));
-      return;
-    }
-    else
-      input->seek(offset, librevenge::RVNG_SEEK_SET);
-  }
-  else
-    input->seek(offset, librevenge::RVNG_SEEK_SET);
-}
-
 void libcdr::CMXParser::parseImage(librevenge::RVNGInputStream *input)
 {
   if (!input)
@@ -195,10 +162,7 @@ void libcdr::CMXParser::readRecord(unsigned fourCC, unsigned &length, librevenge
   {
   case CDR_FOURCC_cont:
     readCMXHeader(input);
-    break;
-  case CDR_FOURCC_page:
-    readPage(input, length);
-    break;
+    return;
   case CDR_FOURCC_info:
     readInfo(input);
     break;
@@ -402,11 +366,22 @@ void libcdr::CMXParser::readIxmr(librevenge::RVNGInputStream *input)
     input->seek(*address, librevenge::RVNG_SEEK_SET);
     readIxef(input);
   }
+
+  if ((address = _getOffsetByType(CMX_PAGE_INDEX_TABLE, offsets)))
+  {
+    input->seek(*address, librevenge::RVNG_SEEK_SET);
+    readIxpg(input);
+  }
   input->seek(oldOffset, librevenge::RVNG_SEEK_SET);
 }
 
-void libcdr::CMXParser::readPage(librevenge::RVNGInputStream *input, unsigned length)
+void libcdr::CMXParser::readPage(librevenge::RVNGInputStream *input)
 {
+  unsigned fourCC = readU32(input, m_bigEndian);
+  if (CDR_FOURCC_page != fourCC)
+    return;
+  unsigned length = readU32(input, m_bigEndian);
+
   long endPosition = length + input->tell();
   while (!input->isEnd() && endPosition > input->tell())
   {
@@ -1568,7 +1543,7 @@ void libcdr::CMXParser::readRclr(librevenge::RVNGInputStream *input)
 
   unsigned numRecords = readU16(input, m_bigEndian);
   CDR_DEBUG_MSG(("CMXParser::readRclr - numRecords %i\n", numRecords));
-  for (unsigned j = 1; j < numRecords+1; ++j)
+  for (unsigned j = 1; j <= numRecords; ++j)
   {
     CDR_DEBUG_MSG(("Color index %i\n", j));
     unsigned char colorModel = 0;
@@ -1618,7 +1593,7 @@ void libcdr::CMXParser::readRdot(librevenge::RVNGInputStream *input)
 
   unsigned numRecords = readU16(input, m_bigEndian);
   CDR_DEBUG_MSG(("CMXParser::readRdot - numRecords %i\n", numRecords));
-  for (unsigned j = 1; j < numRecords+1; ++j)
+  for (unsigned j = 1; j <= numRecords; ++j)
   {
     std::vector<unsigned> dots;
     if (m_precision == libcdr::PRECISION_32BIT)
@@ -1668,7 +1643,7 @@ void libcdr::CMXParser::readRott(librevenge::RVNGInputStream *input)
 
   unsigned numRecords = readU16(input, m_bigEndian);
   CDR_DEBUG_MSG(("CMXParser::readRott - numRecords %i\n", numRecords));
-  for (unsigned j = 1; j < numRecords+1; ++j)
+  for (unsigned j = 1; j <= numRecords; ++j)
   {
     CMXLineStyle lineStyle;
     if (m_precision == libcdr::PRECISION_32BIT)
@@ -1716,7 +1691,7 @@ void libcdr::CMXParser::readRotl(librevenge::RVNGInputStream *input)
 
   unsigned numRecords = readU16(input, m_bigEndian);
   CDR_DEBUG_MSG(("CMXParser::readRotl - numRecords %i\n", numRecords));
-  for (unsigned j = 1; j < numRecords+1; ++j)
+  for (unsigned j = 1; j <= numRecords; ++j)
   {
     CMXOutline outline;
     if (m_precision == libcdr::PRECISION_32BIT)
@@ -1772,7 +1747,7 @@ void libcdr::CMXParser::readRpen(librevenge::RVNGInputStream *input)
 
   unsigned numRecords = readU16(input, m_bigEndian);
   CDR_DEBUG_MSG(("CMXParser::readRpen - numRecords %i\n", numRecords));
-  for (unsigned j = 1; j < numRecords+1; ++j)
+  for (unsigned j = 1; j <= numRecords; ++j)
   {
     CMXPen pen;
     if (m_precision == libcdr::PRECISION_32BIT)
@@ -1833,7 +1808,7 @@ void libcdr::CMXParser::readIxtl(librevenge::RVNGInputStream *input)
       return;
   }
   unsigned type = readU16(input, m_bigEndian);
-  for (unsigned j = 1; j < numRecords+1; ++j)
+  for (unsigned j = 1; j <= numRecords; ++j)
   {
     switch (type)
     {
@@ -1871,7 +1846,7 @@ void libcdr::CMXParser::readIxef(librevenge::RVNGInputStream *input)
 
   unsigned numRecords = readU16(input, m_bigEndian);
   CDR_DEBUG_MSG(("CMXParser::readIxef - numRecords %i\n", numRecords));
-  for (unsigned j = 1; j < numRecords+1; ++j)
+  for (unsigned j = 1; j <= numRecords; ++j)
   {
     int sizeInFile(0);
     if (m_precision == libcdr::PRECISION_32BIT)
@@ -1900,6 +1875,40 @@ void libcdr::CMXParser::readIxef(librevenge::RVNGInputStream *input)
   }
 }
 
+void libcdr::CMXParser::readIxpg(librevenge::RVNGInputStream *input)
+{
+  unsigned fourCC = readU32(input, m_bigEndian);
+  if (CDR_FOURCC_ixpg != fourCC)
+    return;
+  /* unsigned length = */ readU32(input, m_bigEndian);
+
+  unsigned numRecords = readU16(input, m_bigEndian);
+  CDR_DEBUG_MSG(("CMXParser::readIxpg - numRecords %i\n", numRecords));
+  for (unsigned j = 1; j <= numRecords; ++j)
+  {
+    int sizeInFile(0);
+    if (m_precision == libcdr::PRECISION_32BIT)
+    {
+      sizeInFile = readU16(input, m_bigEndian);
+      if (sizeInFile < 16)
+        return;
+    }
+    unsigned pageOffset = readU32(input, m_bigEndian);
+    /* unsigned layerTableOffset = */ readU32(input, m_bigEndian);
+    /* unsigned thumbnailOffset = */ readU32(input, m_bigEndian);
+    /* unsigned refListOffset = */ readU32(input, m_bigEndian);
+    if (pageOffset && pageOffset != (unsigned)-1)
+    {
+      long oldOffset = input->tell();
+      input->seek(pageOffset, librevenge::RVNG_SEEK_SET);
+      readPage(input);
+      input->seek(oldOffset, librevenge::RVNG_SEEK_SET);
+    }
+    if (sizeInFile)
+      input->seek(sizeInFile-16, librevenge::RVNG_SEEK_CUR);
+  }
+}
+
 void libcdr::CMXParser::readInfo(librevenge::RVNGInputStream *input)
 {
   m_currentImageInfo = libcdr::CMXImageInfo();
diff --git a/src/lib/CMXParser.h b/src/lib/CMXParser.h
index 32c7ef5..fb8d3f6 100644
--- a/src/lib/CMXParser.h
+++ b/src/lib/CMXParser.h
@@ -117,7 +117,7 @@ private:
 
   void readCMXHeader(librevenge::RVNGInputStream *input);
   void readDisp(librevenge::RVNGInputStream *input);
-  void readPage(librevenge::RVNGInputStream *input, unsigned length);
+  void readPage(librevenge::RVNGInputStream *input);
   void readRclr(librevenge::RVNGInputStream *input);
   void readRotl(librevenge::RVNGInputStream *input);
   void readRott(librevenge::RVNGInputStream *input);
@@ -126,6 +126,7 @@ private:
   void readIxtl(librevenge::RVNGInputStream *input);
   void readIxef(librevenge::RVNGInputStream *input);
   void readIxmr(librevenge::RVNGInputStream *input);
+  void readIxpg(librevenge::RVNGInputStream *input);
   void readInfo(librevenge::RVNGInputStream *input);
   void readData(librevenge::RVNGInputStream *input);
 
@@ -155,8 +156,6 @@ private:
   CDRLineStyle getLineStyle(unsigned id);
   const unsigned *_getOffsetByType(unsigned short type, const std::map<unsigned short, unsigned> &offsets);
 
-  void _tryToSkipEmbedded(librevenge::RVNGInputStream *input);
-
   bool m_bigEndian;
   unsigned short m_unit;
   double m_scale;


More information about the Libreoffice-commits mailing list