Coverage Report

Created: 2026-03-12 06:42

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