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