Coverage Report

Created: 2026-06-13 06:44

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libmwaw/src/lib/PowerPoint7Parser.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
/* libmwaw
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 <algorithm>
35
#include <iomanip>
36
#include <iostream>
37
#include <sstream>
38
#include <stack>
39
#include <utility>
40
41
#include <librevenge/librevenge.h>
42
43
#include "MWAWPresentationListener.hxx"
44
#include "MWAWFont.hxx"
45
#include "MWAWFontConverter.hxx"
46
#include "MWAWHeader.hxx"
47
#include "MWAWGraphicShape.hxx"
48
#include "MWAWGraphicStyle.hxx"
49
#include "MWAWParagraph.hxx"
50
#include "MWAWPosition.hxx"
51
#include "MWAWPrinter.hxx"
52
53
#include "PowerPoint3OLE.hxx"
54
#include "PowerPoint7Graph.hxx"
55
#include "PowerPoint7Parser.hxx"
56
#include "PowerPoint7Struct.hxx"
57
#include "PowerPoint7Text.hxx"
58
59
/** Internal: the structures of a PowerPoint7Parser */
60
namespace PowerPoint7ParserInternal
61
{
62
//! Internal: the basic information about a slide/notes/... zone in a PowerPoint7Parser
63
struct SlideInfo {
64
  //! constructor
65
  SlideInfo()
66
7.79k
    : m_box()
67
7.79k
    , m_displayMaster(true)
68
7.79k
    , m_hasBackground(false)
69
7.79k
  {
70
7.79k
  }
71
  //! the bdbox
72
  MWAWBox2i m_box;
73
  //! a flag to know if we need to display the master slide graphic
74
  bool m_displayMaster;
75
  //! a flag to know if the slide has some background or no background
76
  bool m_hasBackground;
77
};
78
////////////////////////////////////////
79
//! Internal: the state of a PowerPoint7Parser
80
struct State {
81
  //! constructor
82
  State()
83
4.21k
    : m_fontFamily("CP1252")
84
4.21k
    , m_pageDimension(5760,4320)
85
4.21k
    , m_graphParser()
86
4.21k
    , m_textParser()
87
4.21k
    , m_oleParser()
88
4.21k
    , m_slideList()
89
4.21k
    , m_masterSlideIdToNameMap()
90
4.21k
    , m_idToMasterIdMap()
91
4.21k
    , m_idToSlideInfoMap()
92
4.21k
    , m_slideIdStack()
93
4.21k
    , m_colorListStack()
94
4.21k
  {
95
4.21k
  }
96
  //! add a slide
97
  void addSlide(PowerPoint7Struct::SlideId const &sId, PowerPoint7Struct::SlideId const &mId)
98
2.70k
  {
99
2.70k
    if (!sId.isValid())
100
37
      return;
101
2.66k
    if (sId.m_isMaster) {
102
236
      if (m_masterSlideIdToNameMap.find(sId)!=m_masterSlideIdToNameMap.end())
103
1
        return;
104
235
      std::stringstream s;
105
235
      s << "Master" << m_masterSlideIdToNameMap.size();
106
235
      m_masterSlideIdToNameMap[sId]=librevenge::RVNGString(s.str().c_str());
107
235
      return;
108
236
    }
109
2.42k
    m_slideList.push_back(sId);
110
2.42k
    if (mId.isValid())
111
2.41k
      m_idToMasterIdMap[sId]=mId;
112
2.42k
  }
113
  //! push a new slide id
114
  void pushSlideId(PowerPoint7Struct::SlideId const &id)
115
4.16k
  {
116
4.16k
    if (m_graphParser) m_graphParser->setSlideId(id);
117
4.16k
    m_slideIdStack.push(id);
118
4.16k
  }
119
  //! pop a slide id
120
  void popSlideId()
121
4.16k
  {
122
4.16k
    if (m_slideIdStack.empty()) {
123
0
      MWAW_DEBUG_MSG(("PowerPoint7ParserInternal::State::popSlideId: the stack is empty\n"));
124
0
      return;
125
0
    }
126
4.16k
    m_slideIdStack.pop();
127
4.16k
    if (m_graphParser)
128
4.16k
      m_graphParser->setSlideId(m_slideIdStack.empty() ? PowerPoint7Struct::SlideId() : m_slideIdStack.top());
129
4.16k
  }
130
  //! push a new slide id
131
  void pushColorList(std::vector<MWAWColor> const &colorList)
132
3.54k
  {
133
3.54k
    if (m_graphParser) m_graphParser->setColorList(colorList);
134
3.54k
    m_colorListStack.push(colorList);
135
3.54k
  }
136
  //! pop a slide id
137
  void popColorList()
138
3.54k
  {
139
3.54k
    if (m_colorListStack.empty()) {
140
0
      MWAW_DEBUG_MSG(("PowerPoint7ParserInternal::State::popSlideId: the stack is empty\n"));
141
0
      return;
142
0
    }
143
3.54k
    m_colorListStack.pop();
144
3.54k
    if (m_graphParser)
145
3.54k
      m_graphParser->setColorList(m_colorListStack.empty() ? std::vector<MWAWColor>() : m_colorListStack.top());
146
3.54k
  }
147
  //! the basic pc font family if known
148
  std::string m_fontFamily;
149
  //! the page dimension
150
  MWAWVec2i m_pageDimension;
151
  //! the graph parser
152
  std::shared_ptr<PowerPoint7Graph> m_graphParser;
153
  //! the text parser
154
  std::shared_ptr<PowerPoint7Text> m_textParser;
155
  //! the ole parser
156
  std::shared_ptr<PowerPoint3OLE> m_oleParser;
157
  //! the list of slides
158
  std::vector<PowerPoint7Struct::SlideId> m_slideList;
159
  //! the master slide
160
  std::map<PowerPoint7Struct::SlideId, librevenge::RVNGString> m_masterSlideIdToNameMap;
161
  //! the slideId to masterId slide
162
  std::map<PowerPoint7Struct::SlideId, PowerPoint7Struct::SlideId> m_idToMasterIdMap;
163
  //! the slideId to information slide
164
  std::map<PowerPoint7Struct::SlideId, SlideInfo> m_idToSlideInfoMap;
165
  //! a stack of slide id
166
  std::stack<PowerPoint7Struct::SlideId> m_slideIdStack;
167
  //! a stack of color list
168
  std::stack<std::vector<MWAWColor> > m_colorListStack;
169
};
170
171
}
172
173
////////////////////////////////////////////////////////////
174
// constructor/destructor, ...
175
////////////////////////////////////////////////////////////
176
PowerPoint7Parser::PowerPoint7Parser(MWAWInputStreamPtr const &input, MWAWRSRCParserPtr const &rsrcParser, MWAWHeader *header)
177
4.21k
  : MWAWPresentationParser(input, rsrcParser, header)
178
4.21k
  , m_state(new PowerPoint7ParserInternal::State)
