1 /* AbiWord
2 * Copyright (C) 2006 Marc Maurer <uwog@uwog.net>
3 * Copyright (C) 2006 Fridrich Strba <fridrich.strba@bluewin.ch>
4 * Copyright (C) 2006 Dominic Lachowicz <domlachowicz@gmail.com>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 * 02110-1301 USA.
20 */
21
22 #ifdef ABI_PLUGIN_BUILTIN
23 #define abi_plugin_register abipgn_wpg_register
24 #define abi_plugin_unregister abipgn_wpg_unregister
25 #define abi_plugin_supports_version abipgn_wpg_supports_version
26 #endif
27
28 #include "ie_impGraphic_WPG.h"
29 #include <gsf/gsf-utils.h>
30 #include <gsf/gsf-infile.h>
31 #include <gsf/gsf-input-memory.h>
32 #include <gsf/gsf-input-stdio.h>
33 #include <gsf/gsf-infile-msole.h>
34 #include <gsf/gsf-infile-zip.h>
35 #include <librevenge-stream/librevenge-stream.h>
36 #include "xap_Module.h"
37
38 using libwpg::WPGraphics;
39
40 ABI_PLUGIN_DECLARE("WPG")
41
42 class AbiWordPerfectGraphicsInputStream : public librevenge::RVNGInputStream
43 {
44 public:
45 AbiWordPerfectGraphicsInputStream(GsfInput *input);
46 ~AbiWordPerfectGraphicsInputStream();
47
48 virtual bool isStructured();
49 virtual unsigned subStreamCount();
50 virtual const char* subStreamName(unsigned);
51 bool existsSubStream(const char*);
52 virtual librevenge::RVNGInputStream* getSubStreamByName(const char*);
53 virtual librevenge::RVNGInputStream* getSubStreamById(unsigned);
54 virtual const unsigned char *read(unsigned long numBytes, unsigned long &numBytesRead);
55 virtual int seek(long offset, librevenge::RVNG_SEEK_TYPE seekType);
56 virtual long tell();
57 virtual bool isEnd();
58
59 private:
60
61 GsfInput *m_input;
62 GsfInfile *m_ole;
63 std::map<unsigned, std::string> m_substreams;
64 };
65
AbiWordPerfectGraphicsInputStream(GsfInput * input)66 AbiWordPerfectGraphicsInputStream::AbiWordPerfectGraphicsInputStream(GsfInput *input) :
67 librevenge::RVNGInputStream(),
68 m_input(input),
69 m_ole(NULL),
70 m_substreams()
71 {
72 g_object_ref(G_OBJECT(input));
73 }
74
~AbiWordPerfectGraphicsInputStream()75 AbiWordPerfectGraphicsInputStream::~AbiWordPerfectGraphicsInputStream()
76 {
77 if (m_ole)
78 g_object_unref(G_OBJECT(m_ole));
79
80 g_object_unref(G_OBJECT(m_input));
81 }
82
read(unsigned long numBytes,unsigned long & numBytesRead)83 const unsigned char * AbiWordPerfectGraphicsInputStream::read(unsigned long numBytes, unsigned long &numBytesRead)
84 {
85 const unsigned char *buf = gsf_input_read(m_input, numBytes, NULL);
86
87 if (buf == NULL)
88 numBytesRead = 0;
89 else
90 numBytesRead = numBytes;
91
92 return buf;
93 }
94
seek(long offset,librevenge::RVNG_SEEK_TYPE seekType)95 int AbiWordPerfectGraphicsInputStream::seek(long offset, librevenge::RVNG_SEEK_TYPE seekType)
96 {
97 GSeekType gsfSeekType = G_SEEK_SET;
98 switch(seekType)
99 {
100 case librevenge::RVNG_SEEK_CUR:
101 gsfSeekType = G_SEEK_CUR;
102 break;
103 case librevenge::RVNG_SEEK_SET:
104 gsfSeekType = G_SEEK_SET;
105 break;
106 case librevenge::RVNG_SEEK_END:
107 gsfSeekType = G_SEEK_END;
108 break;
109 }
110
111 return gsf_input_seek(m_input, offset, gsfSeekType);
112 }
113
isStructured()114 bool AbiWordPerfectGraphicsInputStream::isStructured()
115 {
116 if (!m_ole)
117 m_ole = GSF_INFILE(gsf_infile_msole_new (m_input, NULL));
118
119 if (!m_ole)
120 m_ole = GSF_INFILE(gsf_infile_zip_new (m_input, NULL));
121
122 if (m_ole)
123 return true;
124
125 return false;
126 }
127
subStreamCount()128 unsigned AbiWordPerfectGraphicsInputStream::subStreamCount()
129 {
130 if (!m_ole)
131 m_ole = GSF_INFILE(gsf_infile_msole_new (m_input, NULL));
132
133 if (!m_ole)
134 m_ole = GSF_INFILE(gsf_infile_zip_new (m_input, NULL));
135
136 if (m_ole)
137 {
138 int numChildren = gsf_infile_num_children(m_ole);
139 if (numChildren > 0)
140 return numChildren;
141 return 0;
142 }
143
144 return 0;
145 }
146
subStreamName(unsigned id)147 const char * AbiWordPerfectGraphicsInputStream::subStreamName(unsigned id)
148 {
149 if (!m_ole)
150 m_ole = GSF_INFILE(gsf_infile_msole_new (m_input, NULL));
151
152 if (!m_ole)
153 m_ole = GSF_INFILE(gsf_infile_zip_new (m_input, NULL));
154
155 if (m_ole)
156 {
157 if ((int)id >= gsf_infile_num_children(m_ole))
158 {
159 return 0;
160 }
161 std::map<unsigned, std::string>::iterator i = m_substreams.lower_bound(id);
162 if (i == m_substreams.end() || m_substreams.key_comp()(id, i->first))
163 {
164 std::string name = gsf_infile_name_by_index(m_ole, (int)id);
165 i = m_substreams.insert(i, std::map<unsigned, std::string>::value_type(id, name));
166 }
167 return i->second.c_str();
168 }
169
170 return 0;
171 }
172
existsSubStream(const char * name)173 bool AbiWordPerfectGraphicsInputStream::existsSubStream(const char * name)
174 {
175 if (!m_ole)
176 m_ole = GSF_INFILE(gsf_infile_msole_new (m_input, NULL));
177
178 if (!m_ole)
179 m_ole = GSF_INFILE(gsf_infile_zip_new (m_input, NULL));
180
181 if (m_ole)
182 {
183 GsfInput *document = gsf_infile_child_by_name(m_ole, name);
184 if (document)
185 {
186 g_object_unref(G_OBJECT (document));
187 return true;
188 }
189 }
190
191 return false;
192 }
193
getSubStreamByName(const char * name)194 librevenge::RVNGInputStream * AbiWordPerfectGraphicsInputStream::getSubStreamByName(const char * name)
195 {
196 librevenge::RVNGInputStream *documentStream = NULL;
197
198 if (!m_ole)
199 m_ole = GSF_INFILE(gsf_infile_msole_new (m_input, NULL));
200
201 if (!m_ole)
202 m_ole = GSF_INFILE(gsf_infile_zip_new (m_input, NULL));
203
204 if (m_ole)
205 {
206 GsfInput *document = gsf_infile_child_by_name(m_ole, name);
207 if (document)
208 {
209 documentStream = new AbiWordPerfectGraphicsInputStream(document);
210 g_object_unref(G_OBJECT (document)); // the only reference should be encapsulated within the new stream
211 }
212 }
213
214 return documentStream;
215 }
216
getSubStreamById(unsigned id)217 librevenge::RVNGInputStream * AbiWordPerfectGraphicsInputStream::getSubStreamById(unsigned id)
218 {
219 librevenge::RVNGInputStream *documentStream = NULL;
220
221 if (!m_ole)
222 m_ole = GSF_INFILE(gsf_infile_msole_new (m_input, NULL));
223
224 if (!m_ole)
225 m_ole = GSF_INFILE(gsf_infile_zip_new (m_input, NULL));
226
227 if (m_ole)
228 {
229 GsfInput *document = gsf_infile_child_by_index(m_ole, (int)id);
230 if (document)
231 {
232 documentStream = new AbiWordPerfectGraphicsInputStream(document);
233 g_object_unref(G_OBJECT (document)); // the only reference should be encapsulated within the new stream
234 }
235 }
236
237 return documentStream;
238 }
239
tell()240 long AbiWordPerfectGraphicsInputStream::tell()
241 {
242 return gsf_input_tell(m_input);
243 }
244
isEnd()245 bool AbiWordPerfectGraphicsInputStream::isEnd()
246 {
247 return gsf_input_eof(m_input);
248 }
249
250 static IE_Imp_WordPerfectGraphics_Sniffer * m_ImpSniffer = 0;
251
252 ABI_FAR_CALL
abi_plugin_register(XAP_ModuleInfo * mi)253 int abi_plugin_register (XAP_ModuleInfo * mi)
254 {
255 if (!m_ImpSniffer)
256 {
257 m_ImpSniffer = new IE_Imp_WordPerfectGraphics_Sniffer ();
258 }
259
260 UT_ASSERT (m_ImpSniffer);
261
262 mi->name = "WordPerfect(tm) Graphics Importer";
263 mi->desc = "Import WordPerfect(tm) Graphics";
264 mi->version = ABI_VERSION_STRING;
265 mi->author = "Marc Maurer";
266 mi->usage = "No Usage";
267
268 IE_ImpGraphic::registerImporter (m_ImpSniffer);
269 return 1;
270 }
271
272 ABI_FAR_CALL
abi_plugin_unregister(XAP_ModuleInfo * mi)273 int abi_plugin_unregister (XAP_ModuleInfo * mi)
274 {
275 mi->name = 0;
276 mi->desc = 0;
277 mi->version = 0;
278 mi->author = 0;
279 mi->usage = 0;
280
281 UT_ASSERT (m_ImpSniffer);
282
283 IE_ImpGraphic::unregisterImporter (m_ImpSniffer);
284 delete m_ImpSniffer;
285 m_ImpSniffer = 0;
286
287 return 1;
288 }
289
290 ABI_FAR_CALL
abi_plugin_supports_version(UT_uint32,UT_uint32,UT_uint32)291 int abi_plugin_supports_version (UT_uint32 /*major*/, UT_uint32 /*minor*/,
292 UT_uint32 /*release*/)
293 {
294 return 1;
295 }
296
297 // supported suffixes
298 static IE_SuffixConfidence IE_WordPerfectGraphics_Sniffer__SuffixConfidence[] = {
299 { "wpg", UT_CONFIDENCE_PERFECT },
300 { "", UT_CONFIDENCE_ZILCH }
301 };
302
IE_Imp_WordPerfectGraphics_Sniffer()303 IE_Imp_WordPerfectGraphics_Sniffer::IE_Imp_WordPerfectGraphics_Sniffer()
304 {
305 }
306
~IE_Imp_WordPerfectGraphics_Sniffer()307 IE_Imp_WordPerfectGraphics_Sniffer::~IE_Imp_WordPerfectGraphics_Sniffer()
308 {
309 }
310
getSuffixConfidence()311 const IE_SuffixConfidence * IE_Imp_WordPerfectGraphics_Sniffer::getSuffixConfidence()
312 {
313 return IE_WordPerfectGraphics_Sniffer__SuffixConfidence;
314 }
315
recognizeContents(GsfInput * input)316 UT_Confidence_t IE_Imp_WordPerfectGraphics_Sniffer::recognizeContents(GsfInput * input)
317 {
318 AbiWordPerfectGraphicsInputStream gsfInput(input);
319 if (WPGraphics::isSupported(&gsfInput))
320 return UT_CONFIDENCE_PERFECT;
321 return UT_CONFIDENCE_ZILCH;
322 }
323
getDlgLabels(const char ** szDesc,const char ** szSuffixList,IEGraphicFileType * ft)324 bool IE_Imp_WordPerfectGraphics_Sniffer::getDlgLabels (const char ** szDesc,
325 const char ** szSuffixList,
326 IEGraphicFileType *ft)
327 {
328 *szDesc = "WordPerfect(tm) Graphics Images (.wpg)";
329 *szSuffixList = "*.wpg";
330 *ft = getType ();
331 return true;
332 }
333
constructImporter(IE_ImpGraphic ** ppieg)334 UT_Error IE_Imp_WordPerfectGraphics_Sniffer::constructImporter(IE_ImpGraphic **ppieg)
335 {
336 *ppieg = new IE_Imp_WordPerfectGraphics();
337 if (*ppieg == NULL)
338 return UT_IE_NOMEMORY;
339 return UT_OK;
340 }
341
342
importGraphic(GsfInput * input,FG_Graphic ** ppfg)343 UT_Error IE_Imp_WordPerfectGraphics::importGraphic(GsfInput *input, FG_Graphic **ppfg)
344 {
345 AbiWordPerfectGraphicsInputStream gsfInput(input);
346 librevenge::RVNGString svgOutput;
347 librevenge::RVNGStringVector vec;
348 librevenge::RVNGSVGDrawingGenerator generator(vec, "");
349
350 if (!libwpg::WPGraphics::parse(&gsfInput, &generator) || vec.empty() || vec[0].empty())
351 {
352 return UT_ERROR;
353 }
354
355 svgOutput.append("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n");
356 svgOutput.append("<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"");
357 svgOutput.append(" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n");
358 svgOutput.append(vec[0]);
359 svgOutput.append("\n");
360
361 GsfInput * svgInput = gsf_input_memory_new((const guint8*)svgOutput.cstr(), svgOutput.len(), false);
362 UT_Error result = IE_ImpGraphic::loadGraphic(svgInput, IE_ImpGraphic::fileTypeForSuffix(".svg"), ppfg);
363 g_object_unref(svgInput);
364 return result;
365 }
366
367