blob: bc71baee355b0f38cce072521b85a4b862125ee7 [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% %
cristy7e41fe82010-12-04 23:12:08 +000020% Copyright 1999-2011 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*/
cristy4c08aed2011-07-01 19:47:50 +000040#include "MagickCore/studio.h"
41#include "MagickCore/property.h"
42#include "MagickCore/blob.h"
43#include "MagickCore/blob-private.h"
44#include "MagickCore/color.h"
45#include "MagickCore/color-private.h"
46#include "MagickCore/constitute.h"
47#include "MagickCore/exception.h"
48#include "MagickCore/exception-private.h"
49#include "MagickCore/image.h"
50#include "MagickCore/image-private.h"
51#include "MagickCore/list.h"
52#include "MagickCore/log.h"
53#include "MagickCore/magick.h"
54#include "MagickCore/memory_.h"
55#include "MagickCore/monitor.h"
56#include "MagickCore/monitor-private.h"
57#include "MagickCore/paint.h"
58#include "MagickCore/quantum-private.h"
59#include "MagickCore/static.h"
60#include "MagickCore/string_.h"
61#include "MagickCore/module.h"
62#include "MagickCore/type.h"
63#include "MagickCore/module.h"
64#include "MagickWand/MagickWand.h"
cristy3ed852e2009-09-05 21:47:34 +000065
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 */
cristy9950d572011-10-01 18:22:35 +0000153 image=AcquireImage(image_info,exception);
cristy735e8942010-04-02 20:32:57 +0000154 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);
cristy98f91ec2011-02-03 01:15:48 +0000214 SetImageInfoBlob(read_info,(void *) NULL,0);
cristyb51dff52011-05-19 16:55:47 +0000215 (void) FormatLocaleString(read_info->filename,MaxTextExtent,"eps:%s",
cristy735e8942010-04-02 20:32:57 +0000216 filename);
217 image=ReadImage(read_info,exception);
218 read_info=DestroyImageInfo(read_info);
219 if (image != (Image *) NULL)
220 {
221 (void) CopyMagickString(image->filename,image_info->filename,
222 MaxTextExtent);
223 (void) CopyMagickString(image->magick_filename,image_info->filename,
224 MaxTextExtent);
225 (void) CopyMagickString(image->magick,"WMF",MaxTextExtent);
226 }
227 (void) RelinquishUniqueFileResource(filename);
228 return(GetFirstImageInList(image));
cristy3ed852e2009-09-05 21:47:34 +0000229}
cristy735e8942010-04-02 20:32:57 +0000230#endif
cristy3ed852e2009-09-05 21:47:34 +0000231
232/*
233%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
234% %
235% %
236% %
237% R e g i s t e r W M F I m a g e %
238% %
239% %
240% %
241%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
242%
243% RegisterWMFImage() adds attributes for the WMF image format to
244% the list of supported formats. The attributes include the image format
245% tag, a method to read and/or write the format, whether the format
246% supports the saving of more than one frame to the same file or blob,
247% whether the format supports native in-memory I/O, and a brief
248% description of the format.
249%
250% The format of the RegisterWMFImage method is:
251%
cristybb503372010-05-27 20:51:26 +0000252% size_t RegisterWMFImage(void)
cristy3ed852e2009-09-05 21:47:34 +0000253%
254*/
cristybb503372010-05-27 20:51:26 +0000255ModuleExport size_t RegisterWMFImage(void)
cristy3ed852e2009-09-05 21:47:34 +0000256{
257 MagickInfo
258 *entry;
259
260 entry = SetMagickInfo("WMZ");
cristy735e8942010-04-02 20:32:57 +0000261#if defined(MAGICKCORE_WMF_DELEGATE)
cristy3ed852e2009-09-05 21:47:34 +0000262 entry->decoder=ReadWMFImage;
263#endif
264 entry->description=ConstantString("Compressed Windows Meta File");
cristy3ed852e2009-09-05 21:47:34 +0000265 entry->module=ConstantString("WMZ");
cristyffaf9782011-04-13 19:50:51 +0000266 entry->seekable_stream=MagickTrue;
cristy3ed852e2009-09-05 21:47:34 +0000267 (void) RegisterMagickInfo(entry);
268 entry=SetMagickInfo("WMF");
cristy735e8942010-04-02 20:32:57 +0000269#if defined(MAGICKCORE_WMF_DELEGATE)
cristy3ed852e2009-09-05 21:47:34 +0000270 entry->decoder=ReadWMFImage;
271#endif
272 entry->description=ConstantString("Windows Meta File");
cristy3ed852e2009-09-05 21:47:34 +0000273 entry->module=ConstantString("WMF");
274 (void) RegisterMagickInfo(entry);
275 return(MagickImageCoderSignature);
276}
277
278/*
279%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
280% %
281% %
282% %
283% U n r e g i s t e r W M F I m a g e %
284% %
285% %
286% %
287%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
288%
289% UnregisterWMFImage() removes format registrations made by the
290% WMF module from the list of supported formats.
291%
292% The format of the UnregisterWMFImage method is:
293%
294% UnregisterWMFImage(void)
295%
296*/
297ModuleExport void UnregisterWMFImage(void)
298{
299 (void) UnregisterMagickInfo("WMZ");
300 (void) UnregisterMagickInfo("WMF");
301}