Coverage Report

Created: 2026-09-06 07:18

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libstaroffice/src/lib/StarFileManager.cxx
Line
Count
Source
1
/* -*- Mode: C++; c-default-style: "k&r"; indent-tabs-mode: nil; tab-width: 2; c-basic-offset: 2 -*- */
2
3
/* libstaroffice
4
* Version: MPL 2.0 / LGPLv2+
5
*
6
* The contents of this file are subject to the Mozilla Public License Version
7
* 2.0 (the "License"); you may not use this file except in compliance with
8
* the License or as specified alternatively below. You may obtain a copy of
9
* the License at http://www.mozilla.org/MPL/
10
*
11
* Software distributed under the License is distributed on an "AS IS" basis,
12
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13
* for the specific language governing rights and limitations under the
14
* License.
15
*
16
* Major Contributor(s):
17
* Copyright (C) 2002 William Lachance (wrlach@gmail.com)
18
* Copyright (C) 2002,2004 Marc Maurer (uwog@uwog.net)
19
* Copyright (C) 2004-2006 Fridrich Strba (fridrich.strba@bluewin.ch)
20
* Copyright (C) 2006, 2007 Andrew Ziem
21
* Copyright (C) 2011, 2012 Alonso Laurent (alonso@loria.fr)
22
*
23
*
24
* All Rights Reserved.
25
*
26
* For minor contributions see the git repository.
27
*
28
* Alternatively, the contents of this file may be used under the terms of
29
* the GNU Lesser General Public License Version 2 or later (the "LGPLv2+"),
30
* in which case the provisions of the LGPLv2+ are applicable
31
* instead of those above.
32
*/
33
34
#include <cstring>
35
#include <iomanip>
36
#include <iostream>
37
#include <limits>
38
#include <memory>
39
#include <sstream>
40
41
#include <librevenge/librevenge.h>
42
43
#include "StarZone.hxx"
44
45
#include "StarAttribute.hxx"
46
#include "StarBitmap.hxx"
47
#include "StarGraphicStruct.hxx"
48
#include "StarObject.hxx"
49
#include "StarObjectChart.hxx"
50
#include "StarObjectDraw.hxx"
51
#include "StarObjectMath.hxx"
52
#include "StarObjectSpreadsheet.hxx"
53
#include "StarObjectText.hxx"
54
#include "StarItemPool.hxx"
55
#include "STOFFGraphicEncoder.hxx"
56
#include "STOFFGraphicListener.hxx"
57
#include "STOFFPageSpan.hxx"
58
#include "STOFFSpreadsheetEncoder.hxx"
59
#include "STOFFSpreadsheetListener.hxx"
60
61
#include "StarFileManager.hxx"
62
63
/** Internal: the structures of a StarFileManager */
64
namespace StarFileManagerInternal
65
{
66
////////////////////////////////////////
67
//! Internal: a structure use to read SfxMultiRecord zone of a StarFileManager
68
struct SfxMultiRecord {
69
  //! constructor
70
  explicit SfxMultiRecord(StarZone &zone)
71
    : m_zone(zone)
72
    , m_zoneType(0)
73
    , m_zoneOpened(false)
74
    , m_headerType(0)
75
    , m_headerVersion(0)
76
    , m_headerTag(0)
77
    , m_actualRecord(0)
78
    , m_numRecord(0)
79
    , m_contentSize(0)
80
    , m_startPos(0)
81
    , m_endPos(0)
82
    , m_offsetList()
83
    , m_extra("")
84
0
  {
85
0
  }
86
  //! try to open a zone
87
  bool open()
88
0
  {
89
0
    if (m_zoneOpened) {
90
0
      STOFF_DEBUG_MSG(("StarFileManagerInternal::SfxMultiRecord: oops a record has been opened\n"));
91
0
      return false;
92
0
    }
93
0
    m_actualRecord=m_numRecord=0;
94
0
    m_headerType=m_headerVersion=0;
95
0
    m_headerTag=0;
96
0
    m_contentSize=0;
97
0
    m_offsetList.clear();
98
0
99
0
    STOFFInputStreamPtr input=m_zone.input();
100
0
    long pos=input->tell();
101
0
    if (!m_zone.openSfxRecord(m_zoneType)) {
102
0
      input->seek(pos, librevenge::RVNG_SEEK_SET);
103
0
      return false;
104
0
    }
105
0
    if (m_zoneType==static_cast<unsigned char>(0xff)) {
106
0
      STOFF_DEBUG_MSG(("StarFileManagerInternal::SfxMultiRecord: oops end header\n"));
107
0
      m_extra="###emptyZone,";
108
0
      return true; /* empty zone*/
109
0
    }
110
0
    if (m_zoneType!=0) {
111
0
      STOFF_DEBUG_MSG(("StarFileManagerInternal::SfxMultiRecord: find unknown header\n"));
112
0
      m_extra="###badZoneType,";
113
0
      return true;
114
0
    }
115
0
116
0
    m_zoneOpened=true;
117
0
    m_endPos=m_zone.getRecordLastPosition();
118
0
    // filerec.cxx: SfxSingleRecordReader::FindHeader_Impl
119
0
    if (input->tell()+10>m_endPos) {
120
0
      STOFF_DEBUG_MSG(("StarFileManagerInternal::SfxMultiRecord::open: oops the zone seems too short\n"));
121
0
      m_extra="###zoneShort,";
122
0
      return true;
123
0
    }
124
0
    *input >> m_headerType >> m_headerVersion >> m_headerTag;
125
0
    // filerec.cxx: SfxMultiRecordReader::ReadHeader_Impl
126
0
    *input >> m_numRecord >> m_contentSize;
127
0
    m_startPos=input->tell();
128
0
    std::stringstream s;
129
0
    if (m_headerType==2) {
130
0
      // fixed size
131
0
      if (m_startPos+long(m_numRecord)*long(m_contentSize) > m_endPos) {
132
0
        STOFF_DEBUG_MSG(("StarFileManagerInternal::SfxMultiRecord::open: oops the number of record seems bad\n"));
133
0
        s << "##numRecord=" << m_numRecord << ",";
134
0
        if (m_contentSize && m_endPos>m_startPos)
135
0
          m_numRecord=uint16_t((m_endPos-m_startPos)/long(m_contentSize));
136
0
        else
137
0
          m_numRecord=0;
138
0
      }
139
0
      m_extra=s.str();
140
0
      return true;
141
0
    }
142
0
143
0
    long debOffsetList=((m_headerType==3 || m_headerType==7) ? m_startPos : 0) + long(m_contentSize);
144
0
    if (debOffsetList<m_startPos || debOffsetList+4*m_numRecord > m_endPos) {
145
0
      STOFF_DEBUG_MSG(("StarFileManagerInternal::SfxMultiRecord::open: can not find the version map offset\n"));
146
0
      s << "###contentCount";
147
0
      m_numRecord=0;
148
0
      m_extra=s.str();
149
0
      return true;
150
0
    }
151
0
    m_endPos=debOffsetList;
152
0
    input->seek(debOffsetList, librevenge::RVNG_SEEK_SET);
153
0
    for (uint16_t i=0; i<m_numRecord; ++i) {
154
0
      uint32_t offset;
155
0
      *input >> offset;
156
0
      m_offsetList.push_back(offset);
157
0
    }
158
0
    input->seek(m_startPos, librevenge::RVNG_SEEK_SET);
159
0
    return true;
160
0
  }
161
  //! try to close a zone
162
  void close(std::string const &wh)
163
0
  {
164
0
    if (!m_zoneOpened) {
165
0
      STOFF_DEBUG_MSG(("StarFileManagerInternal::SfxMultiRecord::close: can not find any opened zone\n"));
166
0
      return;
167
0
    }
168
0
    m_zoneOpened=false;
169
0
    STOFFInputStreamPtr input=m_zone.input();
170
0
    if (input->tell()<m_endPos && input->tell()+4>=m_endPos) { // small diff is possible
171
0
      m_zone.ascii().addDelimiter(input->tell(),'|');
172
0
      input->seek(m_zone.getRecordLastPosition(), librevenge::RVNG_SEEK_SET);
173
0
    }
174
0
    else if (input->tell()==m_endPos)
175
0
      input->seek(m_zone.getRecordLastPosition(), librevenge::RVNG_SEEK_SET);
176
0
    m_zone.closeSfxRecord(m_zoneType, wh);
177
0
  }
178
  //! returns the header tag or -1
179
  int getHeaderTag() const
180
0
  {
181
0
    return !m_zoneOpened ? -1 : int(m_headerTag);
182
0
  }
183
  //! try to go to the new content positon
184
  bool getNewContent(std::string const &wh)
185
0
  {
186
0
    // SfxMultiRecordReader::GetContent
187
0
    long newPos=getLastContentPosition();
188
0
    if (newPos>=m_endPos) return false;
189
0
    STOFFInputStreamPtr input=m_zone.input();
190
0
    ++m_actualRecord;
191
0
    if (input->tell()<newPos && input->tell()+4>=newPos) { // small diff is possible
192
0
      m_zone.ascii().addDelimiter(input->tell(),'|');
193
0
      input->seek(newPos, librevenge::RVNG_SEEK_SET);
194
0
    }
195
0
    else if (input->tell()!=newPos) {
196
0
      STOFF_DEBUG_MSG(("StarFileManagerInternal::SfxMultiRecord::getNewContent: find extra data\n"));
197
0
      m_zone.ascii().addPos(input->tell());
198
0
      libstoff::DebugStream f;
199
0
      f << wh << ":###extra";
200
0
      m_zone.ascii().addNote(f.str().c_str());
201
0
      input->seek(newPos, librevenge::RVNG_SEEK_SET);
202
0
    }
203
0
    if (m_headerType==7 || m_headerType==8) {
204
0
      // TODO: readtag
205
0
      input->seek(2, librevenge::RVNG_SEEK_CUR);
206
0
    }
207
0
    return true;
208
0
  }
209
  //! returns the last content position
210
  long getLastContentPosition() const
211
0
  {
212
0
    if (m_actualRecord >= m_numRecord) return m_endPos;
213
0
    if (m_headerType==2) return m_startPos+m_actualRecord*long(m_contentSize);
214
0
    if (m_actualRecord >= uint16_t(m_offsetList.size())) {
215
0
      STOFF_DEBUG_MSG(("StarFileManagerInternal::SfxMultiRecord::getLastContentPosition: argh, find unexpected index\n"));
216
0
      return m_endPos;
217
0
    }
218
0
    return m_startPos+long(m_offsetList[size_t(m_actualRecord)]>>8)-14;
219
0
  }
220
221
  //! basic operator<< ; print header data
222
  friend std::ostream &operator<<(std::ostream &o, SfxMultiRecord const &r)
223
0
  {
224
0
    if (!r.m_zoneOpened) {
225
0
      o << r.m_extra;
226
0
      return o;
227
0
    }
228
0
    if (r.m_headerType) o << "type=" << int(r.m_headerType) << ",";
229
0
    if (r.m_headerVersion) o << "version=" << int(r.m_headerVersion) << ",";
230
0
    if (r.m_headerTag) o << "tag=" << r.m_headerTag << ",";
231
0
    if (r.m_numRecord) o << "num[record]=" << r.m_numRecord << ",";
232
0
    if (r.m_contentSize) o << "content[size/pos]=" << r.m_contentSize << ",";
233
0
    if (!r.m_offsetList.empty()) {
234
0
      o << "offset=[";
235
0
      for (unsigned int off : r.m_offsetList) {
236
0
        if (off&0xff)
237
0
          o << (off>>8) << ":" << (off&0xff) << ",";
238
0
        else
239
0
          o << (off>>8) << ",";
240
0
      }
241
0
      o << "],";
242
0
    }
243
0
    o << r.m_extra;
244
0
    return o;
245
0
  }
246
protected:
247
  //! the main zone
248
  StarZone &m_zone;
249
  //! the zone type
250
  unsigned char m_zoneType;
251
  //! true if a SfxRecord has been opened
252
  bool m_zoneOpened;
253
  //! the record type
254
  uint8_t m_headerType;
255
  //! the header version
256
  uint8_t m_headerVersion;
257
  //! the header tag
258
  uint16_t m_headerTag;
259
  //! the actual record
260
  uint16_t m_actualRecord;
261
  //! the number of record
262
  uint16_t m_numRecord;
263
  //! the record/content/pos size
264
  uint32_t m_contentSize;
265
  //! the start of data position
266
  long m_startPos;
267
  //! the end of data position
268
  long m_endPos;
269
  //! the list of (offset + type)
270
  std::vector<uint32_t> m_offsetList;
271
  //! extra data
272
  std::string m_extra;
273
private:
274
  SfxMultiRecord(SfxMultiRecord const &orig);
275
  SfxMultiRecord &operator=(SfxMultiRecord const &orig);
276
};
277
278
////////////////////////////////////////
279
//! Internal: the state of a StarFileManager
280
struct State {
281
  //! constructor
282
  State()
283
89.4k
  {
284
89.4k
  }
285
};
286
287
}
288
289
////////////////////////////////////////////////////////////
290
// constructor/destructor, ...
291
////////////////////////////////////////////////////////////
292
StarFileManager::StarFileManager()
293
89.4k
  : m_state(new StarFileManagerInternal::State)
