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 /** \file MWAWHeader.cxx
35  * Implements MWAWHeader (document's type, version, kind)
36  */
37 
38 #include <string.h>
39 #include <iostream>
40 
41 #include "libmwaw_internal.hxx"
42 
43 #include "MWAWEntry.hxx"
44 #include "MWAWInputStream.hxx"
45 #include "MWAWRSRCParser.hxx"
46 
47 #include "MWAWHeader.hxx"
48 
MWAWHeader(MWAWDocument::Type documentType,int vers,MWAWDocument::Kind kind)49 MWAWHeader::MWAWHeader(MWAWDocument::Type documentType, int vers, MWAWDocument::Kind kind)
50   : m_version(vers)
51   , m_docType(documentType)
52   , m_docKind(kind)
53 {
54 }
55 
~MWAWHeader()56 MWAWHeader::~MWAWHeader()
57 {
58 }
59 
60 /**
61  * So far, we have identified
62  */
constructHeader(MWAWInputStreamPtr input,std::shared_ptr<MWAWRSRCParser>)63 std::vector<MWAWHeader> MWAWHeader::constructHeader
64 (MWAWInputStreamPtr input, std::shared_ptr<MWAWRSRCParser> /*rsrcParser*/)
65 {
66   std::vector<MWAWHeader> res;
67   if (!input) return res;
68   // ------------ first check finder info -------------
69   std::string type, creator;
70   if (input->getFinderInfo(type, creator)) {
71     // set basic version, the correct will be filled by check header
72     if (creator=="ACTA") {
73       if (type=="OTLN") { // at least basic v2
74         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_ACTA, 1));
75         return res;
76       }
77       else if (type=="otln") {   // classic version
78         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_ACTA, 2));
79         return res;
80       }
81     }
82     else if (creator=="APBP") {
83       if (type=="APBL") {
84         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_DRAWINGTABLE, 1, MWAWDocument::MWAW_K_DRAW));
85         return res;
86       }
87     }
88     else if (creator=="ARTX") { // Painter X
89       if (type=="RIFF") {
90         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_CORELPAINTER, 10, MWAWDocument::MWAW_K_PAINT));
91         return res;
92       }
93     }
94     else if (creator=="BOBO") {
95       if (type=="CWDB" || type=="CWD2" || type=="sWDB") {
96         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_CLARISWORKS, 1, MWAWDocument::MWAW_K_DATABASE));
97         return res;
98       }
99       if (type=="CWGR" || type=="sWGR") {
100         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_CLARISWORKS, 1, MWAWDocument::MWAW_K_DRAW));
101         return res;
102       }
103       if (type=="CWSS" || type=="CWS2" || type=="sWSS") {
104         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_CLARISWORKS, 1, MWAWDocument::MWAW_K_SPREADSHEET));
105         return res;
106       }
107       if (type=="CWPR") {
108         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_CLARISWORKS, 1, MWAWDocument::MWAW_K_PRESENTATION));
109         return res;
110       }
111       if (type=="CWPT") {
112         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_CLARISWORKS, 1, MWAWDocument::MWAW_K_PAINT));
113         return res;
114       }
115       if (type=="CWWP" || type=="CWW2" || type=="sWPP") {
116         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_CLARISWORKS, 1, MWAWDocument::MWAW_K_TEXT));
117         return res;
118       }
119     }
120     else if (creator=="BWks") {
121       if (type=="BWwp") {
122         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_BEAGLEWORKS, 1));
123         return res;
124       }
125       if (type=="BWdb") {
126         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_BEAGLEWORKS, 1, MWAWDocument::MWAW_K_DATABASE));
127         return res;
128       }
129       if (type=="BWdr") {
130         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_BEAGLEWORKS, 1, MWAWDocument::MWAW_K_DRAW));
131         return res;
132       }
133       if (type=="BWpt") {
134         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_BEAGLEWORKS, 1, MWAWDocument::MWAW_K_PAINT));
135         return res;
136       }
137       if (type=="BWss") {
138         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_BEAGLEWORKS, 1, MWAWDocument::MWAW_K_SPREADSHEET));
139         return res;
140       }
141     }
142     else if (creator=="CDrw") {
143       if (type=="dDrw" || type=="dDst" || type=="iLib") {
144         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_CLARISDRAW, 1, MWAWDocument::MWAW_K_DRAW));
145         return res;
146       }
147     }
148     else if (creator=="CRDW") {
149       if (type=="CKDT") {
150         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_CRICKETDRAW, 1, MWAWDocument::MWAW_K_DRAW));
151         return res;
152       }
153     }
154     else if (creator=="C#+A") { // solo
155       if (type=="C#+D" || type=="C#+F") {
156         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_RAGTIME, 5));
157         return res;
158       }
159     }
160     else if (creator.substr(0,3)=="DAD") {
161       if (creator=="DAD2") {
162         if (type=="drw2") {
163           res.push_back(MWAWHeader(MWAWDocument::MWAW_T_CANVAS, 2, MWAWDocument::MWAW_K_DRAW));
164           return res;
165         }
166       }
167       else if (creator=="DAD5") {
168         if (type=="drw2") {
169           res.push_back(MWAWHeader(MWAWDocument::MWAW_T_CANVAS, 2, MWAWDocument::MWAW_K_DRAW));
170           return res;
171         }
172         if (type=="drw5" || type=="drwt") {
173           res.push_back(MWAWHeader(MWAWDocument::MWAW_T_CANVAS, 5, MWAWDocument::MWAW_K_DRAW));
174           return res;
175         }
176         if (type=="VINF") {
177           res.push_back(MWAWHeader(MWAWDocument::MWAW_T_CANVAS, 5, MWAWDocument::MWAW_K_PAINT));
178           return res;
179         }
180       }
181       else if (creator=="DAD6") {
182         if (type=="drw6" || type=="drwt") {
183           res.push_back(MWAWHeader(MWAWDocument::MWAW_T_CANVAS, 6, MWAWDocument::MWAW_K_DRAW));
184           return res;
185         }
186         if (type=="VINF") {
187           res.push_back(MWAWHeader(MWAWDocument::MWAW_T_CANVAS, 6, MWAWDocument::MWAW_K_PAINT));
188           return res;
189         }
190       }
191       else if (creator=="DAD7") {
192         if (type=="drw7" || type=="drwt") {
193           res.push_back(MWAWHeader(MWAWDocument::MWAW_T_CANVAS, 7, MWAWDocument::MWAW_K_DRAW));
194           return res;
195         }
196         if (type=="VINF") {
197           res.push_back(MWAWHeader(MWAWDocument::MWAW_T_CANVAS, 7, MWAWDocument::MWAW_K_PAINT));
198           return res;
199         }
200       }
201       else if (creator=="DAD8") {
202         if (type=="drw8" || type=="drwt") {
203           res.push_back(MWAWHeader(MWAWDocument::MWAW_T_CANVAS, 8, MWAWDocument::MWAW_K_DRAW));
204           return res;
205         }
206         if (type=="VINF") {
207           res.push_back(MWAWHeader(MWAWDocument::MWAW_T_CANVAS, 8, MWAWDocument::MWAW_K_PAINT));
208           return res;
209         }
210       }
211       else if (creator=="DAD9" || creator=="DADX") {
212         if (type=="drwX" || type=="drwt") {
213           res.push_back(MWAWHeader(MWAWDocument::MWAW_T_CANVAS, 9, MWAWDocument::MWAW_K_DRAW));
214           return res;
215         }
216       }
217     }
218     else if (creator=="Dc@P" || creator=="Dk@P") {
219       if (type=="APPL") {
220         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_DOCMAKER, 1));
221         return res;
222       }
223     }
224     else if (creator=="FHA2") {
225       if (type=="FHD2" || type=="FHT2") {
226         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_FREEHAND, 2, MWAWDocument::MWAW_K_DRAW));
227         return res;
228       }
229     }
230     else if (creator=="FS03") {
231       if (type=="WRT+") {
232         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_WRITERPLUS, 1));
233         return res;
234       }
235     }
236     else if (creator=="FSPS" || creator=="FSDA") { // Fractal Design Painter or Dabbler
237       if (type=="RIFF") {
238         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_CORELPAINTER, 1, MWAWDocument::MWAW_K_PAINT));
239         return res;
240       }
241     }
242     else if (creator=="FSX3") {
243       if (type=="RIFF") { // also FSFS list of uncompressed picture data for movie
244         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_CORELPAINTER, 3, MWAWDocument::MWAW_K_PAINT));
245         return res;
246       }
247     }
248     else if (creator=="FWRT") {
249       if (type=="FWRM") { // 1.7 ?
250         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_FULLWRITE, 1));
251         return res;
252       }
253       if (type=="FWRT") { // 1.0 ?
254         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_FULLWRITE, 1));
255         return res;
256       }
257       if (type=="FWRI") {
258         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_FULLWRITE,2));
259         return res;
260       }
261     }
262     else if (creator=="F#+A") { // Classic
263       if (type=="F#+D" || type=="F#+F") {
264         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_RAGTIME, 3));
265         return res;
266       }
267     }
268     else if (creator=="GM01") {
269       if (type=="GfMt") {
270         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MOUSEWRITE, 1));
271         return res;
272       }
273     }
274     else if (creator=="HMiw") {   // japonese
275       if (type=="IWDC") {
276         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_HANMACWORDJ,1));
277         return res;
278       }
279     }
280     else if (creator=="HMdr") {   // korean
281       if (type=="DRD2") {
282         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_HANMACWORDK,1));
283         return res;
284       }
285     }
286     else if (creator=="JAZZ") {
287       if (type=="JWPD") {
288         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_JAZZLOTUS,1));
289         return res;
290       }
291       else if (type=="JWKS") {
292         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_JAZZLOTUS, 1, MWAWDocument::MWAW_K_SPREADSHEET));
293         return res;
294       }
295       else if (type=="JDBS") {
296         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_JAZZLOTUS, 1, MWAWDocument::MWAW_K_DATABASE));
297         return res;
298       }
299     }
300     else if (creator=="LMAN") {
301       if (type=="TEXT") {
302         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_CANVAS, 7, MWAWDocument::MWAW_K_DRAW));
303         return res;
304       }
305     }
306     else if (creator=="LWTE") {
307       if (type=="TEXT" || type=="ttro") {
308         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_LIGHTWAYTEXT,1));
309         return res;
310       }
311     }
312     else if (creator=="LWTR") {
313       if (type=="APPL") {
314         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_LIGHTWAYTEXT,1));
315         return res;
316       }
317     }
318     else if (creator=="MACA") {
319       if (type=="WORD") {
320         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MACWRITE, 1));
321         return res;
322       }
323     }
324     else if (creator=="MACD") { // v1.0
325       if (type=="DRWG") {
326         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MACDRAFT, 1, MWAWDocument::MWAW_K_DRAW));
327         return res;
328       }
329     }
330     else if (creator=="MAXW") {
331       if (type=="MWCT") {
332         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MAXWRITE, 1));
333         return res;
334       }
335     }
336     else if (creator=="MD40") {
337       if (type=="MDDC" || type=="MSYM") {
338         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MACDRAFT, 4, MWAWDocument::MWAW_K_DRAW));
339         return res;
340       }
341     }
342     else if (creator=="MDFT") { // v1.2
343       if (type=="DRWG") {
344         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MACDRAFT, 1, MWAWDocument::MWAW_K_DRAW));
345         return res;
346       }
347     }
348     else if (creator=="MDPL") { // MacDraw II
349       if (type=="DRWG") {
350         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MACDRAWPRO, 0, MWAWDocument::MWAW_K_DRAW));
351         return res;
352       }
353       if (type=="STAT") { // stationery
354         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MACDRAWPRO, 0, MWAWDocument::MWAW_K_DRAW));
355         return res;
356       }
357     }
358     else if (creator=="MDRW") {
359       if (type=="DRWG") {
360         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MACDRAW, 1, MWAWDocument::MWAW_K_DRAW));
361         return res;
362       }
363     }
364     else if (creator=="MDsr") {
365       if (type=="APPL") { // auto content
366         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MACDOC, 1));
367         return res;
368       }
369     }
370     else if (creator=="MDvr") {
371       if (type=="MDdc") {
372         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MACDOC, 1));
373         return res;
374       }
375     }
376     else if (creator=="MMBB") {
377       if (type=="MBBT") {
378         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MARINERWRITE, 1));
379         return res;
380       }
381     }
382     else if (creator=="MORE") {
383       if (type=="MORE") {
384         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MORE, 1));
385         return res;
386       }
387     }
388     else if (creator=="MOR2") {
389       if (type=="MOR2") {
390         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MORE, 2));
391         return res;
392       }
393       if (type=="MOR3") {
394         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MORE, 3));
395         return res;
396       }
397     }
398     else if (creator=="MPNT") {
399       if (type=="PNTG") {
400         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MACPAINT, 1, MWAWDocument::MWAW_K_PAINT));
401         return res;
402       }
403     }
404     else if (creator=="MSWD") {
405       if (type=="WDBN" || type=="GLOS") {
406         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MICROSOFTWORD, 3));
407         return res;
408       }
409     }
410     else if (creator=="MSWK") {
411       if (type=="AWWP") {
412         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MICROSOFTWORKS, 3));
413         return res;
414       }
415       if (type=="AWDB") {
416         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MICROSOFTWORKS, 3, MWAWDocument::MWAW_K_DATABASE));
417         return res;
418       }
419       if (type=="AWDR") {
420         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MICROSOFTWORKS, 3, MWAWDocument::MWAW_K_DRAW));
421         return res;
422       }
423       if (type=="AWSS") {
424         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MICROSOFTWORKS, 2, MWAWDocument::MWAW_K_SPREADSHEET));
425         return res;
426       }
427       if (type=="RLRB" || type=="sWRB") {
428         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MICROSOFTWORKS, 4));
429         return res;
430       }
431     }
432     else if (creator=="MWII") {   // MacWriteII
433       if (type=="MW2D") {
434         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MACWRITEPRO, 0));
435         return res;
436       }
437     }
438     else if (creator=="MWPR") {
439       if (type=="MWPd") {
440         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MACWRITEPRO, 1));
441         return res;
442       }
443     }
444     else if (creator=="NISI") {
445       if (type=="TEXT") {
446         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_NISUSWRITER, 1));
447         return res;
448       }
449       if (type=="GLOS") { // checkme: glossary, ie. a list of picture/word, keep it ?
450         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_NISUSWRITER, 1));
451         return res;
452       }
453       // "edtt": empty file, probably created when the file is edited
454     }
455     else if (creator=="PANT") {
456       if (type=="PNTG") {
457         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_FULLPAINT, 1, MWAWDocument::MWAW_K_PAINT));
458         return res;
459       }
460     }
461     else if (creator=="PLAN") {
462       if (type=="MPBN") {
463         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MICROSOFTMULTIPLAN, 1, MWAWDocument::MWAW_K_SPREADSHEET));
464         return res;
465       }
466     }
467     else if (creator=="PIXR") {
468       if (type=="PX01") {
469         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_PIXELPAINT, 1, MWAWDocument::MWAW_K_DRAW));
470         return res;
471       }
472     }
473     else if (creator=="PPT3") {
474       if (type=="SLD3") {
475         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_POWERPOINT, 3, MWAWDocument::MWAW_K_PRESENTATION));
476         return res;
477       }
478     }
479     else if (creator=="PPNT") {
480       if (type=="SLDS") {
481         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_POWERPOINT, 2, MWAWDocument::MWAW_K_PRESENTATION));
482         return res;
483       }
484     }
485     else if (creator=="PSIP") {
486       if (type=="AWWP") {
487         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MICROSOFTWORKS, 1));
488         return res;
489       }
490     }
491     else if (creator=="PSI2") {
492       if (type=="AWWP") {
493         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MICROSOFTWORKS, 2));
494         return res;
495       }
496       if (type=="AWDB") {
497         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MICROSOFTWORKS, 2, MWAWDocument::MWAW_K_DATABASE));
498         return res;
499       }
500       if (type=="AWSS") {
501         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MICROSOFTWORKS, 2, MWAWDocument::MWAW_K_SPREADSHEET));
502         return res;
503       }
504     }
505     else if (creator=="PWRI") {
506       if (type=="OUTL") {
507         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MINDWRITE, 2));
508         return res;
509       }
510     }
511     else if (creator=="Rslv") {
512       if (type=="RsWs") {
513         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_CLARISRESOLVE, 1, MWAWDocument::MWAW_K_SPREADSHEET));
514         return res;
515       }
516     }
517     else if (creator=="R#+A") {
518       if (type=="R#+D" || type=="R#+F") {
519         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_RAGTIME, 3));
520         return res;
521       }
522     }
523     else if (creator=="SPNT") {
524       if (type=="SPTG") {
525         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_SUPERPAINT, 1, MWAWDocument::MWAW_K_PAINT));
526         return res;
527       }
528       if (type=="PNTG") {
529         // same as MacPaint format, so use the MacPaint parser
530         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MACPAINT, 1, MWAWDocument::MWAW_K_PAINT));
531         return res;
532       }
533       // other type seems to correspond to basic picture file, so we do not accept them
534     }
535     else if (creator=="StAV") {
536       if (type=="APPL") { // Style: document application
537         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_STYLE, 1));
538         return res;
539       }
540     }
541     else if (creator==std::string("St")+'\xd8'+"l") { //  argh, not standart character
542       std::string type1=std::string("TEd")+'\xb6'; // argh, not standart character
543       if (type==type1) {
544         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_STYLE, 1));
545         return res;
546       }
547     }
548     else if (creator=="SWCM") {
549       if (type=="JRNL" || type=="LTTR" || type=="NWSL" || type=="RPRT" || type=="SIGN") {
550         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_STUDENTWRITING, 1));
551         return res;
552       }
553     }
554     else if (creator=="TBB5") {
555       if (type=="TEXT" || type=="ttro") {
556         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_TEXEDIT, 1));
557         return res;
558       }
559     }
560     else if (creator=="WMkr") {
561       if (type=="Word" || type=="WSta") {
562         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_WORDMAKER, 1));
563         return res;
564       }
565     }
566     else if (creator=="WNGZ") {
567       if (type=="WZSS") {
568         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_WINGZ, 1, MWAWDocument::MWAW_K_SPREADSHEET));
569         return res;
570       }
571     }
572     else if (creator=="WORD") {
573       if (type=="WDBN") {
574         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MICROSOFTWORD, 1));
575         return res;
576       }
577     }
578     else if (creator=="ZEBR") {
579       if (type=="ZWRT") {
580         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_GREATWORKS, 1));
581         return res;
582       }
583       if (type=="ZOBJ") {
584         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_GREATWORKS, 1, MWAWDocument::MWAW_K_DRAW));
585         return res;
586       }
587       if (type=="PNTG") {
588         // same as MacPaint format, so use the MacPaint parser
589         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MACPAINT, 1, MWAWDocument::MWAW_K_PAINT));
590         return res;
591       }
592       if (type=="ZPNT") {
593         /* the ZPNT(v2) are basic pct files with some resources, but
594            we treat them to be complete */
595         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_GREATWORKS, 2, MWAWDocument::MWAW_K_PAINT));
596         return res;
597       }
598       if (type=="ZCAL") {
599         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_GREATWORKS, 1, MWAWDocument::MWAW_K_SPREADSHEET));
600         return res;
601       }
602       if (type=="ZDBS") {
603         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_GREATWORKS, 1, MWAWDocument::MWAW_K_DATABASE));
604         return res;
605       }
606       // can we treat also ZOLN ?
607     }
608     else if (creator=="ZWRT") {
609       if (type=="Zart") {
610         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_ZWRITE, 1));
611         return res;
612       }
613     }
614     else if (creator=="aca3") {
615       if (type=="acf3" || type=="act3") {
616         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_FREEHAND, 1, MWAWDocument::MWAW_K_DRAW));
617         return res;
618       }
619     }
620     else if (creator=="dPro") {
621       if (type=="dDoc") {
622         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MACDRAWPRO, 1, MWAWDocument::MWAW_K_DRAW));
623         return res;
624       }
625       if (type=="dLib") { // macdraw pro slide/library
626         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MACDRAWPRO, 1, MWAWDocument::MWAW_K_DRAW));
627         return res;
628       }
629     }
630     else if (creator=="eDcR") {
631       if (type=="eDoc") {
632         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_EDOC, 1));
633         return res;
634       }
635     }
636     else if (creator=="eSRD") {   // self reading application
637       if (type=="APPL") {
638         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_EDOC, 1));
639         return res;
640       }
641     }
642     else if (creator=="nX^n") {
643       if (type=="nX^d") {
644         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_WRITENOW, 2));
645         return res;
646       }
647       if (type=="nX^2") {
648         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_WRITENOW, 3));
649         return res;
650       }
651     }
652     else if (creator=="ttxt") {
653       if (type=="TEXT" || type=="ttro") {
654         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_TEACHTEXT, 1));
655         return res;
656       }
657     }
658     else if (type=="PICT") {
659       res.push_back(MWAWHeader(MWAWDocument::MWAW_T_APPLEPICT, 1, MWAWDocument::MWAW_K_DRAW));
660       return res;
661     }
662     MWAW_DEBUG_MSG(("MWAWHeader::constructHeader: unknown finder info: type=%s[%s]\n", type.c_str(), creator.c_str()));
663 
664   }
665 
666   // ----------- now check resource fork ------------
667   // ----------- now check data fork ------------
668   if (!input->hasDataFork() || input->size() < 8)
669     return res;
670 
671   input->seek(0, librevenge::RVNG_SEEK_SET);
672   int val[5];
673   for (auto &v : val) v = int(input->readULong(2));
674 
675   // ----------- clearly discriminant ------------------
676   if (val[2] == 0x424F && val[3] == 0x424F && (val[0]>>8) < 7) {
677     MWAW_DEBUG_MSG(("MWAWHeader::constructHeader: find a Claris Works file\n"));
678     int vers= (val[0] >> 8);
679     static int const typePos[7] = {0, 242, 248, 248, 256, 268, 278};
680     int typeFile=-1;
681     if (vers >= 1 && vers <= 6 && input->checkPosition(typePos[vers])) {
682       input->seek(typePos[vers], librevenge::RVNG_SEEK_SET);
683       typeFile=int(input->readLong(1));
684     }
685     switch (typeFile) {
686     case 0:
687       res.push_back(MWAWHeader(MWAWDocument::MWAW_T_CLARISWORKS, vers, MWAWDocument::MWAW_K_DRAW));
688       return res;
689     case 1:
690       res.push_back(MWAWHeader(MWAWDocument::MWAW_T_CLARISWORKS, vers, MWAWDocument::MWAW_K_TEXT));
691       return res;
692     case 2:
693       res.push_back(MWAWHeader(MWAWDocument::MWAW_T_CLARISWORKS, vers, MWAWDocument::MWAW_K_SPREADSHEET));
694       return res;
695     case 3:
696       res.push_back(MWAWHeader(MWAWDocument::MWAW_T_CLARISWORKS, vers, MWAWDocument::MWAW_K_DATABASE));
697       return res;
698     case 4:
699       res.push_back(MWAWHeader(MWAWDocument::MWAW_T_CLARISWORKS, vers, MWAWDocument::MWAW_K_PAINT));
700       return res;
701     case 5:
702       res.push_back(MWAWHeader(MWAWDocument::MWAW_T_CLARISWORKS, vers, MWAWDocument::MWAW_K_PRESENTATION));
703       return res;
704     default:
705       break;
706     }
707   }
708   if (val[0]==0x5772 && val[1]==0x6974 && val[2]==0x654e && val[3]==0x6f77) {
709     input->seek(8, librevenge::RVNG_SEEK_SET);
710     auto version = int(input->readLong(2));
711 
712 #ifdef DEBUG
713     bool ok = (version >= 0 && version <= 3);
714     if (ok)
715       MWAW_DEBUG_MSG(("MWAWHeader::constructHeader: find a WriteNow file version 3.0 or 4.0\n"));
716     else
717       MWAW_DEBUG_MSG(("MWAWHeader::constructHeader: find a WriteNow file (unknown version %d)\n", version));
718 #else
719     bool ok = version == 2;
720 #endif
721 
722     if (ok) {
723       res.push_back(MWAWHeader(MWAWDocument::MWAW_T_WRITENOW, 3));
724       return res;
725     }
726   }
727   if (val[0]==0x574e && val[1]==0x475a && val[2]==0x575a && val[3]==0x5353) {
728     MWAW_DEBUG_MSG(("MWAWHeader::constructHeader: find a Wingz file\n"));
729     res.push_back(MWAWHeader(MWAWDocument::MWAW_T_WINGZ, 1, MWAWDocument::MWAW_K_SPREADSHEET));
730     return res;
731   }
732   if (val[0]==0x4241 && val[1]==0x545F && val[2]==0x4254 && val[3]==0x5353) {
733     MWAW_DEBUG_MSG(("MWAWHeader::constructHeader: find a ClarisResolve file\n"));
734     res.push_back(MWAWHeader(MWAWDocument::MWAW_T_CLARISRESOLVE, 1, MWAWDocument::MWAW_K_SPREADSHEET));
735     return res;
736   }
737   if (val[0]==0x4323 && val[1]==0x2b44 && val[2]==0xa443 && val[3]==0x4da5) {
738     MWAW_DEBUG_MSG(("MWAWHeader::constructHeader: find a RagTime 5-6 file\n"));
739     res.push_back(MWAWHeader(MWAWDocument::MWAW_T_RAGTIME, 5));
740     return res;
741   }
742   if (val[0]==0x4646 && val[1]==0x4646 && val[2]==0x3030 && val[3]==0x3030) {
743     MWAW_DEBUG_MSG(("MWAWHeader::constructHeader: find a Mariner Write file\n"));
744     res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MARINERWRITE, 1));
745     return res;
746   }
747   if (val[0]==0x000c && val[1]==0x1357 && (val[2]==0x13 || val[2]==0x14) && val[3]==0) {
748     MWAW_DEBUG_MSG(("MWAWHeader::constructHeader: find a Drawing Table file\n"));
749     res.push_back(MWAWHeader(MWAWDocument::MWAW_T_DRAWINGTABLE, 1, MWAWDocument::MWAW_K_DRAW));
750     return res;
751   }
752   if (val[0]==0x4257 && val[1]==0x6b73 && val[2]==0x4257) {
753     if (val[3]==0x7770) {
754       MWAW_DEBUG_MSG(("MWAWHeader::constructHeader: find a BeagleWorks file\n"));
755       res.push_back(MWAWHeader(MWAWDocument::MWAW_T_BEAGLEWORKS, 1));
756       return res;
757     }
758     if (val[3]==0x6462) {
759       MWAW_DEBUG_MSG(("MWAWHeader::constructHeader: find a BeagleWorks Database file\n"));
760       res.push_back(MWAWHeader(MWAWDocument::MWAW_T_BEAGLEWORKS, 1, MWAWDocument::MWAW_K_DATABASE));
761       return res;
762     }
763     if (val[3]==0x6472) {
764       MWAW_DEBUG_MSG(("MWAWHeader::constructHeader: find a BeagleWorks Draw file\n"));
765       res.push_back(MWAWHeader(MWAWDocument::MWAW_T_BEAGLEWORKS, 1, MWAWDocument::MWAW_K_DRAW));
766       return res;
767     }
768     if (val[3]==0x7074) {
769       MWAW_DEBUG_MSG(("MWAWHeader::constructHeader: find a BeagleWorks Paint file\n"));
770       res.push_back(MWAWHeader(MWAWDocument::MWAW_T_BEAGLEWORKS, 1, MWAWDocument::MWAW_K_PAINT));
771       return res;
772     }
773     if (val[3]==0x7373) {
774       MWAW_DEBUG_MSG(("MWAWHeader::constructHeader: find a BeagleWorks Spreadsheet file\n"));
775       res.push_back(MWAWHeader(MWAWDocument::MWAW_T_BEAGLEWORKS, 1, MWAWDocument::MWAW_K_SPREADSHEET));
776       return res;
777     }
778   }
779   if (val[0]==0x4452 && val[1]==0x5747) { // DRWG
780     if (val[2]==0x4d44) { // MD
781       MWAW_DEBUG_MSG(("MWAWHeader::constructHeader: find a MacDraw file\n"));
782       res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MACDRAW, 1, MWAWDocument::MWAW_K_DRAW));
783       return res;
784     }
785     if (val[2]==0 || val[2]==0x4432) { // D2
786       MWAW_DEBUG_MSG(("MWAWHeader::constructHeader: find a MacDraw II file\n"));
787       res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MACDRAWPRO, 0, MWAWDocument::MWAW_K_DRAW));
788       // can also be a classic apple pict, so let's continue
789     }
790   }
791   if (val[0]==0x1a54 && val[1]==0x4c43 && (val[2]&0xfeff)==0x246 && val[3]==0x4600) {
792     MWAW_DEBUG_MSG(("MWAWHeader::constructHeader: find a Student Writing Center file\n"));
793     res.push_back(MWAWHeader(MWAWDocument::MWAW_T_STUDENTWRITING, 1));
794   }
795   if (val[0]==0x5354 && val[1]==0x4154 && (val[2]==0 || val[2]==0x4432)) {
796     MWAW_DEBUG_MSG(("MWAWHeader::constructHeader: find a MacDraw II template file\n"));
797     res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MACDRAWPRO, 0, MWAWDocument::MWAW_K_DRAW));
798     return res;
799   }
800 #ifdef DEBUG
801   // we need the resource fork to find the colors, patterns, ... ; so not active in normal mode
802   if (val[0]==0x6444 && val[1]==0x6f63 && val[2]==0x4432) { // dDocD2
803     MWAW_DEBUG_MSG(("MWAWHeader::constructHeader: find a MacDraw Pro file\n"));
804     res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MACDRAWPRO, 1, MWAWDocument::MWAW_K_DRAW));
805     return res;
806   }
807   if (val[0]==0x644c && val[1]==0x6962 && val[2]==0x4432) { // dLibD2
808     MWAW_DEBUG_MSG(("MWAWHeader::constructHeader: find a MacDraw Pro template file\n"));
809     res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MACDRAWPRO, 1, MWAWDocument::MWAW_K_DRAW));
810     return res;
811   }
812 #endif
813   // Canvas
814   if (val[0]==0x200 && val[1]==0x80) {
815     if (val[2]==0 && val[3]==0 && (val[4]>>8)<=8 && (val[4]&0xff)==0) {
816       MWAW_DEBUG_MSG(("MWAWHeader::constructHeader: find a potential Canvas 5 file\n"));
817       res.push_back(MWAWHeader(MWAWDocument::MWAW_T_CANVAS, 5, MWAWDocument::MWAW_K_DRAW));
818     }
819     else { // 0 followed by compression mode
820       input->seek(9, librevenge::RVNG_SEEK_SET);
821       auto len=input->readULong(4);
822       if (len>=0x800 && len<=0x8000) { // block size
823         auto len1=input->readULong(4);
824         if (len1>0x800 && len1<=0x800c) {
825           MWAW_DEBUG_MSG(("MWAWHeader::constructHeader: find a potential Canvas 6-8 file\n"));
826           res.push_back(MWAWHeader(MWAWDocument::MWAW_T_CANVAS, 6, MWAWDocument::MWAW_K_DRAW));
827         }
828       }
829     }
830   }
831   if (val[0]==0x100 && val[1]==0x8000) {
832     if ((val[2]>=0&&val[2]<=8) && val[3]==0 && (val[4]>>8)==0) {
833       MWAW_DEBUG_MSG(("MWAWHeader::constructHeader: find a potential Canvas 5 win file\n"));
834       res.push_back(MWAWHeader(MWAWDocument::MWAW_T_CANVAS, 5, MWAWDocument::MWAW_K_DRAW));
835     }
836     else {
837       input->setReadInverted(true);
838       input->seek(9, librevenge::RVNG_SEEK_SET);
839       auto len=input->readULong(4);
840       if (len>=0x800 && len<=0x8000) { // block size
841         auto len1=input->readULong(4);
842         if (len1>0x800 && len1<=0x800c) {
843           MWAW_DEBUG_MSG(("MWAWHeader::constructHeader: find a potential Canvas 6-8 win file\n"));
844           res.push_back(MWAWHeader(MWAWDocument::MWAW_T_CANVAS, 6, MWAWDocument::MWAW_K_DRAW));
845         }
846       }
847       input->setReadInverted(false);
848     }
849   }
850   if (val[0]==0 && val[1]==0 && val[2]==0 && val[3]==0 && val[4]==0) {
851     input->seek(10, librevenge::RVNG_SEEK_SET);
852     int v=int(input->readULong(2));
853     if ((v==0x100 && input->readULong(2)==0x8000) || // windows
854         (v==0x200 && input->readULong(2)==0x80)) { // mac
855       MWAW_DEBUG_MSG(("MWAWHeader::constructHeader: find a potential Canvas 9-11 file\n"));
856       res.push_back(MWAWHeader(MWAWDocument::MWAW_T_CANVAS, 9, MWAWDocument::MWAW_K_DRAW));
857     }
858   }
859   if (val[0]==0 && (val[1]==1||val[1]==2) && val[2]==0x4441 && val[3]==0x4435 && val[4]==0x5052) {
860     if (val[1]==1) {
861       MWAW_DEBUG_MSG(("MWAWHeader::constructHeader: find a potential Canvas 5-8 image file\n"));
862     }
863     else {
864       MWAW_DEBUG_MSG(("MWAWHeader::constructHeader: find a potential Canvas 9-10 image file\n"));
865     }
866     res.push_back(MWAWHeader(MWAWDocument::MWAW_T_CANVAS, val[1]==1 ? 5 : 9, MWAWDocument::MWAW_K_PAINT));
867   }
868   if (val[0]==2 && val[1]==0 && val[2]==2 && val[3]==0x262 && val[4]==0x262) {
869     MWAW_DEBUG_MSG(("MWAWHeader::constructHeader: find a MacDraft file\n"));
870     res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MACDRAFT, 1, MWAWDocument::MWAW_K_DRAW));
871     return res;
872   }
873   if (val[0]==0x4859 && val[1]==0x4c53 && val[2]==0x0210) {
874     MWAW_DEBUG_MSG(("MWAWHeader::constructHeader: find a HanMac Word-K file\n"));
875     res.push_back(MWAWHeader(MWAWDocument::MWAW_T_HANMACWORDK, 1));
876     return res;
877   }
878   if (val[0]==0x594c && val[1]==0x5953 && val[2]==0x100) {
879     MWAW_DEBUG_MSG(("MWAWHeader::constructHeader: find a HanMac Word-J file\n"));
880     res.push_back(MWAWHeader(MWAWDocument::MWAW_T_HANMACWORDJ, 1));
881     return res;
882   }
883   if (val[0]==0x6163 && val[1]==0x6633 && val[2]<9) {
884     MWAW_DEBUG_MSG(("MWAWHeader::constructHeader: find a FreeHand v1\n"));
885     res.push_back(MWAWHeader(MWAWDocument::MWAW_T_FREEHAND, 1, MWAWDocument::MWAW_K_DRAW));
886     return res;
887   }
888   if (val[0]==0x4648 && val[1]==0x4432 && val[2]<20) {
889     MWAW_DEBUG_MSG(("MWAWHeader::constructHeader: find a FreeHand v2\n"));
890     res.push_back(MWAWHeader(MWAWDocument::MWAW_T_FREEHAND, 2, MWAWDocument::MWAW_K_DRAW));
891     return res;
892   }
893   if (val[0]==3 && val[1]==0x4d52 && val[2]==0x4949 && val[3]==0x80) { // MRII
894     res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MORE, 2));
895     return res;
896   }
897   if (val[0]==6 && val[1]==0x4d4f && val[2]==0x5233 && val[3]==0x80) { // MOR3
898     res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MORE, 3));
899     return res;
900   }
901   if ((val[0]==0x100||val[0]==0x200) && val[2]==0x4558 && val[3]==0x5057) { // CHANGEME: ClarisDraw
902     res.push_back(MWAWHeader(MWAWDocument::MWAW_T_CLARISDRAW, 1, MWAWDocument::MWAW_K_DRAW));
903     return res;
904   }
905 
906   if (val[0]==0x100 || val[0]==0x200) {
907     if (val[1]==0x5a57 && val[2]==0x5254) {
908       res.push_back(MWAWHeader(MWAWDocument::MWAW_T_GREATWORKS, val[0]==0x100 ? 1 : 2));
909       return res;
910     }
911     if (val[1]==0x5a4f && val[2]==0x424a) {
912       res.push_back(MWAWHeader(MWAWDocument::MWAW_T_GREATWORKS, val[0]==0x100 ? 1 : 2, MWAWDocument::MWAW_K_DRAW));
913       return res;
914     }
915     if (val[1]==0x5a43 && val[2]==0x414C) {
916       res.push_back(MWAWHeader(MWAWDocument::MWAW_T_GREATWORKS, val[0]==0x100 ? 1 : 2, MWAWDocument::MWAW_K_SPREADSHEET));
917       return res;
918     }
919     if (val[1]==0x5a44 && val[2]==0x4253) {
920       res.push_back(MWAWHeader(MWAWDocument::MWAW_T_GREATWORKS, val[0]==0x100 ? 1 : 2, MWAWDocument::MWAW_K_DATABASE));
921       return res;
922     }
923     // maybe we can also add outline: if (val[1]==0x5a4f && val[2]==0x4c4e)
924   }
925   if (val[0]==0x11ab && val[1]==0 && val[2]==0x13e8 && val[3]==0) {
926     res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MICROSOFTMULTIPLAN, 1, MWAWDocument::MWAW_K_SPREADSHEET));
927     return res;
928   }
929   if (val[3]==6 && val[4]<6) {
930     if (val[0]==0x4d44 && val[1]==0x4443 && val[2]==0x3230) {
931       res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MACDRAFT, 4, MWAWDocument::MWAW_K_DRAW));
932       return res;
933     }
934     // can be a library file, this will be test in the parser
935     if (input->size()>=30)
936       res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MACDRAFT, 4, MWAWDocument::MWAW_K_DRAW));
937   }
938   // magic ole header
939   if (val[0]==0xd0cf && val[1]==0x11e0 && val[2]==0xa1b1 && val[3]==0x1ae1 && input->isStructured()) {
940     MWAWInputStreamPtr mainOle = input->getSubStreamByName("MN0");
941     if (mainOle && mainOle->readULong(4) == 0x43484e4b)
942       res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MICROSOFTWORKS, 4));
943     else if (mainOle && mainOle->size()>18) {
944       mainOle->seek(16, librevenge::RVNG_SEEK_SET);
945       auto value=static_cast<int>(mainOle->readULong(2));
946       switch (value) {
947       case 2:
948         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MICROSOFTWORKS, 4, MWAWDocument::MWAW_K_DATABASE));
949         break;
950       case 3:
951         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MICROSOFTWORKS, 4, MWAWDocument::MWAW_K_SPREADSHEET));
952         break;
953       case 12:
954         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MICROSOFTWORKS, 4, MWAWDocument::MWAW_K_DRAW));
955         break;
956       default:
957         break;
958       }
959     }
960     if (!mainOle && input->getSubStreamByName("PP40"))
961       res.push_back(MWAWHeader(MWAWDocument::MWAW_T_POWERPOINT, 4, MWAWDocument::MWAW_K_PRESENTATION));
962     else if (!mainOle && input->getSubStreamByName("PowerPoint Document") && input->getSubStreamByName("PersistentStorage Directory"))
963       res.push_back(MWAWHeader(MWAWDocument::MWAW_T_POWERPOINT, 7, MWAWDocument::MWAW_K_PRESENTATION));
964   }
965   if (val[0]==0 && val[1]==2 && val[2]==11) {
966     MWAW_DEBUG_MSG(("MWAWHeader::constructHeader: find a potential Jazz spreadsheet file\n"));
967     res.push_back(MWAWHeader(MWAWDocument::MWAW_T_JAZZLOTUS, 1, MWAWDocument::MWAW_K_SPREADSHEET));
968   }
969 
970   if ((val[0]==0xfe32 && val[1]==0) || (val[0]==0xfe34 && val[1]==0) ||
971       (val[0] == 0xfe37 && (val[1] == 0x23 || val[1] == 0x1c))) {
972     int vers = -1;
973     switch (val[1]) {
974     case 0:
975       if (val[0]==0xfe34) {
976         MWAW_DEBUG_MSG(("MWAWHeader::constructHeader: find a Word 3.0 file\n"));
977         vers = 3;
978       }
979       else if (val[0]==0xfe32) {
980         MWAW_DEBUG_MSG(("MWAWHeader::constructHeader: find a Word 1.0 file\n"));
981         vers = 1;
982       }
983       break;
984     case 0x1c:
985       MWAW_DEBUG_MSG(("MWAWHeader::constructHeader: find a Word 4.0 file\n"));
986       vers = 4;
987       break;
988     case 0x23:
989       MWAW_DEBUG_MSG(("MWAWHeader::constructHeader: find a Word 5.0 file\n"));
990       vers = 5;
991       break;
992     default:
993       break;
994     }
995     if (vers >= 0)
996       res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MICROSOFTWORD, vers));
997   }
998   if (val[0]==0xbad && val[1]==0xdeed && val[2]==0 && (val[3]>=2 && val[3]<=3)) {
999     MWAW_DEBUG_MSG(("MWAWHeader::constructHeader: find a Presentation file\n"));
1000     res.push_back(MWAWHeader(MWAWDocument::MWAW_T_POWERPOINT, val[3], MWAWDocument::MWAW_K_PRESENTATION));
1001   }
1002   if (val[0]==0xedde && val[1]==0xad0b && val[3]==0 && (val[2]&0xFF)==0) {
1003     int vers=(val[2]>>8);
1004     if (vers>=2 && vers<=3) {
1005       MWAW_DEBUG_MSG(("MWAWHeader::constructHeader: find a Presentation file\n"));
1006       res.push_back(MWAWHeader(MWAWDocument::MWAW_T_POWERPOINT, vers, MWAWDocument::MWAW_K_PRESENTATION));
1007     }
1008   }
1009   if (val[0]==0x4348 && val[1]==0x4e4b && val[2]==0x100 && val[3]==0) {
1010     MWAW_DEBUG_MSG(("MWAWHeader::constructHeader: find a Style file\n"));
1011     res.push_back(MWAWHeader(MWAWDocument::MWAW_T_STYLE, 1));
1012   }
1013   if (val[0]==0x0447 && val[1]==0x4d30 && val[2]==0x3400) { // ^DGM04
1014     MWAW_DEBUG_MSG(("MWAWHeader::constructHeader: find a MouseWrite file\n"));
1015     res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MOUSEWRITE, 1));
1016   }
1017   // ----------- less discriminant ------------------
1018   if (val[0] == 0x2e && val[1] == 0x2e) {
1019     MWAW_DEBUG_MSG(("MWAWHeader::constructHeader: find a MacWrite II file\n"));
1020     res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MACWRITEPRO, 0));
1021   }
1022   if (val[0] == 4 && val[1] == 4) {
1023     MWAW_DEBUG_MSG(("MWAWHeader::constructHeader: find a MacWritePro file\n"));
1024     res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MACWRITEPRO, 1));
1025   }
1026   if (val[0]==0x464f && val[1]==0x524d) {
1027     MWAW_DEBUG_MSG(("MWAWHeader::constructHeader: find a WordMaker file\n"));
1028     res.push_back(MWAWHeader(MWAWDocument::MWAW_T_WORDMAKER, 1));
1029   }
1030   if (val[0] == 0x7704) {
1031     MWAW_DEBUG_MSG(("MWAWHeader::constructHeader: find a MindWrite file 2.1\n"));
1032     res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MINDWRITE, 2));
1033   }
1034 
1035   // ----------- other ------------------
1036   if (val[0]==0 && val[1]==0 && val[2]==0 && val[3]==0) {
1037     input->seek(8, librevenge::RVNG_SEEK_SET);
1038     auto value=static_cast<int>(input->readULong(1));
1039     if (value==0x4 || value==0x44) {
1040       MWAW_DEBUG_MSG(("MWAWHeader::constructHeader: find a WriteNow 1.0 or 2.0 file\n"));
1041       res.push_back(MWAWHeader(MWAWDocument::MWAW_T_WRITENOW, 2));
1042     }
1043   }
1044   if (val[0]==0 && input->size() > 32) {
1045     input->seek(16, librevenge::RVNG_SEEK_SET);
1046     if (input->readLong(2)==0x688f && input->readLong(2)==0x688f) {
1047       MWAW_DEBUG_MSG(("MWAWHeader::constructHeader: find a RagTime file\n"));
1048       res.push_back(MWAWHeader(MWAWDocument::MWAW_T_RAGTIME));
1049     }
1050   }
1051   if (val[0]==0) {
1052     int vers = -1;
1053     switch (val[1]) {
1054     case 4:
1055       vers = 1;
1056       break;
1057     case 8:
1058       vers = 2;
1059       break;
1060     case 9:
1061       vers = 3;
1062       break;
1063     case 11: // embedded data
1064       vers = 4;
1065       break;
1066     default:
1067       break;
1068     }
1069     if (vers > 0 && input->size()>16) {
1070       input->seek(16, librevenge::RVNG_SEEK_SET);
1071       auto value=static_cast<int>(input->readULong(2));
1072       switch (value) {
1073       case 1:
1074         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MICROSOFTWORKS, vers));
1075         break;
1076       case 2:
1077         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MICROSOFTWORKS, vers, MWAWDocument::MWAW_K_DATABASE));
1078         break;
1079       case 3:
1080         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MICROSOFTWORKS, vers, MWAWDocument::MWAW_K_SPREADSHEET));
1081         break;
1082       case 12:
1083         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MICROSOFTWORKS, vers, MWAWDocument::MWAW_K_DRAW));
1084         break;
1085       default:
1086         break;
1087       }
1088     }
1089   }
1090   if (val[0]==0x4d44 && input->size()>=512) { // maybe a MacDraw 0 file, will be check later
1091     res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MACDRAW, 0, MWAWDocument::MWAW_K_DRAW));
1092   }
1093   if (val[0]==2 && (val[1]&0xff)==0 && input->size() > 300) {
1094     res.push_back(MWAWHeader(MWAWDocument::MWAW_T_CORELPAINTER, 1, MWAWDocument::MWAW_K_PAINT));
1095   }
1096   if (val[0] == 3 || val[0] == 6) {
1097     // version will be print by MacWrtParser::check
1098     res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MACWRITE, val[0]));
1099   }
1100   if (val[0] == 0x110) {
1101     MWAW_DEBUG_MSG(("MWAWHeader::constructHeader: find a Writerplus file\n"));
1102     res.push_back(MWAWHeader(MWAWDocument::MWAW_T_WRITERPLUS, 1));
1103   }
1104   if (val[0] == 0x1000) {
1105     input->seek(10, librevenge::RVNG_SEEK_SET);
1106     auto value=static_cast<int>(input->readULong(2));
1107     // 1: bitmap, 2: vectorized graphic
1108     if (value==1)
1109       res.push_back(MWAWHeader(MWAWDocument::MWAW_T_SUPERPAINT, 1, MWAWDocument::MWAW_K_PAINT));
1110     else if (value==2)
1111       res.push_back(MWAWHeader(MWAWDocument::MWAW_T_SUPERPAINT, 1, MWAWDocument::MWAW_K_DRAW));
1112   }
1113   if (val[0]==0 && (val[1]==0x7FFF || val[1]==0x8000)) {
1114     MWAW_DEBUG_MSG(("MWAWHeader::constructHeader: find a potential PixelPaint file\n"));
1115     res.push_back(MWAWHeader(MWAWDocument::MWAW_T_PIXELPAINT, (val[1]==0x7FFF) ? 1  : 2, MWAWDocument::MWAW_K_PAINT));
1116   }
1117   if (val[0]>=1 && val[0]<=4) {
1118     int sSz=(val[1]>>8);
1119     if (sSz>=6 && sSz<=8) {
1120       // check if we find a date
1121       input->seek(3, librevenge::RVNG_SEEK_SET);
1122       bool ok=true;
1123       int numSlash=0;
1124       for (int i=0; i<sSz; ++i) {
1125         auto c=char(input->readULong(1));
1126         if (c>='0' && c<='9')
1127           continue;
1128         if (c=='/')
1129           ++numSlash;
1130         else {
1131           ok=false;
1132           break;
1133         }
1134       }
1135       if (ok && numSlash==2)
1136         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_CRICKETDRAW, 1, MWAWDocument::MWAW_K_DRAW));
1137     }
1138   }
1139 
1140   //
1141   // check for pict
1142   //
1143   for (int st=0; st<2; ++st) {
1144     if (!input->checkPosition(512*st+13))
1145       break;
1146     input->seek(512*st+10, librevenge::RVNG_SEEK_SET);
1147     auto value=static_cast<int>(input->readULong(2));
1148     if (value==0x1101) {
1149       res.push_back(MWAWHeader(MWAWDocument::MWAW_T_APPLEPICT, 1, MWAWDocument::MWAW_K_DRAW));
1150       break;
1151     }
1152     else if (value==0x11 && input->readULong(2)==0x2ff && input->readULong(2) == 0xC00) {
1153       res.push_back(MWAWHeader(MWAWDocument::MWAW_T_APPLEPICT, 2, MWAWDocument::MWAW_K_DRAW));
1154       break;
1155     }
1156   }
1157   //
1158   // middle of file
1159   //
1160   if (input->size()>=512+720*2) {
1161     // check for a MacPaint file
1162     input->seek(512, librevenge::RVNG_SEEK_SET);
1163     bool ok=true;
1164     // check the first 3 row
1165     for (int row=0; row<3; ++row) {
1166       int lastColor=-1;
1167       int col=0;
1168       while (col<72) {
1169         if (input->tell()+2>input->size()) {
1170           ok=false;
1171           break;
1172         }
1173         auto wh=static_cast<int>(input->readULong(1));
1174         if (wh>=0x81) {
1175           auto color=static_cast<int>(input->readULong(1));
1176           // consider that repeat color is anormal...
1177           if (col+(0x101-wh)>72 || (lastColor>=0 && color==lastColor)) {
1178             ok=false;
1179             break;
1180           }
1181           col+=(0x101-wh);
1182           lastColor=color;
1183           continue;
1184         }
1185         if (col+1+wh>72) {
1186           ok=false;
1187           break;
1188         }
1189         lastColor=-1;
1190         col += wh+1;
1191         input->seek(wh+1, librevenge::RVNG_SEEK_CUR);
1192       }
1193       if (!ok) break;
1194     }
1195     if (ok) {
1196       MWAW_DEBUG_MSG(("MWAWHeader::constructHeader: find a potential MacPaint file\n"));
1197       res.push_back(MWAWHeader(MWAWDocument::MWAW_T_MACPAINT, 1, MWAWDocument::MWAW_K_PAINT));
1198     }
1199   }
1200   if ((val[0]>0 || val[1]>=86) && input->size()>0x900) {
1201     input->seek(0x34, librevenge::RVNG_SEEK_SET);
1202     int littleEndian=int(input->readULong(1));
1203     if (littleEndian==1)
1204       input->setReadInverted(true);
1205     input->seek(1, librevenge::RVNG_SEEK_CUR);
1206     int vers=int(input->readULong(2));
1207     if (littleEndian<=1 && (vers==1 || vers==2)) {
1208       input->seek(0, librevenge::RVNG_SEEK_SET);
1209       int numZero=0;
1210       for (int i=0; i<13; ++i) {
1211         int len=int(input->readLong(4));
1212         if (len<0) {
1213           numZero=1000;
1214           break;
1215         }
1216         if (len==0)
1217           ++numZero;
1218       }
1219       if (numZero<=2+littleEndian) {
1220         MWAW_DEBUG_MSG(("MWAWHeader::constructHeader: find a potential Canvas 2/3 file\n"));
1221         res.push_back(MWAWHeader(MWAWDocument::MWAW_T_CANVAS, vers+1, MWAWDocument::MWAW_K_DRAW));
1222       }
1223     }
1224     if (littleEndian==1)
1225       input->setReadInverted(false);
1226   }
1227   //
1228   //ok now look at the end of file
1229   //
1230   if (input->seek(-4, librevenge::RVNG_SEEK_END))
1231     return res;
1232   int lVal[2];
1233   for (auto &v : lVal) v=int(input->readULong(2));
1234   if (lVal[0] == 0x4E4C && lVal[1]==0x544F) // NLTO
1235     res.push_back(MWAWHeader(MWAWDocument::MWAW_T_ACTA, 2));
1236   else if (lVal[1]==0 && val[0]==1 && (val[1]==1||val[1]==2))
1237     res.push_back(MWAWHeader(MWAWDocument::MWAW_T_ACTA, 1));
1238   else if (lVal[0] == 0x4657 && lVal[1]==0x5254) // FWRT
1239     res.push_back(MWAWHeader(MWAWDocument::MWAW_T_FULLWRITE, 2));
1240   else if (lVal[0] == 0 && lVal[1]==1) // not probable, but
1241     res.push_back(MWAWHeader(MWAWDocument::MWAW_T_FULLWRITE, 1));
1242 
1243   input->seek(0, librevenge::RVNG_SEEK_SET);
1244   return res;
1245 }
1246 // vim: set filetype=cpp tabstop=2 shiftwidth=2 cindent autoindent smartindent noexpandtab:
1247