blob: 86beadb5a7e3f0f6c0f24f8ae1ba1f6956b2638a [file] [log] [blame]
cristy3ed852e2009-09-05 21:47:34 +00001/*
2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3% %
4% %
5% %
6% U U RRRR L %
7% U U R R L %
8% U U RRRR L %
9% U U R R L %
10% UUU R R LLLLL %
11% %
12% %
13% Retrieve An Image Via URL. %
14% %
15% Software Design %
16% John Cristy %
17% Bill Radcliffe %
18% March 2000 %
19% %
20% %
cristy7e41fe82010-12-04 23:12:08 +000021% Copyright 1999-2011 ImageMagick Studio LLC, a non-profit organization %
cristy3ed852e2009-09-05 21:47:34 +000022% dedicated to making software imaging solutions freely available. %
23% %
24% You may not use this file except in compliance with the License. You may %
25% obtain a copy of the License at %
26% %
27% http://www.imagemagick.org/script/license.php %
28% %
29% Unless required by applicable law or agreed to in writing, software %
30% distributed under the License is distributed on an "AS IS" BASIS, %
31% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
32% See the License for the specific language governing permissions and %
33% limitations under the License. %
34% %
35%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
36%
37%
38*/
39
40/*
41 Include declarations.
42*/
43#include "magick/studio.h"
44#include "magick/blob.h"
45#include "magick/blob-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/magick.h"
53#include "magick/memory_.h"
cristya134d332010-12-12 20:33:53 +000054#include "magick/module.h"
cristy3ed852e2009-09-05 21:47:34 +000055#include "magick/quantum-private.h"
56#include "magick/static.h"
57#include "magick/resource_.h"
58#include "magick/string_.h"
cristya134d332010-12-12 20:33:53 +000059#include "magick/utility.h"
cristy3ed852e2009-09-05 21:47:34 +000060#if defined(MAGICKCORE_XML_DELEGATE)
cristy0157aea2010-04-24 21:12:18 +000061# if defined(MAGICKCORE_WINDOWS_SUPPORT)
cristy3ed852e2009-09-05 21:47:34 +000062# if defined(__MINGW32__)
63# define _MSC_VER
64# else
65# include <win32config.h>
66# endif
67# endif
68# include <libxml/parser.h>
69# include <libxml/xmlmemory.h>
70# include <libxml/nanoftp.h>
71# include <libxml/nanohttp.h>
72#endif
73
74/*
75%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
76% %
77% %
78% %
79% R e a d U R L I m a g e %
80% %
81% %
82% %
83%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
84%
85% ReadURLImage retrieves an image via URL, decodes the image, and returns
86% it. It allocates the memory necessary for the new Image structure and
87% returns a pointer to the new image.
88%
89% The format of the ReadURLImage method is:
90%
91% Image *ReadURLImage(const ImageInfo *image_info,ExceptionInfo *exception)
92%
93% A description of each parameter follows:
94%
95% o image_info: the image info.
96%
97% o exception: return any errors or warnings in this structure.
98%
99*/
100
101#if defined(__cplusplus) || defined(c_plusplus)
102extern "C" {
103#endif
104
105#if defined(MAGICKCORE_XML_DELEGATE) && defined(LIBXML_FTP_ENABLED)
106static void GetFTPData(void *userdata,const char *data,int size)
107{
108 FILE
109 *file;
110
111 size_t
112 length;
113
114 file=(FILE *) userdata;
115 if (file == (FILE *) NULL)
116 return;
117 if (size <= 0)
118 return;
119 length=fwrite(data,size,1,file);
cristyda16f162011-02-19 23:52:17 +0000120 (void) length;
cristy3ed852e2009-09-05 21:47:34 +0000121}
122#endif
123
124#if defined(__cplusplus) || defined(c_plusplus)
125}
126#endif
127
128static Image *ReadURLImage(const ImageInfo *image_info,ExceptionInfo *exception)
129{
130#define MaxBufferExtent 8192
131
132 char
133 filename[MaxTextExtent];
134
135 FILE
136 *file;
137
138 Image
139 *image;
140
141 ImageInfo
142 *read_info;
143
144 int
145 unique_file;
146
147 image=(Image *) NULL;
148 read_info=CloneImageInfo(image_info);
149 SetImageInfoBlob(read_info,(void *) NULL,0);
150 file=(FILE *) NULL;
151 unique_file=AcquireUniqueFileResource(read_info->filename);
152 if (unique_file != -1)
153 file=fdopen(unique_file,"wb");
154 if ((unique_file == -1) || (file == (FILE *) NULL))
155 {
156 read_info=DestroyImageInfo(read_info);
157 (void) CopyMagickString(image->filename,read_info->filename,
158 MaxTextExtent);
159 ThrowFileException(exception,FileOpenError,"UnableToCreateTemporaryFile",
160 image->filename);
161 image=DestroyImageList(image);
162 return((Image *) NULL);
163 }
164 (void) CopyMagickString(filename,image_info->magick,MaxTextExtent);
165 (void) ConcatenateMagickString(filename,":",MaxTextExtent);
166 LocaleLower(filename);
167 (void) ConcatenateMagickString(filename,image_info->filename,MaxTextExtent);
168 if (LocaleCompare(read_info->magick,"file") == 0)
169 {
170 (void) RelinquishUniqueFileResource(read_info->filename);
171 unique_file=(-1);
172 (void) CopyMagickString(read_info->filename,image_info->filename+2,
173 MaxTextExtent);
174 }
175#if defined(MAGICKCORE_XML_DELEGATE) && defined(LIBXML_FTP_ENABLED)
176 if (LocaleCompare(read_info->magick,"ftp") == 0)
177 {
178 void
179 *context;
180
181 xmlNanoFTPInit();
182 context=xmlNanoFTPNewCtxt(filename);
183 if (context != (void *) NULL)
184 {
185 if (xmlNanoFTPConnect(context) >= 0)
186 (void) xmlNanoFTPGet(context,GetFTPData,(void *) file,
187 (char *) NULL);
188 (void) xmlNanoFTPClose(context);
189 }
190 }
191#endif
192#if defined(MAGICKCORE_XML_DELEGATE) && defined(LIBXML_HTTP_ENABLED)
193 if (LocaleCompare(read_info->magick,"http") == 0)
194 {
195 char
196 buffer[MaxBufferExtent],
197 *type;
198
199 int
200 bytes;
201
202 void
203 *context;
204
205 type=(char *) NULL;
206 context=xmlNanoHTTPMethod(filename,(const char *) NULL,
207 (const char *) NULL,&type,(const char *) NULL,0);
208 if (context != (void *) NULL)
209 {
210 ssize_t
211 count;
212
213 while ((bytes=xmlNanoHTTPRead(context,buffer,MaxBufferExtent)) > 0)
214 count=(ssize_t) fwrite(buffer,bytes,1,file);
cristyda16f162011-02-19 23:52:17 +0000215 (void) count;
cristy3ed852e2009-09-05 21:47:34 +0000216 xmlNanoHTTPClose(context);
217 xmlFree(type);
218 xmlNanoHTTPCleanup();
219 }
220 }
221#endif
222 (void) fclose(file);
223 *read_info->magick='\0';
224 image=ReadImage(read_info,exception);
225 if (unique_file != -1)
226 (void) RelinquishUniqueFileResource(read_info->filename);
227 read_info=DestroyImageInfo(read_info);
cristya134d332010-12-12 20:33:53 +0000228 if (image != (Image *) NULL)
229 GetPathComponent(image_info->filename,TailPath,image->filename);
230 else
cristy3ed852e2009-09-05 21:47:34 +0000231 (void) ThrowMagickException(exception,GetMagickModule(),CoderError,
232 "NoDataReturned","`%s'",filename);
233 return(GetFirstImageInList(image));
234}
235
236/*
237%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
238% %
239% %
240% %
241% R e g i s t e r U R L I m a g e %
242% %
243% %
244% %
245%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
246%
247% RegisterURLImage() adds attributes for the URL image format to
248% the list of supported formats. The attributes include the image format
249% tag, a method to read and/or write the format, whether the format
250% supports the saving of more than one frame to the same file or blob,
251% whether the format supports native in-memory I/O, and a brief
252% description of the format.
253%
254% The format of the RegisterURLImage method is:
255%
cristybb503372010-05-27 20:51:26 +0000256% size_t RegisterURLImage(void)
cristy3ed852e2009-09-05 21:47:34 +0000257%
258*/
cristybb503372010-05-27 20:51:26 +0000259ModuleExport size_t RegisterURLImage(void)
cristy3ed852e2009-09-05 21:47:34 +0000260{
261 MagickInfo
262 *entry;
263
264 entry=SetMagickInfo("HTTP");
265#if defined(MAGICKCORE_XML_DELEGATE) && defined(LIBXML_HTTP_ENABLED)
266 entry->decoder=(DecodeImageHandler *) ReadURLImage;
267#endif
268 entry->description=ConstantString("Uniform Resource Locator (http://)");
269 entry->module=ConstantString("URL");
270 entry->stealth=MagickTrue;
271 (void) RegisterMagickInfo(entry);
272 entry=SetMagickInfo("FTP");
273#if defined(MAGICKCORE_XML_DELEGATE) && defined(LIBXML_FTP_ENABLED)
274 entry->decoder=(DecodeImageHandler *) ReadURLImage;
275#endif
276 entry->description=ConstantString("Uniform Resource Locator (ftp://)");
277 entry->module=ConstantString("URL");
278 entry->stealth=MagickTrue;
279 (void) RegisterMagickInfo(entry);
280 entry=SetMagickInfo("FILE");
281 entry->decoder=(DecodeImageHandler *) ReadURLImage;
282 entry->description=ConstantString("Uniform Resource Locator (file://)");
283 entry->module=ConstantString("URL");
284 entry->stealth=MagickTrue;
285 (void) RegisterMagickInfo(entry);
286 return(MagickImageCoderSignature);
287}
288
289/*
290%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
291% %
292% %
293% %
294% U n r e g i s t e r U R L I m a g e %
295% %
296% %
297% %
298%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
299%
300% UnregisterURLImage() removes format registrations made by the
301% URL module from the list of supported formats.
302%
303% The format of the UnregisterURLImage method is:
304%
305% UnregisterURLImage(void)
306%
307*/
308ModuleExport void UnregisterURLImage(void)
309{
310 (void) UnregisterMagickInfo("HTTP");
311 (void) UnregisterMagickInfo("FTP");
312 (void) UnregisterMagickInfo("FILE");
313}