294
89.4k
{
295
89.4k
}
296
297
StarFileManager::~StarFileManager()
298
89.4k
{
299
89.4k
}
300
301
bool StarFileManager::readOLEDirectory(std::shared_ptr<STOFFOLEParser> oleParser, std::shared_ptr<STOFFOLEParser::OleDirectory> ole, STOFFEmbeddedObject &image, std::shared_ptr<StarObject> &res)
302
7.38k
{
303
7.38k
  image=STOFFEmbeddedObject();
304
7.38k
  if (!oleParser || !ole || ole->m_inUse) {
305
641
    STOFF_DEBUG_MSG(("StarFileManager::readOLEDirectory: can not read an ole\n"));
306
641
    return false;
307
641
  }
308
6.74k
  ole->m_inUse=true;
309
6.74k
  StarObject object(nullptr, oleParser, ole); // do we need password here ?
310
6.74k
  if (object.getDocumentKind()==STOFFDocument::STOFF_K_CHART) {
311
3.17k
    auto chart=std::make_shared<StarObjectChart>(object, false);
312
3.17k
    ole->m_parsed=true;
313
3.17k
    if (chart->parse())
314
3.17k
      res=chart;
315
3.17k
  }
316
3.57k
  else if (object.getDocumentKind()==STOFFDocument::STOFF_K_DRAW) {
317
761
    StarObjectDraw draw(object, false);
318
761
    ole->m_parsed=true;
319
761
    if (draw.parse()) {
320
761
      STOFFGraphicEncoder graphicEncoder;
321
761
      std::vector<STOFFPageSpan> pageList;
322
761
      int numPages;
323
761
      if (!draw.updatePageSpans(pageList, numPages)) {
324
244
        STOFFPageSpan ps;
325
244
        ps.m_pageSpan=1;
326
244
        pageList.push_back(ps);
327
244
      }
328
761
      STOFFGraphicListenerPtr graphicListener(new STOFFGraphicListener(STOFFListManagerPtr(), pageList, &graphicEncoder));
329
761
      graphicListener->startDocument();
330
761
      draw.sendPages(graphicListener);
331
761
      graphicListener->endDocument();
332
761
      graphicEncoder.getBinaryResult(image);
333
761
    }
334
761
  }
335
2.81k
  else if (object.getDocumentKind()==STOFFDocument::STOFF_K_MATH) {
336
1.15k
    auto math=std::make_shared<StarObjectMath>(object, false);
337
1.15k
    ole->m_parsed=true;
338
1.15k
    if (math->parse())
339
1.15k
      res=math;
340
1.15k
  }
341
1.65k
  else if (object.getDocumentKind()==STOFFDocument::STOFF_K_SPREADSHEET) {
342
298
    StarObjectSpreadsheet spreadsheet(object, false);
343
298
    ole->m_parsed=true;
344
298
    if (spreadsheet.parse()) {
345
298
      STOFFSpreadsheetEncoder spreadsheetEncoder;
346
298
      std::vector<STOFFPageSpan> pageList;
347
298
      int numPages;
348
298
      if (!spreadsheet.updatePageSpans(pageList, numPages)) {
349
11
        STOFFPageSpan ps;
350
11
        ps.m_pageSpan=1;
351
11
        pageList.push_back(ps);
352
11
      }
353
298
      STOFFListManagerPtr listManager;
354
298
      STOFFSpreadsheetListenerPtr spreadsheetListener(new STOFFSpreadsheetListener(listManager, pageList, &spreadsheetEncoder));
355
298
      spreadsheetListener->startDocument();
356
298
      spreadsheet.send(spreadsheetListener);
357
298
      spreadsheetListener->endDocument();
358
298
      spreadsheetEncoder.getBinaryResult(image);
359
298
    }
360
298
  }
361
1.35k
  else if (object.getDocumentKind()==STOFFDocument::STOFF_K_TEXT) {
362
0
    auto text=std::make_shared<StarObjectText>(object, false);
363
0
    ole->m_parsed=true;
364
0
    if (text->parse())
365
0
      res=text;
366
0
  }
367
1.35k
  else {
368
1.35k
    ole->m_parsed=true;
369
    // Ole-Object has persist elements, so...
370
1.35k
    if (ole->m_hasCompObj) object.parse();
371
1.35k
    STOFFOLEParser::OleDirectory &direct=*ole;
372
1.35k
    std::vector<std::string> unparsedOLEs=direct.getUnparsedOles();
373
1.35k
    size_t numUnparsed = unparsedOLEs.size();
374
4.17k
    for (size_t i = 0; i < numUnparsed; i++) {
375
2.82k
      std::string const &name = unparsedOLEs[i];
376
2.82k
      STOFFInputStreamPtr stream = ole->m_input->getSubStreamByName(name.c_str());
377
2.82k
      if (!stream.get()) {
378
1.30k
        STOFF_DEBUG_MSG(("StarFileManager::readOLEDirectory: error: can not find OLE part: \"%s\"\n", name.c_str()));
379
1.30k
        continue;
380
1.30k
      }
381
382
1.52k
      std::string::size_type pos = name.find_last_of('/');
383
1.52k
      std::string base;
384
1.52k
      if (pos == std::string::npos) base = name;
385
1.52k
      else
386
1.52k
        base = name.substr(pos+1);
387
1.52k
      stream->setReadInverted(true);
388
1.52k
      if (base=="SfxStyleSheets") {
389
523
        object.readSfxStyleSheets(stream,name);
390
523
        continue;
391
523
      }
392
393
997
      if (base=="StarImageDocument" || base=="StarImageDocument 4.0") {
394
0
        librevenge::RVNGBinaryData data;
395
0
        if (readImageDocument(stream,data,name) && !data.empty())
396
0
          image.add(data);
397
0
        continue;
398
0
      }
399
      // other
400
997
      if (base=="Ole-Object") {
401
0
        librevenge::RVNGBinaryData data;
402
0
        if (readOleObject(stream,data,name))
403
0
          image.add(data,"object/ole");
404
0
        continue;
405
0
      }
406
997
      libstoff::DebugFile asciiFile(stream);
407
997
      asciiFile.open(name);
408
409
997
      bool ok=false;
410
997
      if (base=="OutPlace Object")
411
0
        ok=readOutPlaceObject(stream, asciiFile);
412
997
      if (!ok) {
413
997
        libstoff::DebugStream f;
414
997
        if (base=="Standard") // can be Standard or STANDARD
415
2
          f << "Entries(STANDARD):";
416
995
        else
417
995
          f << "Entries(" << base << "):";
418
997
        asciiFile.addPos(0);
419
997
        asciiFile.addNote(f.str().c_str());
420
997
      }
421
997
      asciiFile.reset();
422
997
    }
423
1.35k
  }
424
  // finally look if some content have image
425
42.4k
  for (auto &content : ole->m_contentList) {
426
42.4k
    librevenge::RVNGBinaryData data;
427
42.4k
    std::string type;
428
42.4k
    if (content.getImageData(data,type))
429
0
      image.add(data, type);
430
42.4k
  }
431
6.74k
  ole->m_inUse=false;
432
6.74k
  return !image.isEmpty();
433
7.38k
}
434
435
void StarFileManager::checkUnparsed(STOFFInputStreamPtr input, std::shared_ptr<STOFFOLEParser> oleParser, char const *password)
436
0
{
437
0
  if (!input || !oleParser) {
438
0
    STOFF_DEBUG_MSG(("StarFileManager::readOLEDirectory: can not find the input/ole parser\n"));
439
0
    return;
440
0
  }
441
0
  auto listDir=oleParser->getDirectoryList();
442
0
  for (auto &dir : listDir) {
443
0
    if (!dir || dir->m_parsed) continue;
444
0
    dir->m_parsed=true;
445
0
    StarObject object(password, oleParser, dir);
446
0
    if (object.getDocumentKind()==STOFFDocument::STOFF_K_CHART) {
447
0
      StarObjectChart chart(object, false);
448
0
      chart.parse();
449
0
      continue;
450
0
    }
451
0
    if (object.getDocumentKind()==STOFFDocument::STOFF_K_DRAW) {
452
0
      StarObjectDraw draw(object, false);
453
0
      draw.parse();
454
0
      continue;
455
0
    }
456
0
    if (object.getDocumentKind()==STOFFDocument::STOFF_K_MATH) {
457
0
      StarObjectMath math(object, false);
458
0
      math.parse();
459
0
      continue;
460
0
    }
461
0
    if (object.getDocumentKind()==STOFFDocument::STOFF_K_SPREADSHEET) {
462
0
      StarObjectSpreadsheet spreadsheet(object, false);
463
0
      spreadsheet.parse();
464
0
      continue;
465
0
    }
466
0
    if (object.getDocumentKind()==STOFFDocument::STOFF_K_TEXT) {
467
0
      StarObjectText text(object, false);
468
0
      text.parse();
469
0
      continue;
470
0
    }
471
    // Ole-Object has persist elements, so...
472
0
    if (dir->m_hasCompObj) object.parse();
473
0
    auto unparsedOLEs=dir->getUnparsedOles();
474
0
    for (auto const &name : unparsedOLEs) {
475
0
      auto ole = input->getSubStreamByName(name.c_str());
476
0
      if (!ole.get()) {
477
0
        STOFF_DEBUG_MSG(("SDWParser::createZones: error: can not find OLE part: \"%s\"\n", name.c_str()));
478
0
        continue;
479
0
      }
480
481
0
      auto pos = name.find_last_of('/');
482
0
      std::string base;
483
0
      if (pos == std::string::npos) base = name;
484
0
      else base = name.substr(pos+1);
485
0
      ole->setReadInverted(true);
486
0
      if (base=="SfxStyleSheets") {
487
0
        object.readSfxStyleSheets(ole,name);
488
0
        continue;
489
0
      }
490
491
0
      if (base=="StarImageDocument" || base=="StarImageDocument 4.0") {
492
0
        librevenge::RVNGBinaryData data;
493
0
        readImageDocument(ole,data,name);
494
0
        continue;
495
0
      }
496
0
      if (base.compare(0,3,"Pic")==0) {
497
0
        librevenge::RVNGBinaryData data;
498
0
        std::string type;
499
0
        readEmbeddedPicture(ole,data,type,name);
500
0
        continue;
501
0
      }
502
      // other
503
0
      if (base=="Ole-Object") {
504
0
        librevenge::RVNGBinaryData data;
505
0
        readOleObject(ole,data,name);
506
0
        continue;
507
0
      }
508
0
      libstoff::DebugFile asciiFile(ole);
509
0
      asciiFile.open(name);
510
511
0
      bool ok=false;
512
0
      if (base=="OutPlace Object")
513
0
        ok=readOutPlaceObject(ole, asciiFile);
514
0
      if (!ok) {
515
0
        libstoff::DebugStream f;
516
0
        if (base=="Standard") // can be Standard or STANDARD
517
0
          f << "Entries(STANDARD):";
518
0
        else
519
0
          f << "Entries(" << base << "):";
520
0
        asciiFile.addPos(0);
521
0
        asciiFile.addNote(f.str().c_str());
522
0
      }
523
0
      asciiFile.reset();
524
0
    }
525
0
  }
526
0
}
527
528
bool StarFileManager::readImageDocument(STOFFInputStreamPtr input, librevenge::RVNGBinaryData &data, std::string const &fileName)
529
0
{
530
  // see this Ole with classic bitmap format
531
0
  libstoff::DebugFile ascii(input);
532
0
  ascii.open(fileName);
533
0
  ascii.skipZone(0, input->size());
534
535
0
  input->seek(0, librevenge::RVNG_SEEK_SET);
536
0
  data.clear();
537
0
  if (!input->readEndDataBlock(data)) {
538
0
    STOFF_DEBUG_MSG(("StarFileManager::readImageDocument: can not read image content\n"));
539
0
    return false;
540
0
  }
541
#ifdef DEBUG_WITH_FILES
542
  libstoff::Debug::dumpFile(data, (fileName+".ppm").c_str());
543
#endif
544
0
  return true;
545
0
}
546
547
bool StarFileManager::readEmbeddedPicture(std::shared_ptr<STOFFOLEParser> oleParser, std::string const &fileName, STOFFEmbeddedObject &image)
548
35
{
549
35
  if (!oleParser) {
550
0
    STOFF_DEBUG_MSG(("StarFileManager::readEmbeddedPicture: called without OLE parser\n"));
551
0
    return false;
552
0
  }
553
35
  auto dir=oleParser->getDirectory("EmbeddedPictures");
554
35
  if (!dir || !dir->m_input || !dir->m_input->isStructured()) {
555
0
    STOFF_DEBUG_MSG(("StarFileManager::readEmbeddedPicture: can not find the embedded picture directory\n"));
556
0
    return false;
557
0
  }
558
35
  std::string name("EmbeddedPictures/");
559
35
  name+=fileName;
560
35
  auto ole= dir->m_input->getSubStreamByName(name.c_str());
561
35
  if (!ole) {
562
10
    STOFF_DEBUG_MSG(("StarFileManager::readEmbeddedPicture: can not find the picture %s\n", name.c_str()));
563
10
    return false;
564
10
  }
565
25
  librevenge::RVNGBinaryData data;
566
25
  std::string type;
567
25
  if (!readEmbeddedPicture(ole,data,type,name))
568
10
    return false;
569
15
  image.add(data, type);
570
15
  return true;
571
25
}
572
573
bool StarFileManager::readEmbeddedPicture(STOFFInputStreamPtr input, librevenge::RVNGBinaryData &data, std::string &dataType, std::string const &fileName)
574
25
try
575
25
{
576
  // see this Ole with classic bitmap format
577
25
  StarZone zone(input, fileName, "EmbeddedPicture", nullptr);
578
579
25
  libstoff::DebugFile &ascii=zone.ascii();
580
25
  ascii.open(fileName);
581
25
  data.clear();
582
25
  dataType="";
583
  // impgraph.cxx: ImpGraphic::ImplReadEmbedded
584
585
25
  input->seek(0, librevenge::RVNG_SEEK_SET);
586
25
  libstoff::DebugStream f;
587
25
  f << "Entries(EmbeddedPicture):";
588
25
  uint32_t nId;
589
25
  int32_t nLen;
590
591
25
  *input>>nId;
592
25
  if (nId==0x35465247 || nId==0x47524635) {
593
13
    if (nId==0x47524635)
594
13
      input->setReadInverted(!input->readInverted());
595
13
    if (!zone.openVersionCompatHeader()) {
596
0
      f << "###";
597
0
      STOFF_DEBUG_MSG(("StarFileManager::readEmbeddedPicture: can not open the header\n"));
598
0
      ascii.addPos(0);
599
0
      ascii.addNote(f.str().c_str());
600
0
      return false;
601
0
    }
602
13
    int32_t nType;
603
13
    int32_t sizeX, sizeY;
604
13
    *input >> nType >> nLen >> sizeX>> sizeY;
605
13
    if (nType)
606
13
      f << "type=" << nType << ",";
607
13
    f << "size=" << sizeX << "x" << sizeY << ",";
608
    // mapmod.cxx: operator>>(..., ImplMapMode& )
609
13
    if (!zone.openVersionCompatHeader()) {
610
0
      f << "###";
611
0
      STOFF_DEBUG_MSG(("StarFileManager::readEmbeddedPicture: can not open the mapmod header\n"));
612
0
    }
613
13
    else {
614
13
      uint16_t nMapMode;
615
13
      int32_t nOffsX, nOffsY, nScaleNumX, nScaleDenomX, nScaleNumY, nScaleDenomY;
616
13
      bool mbSimple;
617
13
      *input >> nMapMode >> nOffsX>> nOffsY;
618
13
      if (nMapMode) f << "mapMode=" << nMapMode << ",";
619
13
      if (nOffsX || nOffsY)
620
0
        f << "offs=" << nOffsX << "x" << nOffsY << ",";
621
13
      *input >> nScaleNumX >> nScaleDenomX >> nScaleNumY >> nScaleDenomY >> mbSimple;
622
13
      f << "scaleX=" << nScaleNumX << "/" << nScaleDenomX << ",";
623
13
      f << "scaleY=" << nScaleNumY << "/" << nScaleDenomY << ",";
624
13
      if (mbSimple) f << "simple,";
625
13
      zone.closeVersionCompatHeader("StarFileManager");
626
13
    }
627
13
    zone.closeVersionCompatHeader("StarFileManager");
628
13
  }
629
12
  else {
630
12
    if (nId>0x100) {
631
12
      input->seek(0, librevenge::RVNG_SEEK_SET);
632
12
      input->setReadInverted(!input->readInverted());
633
12
      *input>>nId;
634
12
    }
635
12
    if (nId)
636
12
      f << "type=" << nId << ",";
637
12
    int32_t nWidth, nHeight, nMapMode, nScaleNumX, nScaleDenomX, nScaleNumY, nScaleDenomY, nOffsX, nOffsY;
638
12
    *input >> nLen >> nWidth >> nHeight >> nMapMode;
639
12
    f << "size=" << nWidth << "x" << nHeight << ",";
640
12
    if (nMapMode) f << "mapMode=" << nMapMode << ",";
641
12
    *input >> nScaleNumX >> nScaleDenomX >> nScaleNumY >> nScaleDenomY;
642
12
    f << "scaleX=" << nScaleNumX << "/" << nScaleDenomX << ",";
643
12
    f << "scaleY=" << nScaleNumY << "/" << nScaleDenomY << ",";
644
12
    *input >> nOffsX >> nOffsY;
645
12
    f << "offset=" << nOffsX << "x" << nOffsY << ",";
646
12
  }
647
25
  if (nLen<10 || input->size()!=input->tell()+nLen) {
648
10
    f << "###";
649
10
    STOFF_DEBUG_MSG(("StarFileManager::readEmbeddedPicture: the length seems bad\n"));
650
10
    ascii.addPos(0);
651
10
    ascii.addNote(f.str().c_str());
652
10
    return false;
653
10
  }
654
15
  long pictPos=input->tell();
655
15
  auto header=int(input->readULong(2));
656
15
  input->seek(pictPos, librevenge::RVNG_SEEK_SET);
657
15
  std::string extension("pict");
658
15
  if (header==0x4142 || header==0x4d42) {
659
3
    dataType="image/bm";
660
3
    extension="bm";
661
#ifdef DEBUG_WITH_FILES
662
    StarBitmap bitmap;
663
    bitmap.readBitmap(zone, true, input->size(), data, dataType);
664
#endif
665
3
  }
666
12
  else if (header==0x5653) {
667
#ifdef DEBUG_WITH_FILES
668
    readSVGDI(zone);
669
#endif
670
0
    dataType="image/svg";
671
0
    extension="svgdi";
672
0
  }
673
12
  else if (header==0xcdd7) {
674
0
    dataType="image/wmf";
675
0
    extension="wmf";
676
0
  }
677
12
  else if (header==0x414e) {
678
12
    bool nat5=input->readULong(4)==0x3554414e;
679
12
    input->seek(pictPos, librevenge::RVNG_SEEK_SET);
680
12
    StarGraphicStruct::StarGraphic graphic;
681
12
    if (nat5 && graphic.read(zone,input->size())) {
682
11
      ascii.addPos(0);
683
11
      ascii.addNote(f.str().c_str());
684
11
      dataType=graphic.m_object.m_typeList.empty() ? "image/pict" : graphic.m_object.m_typeList[0];
685
11
      if (!graphic.m_object.m_dataList.empty())
686
10
        data=graphic.m_object.m_dataList[0];
687
11
      return true;
688
11
    }
689
1
    dataType="image/pict";
690
1
    f << "###unknown";
691
1
    STOFF_DEBUG_MSG(("StarFileManager::readEmbeddedPicture: find unknown format\n"));
692
1
  }
693
0
  else if (header==0x4356) { // VLCMTF
694
0
    dataType="image/pict";
695
0
    extension="pict";
696
0
  }
697
0
  else {
698
0
    dataType="image/pict";
699
0
    f << "###unknown";
700
0
    STOFF_DEBUG_MSG(("StarFileManager::readEmbeddedPicture: find unknown format\n"));
701
0
  }
702
4
  f << extension << ",";
703
4
  if (input->tell()==pictPos) ascii.addDelimiter(input->tell(),'|');
704
4
  ascii.addPos(0);
705
4
  ascii.addNote(f.str().c_str());
706
4
  ascii.skipZone(pictPos+4, input->size());
707
708
4
  input->seek(pictPos, librevenge::RVNG_SEEK_SET);
709
4
  if (!input->readEndDataBlock(data)) {
710
0
    data.clear();
711
0
    STOFF_DEBUG_MSG(("StarFileManager::readEmbeddedPicture: can not read image content\n"));
712
0
    return true;
713
0
  }
714
#ifdef DEBUG_WITH_FILES
715
  libstoff::Debug::dumpFile(data, (fileName+"."+extension).c_str());
716
#endif
717
4
  return true;
718
4
}
719
25
catch (...)
720
25
{
721
0
  return false;
722
0
}
723
724
bool StarFileManager::readOleObject(STOFFInputStreamPtr input, librevenge::RVNGBinaryData &data, std::string const &fileName)
725
0
{
726
  // see this Ole only once with PaintBrush data ?
727
0
  libstoff::DebugFile ascii(input);
728
0
  ascii.open(fileName);
729
0
  ascii.skipZone(0, input->size());
730
731
0
  input->seek(0, librevenge::RVNG_SEEK_SET);
732
0
  if (!input->readEndDataBlock(data)) {
733
0
    STOFF_DEBUG_MSG(("StarFileManager::readOleObject: can not read image content\n"));
734
0
    data.clear();
735
0
    return false;
736
0
  }
737
#ifdef DEBUG_WITH_FILES
738
  libstoff::Debug::dumpFile(data, (fileName+".ole").c_str());
739
#endif
740
0
  return true;
741
0
}
742
743
bool StarFileManager::readOutPlaceObject(STOFFInputStreamPtr input, libstoff::DebugFile &ascii)
744
0
{
745
0
  input->seek(0, librevenge::RVNG_SEEK_SET);
746
0
  libstoff::DebugStream f;
747
0
  f << "Entries(OutPlaceObject):";
748
  // see outplace.cxx SvOutPlaceObject::SaveCompleted
749
0
  if (input->size()<7) {
750
0
    STOFF_DEBUG_MSG(("StarFileManager::readOutPlaceObject: file is too short\n"));
751
0
    f << "###";
752
0
  }
753
0
  else {
754
0
    uint16_t len;
755
0
    uint32_t dwAspect;
756
0
    bool setExtent;
757
0
    *input>>len >> dwAspect >> setExtent;
758
0
    if (len!=7) f << "length=" << len << ",";
759
0
    if (dwAspect) f << "dwAspect=" << dwAspect << ",";
760
0
    if (setExtent) f << setExtent << ",";
761
0
    if (!input->isEnd()) {
762
0
      STOFF_DEBUG_MSG(("StarFileManager::readOutPlaceObject: find extra data\n"));
763
0
      f << "###extra";
764
0
      ascii.addDelimiter(input->tell(),'|');
765
0
    }
766
0
  }
767
0
  ascii.addPos(0);
768
0
  ascii.addNote(f.str().c_str());
769
0
  return true;
770
0
}
771
772
////////////////////////////////////////////////////////////
773
// small zone
774
////////////////////////////////////////////////////////////
775
bool StarFileManager::readFont(StarZone &zone)
776
38.8k
{
777
38.8k
  STOFFInputStreamPtr input=zone.input();
778
38.8k
  libstoff::DebugFile &ascFile=zone.ascii();
779
38.8k
  long pos=input->tell();
780
  // font.cxx:  operator>>( ..., Impl_Font& )
781
38.8k
  libstoff::DebugStream f;
782
38.8k
  f << "Entries(StarFont)[" << zone.getRecordLevel() << "]:";
783
38.8k
  if (!zone.openVersionCompatHeader()) {
784
2.39k
    STOFF_DEBUG_MSG(("StarFileManager::readFont: can not read the header\n"));
785
2.39k
    f << "###header";
786
2.39k
    ascFile.addPos(pos);
787
2.39k
    ascFile.addNote(f.str().c_str());
788
2.39k
    return false;
789
2.39k
  }
790
36.4k
  long lastPos=zone.getRecordLastPosition();
791
106k
  for (int i=0; i<2; ++i) {
792
71.5k
    std::vector<uint32_t> string;
793
71.5k
    if (!zone.readString(string)||input->tell()>lastPos) {
794
1.80k
      STOFF_DEBUG_MSG(("StarFileManager::readFont: can not read a string\n"));
795
1.80k
      f << "###string";
796
1.80k
      ascFile.addPos(pos);
797
1.80k
      ascFile.addNote(f.str().c_str());
798
1.80k
      zone.closeVersionCompatHeader("StarFont");
799
1.80k
      return true;
800
1.80k
    }
801
69.7k
    if (!string.empty()) f << (i==0 ? "name" : "style") << "=" << libstoff::getString(string).cstr() << ",";
802
69.7k
  }
803
34.6k
  f << "size=" << input->readLong(4) << "x" << input->readLong(4) << ",";
804
34.6k
  uint16_t eCharSet, eFamily, ePitch, eWeight, eUnderline, eStrikeOut, eItalic, eLanguage, eWidthType;
805
34.6k
  int16_t orientation;
806
34.6k
  *input >> eCharSet >> eFamily >> ePitch >> eWeight >> eUnderline >> eStrikeOut
807
34.6k
         >> eItalic >> eLanguage >> eWidthType >> orientation;
808
34.6k
  if (eCharSet) f << "eCharSet=" << eCharSet << ",";
809
34.6k
  if (eFamily) f << "eFamily=" << eFamily << ",";
810
34.6k
  if (ePitch) f << "ePitch=" << ePitch << ",";
811
34.6k
  if (eWeight) f << "eWeight=" << eWeight << ",";
812
34.6k
  if (eUnderline) f << "eUnderline=" << eUnderline << ",";
813
34.6k
  if (eStrikeOut) f << "eStrikeOut=" << eStrikeOut << ",";
814
34.6k
  if (eItalic) f << "eItalic=" << eItalic << ",";
815
34.6k
  if (eLanguage) f << "eLanguage=" << eLanguage << ",";
816
34.6k
  if (eWidthType) f << "eWidthType=" << eWidthType << ",";
817
34.6k
  if (orientation) f << "orientation=" << orientation << ",";
818
34.6k
  bool wordline, outline, shadow;
819
34.6k
  uint8_t kerning;
820
34.6k
  *input >> wordline >> outline >> shadow >> kerning;
821
34.6k
  if (wordline) f << "wordline,";
822
34.6k
  if (outline) f << "outline,";
823
34.6k
  if (shadow) f << "shadow,";
824
34.6k
  if (kerning) f << "kerning=" << int(kerning) << ",";
825
34.6k
  if (zone.getHeaderVersion() >= 2) {
826
4.63k
    bool vertical;
827
4.63k
    int8_t relief;
828
4.63k
    uint16_t cjkLanguage, emphasisMark;
829
4.63k
    *input >> relief >> cjkLanguage >> vertical >> emphasisMark;
830
4.63k
    if (relief) f << "relief=" << int(relief) << ",";
831
4.63k
    if (cjkLanguage) f << "cjkLanguage=" << cjkLanguage << ",";
832
4.63k
    if (vertical) f << "vertical,";
833
4.63k
    if (emphasisMark) f << "emphasisMark=" << emphasisMark << ",";
834
4.63k
  }
835
34.6k
  if (zone.getHeaderVersion() >= 3) {
836
4.59k
    int16_t overline;
837
4.59k
    *input>>overline;
838
4.59k
    if (overline) f << "overline=" << overline << ",";
839
4.59k
  }
840
34.6k
  ascFile.addPos(pos);
841
34.6k
  ascFile.addNote(f.str().c_str());
842
843
34.6k
  zone.closeVersionCompatHeader("StarFont");
844
34.6k
  return true;
845
36.4k
}
846
847
bool StarFileManager::readJobSetUp(StarZone &zone, bool useJobLen)
848
11.8k
{
849
11.8k
  STOFFInputStreamPtr input=zone.input();
850
11.8k
  libstoff::DebugFile &ascFile=zone.ascii();
851
11.8k
  long pos=input->tell();
852
  // sw_sw3misc.cxx: InJobSetup
853
11.8k
  libstoff::DebugStream f;
854
11.8k
  f << "Entries(JobSetUp)[" << zone.getRecordLevel() << "]:";
855
  // sfx2_printer.cxx: SfxPrinter::Create
856
  // jobset.cxx: JobSetup operator>>
857
11.8k
  long lastPos=zone.getRecordLastPosition();
858
11.8k
  auto len=int(input->readULong(2));
859
11.8k
  f << "nLen=" << len << ",";
860
11.8k
  if (len==0) {
861
1.39k
    ascFile.addPos(pos);
862
1.39k
    ascFile.addNote(f.str().c_str());
863
1.39k
    return true;
864
1.39k
  }
865
10.4k
  if (useJobLen) {
866
2.54k
    if (pos+len>lastPos) {
867
129
      STOFF_DEBUG_MSG(("StarFileManager::readJobSetUp: the jobs len seems bad\n"));
868
129
      input->seek(pos, librevenge::RVNG_SEEK_SET);
869
129
      return false;
870
129
    }
871
2.41k
    else
872
2.41k
      lastPos=pos+len;
873
2.54k
  }
874
10.3k
  bool ok=false;
875
10.3k
  int nSystem=0;
876
10.3k
  if (input->tell()+2+64+3*32<=lastPos) {
877
9.99k
    nSystem=int(input->readULong(2));
878
9.99k
    f << "system=" << nSystem << ",";
879
49.9k
    for (int i=0; i<4; ++i) {
880
39.9k
      long actPos=input->tell();
881
39.9k
      int const length=(i==0 ? 64 : 32);
882
39.9k
      std::string name("");
883
332k
      for (int c=0; c<length; ++c) {
884
331k
        auto ch=char(input->readULong(1));
885
331k
        if (ch==0) break;
886
292k
        name+=ch;
887
292k
      }
888
39.9k
      if (!name.empty()) {
889
21.4k
        static char const* const wh[]= { "printerName", "deviceName", "portName", "driverName" };
890
21.4k
        f << wh[i] << "=" << name << ",";
891
21.4k
      }
892
39.9k
      input->seek(actPos+length, librevenge::RVNG_SEEK_SET);
893
39.9k
    }
894
9.99k
    ok=true;
895
9.99k
  }
896
10.3k
  if (ok && nSystem<0xfffe) {
897
7.53k
    ascFile.addPos(pos);
898
7.53k
    ascFile.addNote(f.str().c_str());
899
900
7.53k
    pos=input->tell();
901
7.53k
    f.str("");
902
7.53k
    f << "JobSetUp:driverData,";
903
7.53k
    input->seek(lastPos, librevenge::RVNG_SEEK_SET);
904
7.53k
  }
905
2.81k
  else if (ok && input->tell()+22<=lastPos) {
906
2.45k
    int driverDataLen=0;
907
2.45k
    f << "nSize2=" << input->readULong(2) << ",";
908
2.45k
    f << "nSystem2=" << input->readULong(2) << ",";
909
2.45k
    driverDataLen=int(input->readULong(4));
910
2.45k
    f << "nOrientation=" << input->readULong(2) << ",";
911
2.45k
    f << "nPaperBin=" << input->readULong(2) << ",";
912
2.45k
    f << "nPaperFormat=" << input->readULong(2) << ",";
913
2.45k
    f << "nPaperWidth=" << input->readULong(4) << ",";
914
2.45k
    f << "nPaperHeight=" << input->readULong(4) << ",";
915
916
2.45k
    if (driverDataLen && input->tell()+driverDataLen<=lastPos) {
917
1.69k
      ascFile.addPos(input->tell());
918
1.69k
      ascFile.addNote("JobSetUp:driverData");
919
1.69k
      input->seek(driverDataLen, librevenge::RVNG_SEEK_CUR);
920
1.69k
    }
921
758
    else if (driverDataLen)
922
118
      ok=false;
923
2.45k
    if (ok) {
924
2.33k
      ascFile.addPos(pos);
925
2.33k
      ascFile.addNote(f.str().c_str());
926
2.33k
      pos=input->tell();
927
2.33k
      f.str("");
928
2.33k
      f << "JobSetUp[values]:";
929
2.33k
      if (nSystem==0xfffe) {
930
1.41k
        std::vector<uint32_t> text;
931
3.91k
        while (input->tell()<lastPos) {
932
7.68k
          for (int i=0; i<2; ++i) {
933
5.18k
            if (!zone.readString(text)) {
934
174
              f << "###string,";
935
174
              ok=false;
936
174
              break;
937
174
            }
938
5.01k
            f << libstoff::getString(text).cstr() << (i==0 ? ':' : ',');
939
5.01k
          }
940
2.67k
          if (!ok)
941
174
            break;
942
2.67k
        }
943
1.41k
      }
944
921
      else if (input->tell()<lastPos) {
945
59
        ascFile.addPos(input->tell());
946
59
        ascFile.addNote("JobSetUp:driverData");
947
59
        input->seek(lastPos, librevenge::RVNG_SEEK_SET);
948
59
      }
949
2.33k
    }
950
2.45k
  }
951
10.3k
  if (pos!=lastPos) {
952
9.45k
    ascFile.addPos(pos);
953
9.45k
    ascFile.addNote(f.str().c_str());
954
9.45k
  }
955
10.3k
  return true;
956
10.4k
}
957
958
bool StarFileManager::readSVGDI(StarZone &zone)
959
3.74k
{
960
3.74k
  STOFFInputStreamPtr input=zone.input();
961
3.74k
  libstoff::DebugFile &ascFile=zone.ascii();
962
3.74k
  long pos=input->tell();
963
3.74k
  long lastPos=zone.getRecordLevel()==0 ? input->size() : zone.getRecordLastPosition();
964
  // cvtsvm.cxx: SVMConverter::ImplConvertFromSVM1
965
3.74k
  libstoff::DebugStream f;
966
3.74k
  f << "Entries(ImageSVGDI)[" << zone.getRecordLevel() << "]:";
967
3.74k
  std::string code;
968
22.4k
  for (int i=0; i<5; ++i) code+=char(input->readULong(1));
969
3.74k
  if (code!="SVGDI") {
970
170
    input->seek(0, librevenge::RVNG_SEEK_SET);
971
170
    return false;
972
170
  }
973
3.57k
  uint16_t sz;
974
3.57k
  int16_t version;
975
3.57k
  int32_t width, height;
976
3.57k
  *input >> sz >> version >> width >> height;
977
3.57k
  long endPos=pos+5+sz;
978
3.57k
  if (version!=200 || sz<42 || endPos>lastPos) {
979
155
    STOFF_DEBUG_MSG(("StarFileManager::readSVGDI: find unknown version\n"));
980
155
    f << "###";
981
155
    ascFile.addPos(pos);
982
155
    ascFile.addNote(f.str().c_str());
983
155
    return false;
984
155
  }
985
3.41k
  f << "size=" << width << "x" << height << ",";
986
  // map mode
987
3.41k
  int16_t unit;
988
3.41k
  int32_t orgX, orgY, nXNum, nXDenom, nYNum, nYDenom;
989
3.41k
  *input >> unit >> orgX >> orgY >> nXNum >> nXDenom >> nYNum >> nYDenom;
990
3.41k
  if (unit) f << "unit=" << unit << ",";
991
3.41k
  f << "orig=" << orgX << "x" << orgY << ",";
992
3.41k
  f << "x=" << nXNum << "/" << nXDenom << ",";
993
3.41k
  f << "y=" << nYNum << "/" << nYDenom << ",";
994
995
3.41k
  int32_t nActions;
996
3.41k
  *input >> nActions;
997
3.41k
  f << "actions=" << nActions << ",";
998
3.41k
  if (input->tell()!=endPos)
999
3.26k
    ascFile.addDelimiter(input->tell(),'|');
1000
3.41k
  ascFile.addPos(pos);
1001
3.41k
  ascFile.addNote(f.str().c_str());
1002
3.41k
  input->seek(endPos, librevenge::RVNG_SEEK_SET);
1003
3.41k
  uint32_t nUnicodeCommentActionNumber=0;
1004
9.67k
  for (int32_t i=0; i<nActions; ++i) {
1005
9.67k
    pos=input->tell();
1006
9.67k
    f.str("");
1007
9.67k
    f << "ImageSVGDI[" << i << "]:";
1008
9.67k
    int16_t type;
1009
9.67k
    int32_t nActionSize;
1010
9.67k
    *input>>type>>nActionSize;
1011
9.67k
    long endDataPos=pos+2+nActionSize;
1012
9.67k
    if (nActionSize<4 || (lastPos-pos-2)<nActionSize || endDataPos>lastPos) {
1013
3.41k
      STOFF_DEBUG_MSG(("StarFileManager::readSVGDI: bad size\n"));
1014
3.41k
      f << "###";
1015
3.41k
      ascFile.addPos(pos);
1016
3.41k
      ascFile.addNote(f.str().c_str());
1017
3.41k
      input->seek(pos, librevenge::RVNG_SEEK_SET);
1018
3.41k
      break;
1019
3.41k
    }
1020
6.26k
    unsigned char col[3];
1021
6.26k
    STOFFColor color;
1022
6.26k
    int32_t nTmp, nTmp1;
1023
6.26k
    std::vector<uint32_t> text;
1024
6.26k
    switch (type) {
1025
28
    case 1:
1026
28
      f << "pixel=" << input->readLong(4) << "x" << input->readLong(4) << ",";
1027
84
      for (unsigned char &c : col) c=static_cast<unsigned char>(input->readULong(2)>>8);
1028
28
      f << "col=" << STOFFColor(col[0],col[1],col[2]) << ",";
1029
28
      break;
1030
51
    case 2:
1031
51
      f << "point=" << input->readLong(4) << "x" << input->readLong(4) << ",";
1032
51
      break;
1033
29
    case 3:
1034
29
      f << "line=" << input->readLong(4) << "x" << input->readLong(4) << "<->"
1035
29
        << input->readLong(4) << "x" << input->readLong(4) << ",";
1036
29
      break;
1037
19
    case 4:
1038
19
      f << "rect=" << input->readLong(4) << "x" << input->readLong(4) << "<->"
1039
19
        << input->readLong(4) << "x" << input->readLong(4) << ",";
1040
19
      *input >> nTmp >> nTmp1;
1041
19
      if (nTmp || nTmp1) f << "round=" << nTmp << "x" << nTmp1 << ",";
1042
19
      break;
1043
25
    case 5:
1044
25
      f << "ellipse=" << input->readLong(4) << "x" << input->readLong(4) << "<->"
1045
25
        << input->readLong(4) << "x" << input->readLong(4) << ",";
1046
25
      break;
1047
26
    case 6:
1048
47
    case 7:
1049
47
      f << (type==6 ? "arc" : "pie")<< "=" << input->readLong(4) << "x" << input->readLong(4) << "<->"
1050
47
        << input->readLong(4) << "x" << input->readLong(4) << ",";
1051
47
      f << "pt1=" << input->readLong(4) << "x" << input->readLong(4) << ",";
1052
47
      f << "pt2=" << input->readLong(4) << "x" << input->readLong(4) << ",";
1053
47
      break;
1054
25
    case 8:
1055
47
    case 9:
1056
47
      f << (type==8 ? "rect[invert]" : "rect[highlight") << "="
1057
47
        << input->readLong(4) << "x" << input->readLong(4) << "<->"
1058
47
        << input->readLong(4) << "x" << input->readLong(4) << ",";
1059
47
      break;
1060
154
    case 10:
1061
185
    case 11:
1062
185
      f << (type==10 ? "polyline" : "polygon") << ",";
1063
185
      *input >> nTmp;
1064
185
      if (nTmp<0 || nTmp>(endDataPos-input->tell())/8) {
1065
119
        STOFF_DEBUG_MSG(("StarFileManager::readSVGDI: bad number of points\n"));
1066
119
        f << "###nPts=" << nTmp << ",";
1067
119
        break;
1068
119
      }
1069
66
      f << "pts=[";
1070
225
      for (int pt=0; pt<int(nTmp); ++pt) f << input->readLong(4) << "x" << input->readLong(4) << ",";
1071
66
      f << "],";
1072
66
      break;
1073
295
    case 12:
1074
313
    case 1024:
1075
321
    case 1025:
1076
357
    case 1030:
1077
357
      f << (type==12 ? "polypoly" : type==1024 ? "transparent[comment]" :
1078
62
            type==1025 ? "hatch[comment]" : "gradient[comment]") << ",";
1079
357
      *input >> nTmp;
1080
560
      for (int poly=0; poly<int(nTmp) && !input->isEnd(); ++poly) {
1081
424
        *input >> nTmp1;
1082
424
        if (nTmp1<0 || nTmp1>(endDataPos-input->tell())/8) {
1083
221
          STOFF_DEBUG_MSG(("StarFileManager::readSVGDI: bad number of points\n"));
1084
221
          f << "###poly[nPts=" << nTmp1 << "],";
1085
221
          break;
1086
221
        }
1087
203
        f << "poly" << poly << "=[";
1088
460
        for (int pt=0; pt<int(nTmp1); ++pt) f << input->readLong(4) << "x" << input->readLong(4) << ",";
1089
203
        f << "],";
1090
203
      }
1091
357
      if (type==1024) {
1092
18
        f << "nTrans=" << input->readULong(2) << ",";
1093
18
        f << "nComment=" << input->readULong(4) << ",";
1094
18
      }
1095
357
      if (type==1025) {
1096
8
        f << "style=" << input->readULong(2) << ",";
1097
24
        for (unsigned char &c : col) c=static_cast<unsigned char>(input->readULong(2)>>8);
1098
8
        f << "col=" << STOFFColor(col[0],col[1],col[2]) << ",";
1099
8
        f << "distance=" << input->readLong(4) << ",";
1100
8
        f << "nComment=" << input->readULong(4) << ",";
1101
8
      }
1102
357
      if (type==1030) {
1103
36
        STOFF_DEBUG_MSG(("StarFileManager::readSVGDI: reading gradient is not implemented\n"));
1104
36
        f << "###gradient+following";
1105
36
        input->seek(endDataPos, librevenge::RVNG_SEEK_SET);
1106
36
      }
1107
357
      break;
1108
214
    case 13:
1109
304
    case 15: {
1110
304
      f << (type==13 ? "text" : "stretch") << ",";
1111
304
      f << "pos=" << input->readLong(4) << "x" << input->readLong(4) << ",";
1112
304
      int32_t nIndex, nLen;
1113
304
      *input>>nIndex>>nLen >> nTmp;
1114
304
      if (nIndex) f << "index=" << nIndex << ",";
1115
304
      if (nLen) f << "len=" << nLen << ",";
1116
304
      if (type==15) f << "nWidth=" << input->readLong(4) << ",";
1117
304
      if (nTmp<0 || input->tell()+nTmp>endDataPos) {
1118
180
        STOFF_DEBUG_MSG(("StarFileManager::readSVGDI: bad string\n"));
1119
180
        f << "###string";
1120
180
        break;
1121
180
      }
1122
124
      text.clear();
1123
6.28k
      for (int c=0; c<int(nTmp); ++c) text.push_back(static_cast<uint32_t>(input->readULong(1)));
1124
124
      input->seek(1, librevenge::RVNG_SEEK_CUR);
1125
124
      f << libstoff::getString(text).cstr() << ",";
1126
124
      if (nUnicodeCommentActionNumber!=static_cast<uint32_t>(i)) break;
1127
86
      uint16_t type1;
1128
86
      uint32_t len;
1129
86
      *input >> type1 >> len;
1130
86
      if (long(len)<4 || input->tell()+long(len)>endDataPos) {
1131
76
        STOFF_DEBUG_MSG(("StarFileManager::readSVGDI: bad string\n"));
1132
76
        f << "###unicode";
1133
76
        break;
1134
76
      }
1135
10
      if (type1==1032) {
1136
0
        text.clear();
1137
0
        int nUnicode=int(len-4)/2;
1138
0
        for (int c=0; c<nUnicode; ++c) text.push_back(static_cast<uint32_t>(input->readULong(2)));
1139
0
        f << libstoff::getString(text).cstr() << ",";
1140
0
      }
1141
10
      else {
1142
10
        STOFF_DEBUG_MSG(("StarFileManager::readSVGDI: unknown data\n"));
1143
10
        f << "###unknown";
1144
10
        input->seek(long(len)-4, librevenge::RVNG_SEEK_CUR);
1145
10
      }
1146
10
      break;
1147
86
    }
1148
323
    case 14: {
1149
323
      f << "text[array],";
1150
323
      f << "pos=" << input->readLong(4) << "x" << input->readLong(4) << ",";
1151
323
      int32_t nIndex, nLen, nAryLen;
1152
323
      *input>>nIndex>>nLen >> nTmp >> nAryLen;
1153
323
      if (nTmp<0 || nAryLen<0 || nAryLen>(endDataPos-input->tell()-nTmp)/4) {
1154
192
        STOFF_DEBUG_MSG(("StarFileManager::readSVGDI: bad string\n"));
1155
192
        f << "###string";
1156
192
        break;
1157
192
      }
1158
131
      text.clear();
1159
2.54k
      for (int c=0; c<int(nTmp); ++c) text.push_back(static_cast<uint32_t>(input->readULong(1)));
1160
131
      input->seek(1, librevenge::RVNG_SEEK_CUR);
1161
131
      f << libstoff::getString(text).cstr() << ",";
1162
131
      f << "ary=[";
1163
980
      for (int ary=0; ary<int(nAryLen); ++ary) f << input->readLong(4) << ",";
1164
131
      f << "],";
1165
131
      if (nUnicodeCommentActionNumber!=static_cast<uint32_t>(i)) break;
1166
86
      uint16_t type1;
1167
86
      uint32_t len;
1168
86
      *input >> type1 >> len;
1169
86
      if (long(len)<4 || input->tell()+long(len)>endDataPos) {
1170
76
        STOFF_DEBUG_MSG(("StarFileManager::readSVGDI: bad string\n"));
1171
76
        f << "###unicode";
1172
76
        break;
1173
76
      }
1174
10
      if (type1==1032) {
1175
0
        text.clear();
1176
0
        int nUnicode=int(len-4)/2;
1177
0
        for (int c=0; c<nUnicode; ++c) text.push_back(static_cast<uint32_t>(input->readULong(2)));
1178
0
        f << libstoff::getString(text).cstr() << ",";
1179
0
      }
1180
10
      else {
1181
10
        STOFF_DEBUG_MSG(("StarFileManager::readSVGDI: unknown data\n"));
1182
10
        f << "###unknown";
1183
10
        input->seek(long(len)-4, librevenge::RVNG_SEEK_CUR);
1184
10
      }
1185
1186
10
      break;
1187
86
    }
1188
40
    case 16:
1189
40
      STOFF_DEBUG_MSG(("StarFileManager::readSVGDI: reading icon is not implemented\n"));
1190
40
      f << "###icon";
1191
40
      break;
1192
2.40k
    case 17:
1193
2.48k
    case 18:
1194
2.61k
    case 32: {
1195
2.61k
      f << (type==17 ? "bitmap" : type==18 ? "bitmap[scale]" : "bitmap[scale2]");
1196
2.61k
      f << "pos=" << input->readLong(4) << "x" << input->readLong(4) << ",";
1197
2.61k
      if (type>=17) f << "scale=" << input->readLong(4) << "x" << input->readLong(4) << ",";
1198
2.61k
      if (type==32) {
1199
131
        f << "pos2=" << input->readLong(4) << "x" << input->readLong(4) << ",";
1200
131
        f << "scale2=" << input->readLong(4) << "x" << input->readLong(4) << ",";
1201
131
      }
1202
2.61k
      StarBitmap bitmap;
1203
2.61k
      librevenge::RVNGBinaryData data;
1204
2.61k
      std::string dataType;
1205
2.61k
      if (!bitmap.readBitmap(zone, false, endDataPos, data, dataType))
1206
1.73k
        f << "###bitmap,";
1207
2.61k
      break;
1208
2.48k
    }
1209
282
    case 19:
1210
282
      f << "pen,";
1211
846
      for (unsigned char &c : col) c=static_cast<unsigned char>(input->readULong(2)>>8);
1212
282
      color=STOFFColor(col[0],col[1],col[2]);
1213
282
      if (!color.isBlack()) f << "col=" << color << ",";
1214
282
      f << "penWidth=" << input->readULong(4) << ",";
1215
282
      f << "penStyle=" << input->readULong(2) << ",";
1216
282
      break;
1217
193
    case 20: {
1218
193
      f << "font,";
1219
579
      for (int c=0; c<2; ++c) {
1220
1.15k
        for (unsigned char &j : col) j=static_cast<unsigned char>(input->readULong(2)>>8);
1221
386
        color=STOFFColor(col[0],col[1],col[2]);
1222
386
        if ((c==1&&!color.isWhite()) || (c==0&&!color.isBlack()))
1223
224
          f << (c==0 ? "col" : "col[fill]") << "=" << color << ",";
1224
386
      }
1225
193
      long actPos=input->tell();
1226
193
      if (actPos+62>endDataPos) {
1227
20
        STOFF_DEBUG_MSG(("StarFileManager::readSVGDI: the zone seems too short\n"));
1228
20
        f << "###short";
1229
20
        break;
1230
20
      }
1231
173
      std::string name("");
1232
3.57k
      for (int c=0; c<32; ++c) {
1233
3.56k
        auto ch=char(input->readULong(1));
1234
3.56k
        if (!ch) break;
1235
3.40k
        name+=ch;
1236
3.40k
      }
1237
173
      f << name << ",";
1238
173
      input->seek(actPos+32, librevenge::RVNG_SEEK_SET);
1239
173
      f << "size=" << input->readLong(4) << "x" << input->readLong(4) << ",";
1240
173
      int16_t nCharSet, nFamily, nPitch, nAlign, nWeight, nUnderline, nStrikeout, nCharOrient, nLineOrient;
1241
173
      bool bItalic, bOutline, bShadow, bTransparent;
1242
173
      *input >> nCharSet >> nFamily >> nPitch >> nAlign >> nWeight >> nUnderline >> nStrikeout >> nCharOrient >> nLineOrient;
1243
173
      if (nCharSet) f << "char[set]=" << nCharSet << ",";
1244
173
      if (nFamily) f << "family=" << nFamily << ",";
1245
173
      if (nPitch) f << "pitch=" << nPitch << ",";
1246
173
      if (nAlign) f << "align=" << nAlign << ",";
1247
173
      if (nWeight) f << "weight=" << nWeight << ",";
1248
173
      if (nUnderline) f << "underline=" << nUnderline << ",";
1249
173
      if (nStrikeout) f << "strikeout=" << nStrikeout << ",";
1250
173
      if (nCharOrient) f << "charOrient=" << nCharOrient << ",";
1251
173
      if (nLineOrient) f << "lineOrient=" << nLineOrient << ",";
1252
173
      *input >> bItalic >> bOutline >> bShadow >> bTransparent;
1253
173
      if (bItalic) f << "italic,";
1254
173
      if (bOutline) f << "outline,";
1255
173
      if (bShadow) f << "shadow,";
1256
173
      if (bTransparent) f << "transparent,";
1257
173
      break;
1258
193
    }
1259
27
    case 21: // unsure
1260
93
    case 22:
1261
93
      f << (type==21 ? "brush[back]" : "brush[fill]") << ",";
1262
279
      for (unsigned char &j : col) j=static_cast<unsigned char>(input->readULong(2)>>8);
1263
93
      f << STOFFColor(col[0],col[1],col[2]) << ",";
1264
93
      input->seek(6, librevenge::RVNG_SEEK_CUR); // unknown
1265
93
      f << "style=" << input->readLong(2) << ",";
1266
93
      input->seek(2, librevenge::RVNG_SEEK_CUR); // unknown
1267
93
      break;
1268
24
    case 23:
1269
24
      f << "map[mode],";
1270
24
      *input >> unit >> orgX >> orgY >> nXNum >> nXDenom >> nYNum >> nYDenom;
1271
24
      if (unit) f << "unit=" << unit << ",";
1272
24
      f << "orig=" << orgX << "x" << orgY << ",";
1273
24
      f << "x=" << nXNum << "/" << nXDenom << ",";
1274
24
      f << "y=" << nYNum << "/" << nYDenom << ",";
1275
24
      break;
1276
289
    case 24: {
1277
289
      f << "clip[region],";
1278
289
      int16_t clipType, bIntersect;
1279
289
      *input >> clipType >> bIntersect;
1280
289
      f << "rect=" << input->readLong(4) << "x" << input->readLong(4) << "<->"
1281
289
        << input->readLong(4) << "x" << input->readLong(4) << ",";
1282
289
      if (bIntersect) f << "intersect,";
1283
289
      switch (clipType) {
1284
1
      case 0:
1285
1
        break;
1286
11
      case 1:
1287
11
        f << "rect2=" << input->readLong(4) << "x" << input->readLong(4) << "<->"
1288
11
          << input->readLong(4) << "x" << input->readLong(4) << ",";
1289
11
        break;
1290
110
      case 2:
1291
110
        *input >> nTmp;
1292
110
        if (nTmp<0 || nTmp>(endDataPos-input->tell())/8) {
1293
96
          STOFF_DEBUG_MSG(("StarFileManager::readSVGDI: bad number of points\n"));
1294
96
          f << "###nPts=" << nTmp << ",";
1295
96
          break;
1296
96
        }
1297
14
        f << "poly=[";
1298
17
        for (int pt=0; pt<int(nTmp); ++pt) f << input->readLong(4) << "x" << input->readLong(4) << ",";
1299
14
        f << "],";
1300
14
        break;
1301
147
      case 3:
1302
147
        *input >> nTmp;
1303
253
        for (int poly=0; poly<int(nTmp) && !input->isEnd(); ++poly) {
1304
212
          *input >> nTmp1;
1305
212
          if (nTmp1<0 || nTmp1>(endDataPos-input->tell())/8) {
1306
106
            STOFF_DEBUG_MSG(("StarFileManager::readSVGDI: bad number of points\n"));
1307
106
            f << "###poly[nPts=" << nTmp1 << "],";
1308
106
            break;
1309
106
          }
1310
106
          f << "poly" << poly << "=[";
1311
238
          for (int pt=0; pt<int(nTmp1); ++pt) f << input->readLong(4) << "x" << input->readLong(4) << ",";
1312
106
          f << "],";
1313
106
        }
1314
147
        break;
1315
20
      default:
1316
20
        STOFF_DEBUG_MSG(("StarFileManager::readSVGDI: find unknown clip type\n"));
1317
20
        f << "###type=" << clipType << ",";
1318
20
        break;
1319
289
      }
1320
289
      break;
1321
289
    }
1322
289
    case 25:
1323
74
      f << "raster=" << input->readULong(2) << ","; // 1 invert, 4,5: xor other paint
1324
74
      break;
1325
184
    case 26:
1326
184
      f << "push,";
1327
184
      break;
1328
69
    case 27:
1329
69
      f << "pop,";
1330
69
      break;
1331
58
    case 28:
1332
58
      f << "clip[move]=" << input->readLong(4) << "x" << input->readLong(4) << ",";
1333
58
      break;
1334
204
    case 29:
1335
204
      f << "clip[rect]=" << input->readLong(4) << "x" << input->readLong(4) << "<->"
1336
204
        << input->readLong(4) << "x" << input->readLong(4) << ",";
1337
204
      break;
1338
56
    case 30: // checkme
1339
87
    case 1029: {
1340
87
      f << (type==30 ? "mtf" : "floatComment") << ",";;
1341
      // gdimtf.cxx operator>>(... GDIMetaFile )
1342
87
      std::string name("");
1343
609
      for (int c=0; c<6; ++c) name+=char(input->readULong(1));
1344
87
      if (name!="VCLMTF") {
1345
57
        STOFF_DEBUG_MSG(("StarFileManager::readSVGDI: find unexpected header\n"));
1346
57
        f << "###name=" << name << ",";
1347
57
        break;
1348
57
      }
1349
30
      if (!zone.openVersionCompatHeader()) {
1350
22
        STOFF_DEBUG_MSG(("StarFileManager::readSVGDI: can not open compat header\n"));
1351
22
        f << "###compat,";
1352
22
        break;
1353
22
      }
1354
8
      f << "compress=" << input->readULong(4) << ",";
1355
      // map mode
1356
8
      *input >> unit >> orgX >> orgY >> nXNum >> nXDenom >> nYNum >> nYDenom;
1357
8
      f << "map=[";
1358
8
      if (unit) f << "unit=" << unit << ",";
1359
8
      f << "orig=" << orgX << "x" << orgY << ",";
1360
8
      f << "x=" << nXNum << "/" << nXDenom << ",";
1361
8
      f << "y=" << nYNum << "/" << nYDenom << ",";
1362
8
      f << "],";
1363
8
      f << "size=" << input->readULong(4) << ",";
1364
8
      uint32_t nCount;
1365
8
      *input >> nCount;
1366
8
      if (nCount) f << "nCount=" << nCount << ",";
1367
8
      if (input->tell()!=zone.getRecordLastPosition()) {
1368
        // for (int act=0; act<nCount; ++act) MetaAction::ReadMetaAction();
1369
7
        STOFF_DEBUG_MSG(("StarFileManager::readSVGDI: reading mtf action zones is not implemented\n"));
1370
7
        ascFile.addPos(input->tell());
1371
7
        ascFile.addNote("ImageSVGDI:###listMeta");
1372
7
        input->seek(zone.getRecordLastPosition(), librevenge::RVNG_SEEK_SET);
1373
7
      }
1374
8
      zone.closeVersionCompatHeader("ImageSVGDI");
1375
8
      if (type!=30) {
1376
4
        f << "orig=" << input->readLong(4) << "x" << input->readLong(4) << ",";
1377
4
        f << "sz=" << input->readULong(4) << ",";
1378
4
        STOFF_DEBUG_MSG(("StarFileManager::readSVGDI: reading gradient is not implemented\n"));
1379
4
        f << "###gradient+following";
1380
4
        input->seek(endDataPos, librevenge::RVNG_SEEK_SET);
1381
4
      }
1382
8
      break;
1383
30
    }
1384
24
    case 33: {
1385
24
      f << "gradient,";
1386
24
      f << "rect=" << input->readLong(4) << "x" << input->readLong(4) << "<->"
1387
24
        << input->readLong(4) << "x" << input->readLong(4) << ",";
1388
24
      f << "style=" << input->readULong(2) << ",";
1389
72
      for (int c=0; c<2; ++c) {
1390
144
        for (unsigned char &j : col) j=static_cast<unsigned char>(input->readULong(2)>>8);
1391
48
        color=STOFFColor(col[0],col[1],col[2]);
1392
48
        f << "col" << c << "=" << color << ",";
1393
48
      }
1394
24
      f << "angle=" << input->readLong(2) << ",";
1395
24
      f << "border=" << input->readLong(2) << ",";
1396
24
      f << "offs=" << input->readLong(2) << "x" << input->readLong(2) << ",";
1397
24
      f << "intensity=" << input->readLong(2) << "<->" << input->readLong(2) << ",";
1398
24
      break;
1399
30
    }
1400
11
    case 1026:
1401
11
      f << "refpoint[comment],";
1402
11
      f << "pt=" << input->readLong(4) << "x" << input->readLong(4) << ",";
1403
11
      f << "set=" << input->readULong(1) << ",";
1404
11
      f << "nComments=" << input->readULong(4) << ",";
1405
11
      break;
1406
23
    case 1027:
1407
23
      f << "textline[color,comment],";
1408
69
      for (unsigned char &j : col) j=static_cast<unsigned char>(input->readULong(2)>>8);
1409
23
      f << "col=" << STOFFColor(col[0],col[1],col[2]) << ",";
1410
23
      f << "set=" << input->readULong(1) << ",";
1411
23
      f << "nComments=" << input->readULong(4) << ",";
1412
23
      break;
1413
11
    case 1028:
1414
11
      f << "textline[comment],";
1415
11
      f << "pt=" << input->readLong(4) << "x" << input->readLong(4) << ",";
1416
11
      f << "width=" << input->readLong(4) << ",";
1417
11
      f << "strikeOut=" << input->readULong(4) << ",";
1418
11
      f << "underline=" << input->readULong(4) << ",";
1419
11
      f << "nComments=" << input->readULong(4) << ",";
1420
11
      break;
1421
111
    case 1031: {
1422
111
      f << "comment[comment],";
1423
111
      if (!zone.readString(text)) {
1424
4
        STOFF_DEBUG_MSG(("StarFileManager::readSVGDI: can not read the text\n"));
1425
4
        f << "###text,";
1426
4
        break;
1427
4
      }
1428
107
      f << libstoff::getString(text).cstr() << ",";
1429
107
      f << "value=" << input->readULong(4) << ",";
1430
107
      long size=input->readLong(4);
1431
107
      if (size<0 || input->tell()+size+4>endDataPos) {
1432
99
        STOFF_DEBUG_MSG(("StarFileManager::readSVGDI: size seems bad\n"));
1433
99
        f << "###size=" << size << ",";
1434
99
        break;
1435
99
      }
1436
8
      if (size) {
1437
4
        f << "###unknown,";
1438
4
        ascFile.addDelimiter(input->tell(),'|');
1439
4
        input->seek(size, librevenge::RVNG_SEEK_CUR);
1440
4
      }
1441
8
      f << "nComments=" << input->readULong(4) << ",";
1442
8
      break;
1443
107
    }
1444
20
    case 1032:
1445
20
      f << "unicode[next],";
1446
20
      nUnicodeCommentActionNumber=uint32_t(i)+1;
1447
20
      break;
1448
437
    default:
1449
437
      STOFF_DEBUG_MSG(("StarFileManager::readSVGDI: find unimplement type\n"));
1450
437
      f << "###type=" << type << ",";
1451
437
      input->seek(endDataPos, librevenge::RVNG_SEEK_SET);
1452
437
      break;
1453
6.26k
    }
1454
6.26k
    if (input->tell()!=endDataPos) {
1455
4.57k
      STOFF_DEBUG_MSG(("StarFileManager::readSVGDI: find extra data\n"));
1456
4.57k
      f << "###extra,";
1457
4.57k
      ascFile.addDelimiter(input->tell(),'|');
1458
4.57k
    }
1459
6.26k
    ascFile.addPos(pos);
1460
6.26k
    ascFile.addNote(f.str().c_str());
1461
6.26k
    input->seek(endDataPos, librevenge::RVNG_SEEK_SET);
1462
6.26k
  }
1463
1464
3.41k
  return true;
1465
3.41k
}
1466
1467
// vim: set filetype=cpp tabstop=2 shiftwidth=2 cindent autoindent smartindent noexpandtab: