/src/libwpg/src/lib/WPGraphics.cpp
Line | Count | Source |
1 | | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ |
2 | | /* libwpg |
3 | | * Version: MPL 2.0 / LGPLv2.1+ |
4 | | * |
5 | | * This Source Code Form is subject to the terms of the Mozilla Public |
6 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
7 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. |
8 | | * |
9 | | * Major Contributor(s): |
10 | | * Copyright (C) 2006 Ariya Hidayat (ariya@kde.org) |
11 | | * Copyright (C) 2007 Fridrich Strba (fridrich.strba@bluewin.ch) |
12 | | * |
13 | | * For minor contributions see the git repository. |
14 | | * |
15 | | * Alternatively, the contents of this file may be used under the terms |
16 | | * of the GNU Lesser General Public License Version 2.1 or later |
17 | | * (LGPLv2.1+), in which case the provisions of the LGPLv2.1+ are |
18 | | * applicable instead of those above. |
19 | | * |
20 | | * For further information visit http://libwpg.sourceforge.net |
21 | | */ |
22 | | |
23 | | /* "This product is not manufactured, approved, or supported by |
24 | | * Corel Corporation or Corel Corporation Limited." |
25 | | */ |
26 | | |
27 | | #include <memory> |
28 | | #include <sstream> |
29 | | |
30 | | #include <libwpg/libwpg.h> |
31 | | |
32 | | #include "WPG1Parser.h" |
33 | | #include "WPG2Parser.h" |
34 | | #include "WPGHeader.h" |
35 | | #include "WPGXParser.h" |
36 | | #include "libwpg_utils.h" |
37 | | |
38 | | /** |
39 | | Analyzes the content of an input stream to see if it can be parsed |
40 | | \param input The input stream |
41 | | \return A value that indicates whether the content from the input |
42 | | stream is a WordPerfect Graphics that libwpg is able to parse |
43 | | */ |
44 | | WPGAPI bool libwpg::WPGraphics::isSupported(librevenge::RVNGInputStream *input) |
45 | 0 | { |
46 | 0 | if (!input) |
47 | 0 | return false; |
48 | | |
49 | 0 | std::shared_ptr<librevenge::RVNGInputStream> graphics; |
50 | |
|
51 | 0 | if (input->isStructured()) |
52 | 0 | { |
53 | 0 | graphics.reset(input->getSubStreamByName("PerfectOffice_MAIN")); |
54 | 0 | if (!graphics) |
55 | 0 | return false; |
56 | 0 | } |
57 | 0 | else |
58 | 0 | graphics.reset(input, WPGDummyDeleter()); |
59 | | |
60 | 0 | graphics->seek(0, librevenge::RVNG_SEEK_SET); |
61 | |
|
62 | 0 | WPGHeader header; |
63 | 0 | if (header.load(graphics.get())) |
64 | 0 | return header.isSupported(); |
65 | | |
66 | 0 | return false; |
67 | 0 | } |
68 | | |
69 | | /** |
70 | | Parses the input stream content. It will make callbacks to the functions provided by a |
71 | | librevenge::RVNGDrawingInterface class implementation when needed. This is often commonly called the |
72 | | 'main parsing routine'. |
73 | | \param input The input stream |
74 | | \param drawingInterface A WPGPainterInterface implementation |
75 | | \return A value that indicates whether the parsing was successful |
76 | | */ |
77 | | WPGAPI bool libwpg::WPGraphics::parse(librevenge::RVNGInputStream *input, ::librevenge::RVNGDrawingInterface *drawingInterface, libwpg::WPGFileFormat fileFormat) |
78 | 17.7k | { |
79 | 17.7k | if (!input || !drawingInterface) |
80 | 0 | return false; |
81 | | |
82 | 17.7k | std::shared_ptr<librevenge::RVNGInputStream> graphics; |
83 | | |
84 | 17.7k | if (input->isStructured()) |
85 | 1.71k | { |
86 | 1.71k | graphics.reset(input->getSubStreamByName("PerfectOffice_MAIN")); |
87 | 1.71k | if (!graphics) |
88 | 1.35k | return false; |
89 | 1.71k | } |
90 | 16.0k | else |
91 | 16.0k | graphics.reset(input, WPGDummyDeleter()); |
92 | | |
93 | 16.3k | graphics->seek(0, librevenge::RVNG_SEEK_SET); |
94 | | |
95 | 16.3k | WPG_DEBUG_MSG(("Loading header...\n")); |
96 | 16.3k | unsigned char tmpMajorVersion = 0x00; |
97 | 16.3k | if (fileFormat == WPG_WPG1) |
98 | 0 | tmpMajorVersion = 0x01; |
99 | 16.3k | else if (fileFormat == WPG_WPG2) |
100 | 0 | tmpMajorVersion = 0x02; |
101 | 16.3k | WPGHeader header; |
102 | 16.3k | if (!header.load(graphics.get())) |
103 | 110 | return false; |
104 | | |
105 | 16.2k | if (!header.isSupported() && (fileFormat == WPG_AUTODETECT)) |
106 | 990 | { |
107 | 990 | WPG_DEBUG_MSG(("Unsupported file format!\n")); |
108 | 990 | return false; |
109 | 990 | } |
110 | 15.2k | else if (header.isSupported()) |
111 | 15.2k | { |
112 | | // seek to the start of document |
113 | 15.2k | graphics->seek((long)header.startOfDocument(), librevenge::RVNG_SEEK_SET); |
114 | 15.2k | tmpMajorVersion = (unsigned char)(header.majorVersion()); |
115 | 15.2k | if (tmpMajorVersion == 0x01) |
116 | 1.54k | { |
117 | 1.54k | unsigned long returnPosition = header.startOfDocument(); |
118 | | /* Due to a bug in dumping mechanism, we produced |
119 | | * invalid WPG files by prepending a WPG1 header |
120 | | * to a valid WP file. Let us check this kind of files, |
121 | | * so that we can load our own mess too. */ |
122 | 1.54k | if (header.load(graphics.get()) && header.isSupported()) |
123 | 77 | { |
124 | 77 | WPG_DEBUG_MSG(("An invalid graphics we produced :(\n")); |
125 | 77 | graphics->seek((long) header.startOfDocument() + 16, librevenge::RVNG_SEEK_SET); |
126 | 77 | tmpMajorVersion = (unsigned char)(header.majorVersion()); |
127 | 77 | } |
128 | 1.47k | else |
129 | 1.47k | graphics->seek((long) returnPosition, librevenge::RVNG_SEEK_SET); |
130 | | |
131 | 1.54k | } |
132 | 15.2k | } |
133 | 0 | else |
134 | | // here we force parsing of headerless pictures |
135 | 0 | graphics->seek(0, librevenge::RVNG_SEEK_SET); |
136 | | |
137 | 15.2k | std::unique_ptr<WPGXParser> parser; |
138 | 15.2k | switch (tmpMajorVersion) |
139 | 15.2k | { |
140 | 1.53k | case 0x01: // WPG1 |
141 | 1.53k | WPG_DEBUG_MSG(("Parsing WPG1\n")); |
142 | 1.53k | parser.reset(new WPG1Parser(graphics.get(), drawingInterface)); |
143 | 1.53k | return parser->parse(); |
144 | 13.7k | case 0x02: // WPG2 |
145 | 13.7k | WPG_DEBUG_MSG(("Parsing WPG2\n")); |
146 | 13.7k | parser.reset(new WPG2Parser(graphics.get(), drawingInterface)); |
147 | 13.7k | return parser->parse(); |
148 | 0 | default: // other :-) |
149 | 0 | WPG_DEBUG_MSG(("Unknown format\n")); |
150 | 0 | return false; |
151 | 15.2k | } |
152 | 15.2k | } |
153 | | |
154 | | /* vim:set shiftwidth=4 softtabstop=4 noexpandtab: */ |