179
4.21k
{
180
4.21k
  setAsciiName("main-1");
181
4.21k
  m_state->m_graphParser.reset(new PowerPoint7Graph(*this));
182
4.21k
  m_state->m_textParser.reset(new PowerPoint7Text(*this));
183
4.21k
}
184
185
PowerPoint7Parser::~PowerPoint7Parser()
186
4.21k
{
187
4.21k
}
188
189
bool PowerPoint7Parser::sendText(int textId)
190
1.67k
{
191
1.67k
  return m_state->m_textParser->sendText(textId);
192
1.67k
}
193
194
bool PowerPoint7Parser::getColor(int cId, MWAWColor &col) const
195
8.74k
{
196
8.74k
  if (m_state->m_colorListStack.empty() || cId<0 ||
197
8.68k
      cId>=int(m_state->m_colorListStack.top().size())) {
198
396
    MWAW_DEBUG_MSG(("PowerPoint7Parser::getColor: can not find color %d\n", cId));
199
396
    return false;
200
396
  }
201
8.35k
  col=m_state->m_colorListStack.top()[size_t(cId)];
202
8.35k
  return true;
203
8.74k
}
204
205
////////////////////////////////////////////////////////////
206
// the parser
207
////////////////////////////////////////////////////////////
208
void PowerPoint7Parser::parse(librevenge::RVNGPresentationInterface *docInterface)
209
1.18k
{
210
1.18k
  if (!getInput().get() || !checkHeader(nullptr))  throw(libmwaw::ParseException());
211
1.18k
  bool ok = true;
212
1.18k
  try {
213
1.18k
    ok = createZones();
214
1.18k
    if (ok) {
215
693
      createDocument(docInterface);
216
693
      sendSlides();
217
693
    }
218
219
#ifdef DEBUG
220
    if (m_state->m_oleParser)
221
      m_state->m_oleParser->checkForUnparsedStream();
222
    checkForUnparsedZones();
223
#endif
224
1.18k
    ascii().reset();
225
1.18k
  }
226
1.18k
  catch (...) {
227
7
    MWAW_DEBUG_MSG(("PowerPoint7Parser::parse: exception catched when parsing\n"));
228
7
    ok = false;
229
7
  }
230
231
1.18k
  resetPresentationListener();
232
1.18k
  if (!ok) throw(libmwaw::ParseException());
233
1.18k
}
234
235
////////////////////////////////////////////////////////////
236
// create the document
237
////////////////////////////////////////////////////////////
238
void PowerPoint7Parser::createDocument(librevenge::RVNGPresentationInterface *documentInterface)
239
693
{
240
693
  if (!documentInterface) return;
241
693
  if (getPresentationListener()) {
242
0
    MWAW_DEBUG_MSG(("PowerPoint7Parser::createDocument: listener already exist\n"));
243
0
    return;
244
0
  }
245
246
693
  std::vector<MWAWPageSpan> pageList;
247
2.42k
  for (auto const &id : m_state->m_slideList) {
248
2.42k
    if (!id.isValid()) continue;
249
2.42k
    MWAWPageSpan ps(getPageSpan());
250
2.42k
    bool showMaster=true;
251
2.42k
    if (m_state->m_idToSlideInfoMap.find(id)!=m_state->m_idToSlideInfoMap.end())
252
2.37k
      showMaster=m_state->m_idToSlideInfoMap.find(id)->second.m_displayMaster;
253
2.42k
    if (showMaster && m_state->m_idToMasterIdMap.find(id)!=m_state->m_idToMasterIdMap.end()) {
254
1.99k
      PowerPoint7Struct::SlideId mId=m_state->m_idToMasterIdMap.find(id)->second;
255
1.99k
      if (m_state->m_masterSlideIdToNameMap.find(mId)!=m_state->m_masterSlideIdToNameMap.end())
256
799
        ps.setMasterPageName(m_state->m_masterSlideIdToNameMap.find(mId)->second);
257
1.99k
    }
258
2.42k
    pageList.push_back(ps);
259
2.42k
  }
260
261
  //
262
693
  MWAWPresentationListenerPtr listen(new MWAWPresentationListener(*getParserState(), pageList, documentInterface));
263
693
  setPresentationListener(listen);
264
693
  if (m_state->m_oleParser) {
265
693
    librevenge::RVNGPropertyList metaData;
266
693
    m_state->m_oleParser->updateMetaData(metaData);
267
693
    listen->setDocumentMetaData(metaData);
268
693
  }
269
693
  listen->startDocument();
270
693
}
271
272
273
////////////////////////////////////////////////////////////
274
// Intermediate level
275
////////////////////////////////////////////////////////////
276
277
// create the different zones
278
bool PowerPoint7Parser::createZones()
279
1.18k
{
280
1.18k
  MWAWInputStreamPtr input=getInput();
281
1.18k
  if (!input || !input->isStructured()) {
282
0
    MWAW_DEBUG_MSG(("PowerPoint7Parser::createZones: can not find the main input\n"));
283
0
    return false;
284
0
  }
285
286
1.18k
  MWAWInputStreamPtr mainOle=input->getSubStreamByName("PowerPoint Document");
287
1.18k
  if (!mainOle) {
288
0
    MWAW_DEBUG_MSG(("PowerPoint7Parser::createZones: can not find the main ole\n"));
289
0
    return false;
290
0
  }
291
1.18k
  int fId=getFontConverter()->getId("CP1252");
292
1.18k
  m_state->m_oleParser.reset(new PowerPoint3OLE(input, version(), getFontConverter(), fId));
293
1.18k
  m_state->m_oleParser->parse();
294
1.18k
  int encoding=m_state->m_oleParser->getFontEncoding();
295
1.18k
  if (encoding>=1250 && encoding<=1258) {
296
123
    std::stringstream s;
297
123
    s << "CP" << encoding;
298
123
    m_state->m_fontFamily=s.str();
299
123
    m_state->m_textParser->setFontFamily(m_state->m_fontFamily);
300
123
  }
301
1.18k
  parseTextContent(input->getSubStreamByName("Text_Content"));
302
1.18k
  getParserState()->m_input=input=mainOle;
303
1.18k
  input->setReadInverted(true);
304
305
  // create the asciiFile
306
1.18k
  ascii().setStream(input);
307
1.18k
  ascii().open(asciiName());
308
309
1.18k
  input->seek(0, librevenge::RVNG_SEEK_SET);
310
1.18k
  if (!readDocRoot())
311
0
    return false;
312
1.18k
  if (!input->isEnd()) {
313
16
    MWAW_DEBUG_MSG(("PowerPoint7Parser::createZones: find extra data\n"));
314
16
    ascii().addPos(input->tell());
315
16
    ascii().addNote("Entries(Extra):###");
316
16
  }
317
1.18k
  return !m_state->m_slideList.empty();
318
1.18k
}
319
320
bool PowerPoint7Parser::readDocRoot()
321
1.18k
{
322
1.18k
  MWAWInputStreamPtr input=getInput();
323
1.18k
  long pos=input->tell();
324
1.18k
  long lastPos=input->size();
325
326
1.18k
  libmwaw::DebugStream f;
327
1.18k
  PowerPoint7Struct::Zone header;
328
1.18k
  if (!header.read(input,lastPos) || header.m_type!=3) {
329
0
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readDocRoot: can not find the main zone header\n"));
330
0
    input->seek(pos, librevenge::RVNG_SEEK_SET);
331
0
    return false;
332
0
  }
333
1.18k
  f << "Entries(Root):" << header;
334
1.18k
  ascii().addPos(pos);
335
1.18k
  ascii().addNote(f.str().c_str());
336
337
1.18k
  long endPos=pos+16+header.m_dataSize;
338
2.91k
  while (input->tell()<endPos) {
339
2.78k
    pos=input->tell();
340
2.78k
    auto cType=int(input->readULong(2)); //3e8 followed by a
341
2.78k
    input->seek(pos, librevenge::RVNG_SEEK_SET);
342
343
2.78k
    bool done=false;
344
2.78k
    switch (cType) {
345
136
    case 0xa:
346
136
      done=readMainSub10(endPos);
347
136
      break;
348
1.18k
    case 1000:
349
1.18k
      done=readDocument(endPos);
350
1.18k
      break;
351
1.46k
    default:
352
1.46k
      done=readZone(1,endPos);
353
1.46k
      if (done) {
354
424
        MWAW_DEBUG_MSG(("PowerPoint7Parser::readDocRoot: find unexpected zone %d\n", cType));
355
424
      }
356
1.46k
      break;
357
2.78k
    }
358
2.78k
    if (done) continue;
359
1.05k
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readDocRoot: can not read some data\n"));
360
1.05k
    ascii().addPos(pos);
361
1.05k
    ascii().addNote("Root:###extra");
362
1.05k
    input->seek(endPos, librevenge::RVNG_SEEK_SET);
363
1.05k
    break;
364
2.78k
  }
365
1.18k
  return true;
366
1.18k
}
367
368
bool PowerPoint7Parser::readMainSub10(long lastPos)
369
136
{
370
136
  MWAWInputStreamPtr input=getInput();
371
136
  long pos=input->tell();
372
373
136
  libmwaw::DebugStream f;
374
136
  PowerPoint7Struct::Zone header;
375
136
  if (!header.read(input,lastPos) || header.m_type!=10) {
376
3
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readMainSub10: can not find the zone header\n"));
377
3
    input->seek(pos, librevenge::RVNG_SEEK_SET);
378
3
    return false;
379
3
  }
380
133
  f << "Entries(MSub10):" << header;
381
133
  if (header.m_dataSize!=8) {
382
3
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readMainSub10: find unexpected data size\n"));
383
3
    f << "###dataSz=" << header.m_dataSize << ",";
384
3
    if (header.m_dataSize)
385
0
      ascii().addDelimiter(pos+16,'|');
386
3
    input->seek(header.m_dataSize, librevenge::RVNG_SEEK_CUR);
387
3
  }
388
130
  else {
389
130
    int val;
390
390
    for (int i=0; i<2; ++i) {
391
260
      val=int(input->readULong(2));
392
260
      if (val!=1-i) f << "f" << i << "=" << val << ",";
393
260
    }
394
130
    val=int(input->readULong(4)); // 100|11c|123
395
130
    if (val!=0x100) f << "unk=" << std::hex << val << std::dec << ",";
396
130
  }
397
133
  ascii().addPos(pos);
398
133
  ascii().addNote(f.str().c_str());
399
133
  return true;
400
136
}
401
402
bool PowerPoint7Parser::readDocument(long lastPos)
403
1.18k
{
404
1.18k
  MWAWInputStreamPtr input=getInput();
405
1.18k
  long pos=input->tell();
406
407
1.18k
  libmwaw::DebugStream f;
408
1.18k
  PowerPoint7Struct::Zone header;
409
1.18k
  if (!header.read(input,lastPos) || header.m_type!=1000) {
410
10
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readDocument: can not find the zone header\n"));
411
10
    input->seek(pos, librevenge::RVNG_SEEK_SET);
412
10
    return false;
413
10
  }
414
1.17k
  f << "Entries(DocMain):" << header;
415
1.17k
  ascii().addPos(pos);
416
1.17k
  ascii().addNote(f.str().c_str());
417
418
1.17k
  long endPos=pos+16+header.m_dataSize;
419
18.2k
  while (input->tell()<endPos) {
420
18.1k
    pos=input->tell();
421
18.1k
    auto cType=int(input->readULong(2));
422
18.1k
    input->seek(pos, librevenge::RVNG_SEEK_SET);
423
424
18.1k
    bool done=false;
425
18.1k
    switch (cType) {
426
1.16k
    case 1001:
427
1.16k
      done=readDocAtom(1,endPos);
428
1.16k
      break;
429
98
    case 1002:
430
98
      done=readZoneNoData(1,endPos,"DocMain","end");
431
98
      break;
432
713
    case 1008:
433
713
      done=readNotes(1,endPos);
434
713
      break;
435
1.09k
    case 1010:
436
1.09k
      done=readEnvironment(1,endPos);
437
1.09k
      break;
438
2
    case 1025:
439
2
      done=readSSDocInfoAtom(1,endPos);
440
2
      break;
441
109
    case 1026:
442
109
      done=readSummary(1,endPos);
443
109
      break;
444
1.08k
    case 2000:
445
1.08k
      done=readContainerList(1,endPos);
446
1.08k
      break;
447
11
    case 4041:
448
11
      done=readHandout(1,endPos);
449
11
      break;
450
13.8k
    default:
451
13.8k
      done=readZone(1,endPos);
452
13.8k
      if (done) {
453
12.8k
        MWAW_DEBUG_MSG(("PowerPoint7Parser::readDocument: find unexpected zone %d\n", cType));
454
12.8k
      }
455
13.8k
      break;
456
18.1k
    }
457
18.1k
    if (done) continue;
458
1.07k
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readDocument: can not read some data\n"));
459
1.07k
    ascii().addPos(pos);
460
1.07k
    ascii().addNote("DocMain:###extra");
461
1.07k
    input->seek(endPos, librevenge::RVNG_SEEK_SET);
462
1.07k
    break;
463
18.1k
  }
464
1.17k
  return true;
465
1.17k
}
466
467
bool PowerPoint7Parser::readDocAtom(int level, long lastPos)
468
1.16k
{
469
1.16k
  MWAWInputStreamPtr input=getInput();
470
1.16k
  long pos=input->tell();
471
472
1.16k
  libmwaw::DebugStream f;
473
1.16k
  PowerPoint7Struct::Zone header;
474
1.16k
  if (!header.read(input,lastPos) || header.m_type!=1001) {
475
2
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readDocAtom: can not find the zone header\n"));
476
2
    input->seek(pos, librevenge::RVNG_SEEK_SET);
477
2
    return false;
478
2
  }
479
1.16k
  f << "Entries(DocMain)[atom," << level << "]:" << header;
480
1.16k
  if (header.m_dataSize!=0x2c) {
481
61
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readDocAtom: find unexpected data size\n"));
482
61
    f << "###dataSz=" << header.m_dataSize << ",";
483
61
    if (header.m_dataSize)
484
2
      ascii().addDelimiter(pos+16,'|');
485
61
    input->seek(header.m_dataSize, librevenge::RVNG_SEEK_CUR);
486
61
  }
487
1.10k
  else {
488
1.10k
    int val;
489
3.30k
    for (int i=0; i<2; ++i) {
490
2.20k
      int dim[2];
491
4.40k
      for (auto &d : dim) d=int(input->readLong(4));
492
2.20k
      MWAWVec2i size(dim[0],dim[1]);
493
2.20k
      if (i==0 && dim[0]>0 && dim[1]>0) {
494
1.09k
        m_state->m_pageDimension=size;
495
1.09k
        m_state->m_graphParser->setPageSize(size);
496
497
1.09k
        getPageSpan().setFormLength(double(size.y())/576.0);
498
1.09k
        getPageSpan().setFormWidth(double(size.x())/576.0);
499
1.09k
      }
500
2.20k
      char const *wh[]= {"page","paper"};
501
2.20k
      f << "dim[" << wh[i] << "]=" << size << ",";
502
2.20k
    }
503
3.30k
    for (int i=0; i<2; ++i) { // f0=0|1, f1=1
504
2.20k
      val=int(input->readULong(2));
505
2.20k
      if (val)
506
1.93k
        f << "f" << i << "=" << val << ",";
507
2.20k
    }
508
1.10k
    f << "ids=[";
509
3.30k
    for (int i=0; i<2; ++i)
510
2.20k
      f << std::hex << input->readULong(4) << std::dec << ",";
511
1.10k
    f << "],";
512
8.80k
    for (int i=0; i<7; ++i) { // f2=db00|e[34]00, f3,f5,f7 small number
513
7.70k
      val=int(input->readULong(2));
514
7.70k
      if (val)
515
4.24k
        f << "f" << i+2 << "=" << val << ",";
516
7.70k
    }
517
1.10k
    input->seek(pos+16+header.m_dataSize, librevenge::RVNG_SEEK_SET);
518
1.10k
  }
519
1.16k
  ascii().addPos(pos);
520
1.16k
  ascii().addNote(f.str().c_str());
521
1.16k
  return true;
522
1.16k
}
523
524
bool PowerPoint7Parser::readSlideInformation(int level, long lastPos)
525
4.26k
{
526
4.26k
  MWAWInputStreamPtr input=getInput();
527
4.26k
  long pos=input->tell();
528
529
4.26k
  libmwaw::DebugStream f;
530
4.26k
  PowerPoint7Struct::Zone header;
531
4.26k
  if (!header.read(input,lastPos) || header.m_type!=1005) {
532
69
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readSlideInformation: can not find the zone header\n"));
533
69
    input->seek(pos, librevenge::RVNG_SEEK_SET);
534
69
    return false;
535
69
  }
536
4.19k
  f << "Entries(SlideInfo)[" << level << "]:" << header;
537
4.19k
  if (header.m_dataSize!=0x18) {
538
69
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readSlideInformation: find unexpected data size\n"));
539
69
    f << "###dataSz=" << header.m_dataSize << ",";
540
69
    if (header.m_dataSize)
541
49
      ascii().addDelimiter(pos+16,'|');
542
69
    input->seek(header.m_dataSize, librevenge::RVNG_SEEK_CUR);
543
69
    ascii().addPos(pos);
544
69
    ascii().addNote(f.str().c_str());
545
69
    return true;
546
69
  }
547
4.13k
  PowerPoint7ParserInternal::SlideInfo info;
548
4.13k
  int dim[4];
549
16.5k
  for (auto &d : dim) d=int(input->readLong(4));
550
4.13k
  info.m_box=MWAWBox2i(MWAWVec2i(dim[0],dim[1]),MWAWVec2i(dim[2],dim[3]));
551
4.13k
  f << "box=" << info.m_box << ",";
552
4.13k
  int val;
553
12.3k
  for (int i=0; i<2; ++i) { // always 1,1
554
8.26k
    val=int(input->readLong(1));
555
8.26k
    if (val==1) continue;
556
1.35k
    if (i==0) {
557
644
      if (val==0) {
558
474
        info.m_displayMaster=false;
559
474
        f << "omit[graphic,master],";
560
474
      }
561
170
      else
562
170
        f << "###omit[graphic,master]=" << val << ",";
563
644
    }
564
712
    else
565
712
      f << "fl" << i << "=" << val << ",";
566
1.35k
  }
567
4.13k
  val=int(input->readLong(2)); // 0
568
4.13k
  if (val) f << "f0=" << val << ",";
569
4.13k
  val=int(input->readULong(1));
570
4.13k
  if (val==0) {
571
871
    info.m_hasBackground=true;
572
871
    f << "has[background],";
573
871
  }
574
3.25k
  else if (val!=1)
575
17
    f << "##has[background]=" << val << ",";
576
16.5k
  for (int i=0; i<3; ++i) { //  fl2=0-e3, fl3=0|8|9|62|b7,fl4=0|50
577
12.3k
    val=int(input->readULong(1));
578
12.3k
    if (val) f << "fl" << i+2 << "=" << std::hex << val << std::dec << ",";
579
12.3k
  }
580
4.13k
  if (m_state->m_slideIdStack.empty() ||
581
3.98k
      m_state->m_idToSlideInfoMap.find(m_state->m_slideIdStack.top())!=m_state->m_idToSlideInfoMap.end()) {
582
461
    f << "###noSave,";
583
461
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readSlideInformation: can not save the information\n"));
584
461
  }
585
3.66k
  else
586
3.66k
    m_state->m_idToSlideInfoMap[m_state->m_slideIdStack.top()]=info;
587
4.13k
  input->seek(pos+16+header.m_dataSize, librevenge::RVNG_SEEK_SET);
588
4.13k
  ascii().addPos(pos);
589
4.13k
  ascii().addNote(f.str().c_str());
590
4.13k
  return true;
591
4.19k
}
592
593
bool PowerPoint7Parser::readSlides(int level, long lastPos, bool master)
594
2.78k
{
595
2.78k
  MWAWInputStreamPtr input=getInput();
596
2.78k
  long pos=input->tell();
597
598
2.78k
  libmwaw::DebugStream f;
599
2.78k
  PowerPoint7Struct::Zone header;
600
2.78k
  int const expectedType=master ? 1016 : 1006;
601
2.78k
  if (!header.read(input,lastPos) || header.m_type!=expectedType) {
602
8
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readSlides: can not find the zone header\n"));
603
8
    input->seek(pos, librevenge::RVNG_SEEK_SET);
604
8
    return false;
605
8
  }
606
2.78k
  f << "Entries(SlideContent)[" << level << "]:" << header;
607
2.78k
  if (master) f << "master,";
608
2.78k
  ascii().addPos(pos);
609
2.78k
  ascii().addNote(f.str().c_str());
610
611
2.78k
  long endPos=pos+16+header.m_dataSize;
612
2.78k
  bool pushSlideId=false, pushColor=false;
613
24.4k
  while (input->tell()<endPos) {
614
22.1k
    pos=input->tell();
615
22.1k
    auto cType=int(input->readULong(2));
616
22.1k
    input->seek(pos, librevenge::RVNG_SEEK_SET);
617
618
22.1k
    bool done=false;
619
22.1k
    switch (cType) {
620
2.65k
    case 1005:
621
2.65k
      done=readSlideInformation(level+1,endPos);
622
2.65k
      break;
623
2.72k
    case 1007: {
624
2.72k
      PowerPoint7Struct::SlideId sId, mId;
625
2.72k
      done=readSlideAtom(level+1,endPos, sId, mId);
626
2.72k
      if (done && !pushSlideId) {
627
2.70k
        pushSlideId=true;
628
2.70k
        m_state->addSlide(sId,mId);
629
2.70k
        m_state->pushSlideId(sId);
630
2.70k
      }
631
2.72k
      break;
632
0
    }
633
1.07k
    case 1008:
634
1.07k
      done=readNotes(level+1,endPos);
635
1.07k
      break;
636
2.36k
    case 1012: {
637
2.36k
      std::vector<MWAWColor> colors;
638
2.36k
      done=readColorScheme(level+1,endPos,colors);
639
2.36k
      if (done && !pushColor) {
640
2.34k
        pushColor=true;
641
2.34k
        m_state->pushColorList(colors);
642
2.34k
      }
643
2.36k
      break;
644
0
    }
645
2.50k
    case 1015:
646
2.50k
      done=readZone1015(level+1,endPos);
647
2.50k
      break;
648
441
    case 1017:
649
441
      done=readSlideShowInfo(level+1,endPos);
650
441
      break;
651
1.37k
    case 2031: { // in master, the different color scheme are stored directly here
652
1.37k
      std::vector<MWAWColor> colors;
653
1.37k
      done=readColorList(level+1,endPos, colors);
654
1.37k
      break;
655
0
    }
656
2.35k
    case 3000:
657
2.35k
      done=readZone3000(level+1,endPos);
658
2.35k
      break;
659
2.38k
    case 3008:
660
2.38k
      done=m_state->m_graphParser->readRect(level+1,endPos);
661
2.38k
      break;
662
217
    case 4026: {
663
217
      std::string string;
664
217
      int zId; // 140: template name(in master)
665
217
      done=readString(level+1,endPos, string, zId, "SlideContent");
666
217
      break;
667
0
    }
668
2.38k
    case 4057:
669
2.38k
      done=readHeaderFooters(level+1,endPos);
670
2.38k
      break;
671
1.70k
    default:
672
1.70k
      done=readZone(level+1,endPos);
673
1.70k
      if (done) {
674
1.35k
        MWAW_DEBUG_MSG(("PowerPoint7Parser::readSlides: find unexpected zone %d\n", cType));
675
1.35k
      }
676
1.70k
      break;
677
22.1k
    }
678
22.1k
    if (done) continue;
679
506
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readSlides: can not read some data\n"));
680
506
    ascii().addPos(pos);
681
506
    ascii().addNote("SlideContent:###extra");
682
506
    input->seek(endPos, librevenge::RVNG_SEEK_SET);
683
506
    break;
684
22.1k
  }
685
2.78k
  if (pushColor)
686
2.34k
    m_state->popColorList();
687
2.78k
  if (pushSlideId)
688
2.70k
    m_state->popSlideId();
689
2.78k
  return true;
690
2.78k
}
691
692
bool PowerPoint7Parser::readSlideAtom(int level, long lastPos, PowerPoint7Struct::SlideId &sId, PowerPoint7Struct::SlideId &mId)
693
2.72k
{
694
2.72k
  MWAWInputStreamPtr input=getInput();
695
2.72k
  long pos=input->tell();
696
697
2.72k
  libmwaw::DebugStream f;
698
2.72k
  PowerPoint7Struct::Zone header;
699
2.72k
  if (!header.read(input,lastPos) || header.m_type!=1007) {
700
21
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readSlideAtom: can not find the zone header\n"));
701
21
    input->seek(pos, librevenge::RVNG_SEEK_SET);
702
21
    return false;
703
21
  }
704
2.70k
  f << "Entries(SlideContent)[atom," << level << "]:" << header;
705
2.70k
  if (header.m_dataSize!=8) {
706
22
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readSlideAtom: find unexpected data size\n"));
707
22
    f << "###dataSz=" << header.m_dataSize << ",";
708
22
    if (header.m_dataSize)
709
8
      ascii().addDelimiter(pos+16,'|');
710
22
    input->seek(header.m_dataSize, librevenge::RVNG_SEEK_CUR);
711
22
  }
712
2.67k
  else {
713
8.03k
    for (int i=0; i<2; ++i) {
714
5.35k
      PowerPoint7Struct::SlideId id(input->readULong(4));
715
5.35k
      if (!id.isValid()) continue;
716
5.11k
      if (i==0) {
717
2.66k
        sId=id;
718
2.66k
        f << id << ",";
719
2.66k
      }
720
2.44k
      else {
721
2.44k
        mId=id;
722
2.44k
        f << "master=" << id << ",";
723
2.44k
      }
724
5.11k
    }
725
2.67k
  }
726
2.70k
  ascii().addPos(pos);
727
2.70k
  ascii().addNote(f.str().c_str());
728
2.70k
  return true;
729
2.72k
}
730
731
bool PowerPoint7Parser::readNotes(int level, long lastPos)
732
1.78k
{
733
1.78k
  MWAWInputStreamPtr input=getInput();
734
1.78k
  long pos=input->tell();
735
736
1.78k
  libmwaw::DebugStream f;
737
1.78k
  PowerPoint7Struct::Zone header;
738
1.78k
  if (!header.read(input,lastPos) || header.m_type!=1008) {
739
39
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readNotes: can not find the zone header\n"));
740
39
    input->seek(pos, librevenge::RVNG_SEEK_SET);
741
39
    return false;
742
39
  }
743
1.74k
  f << "Entries(Note)[" << level << "]:" << header;
744
1.74k
  ascii().addPos(pos);
745
1.74k
  ascii().addNote(f.str().c_str());
746
747
1.74k
  long endPos=pos+16+header.m_dataSize;
748
1.74k
  bool pushSlideId=false, pushColor=false;
749
12.2k
  while (input->tell()<endPos) {
750
11.1k
    pos=input->tell();
751
11.1k
    auto cType=int(input->readULong(2));
752
11.1k
    input->seek(pos, librevenge::RVNG_SEEK_SET);
753
754
11.1k
    bool done=false;
755
11.1k
    switch (cType) {
756
1.60k
    case 1005:
757
1.60k
      done=readSlideInformation(level+1,endPos);
758
1.60k
      break;
759
1.73k
    case 1009: {
760
1.73k
      PowerPoint7Struct::SlideId sId;
761
1.73k
      done=readNoteAtom(level+1,endPos, sId);
762
1.73k
      if (done && !pushSlideId) {
763
1.45k
        pushSlideId=true;
764
1.45k
        m_state->pushSlideId(sId);
765
1.45k
      }
766
1.73k
      break;
767
0
    }
768
1.21k
    case 1012: {
769
1.21k
      std::vector<MWAWColor> colors;
770
1.21k
      done=readColorScheme(level+1,endPos,colors);
771
1.21k
      if (done && !pushColor) {
772
1.19k
        pushColor=true;
773
1.19k
        m_state->pushColorList(colors);
774
1.19k
      }
775
1.21k
      break;
776
0
    }
777
1.10k
    case 3000:
778
1.10k
      done=readZone3000(level+1,endPos);
779
1.10k
      break;
780
1.10k
    case 3008:
781
1.10k
      done=m_state->m_graphParser->readRect(level+1,endPos);
782
1.10k
      break;
783
1.46k
    case 4057:
784
1.46k
      done=readHeaderFooters(level+1,endPos);
785
1.46k
      break;
786
2.92k
    default:
787
2.92k
      done=readZone(level+1,endPos);
788
2.92k
      if (done) {
789
2.55k
        MWAW_DEBUG_MSG(("PowerPoint7Parser::readNotes: find unexpected zone %d\n", cType));
790
2.55k
      }
791
2.92k
      break;
792
11.1k
    }
793
11.1k
    if (done) continue;
794
658
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readNotes: can not read some data\n"));
795
658
    ascii().addPos(pos);
796
658
    ascii().addNote("Note:###extra");
797
658
    input->seek(endPos, librevenge::RVNG_SEEK_SET);
798
658
    break;
799
11.1k
  }
800
1.74k
  if (pushColor)
801
1.19k
    m_state->popColorList();
802
1.74k
  if (pushSlideId)
803
1.45k
    m_state->popSlideId();
804
1.74k
  return true;
805
1.74k
}
806
807
bool PowerPoint7Parser::readNoteAtom(int level, long lastPos, PowerPoint7Struct::SlideId &sId)
808
1.73k
{
809
1.73k
  MWAWInputStreamPtr input=getInput();
810
1.73k
  long pos=input->tell();
811
812
1.73k
  libmwaw::DebugStream f;
813
1.73k
  PowerPoint7Struct::Zone header;
814
1.73k
  if (!header.read(input,lastPos) || header.m_type!=1009) {
815
87
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readNoteAtom: can not find the zone header\n"));
816
87
    input->seek(pos, librevenge::RVNG_SEEK_SET);
817
87
    return false;
818
87
  }
819
1.65k
  f << "Entries(Note)[atom" << level << "]:" << header;
820
1.65k
  if (header.m_dataSize!=4) {
821
271
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readNoteAtom: find unexpected data size\n"));
822
271
    f << "###dataSz=" << header.m_dataSize << ",";
823
271
    if (header.m_dataSize)
824
40
      ascii().addDelimiter(pos+16,'|');
825
271
    input->seek(header.m_dataSize, librevenge::RVNG_SEEK_CUR);
826
271
  }
827
1.38k
  else {
828
1.38k
    sId=PowerPoint7Struct::SlideId(input->readULong(4));
829
1.38k
    sId.m_inNotes=true;
830
1.38k
    if (sId.isValid())
831
1.38k
      f << sId << ",";
832
1.38k
  }
833
1.65k
  ascii().addPos(pos);
834
1.65k
  ascii().addNote(f.str().c_str());
835
1.65k
  return true;
836
1.73k
}
837
838
bool PowerPoint7Parser::readEnvironment(int level, long lastPos)
839
1.09k
{
840
1.09k
  MWAWInputStreamPtr input=getInput();
841
1.09k
  long pos=input->tell();
842
843
1.09k
  libmwaw::DebugStream f;
844
1.09k
  PowerPoint7Struct::Zone header;
845
1.09k
  if (!header.read(input,lastPos) || header.m_type!=1010) {
846
3
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readEnvironment: can not find the zone header\n"));
847
3
    input->seek(pos, librevenge::RVNG_SEEK_SET);
848
3
    return false;
849
3
  }
850
1.08k
  f << "Entries(EnvironList)[" << level << "]:" << header;
851
1.08k
  ascii().addPos(pos);
852
1.08k
  ascii().addNote(f.str().c_str());
853
854
1.08k
  long endPos=pos+16+header.m_dataSize;
855
24.9k
  while (input->tell()<endPos) {
856
24.5k
    pos=input->tell();
857
24.5k
    auto cType=int(input->readULong(2));
858
24.5k
    input->seek(pos, librevenge::RVNG_SEEK_SET);
859
860
24.5k
    bool done=false;
861
24.5k
    switch (cType) {
862
399
    case 1028:
863
399
      done=readZone1028(level+1,endPos);
864
399
      break;
865
1.06k
    case 2005: // FontCollection
866
1.06k
      done=m_state->m_textParser->readFontCollection(level+1,endPos);
867
1.06k
      break;
868
890
    case 2006:
869
890
      done=m_state->m_graphParser->readPictureList(level+1,endPos);
870
890
      break;
871
269
    case 2020: // SoundCollection
872
269
      done=readSoundCollection(level+1,endPos);
873
269
      break;
874
1.04k
    case 2027:
875
1.04k
      done=m_state->m_textParser->readFieldList(level+1,endPos);
876
1.04k
      break;
877
409
    case 2031: { // basic font color?
878
409
      std::vector<MWAWColor> colors;
879
409
      done=readColorList(level+1,endPos, colors);
880
409
      break;
881
0
    }
882
350
    case 3012:
883
350
      done=readZone3012(level+1,endPos);
884
350
      break;
885
774
    case 4016:
886
774
      done=m_state->m_textParser->readRulerList(level+1,endPos);
887
774
      break;
888
1.04k
    case 4040:
889
1.04k
      done=readKinsoku(level+1,endPos);
890
1.04k
      break;
891
18.3k
    default:
892
18.3k
      done=readZone(level+1,endPos);
893
18.3k
      if (done) {
894
17.7k
        MWAW_DEBUG_MSG(("PowerPoint7Parser::readEnvironment: find unexpected zone %d\n", cType));
895
17.7k
      }
896
18.3k
      break;
897
24.5k
    }
898
24.5k
    if (done) continue;
899
717
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readEnvironment: can not read some data\n"));
900
717
    ascii().addPos(pos);
901
717
    ascii().addNote("EnvironList:###extra");
902
717
    input->seek(endPos, librevenge::RVNG_SEEK_SET);
903
717
    break;
904
24.5k
  }
905
1.08k
  return true;
906
1.08k
}
907
908
bool PowerPoint7Parser::readColorScheme(int level, long lastPos, std::vector<MWAWColor> &colors)
909
3.57k
{
910
3.57k
  MWAWInputStreamPtr input=getInput();
911
3.57k
  long pos=input->tell();
912
913
3.57k
  libmwaw::DebugStream f;
914
3.57k
  PowerPoint7Struct::Zone header;
915
3.57k
  if (!header.read(input,lastPos) || header.m_type!=1012) {
916
20
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readColorScheme: can not find the zone header\n"));
917
20
    input->seek(pos, librevenge::RVNG_SEEK_SET);
918
20
    return false;
919
20
  }
920
3.55k
  f << "Entries(ColorScheme)[" << level << "]:" << header;
921
3.55k
  ascii().addPos(pos);
922
3.55k
  ascii().addNote(f.str().c_str());
923
924
3.55k
  long endPos=pos+16+header.m_dataSize;
925
7.00k
  while (input->tell()<endPos) {
926
3.65k
    pos=input->tell();
927
3.65k
    auto cType=int(input->readULong(2));
928
3.65k
    input->seek(pos, librevenge::RVNG_SEEK_SET);
929
930
3.65k
    bool done=false;
931
3.65k
    switch (cType) {
932
3.53k
    case 2031:
933
3.53k
      done=readColorList(level+1,endPos, colors);
934
3.53k
      break;
935
126
    default:
936
126
      done=readZone(level+1,endPos);
937
126
      if (done) {
938
45
        MWAW_DEBUG_MSG(("PowerPoint7Parser::readColorScheme: find unexpected zone %d\n", cType));
939
45
      }
940
126
      break;
941
3.65k
    }
942
3.65k
    if (done) continue;
943
200
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readColorScheme: can not read some data\n"));
944
200
    ascii().addPos(pos);
945
200
    ascii().addNote("ColorScheme:###extra");
946
200
    input->seek(endPos, librevenge::RVNG_SEEK_SET);
947
200
    break;
948
3.65k
  }
949
3.55k
  return true;
950
3.55k
}
951
952
bool PowerPoint7Parser::readZone1015(int level, long lastPos)
953
2.50k
{
954
2.50k
  MWAWInputStreamPtr input=getInput();
955
2.50k
  long pos=input->tell();
956
957
2.50k
  libmwaw::DebugStream f;
958
2.50k
  PowerPoint7Struct::Zone header;
959
2.50k
  if (!header.read(input,lastPos) || header.m_type!=1015) {
960
4
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readZone1015: can not find the zone header\n"));
961
4
    input->seek(pos, librevenge::RVNG_SEEK_SET);
962
4
    return false;
963
4
  }
964
2.50k
  f << "Entries(Zone1015B)[" << level << "]:" << header;
965
2.50k
  if (header.m_dataSize!=12) {
966
9
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readZone1015: find unexpected data size\n"));
967
9
    f << "###dataSz=" << header.m_dataSize << ",";
968
9
    if (header.m_dataSize)
969
2
      ascii().addDelimiter(pos+16,'|');
970
9
    input->seek(header.m_dataSize, librevenge::RVNG_SEEK_CUR);
971
9
  }
972
2.49k
  else {
973
2.49k
    int val;
974
7.47k
    for (int i=0; i<2; ++i) { // f0=1|10
975
4.98k
      val=int(input->readULong(2));
976
4.98k
      if (val) f << "f" << i << "=" << val << ",";
977
4.98k
    }
978
12.4k
    for (int i=0; i<4; ++i) { // small number
979
9.96k
      val=int(input->readULong(1));
980
9.96k
      if (val) f << "f" << i+2 << "=" << val << ",";
981
9.96k
    }
982
7.47k
    for (int i=0; i<2; ++i) { // f6=0|7
983
4.98k
      val=int(input->readULong(2));
984
4.98k
      if (val) f << "f" << i+6 << "=" << val << ",";
985
4.98k
    }
986
2.49k
  }
987
2.50k
  ascii().addPos(pos);
988
2.50k
  ascii().addNote(f.str().c_str());
989
2.50k
  return true;
990
2.50k
}
991
992
bool PowerPoint7Parser::readSlideShowInfo(int level, long lastPos)
993
441
{
994
441
  MWAWInputStreamPtr input=getInput();
995
441
  long pos=input->tell();
996
997
441
  libmwaw::DebugStream f;
998
441
  PowerPoint7Struct::Zone header;
999
441
  if (!header.read(input,lastPos) || header.m_type!=1017) {
1000
79
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readSlideShowInfo: can not find the zone header\n"));
1001
79
    input->seek(pos, librevenge::RVNG_SEEK_SET);
1002
79
    return false;
1003
79
  }
1004
362
  f << "Entries(SlideShowInfo)[" << level << "]:" << header;
1005
362
  if (header.m_dataSize!=24) {
1006
9
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readSlideShowInfo: find unexpected data size\n"));
1007
9
    f << "###dataSz=" << header.m_dataSize << ",";
1008
9
    if (header.m_dataSize)
1009
6
      ascii().addDelimiter(pos+16,'|');
1010
9
    input->seek(header.m_dataSize, librevenge::RVNG_SEEK_CUR);
1011
9
  }
1012
353
  else {
1013
2.47k
    for (int i=0; i<6; ++i) {
1014
2.11k
      auto val=int(input->readLong(4));
1015
2.11k
      int const expected[]= {0,2,2,0,1, -1};
1016
2.11k
      if (val!=expected[i])
1017
44
        f << "f" << i << "=" << val << ",";
1018
2.11k
    }
1019
353
  }
1020
362
  ascii().addPos(pos);
1021
362
  ascii().addNote(f.str().c_str());
1022
362
  return true;
1023
441
}
1024
1025
bool PowerPoint7Parser::readSlideViewInfo(int level, long lastPos)
1026
230
{
1027
230
  MWAWInputStreamPtr input=getInput();
1028
230
  long pos=input->tell();
1029
1030
230
  libmwaw::DebugStream f;
1031
230
  PowerPoint7Struct::Zone header;
1032
230
  if (!header.read(input,lastPos) || header.m_type!=1018) {
1033
2
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readSlideViewInfo: can not find the zone header\n"));
1034
2
    input->seek(pos, librevenge::RVNG_SEEK_SET);
1035
2
    return false;
1036
2
  }
1037
228
  f << "Entries(SlideViewInfo)[list," << level << "]:" << header;
1038
228
  ascii().addPos(pos);
1039
228
  ascii().addNote(f.str().c_str());
1040
1041
228
  long endPos=pos+16+header.m_dataSize;
1042
887
  while (input->tell()<endPos) {
1043
676
    pos=input->tell();
1044
676
    auto cType=int(input->readULong(2));
1045
676
    input->seek(pos, librevenge::RVNG_SEEK_SET);
1046
1047
676
    bool done=false;
1048
676
    switch (cType) {
1049
202
    case 1021:
1050
202
      done=readViewInfoAtom(level+1,endPos);
1051
202
      break;
1052
208
    case 1022:
1053
208
      done=readSlideViewInfoAtom(level+1,endPos);
1054
208
      break;
1055
207
    case 2026:
1056
207
      done=readZone2026(level+1,endPos);
1057
207
      break;
1058
59
    default:
1059
59
      done=readZone(level+1,endPos);
1060
59
      if (done) {
1061
45
        MWAW_DEBUG_MSG(("PowerPoint7Parser::readSlideViewInfo: find unexpected zone %d\n", cType));
1062
45
      }
1063
59
      break;
1064
676
    }
1065
676
    if (done) continue;
1066
17
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readSlideViewInfo: can not read some data\n"));
1067
17
    ascii().addPos(pos);
1068
17
    ascii().addNote("SlideViewInfo:###extra");
1069
17
    input->seek(endPos, librevenge::RVNG_SEEK_SET);
1070
17
    break;
1071
676
  }
1072
228
  return true;
1073
228
}
1074
1075
bool PowerPoint7Parser::readGuideAtom(int level, long lastPos)
1076
403
{
1077
403
  MWAWInputStreamPtr input=getInput();
1078
403
  long pos=input->tell();
1079
1080
403
  libmwaw::DebugStream f;
1081
403
  PowerPoint7Struct::Zone header;
1082
403
  if (!header.read(input,lastPos) || header.m_type!=1019) {
1083
3
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readGuideAtom: can not find the zone header\n"));
1084
3
    input->seek(pos, librevenge::RVNG_SEEK_SET);
1085
3
    return false;
1086
3
  }
1087
400
  f << "Entries(GuideAtom)[" << level << "]:" << header;
1088
400
  if (header.m_dataSize!=8) {
1089
0
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readGuideAtom: find unexpected data size\n"));
1090
0
    f << "###dataSz=" << header.m_dataSize << ",";
1091
0
    if (header.m_dataSize)
1092
0
      ascii().addDelimiter(pos+16,'|');
1093
0
    input->seek(header.m_dataSize, librevenge::RVNG_SEEK_CUR);
1094
0
  }
1095
400
  else {
1096
2.00k
    for (int i=0; i<4; ++i) { // f0=0|1
1097
1.60k
      auto val=int(input->readLong(2));
1098
1.60k
      if (val) f << "f" << i << "=" << val << ",";
1099
1.60k
    }
1100
400
  }
1101
400
  ascii().addPos(pos);
1102
400
  ascii().addNote(f.str().c_str());
1103
400
  return true;
1104
403
}
1105
1106
bool PowerPoint7Parser::readViewInfoAtom(int level, long lastPos)
1107
401
{
1108
401
  MWAWInputStreamPtr input=getInput();
1109
401
  long pos=input->tell();
1110
1111
401
  libmwaw::DebugStream f;
1112
401
  PowerPoint7Struct::Zone header;
1113
401
  if (!header.read(input,lastPos) || header.m_type!=1021) {
1114
12
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readViewInfoAtom: can not find the zone header\n"));
1115
12
    input->seek(pos, librevenge::RVNG_SEEK_SET);
1116
12
    return false;
1117
12
  }
1118
389
  f << "Entries(VViewInfoAtom)[" << level << "]:" << header;
1119
389
  if (header.m_dataSize!=52) {
1120
1
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readViewInfoAtom: find unexpected data size\n"));
1121
1
    f << "###dataSz=" << header.m_dataSize << ",";
1122
1
    if (header.m_dataSize)
1123
1
      ascii().addDelimiter(pos+16,'|');
1124
1
    input->seek(header.m_dataSize, librevenge::RVNG_SEEK_CUR);
1125
1
  }
1126
388
  else {
1127
388
    f << "dims=[";
1128
1.94k
    for (int i=0; i<4; ++i) {
1129
1.55k
      long number=int(input->readLong(4));
1130
1.55k
      long denom=int(input->readLong(4));
1131
1.55k
      f << number << "/" << denom << ",";
1132
1.55k
    }
1133
388
    f << "],";
1134
388
    f << "dim2=[";
1135
1.94k
    for (int i=0; i<4; ++i)
1136
1.55k
      f << input->readLong(4) << ",";
1137
388
    f << "],";
1138
1.16k
    for (int i=0; i<2; ++i) { // f0=0|1, f1=76-b8
1139
776
      auto val=int(input->readLong(2));
1140
776
      if (val) f << "f" << i << "=" << val << ",";
1141
776
    }
1142
388
  }
1143
389
  ascii().addPos(pos);
1144
389
  ascii().addNote(f.str().c_str());
1145
389
  return true;
1146
401
}
1147
1148
bool PowerPoint7Parser::readSlideViewInfoAtom(int level, long lastPos)
1149
208
{
1150
208
  MWAWInputStreamPtr input=getInput();
1151
208
  long pos=input->tell();
1152
1153
208
  libmwaw::DebugStream f;
1154
208
  PowerPoint7Struct::Zone header;
1155
208
  if (!header.read(input,lastPos) || header.m_type!=1022) {
1156
1
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readSlideViewInfoAtom: can not find the zone header\n"));
1157
1
    input->seek(pos, librevenge::RVNG_SEEK_SET);
1158
1
    return false;
1159
1
  }
1160
207
  f << "Entries(SlideViewInfo)[atom," << level << "]:" << header;
1161
207
  if (header.m_dataSize!=2) {
1162
0
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readSlideViewInfoAtom: find unexpected data size\n"));
1163
0
    f << "###dataSz=" << header.m_dataSize << ",";
1164
0
    if (header.m_dataSize)
1165
0
      ascii().addDelimiter(pos+16,'|');
1166
0
    input->seek(header.m_dataSize, librevenge::RVNG_SEEK_CUR);
1167
0
  }
1168
207
  else {
1169
207
    unsigned long val=input->readULong(2);
1170
207
    if (val!=0x100)
1171
0
      f << "id?=" << val << ",";
1172
207
  }
1173
207
  ascii().addPos(pos);
1174
207
  ascii().addNote(f.str().c_str());
1175
207
  return true;
1176
208
}
1177
1178
bool PowerPoint7Parser::readVbaInfo(int level, long lastPos)
1179
117
{
1180
117
  MWAWInputStreamPtr input=getInput();
1181
117
  long pos=input->tell();
1182
1183
117
  libmwaw::DebugStream f;
1184
117
  PowerPoint7Struct::Zone header;
1185
117
  if (!header.read(input,lastPos) || header.m_type!=1023) {
1186
1
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readVbaInfo: can not find the zone header\n"));
1187
1
    input->seek(pos, librevenge::RVNG_SEEK_SET);
1188
1
    return false;
1189
1
  }
1190
116
  f << "Entries(VbaInfo)[" << level << "]:" << header;
1191
116
  ascii().addPos(pos);
1192
116
  ascii().addNote(f.str().c_str());
1193
1194
116
  long endPos=pos+16+header.m_dataSize;
1195
474
  while (input->tell()<endPos) {
1196
367
    pos=input->tell();
1197
367
    auto cType=int(input->readULong(2));
1198
367
    input->seek(pos, librevenge::RVNG_SEEK_SET);
1199
1200
367
    bool done=false;
1201
367
    switch (cType) {
1202
108
    case 1024:
1203
108
      done=readVbaInfoAtom(level+1,endPos);
1204
108
      break;
1205
215
    case 4026: {
1206
215
      std::string string;
1207
215
      int zId; // 7:_VBA_PROJECT, 160:""
1208
215
      done=readString(level+1,endPos,string,zId,"VbaInfo");
1209
215
      break;
1210
0
    }
1211
44
    default:
1212
44
      done=readZone(level+1,endPos);
1213
44
      if (done) {
1214
36
        MWAW_DEBUG_MSG(("PowerPoint7Parser::readVbaInfo: find unexpected zone %d\n", cType));
1215
36
      }
1216
44
      break;
1217
367
    }
1218
367
    if (done) continue;
1219
9
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readVbaInfo: can not read some data\n"));
1220
9
    ascii().addPos(pos);
1221
9
    ascii().addNote("VbaInfo:###extra");
1222
9
    input->seek(endPos, librevenge::RVNG_SEEK_SET);
1223
9
    break;
1224
367
  }
1225
116
  return true;
1226
116
}
1227
1228
bool PowerPoint7Parser::readVbaInfoAtom(int level, long lastPos)
1229
108
{
1230
108
  MWAWInputStreamPtr input=getInput();
1231
108
  long pos=input->tell();
1232
1233
108
  libmwaw::DebugStream f;
1234
108
  PowerPoint7Struct::Zone header;
1235
108
  if (!header.read(input,lastPos) || header.m_type!=1024) {
1236
1
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readVbaInfoAtom: can not find the zone header\n"));
1237
1
    input->seek(pos, librevenge::RVNG_SEEK_SET);
1238
1
    return false;
1239
1
  }
1240
107
  f << "Entries(VbaInfo)[atom," << level << "]:" << header;
1241
107
  if (header.m_dataSize%4) {
1242
0
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readVbaInfoAtom: find unexpected data size\n"));
1243
0
    f << "###dataSz=" << header.m_dataSize << ",";
1244
0
    if (header.m_dataSize)
1245
0
      ascii().addDelimiter(pos+16,'|');
1246
0
    input->seek(header.m_dataSize, librevenge::RVNG_SEEK_CUR);
1247
0
  }
1248
107
  else {
1249
107
    auto N=int(header.m_dataSize/4);
1250
319
    for (int i=0; i<N; ++i) { // always 0
1251
212
      auto val=int(input->readLong(4));
1252
212
      if (val) f << "f" << i << "=" << val << ",";
1253
212
    }
1254
107
    input->seek(pos+16+header.m_dataSize, librevenge::RVNG_SEEK_SET);
1255
107
  }
1256
107
  ascii().addPos(pos);
1257
107
  ascii().addNote(f.str().c_str());
1258
107
  return true;
1259
108
}
1260
1261
bool PowerPoint7Parser::readSSDocInfoAtom(int level, long lastPos)
1262
2
{
1263
2
  MWAWInputStreamPtr input=getInput();
1264
2
  long pos=input->tell();
1265
1266
2
  libmwaw::DebugStream f;
1267
2
  PowerPoint7Struct::Zone header;
1268
2
  if (!header.read(input,lastPos) || header.m_type!=1025) {
1269
1
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readSSDocInfoAtom: can not find the zone header\n"));
1270
1
    input->seek(pos, librevenge::RVNG_SEEK_SET);
1271
1
    return false;
1272
1
  }
1273
1
  f << "Entries(SSDocInfoAtom)[" << level << "]:" << header;
1274
1
  if (header.m_dataSize!=0xc) {
1275
1
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readSSDocInfoAtom: find unexpected data size\n"));
1276
1
    f << "###dataSz=" << header.m_dataSize << ",";
1277
1
    if (header.m_dataSize)
1278
0
      ascii().addDelimiter(pos+16,'|');
1279
1
    input->seek(header.m_dataSize, librevenge::RVNG_SEEK_CUR);
1280
1
  }
1281
0
  else {
1282
0
    for (int i=0; i<6; ++i) {
1283
0
      auto val=int(input->readLong(2));
1284
0
      int const expected[]= {1,0,0,0,0,0x100};
1285
0
      if (val!=expected[i])
1286
0
        f << "f" << i << "=" << val << ",";
1287
0
    }
1288
0
  }
1289
1
  ascii().addPos(pos);
1290
1
  ascii().addNote(f.str().c_str());
1291
1
  return true;
1292
2
}
1293
1294
bool PowerPoint7Parser::readSummary(int level, long lastPos)
1295
109
{
1296
109
  MWAWInputStreamPtr input=getInput();
1297
109
  long pos=input->tell();
1298
1299
109
  libmwaw::DebugStream f;
1300
109
  PowerPoint7Struct::Zone header;
1301
109
  if (!header.read(input,lastPos) || header.m_type!=1026) {
1302
2
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readSummary: can not find the zone header\n"));
1303
2
    input->seek(pos, librevenge::RVNG_SEEK_SET);
1304
2
    return false;
1305
2
  }
1306
107
  f << "Entries(SummaryList)[" << level << "]:" << header;
1307
107
  ascii().addPos(pos);
1308
107
  ascii().addNote(f.str().c_str());
1309
1310
107
  long endPos=pos+16+header.m_dataSize;
1311
232
  while (input->tell()<endPos) {
1312
134
    pos=input->tell();
1313
134
    auto cType=int(input->readULong(2));
1314
134
    input->seek(pos, librevenge::RVNG_SEEK_SET);
1315
1316
134
    bool done=false;
1317
134
    switch (cType) {
1318
99
    case 2019:
1319
99
      done=readBookmarkCollection(level+1,endPos);
1320
99
      break;
1321
35
    default:
1322
35
      done=readZone(level+1,endPos);
1323
35
      if (done) {
1324
27
        MWAW_DEBUG_MSG(("PowerPoint7Parser::readSummary: find unexpected zone %d\n", cType));
1325
27
      }
1326
35
      break;
1327
134
    }
1328
134
    if (done) continue;
1329
9
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readSummary: can not read some data\n"));
1330
9
    ascii().addPos(pos);
1331
9
    ascii().addNote("SummaryList:###extra");
1332
9
    input->seek(endPos, librevenge::RVNG_SEEK_SET);
1333
9
    break;
1334
134
  }
1335
107
  return true;
1336
107
}
1337
1338
bool PowerPoint7Parser::readZone1028(int level, long lastPos)
1339
399
{
1340
399
  MWAWInputStreamPtr input=getInput();
1341
399
  long pos=input->tell();
1342
1343
399
  libmwaw::DebugStream f;
1344
399
  PowerPoint7Struct::Zone header;
1345
399
  if (!header.read(input,lastPos) || header.m_type!=1028) {
1346
4
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readZone1028: can not find the zone header\n"));
1347
4
    input->seek(pos, librevenge::RVNG_SEEK_SET);
1348
4
    return false;
1349
4
  }
1350
395
  f << "Entries(Zone1028B)[" << level << "]:" << header;
1351
395
  ascii().addPos(pos);
1352
395
  ascii().addNote(f.str().c_str());
1353
1354
395
  long endPos=pos+16+header.m_dataSize;
1355
3.88k
  while (input->tell()<endPos) {
1356
3.55k
    pos=input->tell();
1357
3.55k
    auto cType=int(input->readULong(2));
1358
3.55k
    input->seek(pos, librevenge::RVNG_SEEK_SET);
1359
1360
3.55k
    bool done=false;
1361
3.55k
    switch (cType) {
1362
382
    case 1029:
1363
382
      done=readZone1028Atom(level+1,endPos);
1364
382
      break;
1365
2.52k
    case 4052:
1366
2.52k
      done=readZone1028Data(level+1,endPos);
1367
2.52k
      break;
1368
643
    default:
1369
643
      done=readZone(level+1,endPos);
1370
643
      if (done) {
1371
582
        MWAW_DEBUG_MSG(("PowerPoint7Parser::readZone1028: find unexpected zone %d\n", cType));
1372
582
      }
1373
643
      break;
1374
3.55k
    }
1375
3.55k
    if (done) continue;
1376
66
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readZone1028: can not read some data\n"));
1377
66
    ascii().addPos(pos);
1378
66
    ascii().addNote("Zone1028:###extra");
1379
66
    input->seek(endPos, librevenge::RVNG_SEEK_SET);
1380
66
    break;
1381
3.55k
  }
1382
395
  return true;
1383
395
}
1384
1385
bool PowerPoint7Parser::readZone1028Atom(int level, long lastPos)
1386
382
{
1387
382
  MWAWInputStreamPtr input=getInput();
1388
382
  long pos=input->tell();
1389
1390
382
  libmwaw::DebugStream f;
1391
382
  PowerPoint7Struct::Zone header;
1392
382
  if (!header.read(input,lastPos) || header.m_type!=1029) {
1393
1
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readZone1028Atom: can not find the zone header\n"));
1394
1
    input->seek(pos, librevenge::RVNG_SEEK_SET);
1395
1
    return false;
1396
1
  }
1397
381
  f << "Entries(Zone1028B)[atom," << level << "]:" << header;
1398
381
  if (header.m_dataSize!=0xa) {
1399
21
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readZone1028Atom: find unexpected data size\n"));
1400
21
    f << "###dataSz=" << header.m_dataSize << ",";
1401
21
    if (header.m_dataSize)
1402
11
      ascii().addDelimiter(pos+16,'|');
1403
21
    input->seek(header.m_dataSize, librevenge::RVNG_SEEK_CUR);
1404
21
  }
1405
360
  else {
1406
3.96k
    for (int i=0; i<10; ++i) { // f0-f6=0|1,f7=f8=0, f9=d-b2
1407
3.60k
      auto val=int(input->readULong(1));
1408
3.60k
      if (val==1)
1409
2.11k
        f << "f" << i << ",";
1410
1.48k
      else if (val)
1411
290
        f << "f" << i << "=" << std::hex << val << std::dec << ",";
1412
3.60k
    }
1413
360
  }
1414
381
  ascii().addPos(pos);
1415
381
  ascii().addNote(f.str().c_str());
1416
381
  return true;
1417
382
}
1418
1419
bool PowerPoint7Parser::readOutlineViewInfo(int level, long lastPos)
1420
247
{
1421
247
  MWAWInputStreamPtr input=getInput();
1422
247
  long pos=input->tell();
1423
1424
247
  libmwaw::DebugStream f;
1425
247
  PowerPoint7Struct::Zone header;
1426
247
  if (!header.read(input,lastPos) || header.m_type!=1031) {
1427
8
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readOutlineViewInfo: can not find the zone header\n"));
1428
8
    input->seek(pos, librevenge::RVNG_SEEK_SET);
1429
8
    return false;
1430
8
  }
1431
239
  f << "Entries(OutlineViewInfo)[" << level << "]:" << header;
1432
239
  ascii().addPos(pos);
1433
239
  ascii().addNote(f.str().c_str());
1434
1435
239
  long endPos=pos+16+header.m_dataSize;
1436
341
  while (input->tell()<endPos) {
1437
248
    pos=input->tell();
1438
248
    auto cType=int(input->readULong(2));
1439
248
    input->seek(pos, librevenge::RVNG_SEEK_SET);
1440
1441
248
    bool done=false;
1442
248
    switch (cType) {
1443
101
    case 1021:
1444
101
      done=readViewInfoAtom(level+1,endPos);
1445
101
      break;
1446
147
    default:
1447
147
      done=readZone(level+1,endPos);
1448
147
      if (done) {
1449
9
        MWAW_DEBUG_MSG(("PowerPoint7Parser::readOutlineViewInfo: find unexpected zone %d\n", cType));
1450
9
      }
1451
147
      break;
1452
248
    }
1453
248
    if (done) continue;
1454
146
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readOutlineViewInfo: can not read some data\n"));
1455
146
    ascii().addPos(pos);
1456
146
    ascii().addNote("OutlineViewInfo:###extra");
1457
146
    input->seek(endPos, librevenge::RVNG_SEEK_SET);
1458
146
    break;
1459
248
  }
1460
239
  return true;
1461
239
}
1462
1463
bool PowerPoint7Parser::readSorterViewInfo(int level, long lastPos)
1464
101
{
1465
101
  MWAWInputStreamPtr input=getInput();
1466
101
  long pos=input->tell();
1467
1468
101
  libmwaw::DebugStream f;
1469
101
  PowerPoint7Struct::Zone header;
1470
101
  if (!header.read(input,lastPos) || header.m_type!=1032) {
1471
1
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readSorterViewInfo: can not find the zone header\n"));
1472
1
    input->seek(pos, librevenge::RVNG_SEEK_SET);
1473
1
    return false;
1474
1
  }
1475
100
  f << "Entries(SorterViewInfo)[" << level << "]:" << header;
1476
100
  ascii().addPos(pos);
1477
100
  ascii().addNote(f.str().c_str());
1478
1479
100
  long endPos=pos+16+header.m_dataSize;
1480
202
  while (input->tell()<endPos) {
1481
108
    pos=input->tell();
1482
108
    auto cType=int(input->readULong(2));
1483
108
    input->seek(pos, librevenge::RVNG_SEEK_SET);
1484
1485
108
    bool done=false;
1486
108
    switch (cType) {
1487
98
    case 1021:
1488
98
      done=readViewInfoAtom(level+1,endPos);
1489
98
      break;
1490
10
    default:
1491
10
      done=readZone(level+1,endPos);
1492
10
      if (done) {
1493
7
        MWAW_DEBUG_MSG(("PowerPoint7Parser::readSorterViewInfo: find unexpected zone %d\n", cType));
1494
7
      }
1495
10
      break;
1496
108
    }
1497
108
    if (done) continue;
1498
6
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readSorterViewInfo: can not read some data\n"));
1499
6
    ascii().addPos(pos);
1500
6
    ascii().addNote("SorterViewInfo:###extra");
1501
6
    input->seek(endPos, librevenge::RVNG_SEEK_SET);
1502
6
    break;
1503
108
  }
1504
100
  return true;
1505
100
}
1506
1507
bool PowerPoint7Parser::readContainerList(int level, long lastPos)
1508
1.10k
{
1509
1.10k
  MWAWInputStreamPtr input=getInput();
1510
1.10k
  long pos=input->tell();
1511
1512
1.10k
  libmwaw::DebugStream f;
1513
1.10k
  PowerPoint7Struct::Zone header;
1514
1.10k
  if (!header.read(input,lastPos) || header.m_type!=2000) {
1515
5
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readContainerList: can not find the zone header\n"));
1516
5
    input->seek(pos, librevenge::RVNG_SEEK_SET);
1517
5
    return false;
1518
5
  }
1519
1.09k
  f << "Entries(Container)[list," << level << "]:" << header;
1520
1.09k
  switch (header.m_values[3]) {
1521
763
  case 10:
1522
763
    f << "slides,";
1523
763
    break;
1524
211
  case 11:
1525
211
    f << "slides[master],";
1526
211
    break;
1527
110
  case 12: // vbaInfo, viewInfo, bookmark collection
1528
110
    f << "info,";
1529
110
    break;
1530
12
  case 15:
1531
12
    f << "group,";
1532
12
    break;
1533
0
  default:
1534
0
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readContainerList: unknown type\n"));
1535
0
    f << "##type=" << header.m_values[3] << ",";
1536
1.09k
  }
1537
1.09k
  ascii().addPos(pos);
1538
1.09k
  ascii().addNote(f.str().c_str());
1539
1540
1.09k
  long endPos=pos+16+header.m_dataSize;
1541
13.4k
  while (input->tell()<endPos) {
1542
12.9k
    pos=input->tell();
1543
12.9k
    auto cType=int(input->readULong(2));
1544
12.9k
    input->seek(pos, librevenge::RVNG_SEEK_SET);
1545
1546
12.9k
    bool done=false;
1547
12.9k
    switch (cType) {
1548
2.57k
    case 1006:
1549
2.57k
      done=readSlides(level+1,endPos,false);
1550
2.57k
      break;
1551
211
    case 1016:
1552
211
      done=readSlides(level+1,endPos,true);
1553
211
      break;
1554
230
    case 1018:
1555
230
      done=readSlideViewInfo(level+1,endPos);
1556
230
      break;
1557
117
    case 1023:
1558
117
      done=readVbaInfo(level+1,endPos);
1559
117
      break;
1560
247
    case 1031:
1561
247
      done=readOutlineViewInfo(level+1,endPos);
1562
247
      break;
1563
101
    case 1032:
1564
101
      done=readSorterViewInfo(level+1,endPos);
1565
101
      break;
1566
1.07k
    case 2001: {
1567
1.07k
      int N; // the number of child: slides, shapes, ...
1568
1.07k
      done=readContainerAtom(level+1,endPos,N);
1569
1.07k
      break;
1570
0
    }
1571
1
    case 3001:
1572
1
      done=m_state->m_graphParser->readGroup(level+1,endPos);
1573
1
      break;
1574
258
    case 3008:
1575
258
      done=m_state->m_graphParser->readRect(level+1,endPos);
1576
258
      break;
1577
27
    case 3014:
1578
27
      done=m_state->m_graphParser->readLine(level+1,endPos);
1579
27
      break;
1580
4
    case 3016:
1581
4
      done=m_state->m_graphParser->readPolygon(level+1,endPos);
1582
4
      break;
1583
4
    case 3018:
1584
4
      done=m_state->m_graphParser->readArc(level+1,endPos);
1585
4
      break;
1586
8.09k
    default:
1587
8.09k
      done=readZone(level+1,endPos);
1588
8.09k
      if (done) {
1589
7.52k
        MWAW_DEBUG_MSG(("PowerPoint7Parser::readContainerList: find unexpected zone %d\n", cType));
1590
7.52k
      }
1591
8.09k
      break;
1592
12.9k
    }
1593
12.9k
    if (done) continue;
1594
599
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readContainerList: can not read some data\n"));
1595
599
    ascii().addPos(pos);
1596
599
    ascii().addNote("Container:###extra");
1597
599
    input->seek(endPos, librevenge::RVNG_SEEK_SET);
1598
599
    break;
1599
12.9k
  }
1600
1.09k
  return true;
1601
1.09k
}
1602
1603
bool PowerPoint7Parser::readContainerAtom(int level, long lastPos, int &N)
1604
1.07k
{
1605
1.07k
  MWAWInputStreamPtr input=getInput();
1606
1.07k
  long pos=input->tell();
1607
1608
1.07k
  libmwaw::DebugStream f;
1609
1.07k
  PowerPoint7Struct::Zone header;
1610
1.07k
  if (!header.read(input,lastPos) || header.m_type!=2001) {
1611
3
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readContainerAtom: can not find the zone header\n"));
1612
3
    input->seek(pos, librevenge::RVNG_SEEK_SET);
1613
3
    return false;
1614
3
  }
1615
1.06k
  f << "Entries(Container)[atom," << level << "]:" << header;
1616
1.06k
  if (header.m_dataSize!=0x4) {
1617
8
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readContainerAtom: find unexpected data size\n"));
1618
8
    f << "###dataSz=" << header.m_dataSize << ",";
1619
8
    if (header.m_dataSize)
1620
1
      ascii().addDelimiter(pos+16,'|');
1621
8
    input->seek(header.m_dataSize, librevenge::RVNG_SEEK_CUR);
1622
8
    N=0;
1623
8
  }
1624
1.06k
  else {
1625
1.06k
    N=int(input->readULong(4));
1626
1.06k
    f << "N=" << N << ",";
1627
1.06k
  }
1628
1.06k
  ascii().addPos(pos);
1629
1.06k
  ascii().addNote(f.str().c_str());
1630
1.06k
  return true;
1631
1.07k
}
1632
1633
bool PowerPoint7Parser::readIdentifier(int level, long endPos, int &id, std::string const &wh)
1634
10.8k
{
1635
10.8k
  MWAWInputStreamPtr input=getInput();
1636
10.8k
  long pos=input->tell();
1637
10.8k
  long lastPos=endPos<0 ? input->size() : endPos;
1638
10.8k
  if (pos+16>lastPos)
1639
1
    return false;
1640
1641
10.8k
  PowerPoint7Struct::Zone header;
1642
10.8k
  if (!header.read(input,lastPos) || header.m_type!=2017) {
1643
60
    input->seek(pos, librevenge::RVNG_SEEK_SET);
1644
60
    return false;
1645
60
  }
1646
10.8k
  libmwaw::DebugStream f;
1647
10.8k
  if (!wh.empty())
1648
10.8k
    f << "Entries(" << wh << ")[id," << level << "]:" << header;
1649
0
  else
1650
0
    f << "Entries(Identifier)[" << level << "]:" << header;
1651
10.8k
  if (header.m_dataSize) {
1652
3
    f << "###dSz=" << header.m_dataSize << ",";
1653
3
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readIdentifier: find unexpected data for zone\n"));
1654
3
  }
1655
10.8k
  id=header.m_values[3];
1656
10.8k
  ascii().addPos(pos);
1657
10.8k
  ascii().addNote(f.str().c_str());
1658
10.8k
  return true;
1659
10.8k
}
1660
1661
bool PowerPoint7Parser::readBookmarkCollection(int level, long lastPos)
1662
99
{
1663
99
  MWAWInputStreamPtr input=getInput();
1664
99
  long pos=input->tell();
1665
1666
99
  libmwaw::DebugStream f;
1667
99
  PowerPoint7Struct::Zone header;
1668
99
  if (!header.read(input,lastPos) || header.m_type!=2019) {
1669
1
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readBookmarkCollection: can not find the zone header\n"));
1670
1
    input->seek(pos, librevenge::RVNG_SEEK_SET);
1671
1
    return false;
1672
1
  }
1673
98
  f << "Entries(BookmarkCollection)[" << level << "]:" << header;
1674
98
  ascii().addPos(pos);
1675
98
  ascii().addNote(f.str().c_str());
1676
1677
98
  long endPos=pos+16+header.m_dataSize;
1678
196
  while (input->tell()<endPos) {
1679
98
    pos=input->tell();
1680
98
    auto cType=int(input->readULong(2));
1681
98
    input->seek(pos, librevenge::RVNG_SEEK_SET);
1682
1683
98
    bool done=false;
1684
98
    switch (cType) {
1685
0
    case 2017: {
1686
0
      int id;
1687
0
      done=readIdentifier(level+1,endPos,id,"BookmarkCollection");
1688
0
      break;
1689
0
    }
1690
0
    case 2018:
1691
0
      done=readZoneNoData(level+1,endPos,"BookmarkCollection","id,end");
1692
0
      break;
1693
98
    case 2025:
1694
98
      done=readBookmarkSeedAtom(level+1,endPos);
1695
98
      break;
1696
0
    default:
1697
0
      done=readZone(level+1,endPos);
1698
0
      if (done) {
1699
0
        MWAW_DEBUG_MSG(("PowerPoint7Parser::readBookmarkCollection: find unexpected zone %d\n", cType));
1700
0
      }
1701
0
      break;
1702
98
    }
1703
98
    if (done) continue;
1704
0
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readBookmarkCollection: can not read some data\n"));
1705
0
    ascii().addPos(pos);
1706
0
    ascii().addNote("BookmarkCollection:###extra");
1707
0
    input->seek(endPos, librevenge::RVNG_SEEK_SET);
1708
0
    break;
1709
98
  }
1710
98
  return true;
1711
98
}
1712
1713
bool PowerPoint7Parser::readSoundCollection(int level, long lastPos)
1714
269
{
1715
269
  MWAWInputStreamPtr input=getInput();
1716
269
  long pos=input->tell();
1717
1718
269
  libmwaw::DebugStream f;
1719
269
  PowerPoint7Struct::Zone header;
1720
269
  if (!header.read(input,lastPos) || header.m_type!=2020) {
1721
2
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readSoundCollection: can not find the zone header\n"));
1722
2
    input->seek(pos, librevenge::RVNG_SEEK_SET);
1723
2
    return false;
1724
2
  }
1725
267
  f << "Entries(SoundCollection)[" << level << "]:" << header;
1726
267
  ascii().addPos(pos);
1727
267
  ascii().addNote(f.str().c_str());
1728
1729
267
  long endPos=pos+16+header.m_dataSize;
1730
316
  while (input->tell()<endPos) {
1731
54
    pos=input->tell();
1732
54
    auto cType=int(input->readULong(2));
1733
54
    input->seek(pos, librevenge::RVNG_SEEK_SET);
1734
1735
54
    bool done=false;
1736
54
    switch (cType) {
1737
54
    default:
1738
54
      done=readZone(level+1,endPos);
1739
54
      if (done) {
1740
49
        MWAW_DEBUG_MSG(("PowerPoint7Parser::readSoundCollection: find unexpected zone %d\n", cType));
1741
49
      }
1742
54
      break;
1743
54
    }
1744
54
    if (done) continue;
1745
5
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readSoundCollection: can not read some data\n"));
1746
5
    ascii().addPos(pos);
1747
5
    ascii().addNote("SoundCollection:###extra");
1748
5
    input->seek(endPos, librevenge::RVNG_SEEK_SET);
1749
5
    break;
1750
54
  }
1751
267
  return true;
1752
267
}
1753
1754
bool PowerPoint7Parser::readBookmarkSeedAtom(int level, long lastPos)
1755
98
{
1756
98
  MWAWInputStreamPtr input=getInput();
1757
98
  long pos=input->tell();
1758
1759
98
  libmwaw::DebugStream f;
1760
98
  PowerPoint7Struct::Zone header;
1761
98
  if (!header.read(input,lastPos) || header.m_type!=2025) {
1762
0
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readBookmarkSeedAtom: can not find the zone header\n"));
1763
0
    input->seek(pos, librevenge::RVNG_SEEK_SET);
1764
0
    return false;
1765
0
  }
1766
98
  f << "Entries(BookmarkSeedAtom)[" << level << "]:" << header;
1767
98
  if (header.m_dataSize!=4) {
1768
0
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readBookmarkSeedAtom: find unexpected data size\n"));
1769
0
    f << "###dataSz=" << header.m_dataSize << ",";
1770
0
    if (header.m_dataSize)
1771
0
      ascii().addDelimiter(pos+16,'|');
1772
0
    input->seek(header.m_dataSize, librevenge::RVNG_SEEK_CUR);
1773
0
  }
1774
98
  else {
1775
294
    for (int i=0; i<2; ++i) { // f0=1
1776
196
      auto val=int(input->readULong(2));
1777
196
      if (val) f << "f" << i << "=" << val << ",";
1778
196
    }
1779
98
  }
1780
98
  ascii().addPos(pos);
1781
98
  ascii().addNote(f.str().c_str());
1782
98
  return true;
1783
98
}
1784
1785
bool PowerPoint7Parser::readZone2026(int level, long lastPos)
1786
207
{
1787
207
  MWAWInputStreamPtr input=getInput();
1788
207
  long pos=input->tell();
1789
1790
207
  libmwaw::DebugStream f;
1791
207
  PowerPoint7Struct::Zone header;
1792
207
  if (!header.read(input,lastPos) || header.m_type!=2026) {
1793
1
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readZone2026: can not find the zone header\n"));
1794
1
    input->seek(pos, librevenge::RVNG_SEEK_SET);
1795
1
    return false;
1796
1
  }
1797
206
  f << "Entries(Zone2026B)[" << level << "]:" << header;
1798
206
  ascii().addPos(pos);
1799
206
  ascii().addNote(f.str().c_str());
1800
1801
206
  long endPos=pos+16+header.m_dataSize;
1802
610
  while (input->tell()<endPos) {
1803
410
    pos=input->tell();
1804
410
    auto cType=int(input->readULong(2));
1805
410
    input->seek(pos, librevenge::RVNG_SEEK_SET);
1806
1807
410
    bool done=false;
1808
410
    switch (cType) {
1809
403
    case 1019:
1810
403
      done=readGuideAtom(level+1,endPos);
1811
403
      break;
1812
7
    default:
1813
7
      done=readZone(level+1,endPos);
1814
7
      if (done) {
1815
4
        MWAW_DEBUG_MSG(("PowerPoint7Parser::readZone2026: find unexpected zone %d\n", cType));
1816
4
      }
1817
7
      break;
1818
410
    }
1819
410
    if (done) continue;
1820
6
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readZone2026: can not read some data\n"));
1821
6
    ascii().addPos(pos);
1822
6
    ascii().addNote("Zone2026B:###extra");
1823
6
    input->seek(endPos, librevenge::RVNG_SEEK_SET);
1824
6
    break;
1825
410
  }
1826
206
  return true;
1827
206
}
1828
1829
bool PowerPoint7Parser::readColorList(int level, long lastPos, std::vector<MWAWColor> &colors)
1830
5.31k
{
1831
5.31k
  colors.resize(0);
1832
1833
5.31k
  MWAWInputStreamPtr input=getInput();
1834
5.31k
  long pos=input->tell();
1835
1836
5.31k
  libmwaw::DebugStream f;
1837
5.31k
  PowerPoint7Struct::Zone header;
1838
5.31k
  if (!header.read(input,lastPos) || header.m_type!=2031) {
1839
121
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readColorList: can not find the zone header\n"));
1840
121
    input->seek(pos, librevenge::RVNG_SEEK_SET);
1841
121
    return false;
1842
121
  }
1843
5.19k
  long endPos=pos+16+header.m_dataSize;
1844
5.19k
  f << "Entries(ColorList)[" << level << "]:" << header;
1845
5.19k
  bool ok=true;
1846
5.19k
  if (header.m_dataSize<4 || (header.m_dataSize%4)!=0) {
1847
48
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readColorList: find unexpected data size\n"));
1848
48
    f << "###dataSz=" << header.m_dataSize << ",";
1849
48
    ok=false;
1850
48
  }
1851
5.19k
  int N=ok? int(input->readULong(4)) : 0;
1852
5.19k
  if (ok && header.m_dataSize/4-1!=N) {
1853
42
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readColorList: the number of colors seems bad\n"));
1854
42
    f << "###N=" << N << ",";
1855
42
    N=0;
1856
42
  }
1857
5.19k
  f << "colors=[";
1858
5.19k
  colors.resize(size_t(N));
1859
37.8k
  for (auto &color : colors) {
1860
37.8k
    unsigned char col[4];
1861
151k
    for (auto &c : col) c=static_cast<unsigned char>(input->readULong(1));
1862
37.8k
    color=MWAWColor(col[0],col[1],col[2]);
1863
37.8k
    f << color << ",";
1864
37.8k
  }
1865
5.19k
  f << "],";
1866
5.19k
  if (input->tell()!=endPos) {
1867
46
    ascii().addDelimiter(pos+16,'|');
1868
46
    input->seek(endPos, librevenge::RVNG_SEEK_SET);
1869
46
  }
1870
5.19k
  ascii().addPos(pos);
1871
5.19k
  ascii().addNote(f.str().c_str());
1872
5.19k
  return true;
1873
5.31k
}
1874
1875
bool PowerPoint7Parser::readZone3000(int level, long lastPos)
1876
3.69k
{
1877
3.69k
  MWAWInputStreamPtr input=getInput();
1878
3.69k
  long pos=input->tell();
1879
1880
3.69k
  libmwaw::DebugStream f;
1881
3.69k
  PowerPoint7Struct::Zone header;
1882
3.69k
  if (!header.read(input,lastPos) || header.m_type!=3000) {
1883
49
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readZone3000: can not find the zone header\n"));
1884
49
    input->seek(pos, librevenge::RVNG_SEEK_SET);
1885
49
    return false;
1886
49
  }
1887
3.64k
  f << "Entries(Zone3000B)[" << level << "]:" << header;
1888
3.64k
  ascii().addPos(pos);
1889
3.64k
  ascii().addNote(f.str().c_str());
1890
1891
3.64k
  long endPos=pos+16+header.m_dataSize;
1892
37.0k
  while (input->tell()<endPos) {
1893
34.0k
    pos=input->tell();
1894
34.0k
    auto cType=int(input->readULong(2));
1895
34.0k
    input->seek(pos, librevenge::RVNG_SEEK_SET);
1896
1897
34.0k
    bool done=false;
1898
34.0k
    switch (cType) {
1899
253
    case 3001:
1900
253
      done=m_state->m_graphParser->readGroup(level+1,endPos);
1901
253
      break;
1902
15.3k
    case 3008:
1903
15.3k
      done=m_state->m_graphParser->readRect(level+1,endPos);
1904
15.3k
      break;
1905
6.22k
    case 3010:
1906
6.22k
      done=m_state->m_graphParser->readPlaceholderContainer(level+1,endPos);
1907
6.22k
      break;
1908
5.13k
    case 3014:
1909
5.13k
      done=m_state->m_graphParser->readLine(level+1,endPos);
1910
5.13k
      break;
1911
1.03k
    case 3016:
1912
1.03k
      done=m_state->m_graphParser->readPolygon(level+1,endPos);
1913
1.03k
      break;
1914
2.27k
    case 3018:
1915
2.27k
      done=m_state->m_graphParser->readArc(level+1,endPos);
1916
2.27k
      break;
1917
3.70k
    default:
1918
3.70k
      done=readZone(level+1,endPos);
1919
3.70k
      if (done) {
1920
3.16k
        MWAW_DEBUG_MSG(("PowerPoint7Parser::readZone3000: find unexpected zone %d\n", cType));
1921
3.16k
      }
1922
3.70k
      break;
1923
34.0k
    }
1924
34.0k
    if (done) continue;
1925
640
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readZone3000: can not read some data\n"));
1926
640
    ascii().addPos(pos);
1927
640
    ascii().addNote("Zone3000B:###extra");
1928
640
    input->seek(endPos, librevenge::RVNG_SEEK_SET);
1929
640
    break;
1930
34.0k
  }
1931
3.64k
  return true;
1932
3.64k
}
1933
1934
bool PowerPoint7Parser::readZone3012(int level, long lastPos)
1935
350
{
1936
  // one by file: maybe a default frame?
1937
350
  MWAWInputStreamPtr input=getInput();
1938
350
  long pos=input->tell();
1939
1940
350
  libmwaw::DebugStream f;
1941
350
  PowerPoint7Struct::Zone header;
1942
350
  if (!header.read(input,lastPos) || header.m_type!=3012) {
1943
6
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readZone3012: can not find the zone header\n"));
1944
6
    input->seek(pos, librevenge::RVNG_SEEK_SET);
1945
6
    return false;
1946
6
  }
1947
344
  f << "Entries(Zone3012B)[" << level << "]:" << header;
1948
344
  ascii().addPos(pos);
1949
344
  ascii().addNote(f.str().c_str());
1950
1951
344
  long endPos=pos+16+header.m_dataSize;
1952
1.79k
  while (input->tell()<endPos) {
1953
1.49k
    pos=input->tell();
1954
1.49k
    auto cType=int(input->readULong(2));
1955
1.49k
    input->seek(pos, librevenge::RVNG_SEEK_SET);
1956
1957
1.49k
    bool done=false;
1958
1.49k
    switch (cType) {
1959
327
    case 3005:
1960
327
      done=m_state->m_graphParser->readStyle(level+1,endPos);
1961
327
      break;
1962
323
    case 3009:
1963
323
      done=m_state->m_graphParser->readRectAtom(level+1,endPos);
1964
323
      break;
1965
342
    case 3013:
1966
342
      done=readZone3012Atom(level+1,endPos);
1967
342
      break;
1968
297
    case 4001: {
1969
297
      int tId=-1;
1970
297
      done=readStyleTextPropAtom(level+1,endPos,tId);
1971
297
      break;
1972
0
    }
1973
206
    default:
1974
206
      done=readZone(level+1,endPos);
1975
206
      if (done) {
1976
162
        MWAW_DEBUG_MSG(("PowerPoint7Parser::readZone3012: find unexpected zone %d\n", cType));
1977
162
      }
1978
206
      break;
1979
1.49k
    }
1980
1.49k
    if (done) continue;
1981
47
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readZone3012: can not read some data\n"));
1982
47
    ascii().addPos(pos);
1983
47
    ascii().addNote("Zone3012B:###extra");
1984
47
    input->seek(endPos, librevenge::RVNG_SEEK_SET);
1985
47
    break;
1986
1.49k
  }
1987
344
  return true;
1988
344
}
1989
1990
bool PowerPoint7Parser::readZone3012Atom(int level, long lastPos)
1991
342
{
1992
342
  MWAWInputStreamPtr input=getInput();
1993
342
  long pos=input->tell();
1994
1995
342
  libmwaw::DebugStream f;
1996
342
  PowerPoint7Struct::Zone header;
1997
342
  if (!header.read(input,lastPos) || header.m_type!=3013) {
1998
1
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readZone3012Atom: can not find the zone header\n"));
1999
1
    input->seek(pos, librevenge::RVNG_SEEK_SET);
2000
1
    return false;
2001
1
  }
2002
341
  f << "Entries(Zone3012B)[atom," << level << "]:" << header;
2003
341
  if (header.m_dataSize!=2) {
2004
4
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readZone3012Atom: find unexpected data size\n"));
2005
4
    f << "###dataSz=" << header.m_dataSize << ",";
2006
4
    if (header.m_dataSize)
2007
3
      ascii().addDelimiter(pos+16,'|');
2008
4
    input->seek(header.m_dataSize, librevenge::RVNG_SEEK_CUR);
2009
4
  }
2010
337
  else {
2011
337
    auto val=int(input->readULong(2)); // 0
2012
337
    if (val)
2013
1
      f << "f0=" << val << ",";
2014
337
  }
2015
341
  ascii().addPos(pos);
2016
341
  ascii().addNote(f.str().c_str());
2017
341
  return true;
2018
342
}
2019
2020
bool PowerPoint7Parser::readTextCharsAtom(int level, long lastPos)
2021
6.23k
{
2022
6.23k
  MWAWInputStreamPtr input=getInput();
2023
6.23k
  long pos=input->tell();
2024
2025
6.23k
  libmwaw::DebugStream f;
2026
6.23k
  PowerPoint7Struct::Zone header;
2027
6.23k
  if (!header.read(input,lastPos) || header.m_type!=4000) {
2028
13
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readTextCharsAtom: can not find the zone header\n"));
2029
13
    input->seek(pos, librevenge::RVNG_SEEK_SET);
2030
13
    return false;
2031
13
  }
2032
6.21k
  f << "Entries(TextCharsAtom)[" << level << "]:" << header;
2033
6.21k
  if (header.m_dataSize!=16) {
2034
6
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readTextCharsAtom: find unexpected data size\n"));
2035
6
    f << "###dataSz=" << header.m_dataSize << ",";
2036
6
    if (header.m_dataSize)
2037
3
      ascii().addDelimiter(pos+16,'|');
2038
6
    input->seek(header.m_dataSize, librevenge::RVNG_SEEK_CUR);
2039
6
  }
2040
6.21k
  else {
2041
18.6k
    for (int i=0; i<2; ++i) { // the text anchor dimension
2042
12.4k
      unsigned long val=input->readULong(4);
2043
12.4k
      if (!val) continue;
2044
11.9k
      f << "anchor" << (i==0 ? "LR" : "BT") << "=" << float(val)/8.f << "pt,";
2045
11.9k
    }
2046
6.21k
    auto val=int(input->readULong(1));
2047
6.21k
    if (val&1) f << "adjust[text],";
2048
6.21k
    if (val&4) f << "wrap[word],";
2049
6.21k
    val&=0xfa;
2050
6.21k
    if (val!=0xc0)
2051
1.19k
      f << "fl0=" << std::hex << val << std::dec << ",";
2052
49.6k
    for (int i=0; i<7; ++i) {
2053
43.4k
      val=int(input->readULong(1));
2054
43.4k
      int const expected[]= {0x6e,7,0x50,3,0xe0,0x62,0};
2055
43.4k
      if (val==expected[i])
2056
35.1k
        continue;
2057
8.33k
      if (i==3) {
2058
2.89k
        f << "v[align]=" << (val>>4) << ","; // 1: center, 2:top
2059
2.89k
        f << "h[align]=" << (val&0xf) << ","; // 1: center, 3:left?
2060
2.89k
      }
2061
5.43k
      else
2062
5.43k
        f << "fl" << i+1 << "=" << std::hex << val << std::dec << ",";
2063
8.33k
    }
2064
6.21k
  }
2065
6.21k
  ascii().addPos(pos);
2066
6.21k
  ascii().addNote(f.str().c_str());
2067
6.21k
  return true;
2068
6.23k
}
2069
2070
bool PowerPoint7Parser::readStyleTextPropAtom(int level, long lastPos, int &tId)
2071
6.29k
{
2072
6.29k
  tId=-1;
2073
6.29k
  MWAWInputStreamPtr input=getInput();
2074
6.29k
  long pos=input->tell();
2075
2076
6.29k
  libmwaw::DebugStream f;
2077
6.29k
  PowerPoint7Struct::Zone header;
2078
6.29k
  if (!header.read(input,lastPos) || header.m_type!=4001) {
2079
57
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readStyleTextPropAtom: can not find the zone header\n"));
2080
57
    input->seek(pos, librevenge::RVNG_SEEK_SET);
2081
57
    return false;
2082
57
  }
2083
6.23k
  f << "Entries(StyleTextPropAtom)[" << level << "]:" << header;
2084
6.23k
  ascii().addPos(pos);
2085
6.23k
  ascii().addNote(f.str().c_str());
2086
2087
6.23k
  long endPos=pos+16+header.m_dataSize;
2088
18.3k
  while (input->tell()<endPos) {
2089
12.1k
    pos=input->tell();
2090
12.1k
    auto cType=int(input->readULong(2));
2091
12.1k
    input->seek(pos, librevenge::RVNG_SEEK_SET);
2092
2093
12.1k
    bool done=false;
2094
12.1k
    switch (cType) {
2095
6.23k
    case 4000:
2096
6.23k
      done=readTextCharsAtom(level+1,endPos);
2097
6.23k
      break;
2098
5.27k
    case 4002:
2099
5.27k
      if (tId!=-1) {
2100
0
        MWAW_DEBUG_MSG(("PowerPoint7Parser::readStyleTextPropAtom: find duplicated text zone\n"));
2101
0
      }
2102
5.27k
      done=m_state->m_textParser->readTextMasterProp(level+1,endPos,tId);
2103
5.27k
      break;
2104
475
    case 4068:
2105
475
      if (tId!=-1) {
2106
0
        MWAW_DEBUG_MSG(("PowerPoint7Parser::readStyleTextPropAtom: find duplicated text zone\n"));
2107
0
      }
2108
475
      done=m_state->m_textParser->readExternalHyperlink9(level+1,endPos,tId);
2109
475
      break;
2110
147
    default:
2111
147
      done=readZone(level+1,endPos);
2112
147
      if (done) {
2113
125
        MWAW_DEBUG_MSG(("PowerPoint7Parser::readStyleTextPropAtom: find unexpected zone %d\n", cType));
2114
125
      }
2115
147
      break;
2116
12.1k
    }
2117
12.1k
    if (done) continue;
2118
48
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readStyleTextPropAtom: can not read some data\n"));
2119
48
    ascii().addPos(pos);
2120
48
    ascii().addNote("StyleTextPropAtom:###extra");
2121
48
    input->seek(endPos, librevenge::RVNG_SEEK_SET);
2122
48
    break;
2123
12.1k
  }
2124
6.23k
  return true;
2125
6.23k
}
2126
2127
bool PowerPoint7Parser::readOutlineTextProps9Atom(int level, long lastPos, int &id, PowerPoint7Struct::SlideId &sId)
2128
2.01k
{
2129
2.01k
  id=-1;
2130
2.01k
  sId=PowerPoint7Struct::SlideId();
2131
2.01k
  MWAWInputStreamPtr input=getInput();
2132
2.01k
  long pos=input->tell();
2133
2134
2.01k
  libmwaw::DebugStream f;
2135
2.01k
  PowerPoint7Struct::Zone header;
2136
2.01k
  if (!header.read(input,lastPos) || header.m_type!=4014) {
2137
19
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readOutlineTextProps9Atom: can not find the zone header\n"));
2138
19
    input->seek(pos, librevenge::RVNG_SEEK_SET);
2139
19
    return false;
2140
19
  }
2141
2.00k
  f << "Entries(OutlineTextProps9)[" << level << "]:" << header;
2142
2.00k
  ascii().addPos(pos);
2143
2.00k
  ascii().addNote(f.str().c_str());
2144
2145
2.00k
  long endPos=pos+16+header.m_dataSize;
2146
5.91k
  while (input->tell()<endPos) {
2147
3.97k
    pos=input->tell();
2148
3.97k
    auto cType=int(input->readULong(2));
2149
3.97k
    input->seek(pos, librevenge::RVNG_SEEK_SET);
2150
2151
3.97k
    bool done=false;
2152
3.97k
    switch (cType) {
2153
2.00k
    case 4015:
2154
2.00k
      done=readOutlineTextPropsHeader9Atom(level+1,endPos);
2155
2.00k
      break;
2156
217
    case 4044: {
2157
217
      int pId;
2158
217
      done=m_state->m_graphParser->readExternalOleEmbed(level+1,endPos,pId);
2159
217
      if (done && pId!=-1 && id==-1) id=pId;
2160
217
      break;
2161
0
    }
2162
851
    case 4053: {
2163
851
      int pId;
2164
851
      done=m_state->m_graphParser->readPictureIdContainer(level+1,endPos,pId);
2165
851
      if (done && pId!=-1) id=pId;
2166
851
      break;
2167
0
    }
2168
869
    case 4054:
2169
869
      done=readSlideIdentifierContainer(level+1,endPos,sId);
2170
869
      break;
2171
37
    default:
2172
37
      done=readZone(level+1,endPos);
2173
37
      if (done) {
2174
28
        MWAW_DEBUG_MSG(("PowerPoint7Parser::readOutlineTextProps9Atom: find unexpected zone %d\n", cType));
2175
28
      }
2176
37
      break;
2177
3.97k
    }
2178
3.97k
    if (done) continue;
2179
57
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readOutlineTextProps9Atom: can not read some data\n"));
2180
57
    ascii().addPos(pos);
2181
57
    ascii().addNote("OutlineTextProps9:###extra");
2182
57
    input->seek(endPos, librevenge::RVNG_SEEK_SET);
2183
57
    break;
2184
3.97k
  }
2185
2.00k
  if (id==-1 && !sId.isValid()) {
2186
117
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readOutlineTextProps9Atom: does not find any data\n"));
2187
117
  }
2188
2.00k
  return true;
2189
2.00k
}
2190
2191
bool PowerPoint7Parser::readOutlineTextPropsHeader9Atom(int level, long lastPos)
2192
2.00k
{
2193
2.00k
  MWAWInputStreamPtr input=getInput();
2194
2.00k
  long pos=input->tell();
2195
2196
2.00k
  libmwaw::DebugStream f;
2197
2.00k
  PowerPoint7Struct::Zone header;
2198
2.00k
  if (!header.read(input,lastPos) || header.m_type!=4015) {
2199
34
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readOutlineTextPropsHeader9Atom: can not find the zone header\n"));
2200
34
    input->seek(pos, librevenge::RVNG_SEEK_SET);
2201
34
    return false;
2202
34
  }
2203
1.96k
  f << "Entries(OutlineTextProps9)[header," << level << "]:" << header;
2204
1.96k
  if (header.m_dataSize!=16) {
2205
2
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readOutlineTextPropsHeader9Atom: find unexpected data size\n"));
2206
2
    f << "###dataSz=" << header.m_dataSize << ",";
2207
2
    if (header.m_dataSize)
2208
1
      ascii().addDelimiter(pos+16,'|');
2209
2
    input->seek(header.m_dataSize, librevenge::RVNG_SEEK_CUR);
2210
2
  }
2211
1.96k
  else {
2212
17.6k
    for (int i=0; i<8; ++i) { // 0
2213
15.7k
      auto val=int(input->readULong(2));
2214
15.7k
      if (val) f << "f" << i << "=" << val << ",";
2215
15.7k
    }
2216
1.96k
  }
2217
1.96k
  ascii().addPos(pos);
2218
1.96k
  ascii().addNote(f.str().c_str());
2219
1.96k
  return true;
2220
2.00k
}
2221
2222
bool PowerPoint7Parser::readString(int level, long lastPos, std::string &text, int &zId, std::string const &what)
2223
14.1k
{
2224
14.1k
  text="";
2225
14.1k
  MWAWInputStreamPtr input=getInput();
2226
14.1k
  long pos=input->tell();
2227
2228
14.1k
  libmwaw::DebugStream f;
2229
14.1k
  PowerPoint7Struct::Zone header;
2230
14.1k
  if (!header.read(input,lastPos) || header.m_type!=4026) {
2231
135
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readString: can not find the zone header\n"));
2232
135
    input->seek(pos, librevenge::RVNG_SEEK_SET);
2233
135
    return false;
2234
135
  }
2235
14.0k
  zId=header.m_values[3];
2236
14.0k
  if (!what.empty())
2237
14.0k
    f << "Entries(" << what << ")[string," << level << "]:" << header;
2238
0
  else
2239
0
    f << "Entries(CString)[" << level << "]:" << header;
2240
62.1k
  for (long i=0; i<header.m_dataSize; ++i) text+=char(input->readULong(1));
2241
14.0k
  f << text << ",";
2242
14.0k
  ascii().addPos(pos);
2243
14.0k
  ascii().addNote(f.str().c_str());
2244
14.0k
  return true;
2245
14.1k
}
2246
2247
bool PowerPoint7Parser::readSlideIdentifier(int level, long lastPos, PowerPoint7Struct::SlideId &sId)
2248
849
{
2249
849
  sId=PowerPoint7Struct::SlideId();
2250
849
  MWAWInputStreamPtr input=getInput();
2251
849
  long pos=input->tell();
2252
2253
849
  libmwaw::DebugStream f;
2254
849
  PowerPoint7Struct::Zone header;
2255
849
  if (!header.read(input,lastPos) || header.m_type!=4032) {
2256
6
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readSlideIdentifier: can not find the zone header\n"));
2257
6
    input->seek(pos, librevenge::RVNG_SEEK_SET);
2258
6
    return false;
2259
6
  }
2260
843
  f << "Entries(SlideId)[" << level << "]:" << header;
2261
843
  if (header.m_dataSize!=4) {
2262
2
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readSlideIdentifier: find unexpected data size\n"));
2263
2
    f << "###dataSz=" << header.m_dataSize << ",";
2264
2
    if (header.m_dataSize)
2265
2
      ascii().addDelimiter(pos+16,'|');
2266
2
    input->seek(header.m_dataSize, librevenge::RVNG_SEEK_CUR);
2267
2
  }
2268
841
  else {
2269
841
    sId=PowerPoint7Struct::SlideId(input->readULong(4));
2270
841
    if (sId.isValid())
2271
840
      f << sId << ",";
2272
841
  }
2273
843
  ascii().addPos(pos);
2274
843
  ascii().addNote(f.str().c_str());
2275
843
  return true;
2276
849
}
2277
2278
bool PowerPoint7Parser::readKinsoku(int level, long lastPos)
2279
1.04k
{
2280
1.04k
  MWAWInputStreamPtr input=getInput();
2281
1.04k
  long pos=input->tell();
2282
2283
1.04k
  libmwaw::DebugStream f;
2284
1.04k
  PowerPoint7Struct::Zone header;
2285
1.04k
  if (!header.read(input,lastPos) || header.m_type!=4040) {
2286
30
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readKinsoku: can not find the zone header\n"));
2287
30
    input->seek(pos, librevenge::RVNG_SEEK_SET);
2288
30
    return false;
2289
30
  }
2290
1.01k
  f << "Entries(Kinsoku)[" << level << "]:" << header;
2291
1.01k
  ascii().addPos(pos);
2292
1.01k
  ascii().addNote(f.str().c_str());
2293
2294
1.01k
  long endPos=pos+16+header.m_dataSize;
2295
3.68k
  while (input->tell()<endPos) {
2296
2.87k
    pos=input->tell();
2297
2.87k
    auto cType=int(input->readULong(2));
2298
2.87k
    input->seek(pos, librevenge::RVNG_SEEK_SET);
2299
2300
2.87k
    bool done=false;
2301
2.87k
    switch (cType) {
2302
1.62k
    case 4026: {
2303
1.62k
      std::string string;
2304
1.62k
      int zId; // 4:"", 5:""
2305
1.62k
      done=readString(level+1,endPos,string,zId,"Kinsoku");
2306
1.62k
      break;
2307
0
    }
2308
975
    case 4050:
2309
975
      done=readKinsokuAtom(level+1,endPos);
2310
975
      break;
2311
274
    default:
2312
274
      done=readZone(level+1,endPos);
2313
274
      if (done) {
2314
118
        MWAW_DEBUG_MSG(("PowerPoint7Parser::readKinsoku: find unexpected zone %d\n", cType));
2315
118
      }
2316
274
      break;
2317
2.87k
    }
2318
2.87k
    if (done) continue;
2319
207
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readKinsoku: can not read some data\n"));
2320
207
    ascii().addPos(pos);
2321
207
    ascii().addNote("Kinsoku:###extra");
2322
207
    input->seek(endPos, librevenge::RVNG_SEEK_SET);
2323
207
    break;
2324
2.87k
  }
2325
1.01k
  return true;
2326
1.01k
}
2327
2328
bool PowerPoint7Parser::readZone4039(int level, long lastPos)
2329
219
{
2330
219
  MWAWInputStreamPtr input=getInput();
2331
219
  long pos=input->tell();
2332
2333
219
  libmwaw::DebugStream f;
2334
219
  PowerPoint7Struct::Zone header;
2335
219
  if (!header.read(input,lastPos) || header.m_type!=4039) {
2336
0
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readZone4039: can not find the zone header\n"));
2337
0
    input->seek(pos, librevenge::RVNG_SEEK_SET);
2338
0
    return false;
2339
0
  }
2340
219
  f << "Entries(Zone4039B)[" << level << "]:" << header;
2341
219
  if (header.m_dataSize!=0x20) {
2342
1
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readZone4039: find unexpected data size\n"));
2343
1
    f << "###dataSz=" << header.m_dataSize << ",";
2344
1
    if (header.m_dataSize)
2345
1
      ascii().addDelimiter(pos+16,'|');
2346
1
    input->seek(header.m_dataSize, librevenge::RVNG_SEEK_CUR);
2347
1
    ascii().addPos(pos);
2348
1
    ascii().addNote(f.str().c_str());
2349
1
    return true;
2350
1
  }
2351
2352
3.70k
  for (int i=0; i<16; ++i) { // f0=1010,f1=6,f14=f15=-1
2353
3.48k
    auto val=int(input->readLong(2));
2354
3.48k
    if (val) f << "f" << i << "=" << val << ",";
2355
3.48k
  }
2356
218
  input->seek(pos+16+header.m_dataSize, librevenge::RVNG_SEEK_SET);
2357
218
  ascii().addPos(pos);
2358
218
  ascii().addNote(f.str().c_str());
2359
2360
218
  return true;
2361
219
}
2362
2363
bool PowerPoint7Parser::readHandout(int level, long lastPos)
2364
11
{
2365
11
  MWAWInputStreamPtr input=getInput();
2366
11
  long pos=input->tell();
2367
2368
11
  libmwaw::DebugStream f;
2369
11
  PowerPoint7Struct::Zone header;
2370
11
  if (!header.read(input,lastPos) || header.m_type!=4041) {
2371
1
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readHandout: can not find the zone header\n"));
2372
1
    input->seek(pos, librevenge::RVNG_SEEK_SET);
2373
1
    return false;
2374
1
  }
2375
10
  f << "Entries(HandoutList)[" << level << "]:" << header;
2376
10
  ascii().addPos(pos);
2377
10
  ascii().addNote(f.str().c_str());
2378
2379
10
  PowerPoint7Struct::SlideId hId;
2380
10
  hId.m_inHandout=true;
2381
10
  m_state->pushSlideId(hId);
2382
10
  long endPos=pos+16+header.m_dataSize;
2383
10
  bool pushColor=false;
2384
21
  while (input->tell()<endPos) {
2385
16
    pos=input->tell();
2386
16
    auto cType=int(input->readULong(2));
2387
16
    input->seek(pos, librevenge::RVNG_SEEK_SET);
2388
2389
16
    bool done=false;
2390
16
    switch (cType) {
2391
0
    case 1005:
2392
0
      done=readSlideInformation(level+1,endPos);
2393
0
      break;
2394
0
    case 1012: {
2395
0
      std::vector<MWAWColor> colors;
2396
0
      done=readColorScheme(level+1,endPos,colors);
2397
0
      if (done && !pushColor) {
2398
0
        pushColor=true;
2399
0
        m_state->pushColorList(colors);
2400
0
      }
2401
0
      break;
2402
0
    }
2403
0
    case 3000:
2404
0
      done=readZone3000(level+1,endPos);
2405
0
      break;
2406
0
    case 3008:
2407
0
      done=m_state->m_graphParser->readRect(level+1,endPos);
2408
0
      break;
2409
0
    case 4057:
2410
0
      done=readHeaderFooters(level+1,endPos);
2411
0
      break;
2412
16
    default:
2413
16
      done=readZone(level+1,endPos);
2414
16
      if (done) {
2415
11
        MWAW_DEBUG_MSG(("PowerPoint7Parser::readHandout: find unexpected zone %d\n", cType));
2416
11
      }
2417
16
      break;
2418
16
    }
2419
16
    if (done) continue;
2420
5
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readHandout: can not read some data\n"));
2421
5
    ascii().addPos(pos);
2422
5
    ascii().addNote("HandoutList:###extra");
2423
5
    input->seek(endPos, librevenge::RVNG_SEEK_SET);
2424
5
    break;
2425
16
  }
2426
10
  if (pushColor)
2427
0
    m_state->popColorList();
2428
10
  m_state->popSlideId();
2429
10
  return true;
2430
10
}
2431
2432
bool PowerPoint7Parser::readKinsokuAtom(int level, long lastPos)
2433
975
{
2434
975
  MWAWInputStreamPtr input=getInput();
2435
975
  long pos=input->tell();
2436
2437
975
  libmwaw::DebugStream f;
2438
975
  PowerPoint7Struct::Zone header;
2439
975
  if (!header.read(input,lastPos) || header.m_type!=4050) {
2440
31
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readKinsokuAtom: can not find the zone header\n"));
2441
31
    input->seek(pos, librevenge::RVNG_SEEK_SET);
2442
31
    return false;
2443
31
  }
2444
944
  f << "Entries(Kinsoku)[atom," << level << "]:" << header;
2445
944
  if (header.m_dataSize!=4) {
2446
35
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readKinsokuAtom: find unexpected data size\n"));
2447
35
    f << "###dataSz=" << header.m_dataSize << ",";
2448
35
    if (header.m_dataSize)
2449
34
      ascii().addDelimiter(pos+16,'|');
2450
35
    input->seek(header.m_dataSize, librevenge::RVNG_SEEK_CUR);
2451
35
  }
2452
909
  else { // 0,10000,cdcdcdcd
2453
909
    f << "f0=" << std::hex << input->readULong(4) << std::dec << ",";
2454
909
  }
2455
944
  ascii().addPos(pos);
2456
944
  ascii().addNote(f.str().c_str());
2457
944
  return true;
2458
975
}
2459
2460
bool PowerPoint7Parser::readZone1028Data(int level, long lastPos)
2461
2.52k
{
2462
2.52k
  MWAWInputStreamPtr input=getInput();
2463
2.52k
  long pos=input->tell();
2464
2465
2.52k
  libmwaw::DebugStream f;
2466
2.52k
  PowerPoint7Struct::Zone header;
2467
2.52k
  if (!header.read(input,lastPos) || header.m_type!=4052) {
2468
4
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readZone1028Data: can not find the zone header\n"));
2469
4
    input->seek(pos, librevenge::RVNG_SEEK_SET);
2470
4
    return false;
2471
4
  }
2472
2.52k
  f << "Entries(Zone1028B)[data," << level << "]:" << header;
2473
2.52k
  if (header.m_dataSize!=0x1d8) {
2474
3
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readZone1028Data: find unexpected data size\n"));
2475
3
    f << "###dataSz=" << header.m_dataSize << ",";
2476
3
    if (header.m_dataSize)
2477
3
      ascii().addDelimiter(pos+16,'|');
2478
3
    input->seek(header.m_dataSize, librevenge::RVNG_SEEK_CUR);
2479
3
    ascii().addPos(pos);
2480
3
    ascii().addNote(f.str().c_str());
2481
3
    return true;
2482
3
  }
2483
2.51k
  ascii().addDelimiter(input->tell(),'|');
2484
2.51k
  input->seek(pos+16+8, librevenge::RVNG_SEEK_SET);
2485
2.51k
  ascii().addPos(pos);
2486
2.51k
  ascii().addNote(f.str().c_str());
2487
32.7k
  for (int i=0; i<12; ++i) {
2488
    // A0-A4 is probably related to font, A6-A11 is probably related to ruler
2489
30.2k
    pos=input->tell();
2490
30.2k
    int const dSz=i<5 ? 24 : i==5 ? 32 : 52;
2491
30.2k
    f.str("");
2492
30.2k
    f << "Zone1028B-A" << i << ":";
2493
30.2k
    ascii().addPos(pos);
2494
30.2k
    ascii().addNote(f.str().c_str());
2495
30.2k
    input->seek(pos+dSz, librevenge::RVNG_SEEK_SET);
2496
30.2k
  }
2497
2.51k
  return true;
2498
2.52k
}
2499
2500
bool PowerPoint7Parser::readSlideIdentifierContainer(int level, long lastPos, PowerPoint7Struct::SlideId &sId)
2501
869
{
2502
869
  MWAWInputStreamPtr input=getInput();
2503
869
  long pos=input->tell();
2504
2505
869
  libmwaw::DebugStream f;
2506
869
  PowerPoint7Struct::Zone header;
2507
869
  if (!header.read(input,lastPos) || header.m_type!=4054) {
2508
8
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readSlideIdentifierContainer: can not find the zone header\n"));
2509
8
    input->seek(pos, librevenge::RVNG_SEEK_SET);
2510
8
    return false;
2511
8
  }
2512
861
  f << "Entries(SlideId)[container," << level << "]:" << header;
2513
861
  ascii().addPos(pos);
2514
861
  ascii().addNote(f.str().c_str());
2515
2516
861
  long endPos=pos+16+header.m_dataSize;
2517
1.71k
  while (input->tell()<endPos) {
2518
867
    pos=input->tell();
2519
867
    auto cType=int(input->readULong(2));
2520
867
    input->seek(pos, librevenge::RVNG_SEEK_SET);
2521
2522
867
    bool done=false;
2523
867
    switch (cType) {
2524
849
    case 4032:
2525
849
      done=readSlideIdentifier(level+1,endPos, sId);
2526
849
      break;
2527
18
    default:
2528
18
      done=readZone(level+1,endPos);
2529
18
      if (done) {
2530
12
        MWAW_DEBUG_MSG(("PowerPoint7Parser::readSlideIdentifierContainer: find unexpected zone %d\n", cType));
2531
12
      }
2532
18
      break;
2533
867
    }
2534
867
    if (done) continue;
2535
12
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readSlideIdentifierContainer: can not read some data\n"));
2536
12
    ascii().addPos(pos);
2537
12
    ascii().addNote("SlideId:###extra");
2538
12
    input->seek(endPos, librevenge::RVNG_SEEK_SET);
2539
12
    break;
2540
867
  }
2541
861
  return true;
2542
861
}
2543
2544
bool PowerPoint7Parser::readHeaderFooters(int level, long lastPos)
2545
3.85k
{
2546
3.85k
  MWAWInputStreamPtr input=getInput();
2547
3.85k
  long pos=input->tell();
2548
2549
3.85k
  libmwaw::DebugStream f;
2550
3.85k
  PowerPoint7Struct::Zone header;
2551
3.85k
  if (!header.read(input,lastPos) || header.m_type!=4057) {
2552
101
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readHeaderFooters: can not find the zone header\n"));
2553
101
    input->seek(pos, librevenge::RVNG_SEEK_SET);
2554
101
    return false;
2555
101
  }
2556
3.75k
  f << "Entries(HF)[list," << level << "]:" << header;
2557
3.75k
  ascii().addPos(pos);
2558
3.75k
  ascii().addNote(f.str().c_str());
2559
2560
3.75k
  long endPos=pos+16+header.m_dataSize;
2561
17.4k
  while (input->tell()<endPos) {
2562
13.9k
    pos=input->tell();
2563
13.9k
    auto cType=int(input->readULong(2));
2564
13.9k
    input->seek(pos, librevenge::RVNG_SEEK_SET);
2565
2566
13.9k
    bool done=false;
2567
13.9k
    switch (cType) {
2568
10.0k
    case 4026: {
2569
10.0k
      std::string string;
2570
10.0k
      int zId; // 46:"", 47:"", 48:""
2571
10.0k
      done=readString(level+1,endPos,string,zId,"HF");
2572
10.0k
      break;
2573
0
    }
2574
3.66k
    case 4058:
2575
3.66k
      done=readHeaderFooterAtom(level+1,endPos);
2576
3.66k
      break;
2577
215
    default:
2578
215
      done=readZone(level+1,endPos);
2579
215
      if (done) {
2580
121
        MWAW_DEBUG_MSG(("PowerPoint7Parser::readHeaderFooters: find unexpected zone %d\n", cType));
2581
121
      }
2582
215
      break;
2583
13.9k
    }
2584
13.9k
    if (done) continue;
2585
255
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readHeaderFooters: can not read some data\n"));
2586
255
    ascii().addPos(pos);
2587
255
    ascii().addNote("HF:###extra");
2588
255
    input->seek(endPos, librevenge::RVNG_SEEK_SET);
2589
255
    break;
2590
13.9k
  }
2591
3.75k
  return true;
2592
3.75k
}
2593
2594
bool PowerPoint7Parser::readHeaderFooterAtom(int level, long lastPos)
2595
3.66k
{
2596
3.66k
  MWAWInputStreamPtr input=getInput();
2597
3.66k
  long pos=input->tell();
2598
2599
3.66k
  libmwaw::DebugStream f;
2600
3.66k
  PowerPoint7Struct::Zone header;
2601
3.66k
  if (!header.read(input,lastPos) || header.m_type!=4058) {
2602
50
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readHeaderFooterAtom: can not find the zone header\n"));
2603
50
    input->seek(pos, librevenge::RVNG_SEEK_SET);
2604
50
    return false;
2605
50
  }
2606
3.61k
  f << "Entries(HF)[atom," << level << "]:" << header;
2607
3.61k
  if (header.m_dataSize!=8) {
2608
49
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readHeaderFooterAtom: find unexpected data size\n"));
2609
49
    f << "###dataSz=" << header.m_dataSize << ",";
2610
49
    if (header.m_dataSize)
2611
48
      ascii().addDelimiter(pos+16,'|');
2612
49
    input->seek(header.m_dataSize, librevenge::RVNG_SEEK_CUR);
2613
49
  }
2614
3.56k
  else {
2615
3.56k
    f << "flags=[";
2616
32.0k
    for (int i=0; i<8; ++i) { // list of 0 and 1
2617
28.5k
      auto val=int(input->readULong(1));
2618
28.5k
      if (val==1)
2619
14.7k
        f << "*,";
2620
13.7k
      else if (val)
2621
340
        f << val << ",";
2622
13.4k
      else
2623
13.4k
        f << "_,";
2624
28.5k
    }
2625
3.56k
    f << "],";
2626
3.56k
  }
2627
3.61k
  ascii().addPos(pos);
2628
3.61k
  ascii().addNote(f.str().c_str());
2629
3.61k
  return true;
2630
3.66k
}
2631
2632
bool PowerPoint7Parser::readZone4072(int level, long lastPos)
2633
221
{
2634
221
  MWAWInputStreamPtr input=getInput();
2635
221
  long pos=input->tell();
2636
2637
221
  libmwaw::DebugStream f;
2638
221
  PowerPoint7Struct::Zone header;
2639
221
  if (!header.read(input,lastPos) || header.m_type!=4072) {
2640
1
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readZone4072: can not find the zone header\n"));
2641
1
    input->seek(pos, librevenge::RVNG_SEEK_SET);
2642
1
    return false;
2643
1
  }
2644
220
  f << "Entries(Zone4072B)[" << level << "]:" << header;
2645
220
  ascii().addPos(pos);
2646
220
  ascii().addNote(f.str().c_str());
2647
2648
220
  long endPos=pos+16+header.m_dataSize;
2649
658
  while (input->tell()<endPos) {
2650
440
    pos=input->tell();
2651
440
    auto cType=int(input->readULong(2));
2652
440
    input->seek(pos, librevenge::RVNG_SEEK_SET);
2653
2654
440
    bool done=false;
2655
440
    switch (cType) {
2656
217
    case 4026: {
2657
217
      std::string string;
2658
217
      int zId; // 160:""
2659
217
      done=readString(level+1,endPos,string,zId,"Zone4072B");
2660
217
      break;
2661
0
    }
2662
219
    case 4039:
2663
219
      done=readZone4039(level+1,endPos);
2664
219
      break;
2665
4
    default:
2666
4
      done=readZone(level+1,endPos);
2667
4
      if (done) {
2668
2
        MWAW_DEBUG_MSG(("PowerPoint7Parser::readZone4072: find unexpected zone %d\n", cType));
2669
2
      }
2670
4
      break;
2671
440
    }
2672
440
    if (done) continue;
2673
2
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readZone4072: can not read some data\n"));
2674
2
    ascii().addPos(pos);
2675
2
    ascii().addNote("Zone4072B:###extra");
2676
2
    input->seek(endPos, librevenge::RVNG_SEEK_SET);
2677
2
    break;
2678
440
  }
2679
220
  return true;
2680
220
}
2681
2682
bool PowerPoint7Parser::readZoneNoData(int level, long endPos, std::string const &name, std::string const &wh)
2683
11.7k
{
2684
11.7k
  MWAWInputStreamPtr input=getInput();
2685
11.7k
  long pos=input->tell();
2686
11.7k
  long lastPos=endPos<0 ? input->size() : endPos;
2687
11.7k
  if (pos+16>lastPos)
2688
1
    return false;
2689
2690
11.7k
  PowerPoint7Struct::Zone header;
2691
11.7k
  if (!header.read(input,lastPos)) {
2692
49
    input->seek(pos, librevenge::RVNG_SEEK_SET);
2693
49
    return false;
2694
49
  }
2695
11.7k
  libmwaw::DebugStream f;
2696
11.7k
  if (!wh.empty())
2697
11.7k
    f << "Entries(" << name << ")[" << wh << "," << level << "]:" << header;
2698
0
  else
2699
0
    f << "Entries(" << name << ")[" << level << "]:" << header;
2700
11.7k
  if (header.m_dataSize) {
2701
14
    f << "###dSz=" << header.m_dataSize << ",";
2702
14
    MWAW_DEBUG_MSG(("PowerPoint7Parser::readZoneNoData: find unexpected data for zone %s\n", name.c_str()));
2703
14
    input->seek(pos+16+header.m_dataSize, librevenge::RVNG_SEEK_SET);
2704
14
  }
2705
11.7k
  ascii().addPos(pos);
2706
11.7k
  ascii().addNote(f.str().c_str());
2707
11.7k
  return true;
2708
11.7k
}
2709
2710
bool PowerPoint7Parser::readZone(int level, long endPos)
2711
79.4k
{
2712
79.4k
  MWAWInputStreamPtr input=getInput();
2713
79.4k
  long pos=input->tell();
2714
79.4k
  long lastPos=endPos<0 ? input->size() : endPos;
2715
79.4k
  if (pos+16>lastPos)
2716
539
    return false;
2717
2718
78.9k
  PowerPoint7Struct::Zone header;
2719
78.9k
  if (!header.read(input,lastPos)) {
2720
6.77k
    input->seek(pos, librevenge::RVNG_SEEK_SET);
2721
6.77k
    return false;
2722
6.77k
  }
2723
72.1k
  libmwaw::DebugStream f;
2724
72.1k
  f << "Entries(" << header.getName() << ")[" << level << "]:" << header;
2725
72.1k
  long lastDataPos=pos+16+header.m_dataSize;
2726
72.1k
  bool isList=false;
2727
72.1k
  if (header.m_dataSize>=16) {
2728
    // first check that we can read all data
2729
10.6k
    isList=true;
2730
24.7k
    while (input->tell()<lastDataPos) {
2731
21.1k
      PowerPoint7Struct::Zone cHeader;
2732
21.1k
      if (!cHeader.read(input, lastDataPos)) {
2733
7.13k
        isList=false;
2734
7.13k
        break;
2735
7.13k
      }
2736
14.0k
      input->seek(cHeader.m_dataSize, librevenge::RVNG_SEEK_CUR);
2737
14.0k
    }
2738
10.6k
    input->seek(pos+16, librevenge::RVNG_SEEK_SET);
2739
10.6k
    if (isList) {
2740
11.7k
      while (input->tell()<lastDataPos) {
2741
8.20k
        long actPos=input->tell();
2742
8.20k
        if (readZone(level+1, lastDataPos))
2743
8.20k
          continue;
2744
0
        MWAW_DEBUG_MSG(("PowerPoint7Parser::readZone: can not read some data\n"));
2745
0
        libmwaw::DebugStream f1;
2746
0
        f1 <<  header.getName() << ":###extra";
2747
0
        ascii().addPos(actPos);
2748
0
        ascii().addNote(f1.str().c_str());
2749
0
        break;
2750
8.20k
      }
2751
3.53k
    }
2752
10.6k
  }
2753
72.1k
  if (header.m_dataSize && !isList)
2754
9.98k
    ascii().addDelimiter(input->tell(),'|');
2755
72.1k
  input->seek(lastDataPos, librevenge::RVNG_SEEK_SET);
2756
72.1k
  ascii().addPos(pos);
2757
72.1k
  ascii().addNote(f.str().c_str());
2758
72.1k
  return true;
2759
78.9k
}
2760
2761
void PowerPoint7Parser::checkForUnparsedZones()
2762
0
{
2763
  // check if there remains some unparsed zone
2764
0
}
2765
2766
////////////////////////////////////////////////////////////
2767
// try to read the different zones
2768
////////////////////////////////////////////////////////////
2769
bool PowerPoint7Parser::parseTextContent(MWAWInputStreamPtr input)
2770
1.18k
{
2771
1.18k
  if (!input) {
2772
740
    MWAW_DEBUG_MSG(("PowerPoint7Parser::parseTextContent: can not find the input\n"));
2773
740
    return false;
2774
740
  }
2775
445
  libmwaw::DebugFile ascFile(input);
2776
445
  ascFile.open("Text_Content");
2777
445
  libmwaw::DebugStream f;
2778
445
  f << "Entries(TextContent):";
2779
445
  input->seek(0, librevenge::RVNG_SEEK_SET);
2780
445
  long pos=0;
2781
140k
  while (!input->isEnd()) {
2782
140k
    auto c=char(input->readULong(1));
2783
140k
    if (c==0) {
2784
445
      input->seek(-1, librevenge::RVNG_SEEK_CUR);
2785
445
      break;
2786
445
    }
2787
140k
    f << c;
2788
140k
    if (c==0xd) {
2789
13.9k
      ascFile.addPos(pos);
2790
13.9k
      ascFile.addNote(f.str().c_str());
2791
13.9k
      pos=input->tell();
2792
13.9k
      f.str("");
2793
13.9k
      f << "TextContent:";
2794
13.9k
    }
2795
140k
  }
2796
445
  if (!input->isEnd()) {
2797
445
    ascFile.addPos(input->tell());
2798
445
    ascFile.addNote("TextContent:#");
2799
445
  }
2800
445
  return true;
2801
1.18k
}
2802
2803
////////////////////////////////////////////////////////////
2804
// try to send data
2805
////////////////////////////////////////////////////////////
2806
void PowerPoint7Parser::sendSlides()
2807
693
{
2808
693
  MWAWPresentationListenerPtr listener=getPresentationListener();
2809
693
  if (!listener) {
2810
0
    MWAW_DEBUG_MSG(("PowerPoint7Parser::sendSlides: can not find the listener\n"));
2811
0
    return;
2812
0
  }
2813
693
  for (auto const &mIt : m_state->m_masterSlideIdToNameMap) {
2814
222
    if (!mIt.first.isValid()) continue;
2815
222
    MWAWPageSpan ps(getPageSpan());
2816
222
    ps.setMasterPageName(mIt.second);
2817
222
    if (!listener->openMasterPage(ps)) {
2818
0
      MWAW_DEBUG_MSG(("PowerPoint7Parser::sendSlides: can not create the master page\n"));
2819
0
    }
2820
222
    else {
2821
222
      m_state->m_graphParser->sendSlide(mIt.first,true);
2822
222
      listener->closeMasterPage();
2823
222
    }
2824
222
  }
2825
693
  bool firstSlideSent=false;
2826
2.41k
  for (auto const &id : m_state->m_slideList) {
2827
2.41k
    if (!id.isValid()) continue;
2828
2.41k
    if (firstSlideSent)
2829
1.72k
      listener->insertBreak(MWAWListener::PageBreak);
2830
2.41k
    firstSlideSent=true;
2831
2.41k
    bool sendBackground=false;
2832
2.41k
    if (m_state->m_idToSlideInfoMap.find(id)!=m_state->m_idToSlideInfoMap.end())
2833
2.36k
      sendBackground=m_state->m_idToSlideInfoMap.find(id)->second.m_hasBackground;
2834
2.41k
    m_state->m_graphParser->sendSlide(id,sendBackground);
2835
2.41k
  }
2836
693
}
2837
2838
2839
////////////////////////////////////////////////////////////
2840
// Low level
2841
////////////////////////////////////////////////////////////
2842
2843
// read the header
2844
bool PowerPoint7Parser::checkHeader(MWAWHeader *header, bool /*strict*/)
2845
4.21k
{
2846
4.21k
  MWAWInputStreamPtr input = getInput();
2847
4.21k
  if (!input || !input->hasDataFork() || !input->isStructured())
2848
0
    return false;
2849
  /* a PPT95 containing a PPT97. Let suppose that a PPT97 filter
2850
     exists...*/
2851
4.21k
  if (input->getSubStreamByName("PP97_DUALSTORAGE/PowerPoint Document")) {
2852
0
#ifndef DEBUG
2853
0
    MWAW_DEBUG_MSG(("PowerPoint7Parser::checkHeader: this file is a dual PowerPoint 95 and 97, it will only be converted in debug mode\n"));
2854
0
#endif
2855
0
    return false;
2856
0
  }
2857
4.21k
  input=input->getSubStreamByName("PowerPoint Document");
2858
4.21k
  if (!input || !getInput()->getSubStreamByName("PersistentStorage Directory"))
2859
0
    return false;
2860
4.21k
  auto endPos=long(input->size());
2861
4.21k
  input->setReadInverted(true);
2862
4.21k
  input->seek(0, librevenge::RVNG_SEEK_SET);
2863
4.21k
  if (endPos<116 || input->readULong(2)!=3) {
2864
1.41k
    MWAW_DEBUG_MSG(("PowerPoint7Parser::checkHeader: file is too short\n"));
2865
1.41k
    return false;
2866
1.41k
  }
2867
2.80k
  input->seek(8, librevenge::RVNG_SEEK_SET);
2868
2.80k
  auto dSz=long(input->readULong(4));
2869
2.80k
  if (dSz<100 || endPos-16<dSz || 16+dSz>endPos) return false;
2870
2871
2.57k
  setVersion(7);
2872
2.57k
  if (header)
2873
1.39k
    header->reset(MWAWDocument::MWAW_T_POWERPOINT, 7, MWAWDocument::MWAW_K_PRESENTATION);
2874
2.57k
  return true;
2875
2.80k
}
2876
2877
// vim: set filetype=cpp tabstop=2 shiftwidth=2 cindent autoindent smartindent noexpandtab: