blob: bc978c050927819b296aa3c24bbcf165b7dff3d3 [file] [log] [blame]
cristy3ed852e2009-09-05 21:47:34 +00001/*
2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3% %
4% %
5% %
6% W W M M FFFFF %
7% W W MM MM F %
8% W W W M M M FFF %
9% WW WW M M F %
10% W W M M F %
11% %
12% %
13% Read Windows Metafile Format %
14% %
15% Software Design %
cristy735e8942010-04-02 20:32:57 +000016% John Cristy %
17% December 2000 %
cristy3ed852e2009-09-05 21:47:34 +000018% %
19% %
cristy16af1cb2009-12-11 21:38:29 +000020% Copyright 1999-2010 ImageMagick Studio LLC, a non-profit organization %
cristy3ed852e2009-09-05 21:47:34 +000021% dedicated to making software imaging solutions freely available. %
22% %
23% You may not use this file except in compliance with the License. You may %
24% obtain a copy of the License at %
25% %
26% http://www.imagemagick.org/script/license.php %
27% %
28% Unless required by applicable law or agreed to in writing, software %
29% distributed under the License is distributed on an "AS IS" BASIS, %
30% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
31% See the License for the specific language governing permissions and %
32% limitations under the License. %
33% %
34%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
35*/
36
37/*
38 Include declarations.
39*/
40#include "magick/studio.h"
41#include "magick/property.h"
42#include "magick/blob.h"
43#include "magick/blob-private.h"
44#include "magick/color.h"
45#include "magick/color-private.h"
46#include "magick/constitute.h"
47#include "magick/exception.h"
48#include "magick/exception-private.h"
49#include "magick/image.h"
50#include "magick/image-private.h"
51#include "magick/list.h"
52#include "magick/log.h"
53#include "magick/magick.h"
54#include "magick/memory_.h"
55#include "magick/monitor.h"
56#include "magick/monitor-private.h"
57#include "magick/paint.h"
58#include "magick/quantum-private.h"
59#include "magick/static.h"
60#include "magick/string_.h"
61#include "magick/module.h"
62#include "magick/type.h"
63#include "magick/module.h"
64#include "wand/MagickWand.h"
65
cristy735e8942010-04-02 20:32:57 +000066#if defined(MAGICKCORE_WMF_DELEGATE)
cristy3ed852e2009-09-05 21:47:34 +000067#include "libwmf/api.h"
cristy2e68c0c2010-04-06 13:10:46 +000068#include "libwmf/eps.h"
cristyb85b2f32010-04-03 03:05:15 +000069
70/*
71%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
72% %
73% %
74% %
75% R e a d W M F I m a g e %
76% %
77% %
78% %
79%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
80%
81% ReadWMFImage() reads an Windows Metafile image file and returns it. It
82% allocates the memory necessary for the new Image structure and returns a
83% pointer to the new image.
84%
85% The format of the ReadWMFImage method is:
86%
87% Image *ReadWMFImage(const ImageInfo *image_info,ExceptionInfo *exception)
88%
89% A description of each parameter follows:
90%
91% o image_info: the image info.
92%
93% o exception: return any errors or warnings in this structure.
94%
95*/
96
97static int WMFReadBlob(void *image)
98{
99 return(ReadBlobByte((Image *) image));
100}
101
cristyf1d91242010-05-28 02:23:19 +0000102static int WMFSeekBlob(void *image,long offset)
cristyb85b2f32010-04-03 03:05:15 +0000103{
104 return((int) SeekBlob((Image *) image,(MagickOffsetType) offset,SEEK_SET));
105}
106
cristyf1d91242010-05-28 02:23:19 +0000107static long WMFTellBlob(void *image)
cristyb85b2f32010-04-03 03:05:15 +0000108{
cristyf1d91242010-05-28 02:23:19 +0000109 return((long) TellBlob((Image*) image));
cristyb85b2f32010-04-03 03:05:15 +0000110}
cristy3ed852e2009-09-05 21:47:34 +0000111
cristy735e8942010-04-02 20:32:57 +0000112static Image *ReadWMFImage(const ImageInfo *image_info,ExceptionInfo *exception)
cristy3ed852e2009-09-05 21:47:34 +0000113{
114 char
cristy735e8942010-04-02 20:32:57 +0000115 filename[MaxTextExtent];
cristy3ed852e2009-09-05 21:47:34 +0000116
cristy735e8942010-04-02 20:32:57 +0000117 int
118 unique_file;
cristy3ed852e2009-09-05 21:47:34 +0000119
cristy735e8942010-04-02 20:32:57 +0000120 FILE
121 *file;
cristy3ed852e2009-09-05 21:47:34 +0000122
123 Image
124 *image;
125
126 ImageInfo
cristy735e8942010-04-02 20:32:57 +0000127 *read_info;
cristy3ed852e2009-09-05 21:47:34 +0000128
cristy19eb6412010-04-23 14:42:29 +0000129 MagickBooleanType
130 status;
131
cristybb503372010-05-27 20:51:26 +0000132 size_t
cristy735e8942010-04-02 20:32:57 +0000133 flags;
cristy3ed852e2009-09-05 21:47:34 +0000134
135 wmfAPI
cristy735e8942010-04-02 20:32:57 +0000136 *wmf_info;
cristy3ed852e2009-09-05 21:47:34 +0000137
138 wmfAPI_Options
cristy735e8942010-04-02 20:32:57 +0000139 options;
cristy3ed852e2009-09-05 21:47:34 +0000140
141 wmfD_Rect
cristy735e8942010-04-02 20:32:57 +0000142 bounding_box;
cristy3ed852e2009-09-05 21:47:34 +0000143
cristy2e68c0c2010-04-06 13:10:46 +0000144 wmf_eps_t
cristyfc5fbc42010-04-06 17:58:30 +0000145 *eps_info;
cristy735e8942010-04-02 20:32:57 +0000146
147 wmf_error_t
cristy19eb6412010-04-23 14:42:29 +0000148 wmf_status;
cristy735e8942010-04-02 20:32:57 +0000149
cristyb85b2f32010-04-03 03:05:15 +0000150 /*
151 Read WMF image.
152 */
cristy735e8942010-04-02 20:32:57 +0000153 image=AcquireImage(image_info);
154 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
155 if (status == MagickFalse)
cristy3ed852e2009-09-05 21:47:34 +0000156 {
cristy3ed852e2009-09-05 21:47:34 +0000157 image=DestroyImageList(image);
158 return((Image *) NULL);
159 }
cristy735e8942010-04-02 20:32:57 +0000160 wmf_info=(wmfAPI *) NULL;
161 flags=0;
162 flags|=WMF_OPT_IGNORE_NONFATAL;
163 flags|=WMF_OPT_FUNCTION;
cristy2e68c0c2010-04-06 13:10:46 +0000164 options.function=wmf_eps_function;
cristyeaedf062010-05-29 22:36:02 +0000165 wmf_status=wmf_api_create(&wmf_info,(unsigned long) flags,&options);
cristy19eb6412010-04-23 14:42:29 +0000166 if (wmf_status != wmf_E_None)
cristy3ed852e2009-09-05 21:47:34 +0000167 {
cristy735e8942010-04-02 20:32:57 +0000168 if (wmf_info != (wmfAPI *) NULL)
169 wmf_api_destroy(wmf_info);
cristy3ed852e2009-09-05 21:47:34 +0000170 ThrowReaderException(DelegateError,"UnableToInitializeWMFLibrary");
171 }
cristy19eb6412010-04-23 14:42:29 +0000172 wmf_status=wmf_bbuf_input(wmf_info,WMFReadBlob,WMFSeekBlob,WMFTellBlob,
cristyb85b2f32010-04-03 03:05:15 +0000173 (void *) image);
cristy19eb6412010-04-23 14:42:29 +0000174 if (wmf_status != wmf_E_None)
cristy3ed852e2009-09-05 21:47:34 +0000175 {
cristyb85b2f32010-04-03 03:05:15 +0000176 wmf_api_destroy(wmf_info);
cristy3ed852e2009-09-05 21:47:34 +0000177 ThrowFileException(exception,FileOpenError,"UnableToOpenFile",
178 image->filename);
cristyb85b2f32010-04-03 03:05:15 +0000179 image=DestroyImageList(image);
180 return((Image *) NULL);
cristy3ed852e2009-09-05 21:47:34 +0000181 }
cristy19eb6412010-04-23 14:42:29 +0000182 wmf_status=wmf_scan(wmf_info,0,&bounding_box);
183 if (wmf_status != wmf_E_None)
cristy3ed852e2009-09-05 21:47:34 +0000184 {
cristyb85b2f32010-04-03 03:05:15 +0000185 wmf_api_destroy(wmf_info);
cristy3ed852e2009-09-05 21:47:34 +0000186 ThrowReaderException(DelegateError,"FailedToScanFile");
187 }
cristy2e68c0c2010-04-06 13:10:46 +0000188 eps_info=WMF_EPS_GetData(wmf_info);
cristy735e8942010-04-02 20:32:57 +0000189 file=(FILE *) NULL;
190 unique_file=AcquireUniqueFileResource(filename);
191 if (unique_file != -1)
192 file=fdopen(unique_file,"wb");
193 if ((unique_file == -1) || (file == (FILE *) NULL))
cristy3ed852e2009-09-05 21:47:34 +0000194 {
cristyb85b2f32010-04-03 03:05:15 +0000195 wmf_api_destroy(wmf_info);
196 ThrowReaderException(FileOpenError,"UnableToCreateTemporaryFile");
cristy3ed852e2009-09-05 21:47:34 +0000197 }
cristy2e68c0c2010-04-06 13:10:46 +0000198 eps_info->out=wmf_stream_create(wmf_info,file);
199 eps_info->bbox=bounding_box;
cristy19eb6412010-04-23 14:42:29 +0000200 wmf_status=wmf_play(wmf_info,0,&bounding_box);
201 if (wmf_status != wmf_E_None)
cristy3ed852e2009-09-05 21:47:34 +0000202 {
cristyb85b2f32010-04-03 03:05:15 +0000203 wmf_api_destroy(wmf_info);
cristy3ed852e2009-09-05 21:47:34 +0000204 ThrowReaderException(DelegateError,"FailedToRenderFile");
205 }
cristy735e8942010-04-02 20:32:57 +0000206 (void) fclose(file);
cristyb85b2f32010-04-03 03:05:15 +0000207 wmf_api_destroy(wmf_info);
cristy3ed852e2009-09-05 21:47:34 +0000208 (void) CloseBlob(image);
cristy735e8942010-04-02 20:32:57 +0000209 image=DestroyImage(image);
210 /*
cristy2e68c0c2010-04-06 13:10:46 +0000211 Read EPS image.
cristy735e8942010-04-02 20:32:57 +0000212 */
213 read_info=CloneImageInfo(image_info);
cristy2e68c0c2010-04-06 13:10:46 +0000214 (void) FormatMagickString(read_info->filename,MaxTextExtent,"eps:%.1024s",
cristy735e8942010-04-02 20:32:57 +0000215 filename);
216 image=ReadImage(read_info,exception);
217 read_info=DestroyImageInfo(read_info);
218 if (image != (Image *) NULL)
219 {
220 (void) CopyMagickString(image->filename,image_info->filename,
221 MaxTextExtent);
222 (void) CopyMagickString(image->magick_filename,image_info->filename,
223 MaxTextExtent);
224 (void) CopyMagickString(image->magick,"WMF",MaxTextExtent);
225 }
226 (void) RelinquishUniqueFileResource(filename);
227 return(GetFirstImageInList(image));
cristy3ed852e2009-09-05 21:47:34 +0000228}
cristy735e8942010-04-02 20:32:57 +0000229#endif
cristy3ed852e2009-09-05 21:47:34 +0000230
231/*
232%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
233% %
234% %
235% %
236% R e g i s t e r W M F I m a g e %
237% %
238% %
239% %
240%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
241%
242% RegisterWMFImage() adds attributes for the WMF image format to
243% the list of supported formats. The attributes include the image format
244% tag, a method to read and/or write the format, whether the format
245% supports the saving of more than one frame to the same file or blob,
246% whether the format supports native in-memory I/O, and a brief
247% description of the format.
248%
249% The format of the RegisterWMFImage method is:
250%
cristybb503372010-05-27 20:51:26 +0000251% size_t RegisterWMFImage(void)
cristy3ed852e2009-09-05 21:47:34 +0000252%
253*/
cristybb503372010-05-27 20:51:26 +0000254ModuleExport size_t RegisterWMFImage(void)
cristy3ed852e2009-09-05 21:47:34 +0000255{
256 MagickInfo
257 *entry;
258
259 entry = SetMagickInfo("WMZ");
cristy735e8942010-04-02 20:32:57 +0000260#if defined(MAGICKCORE_WMF_DELEGATE)
cristy3ed852e2009-09-05 21:47:34 +0000261 entry->decoder=ReadWMFImage;
262#endif
263 entry->description=ConstantString("Compressed Windows Meta File");
cristy3ed852e2009-09-05 21:47:34 +0000264 entry->module=ConstantString("WMZ");
265 (void) RegisterMagickInfo(entry);
266 entry=SetMagickInfo("WMF");
cristy735e8942010-04-02 20:32:57 +0000267#if defined(MAGICKCORE_WMF_DELEGATE)
cristy3ed852e2009-09-05 21:47:34 +0000268 entry->decoder=ReadWMFImage;
269#endif
270 entry->description=ConstantString("Windows Meta File");
cristy3ed852e2009-09-05 21:47:34 +0000271 entry->module=ConstantString("WMF");
272 (void) RegisterMagickInfo(entry);
273 return(MagickImageCoderSignature);
274}
275
276/*
277%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
278% %
279% %
280% %
281% U n r e g i s t e r W M F I m a g e %
282% %
283% %
284% %
285%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
286%
287% UnregisterWMFImage() removes format registrations made by the
288% WMF module from the list of supported formats.
289%
290% The format of the UnregisterWMFImage method is:
291%
292% UnregisterWMFImage(void)
293%
294*/
295ModuleExport void UnregisterWMFImage(void)
296{
297 (void) UnregisterMagickInfo("WMZ");
298 (void) UnregisterMagickInfo("WMF");
299}