blob: 4df19b4b9201a4676f974f261e34c8bf3ec06dbb [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% %
cristy16af1cb2009-12-11 21:38:29 +000021% Copyright 1999-2010 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"
54#include "magick/quantum-private.h"
55#include "magick/static.h"
56#include "magick/resource_.h"
57#include "magick/string_.h"
58#include "magick/module.h"
59#if defined(MAGICKCORE_XML_DELEGATE)
cristy0157aea2010-04-24 21:12:18 +000060# if defined(MAGICKCORE_WINDOWS_SUPPORT)
cristy3ed852e2009-09-05 21:47:34 +000061# if defined(__MINGW32__)
62# define _MSC_VER
63# else
64# include <win32config.h>
65# endif
66# endif
67# include <libxml/parser.h>
68# include <libxml/xmlmemory.h>
69# include <libxml/nanoftp.h>
70# include <libxml/nanohttp.h>
71#endif
72
73/*
74%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
75% %
76% %
77% %
78% R e a d U R L I m a g e %
79% %
80% %
81% %
82%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
83%
84% ReadURLImage retrieves an image via URL, decodes the image, and returns
85% it. It allocates the memory necessary for the new Image structure and
86% returns a pointer to the new image.
87%
88% The format of the ReadURLImage method is:
89%
90% Image *ReadURLImage(const ImageInfo *image_info,ExceptionInfo *exception)
91%
92% A description of each parameter follows:
93%
94% o image_info: the image info.
95%
96% o exception: return any errors or warnings in this structure.
97%
98*/
99
100#if defined(__cplusplus) || defined(c_plusplus)
101extern "C" {
102#endif
103
104#if defined(MAGICKCORE_XML_DELEGATE) && defined(LIBXML_FTP_ENABLED)
105static void GetFTPData(void *userdata,const char *data,int size)
106{
107 FILE
108 *file;
109
110 size_t
111 length;
112
113 file=(FILE *) userdata;
114 if (file == (FILE *) NULL)
115 return;
116 if (size <= 0)
117 return;
118 length=fwrite(data,size,1,file);
119}
120#endif
121
122#if defined(__cplusplus) || defined(c_plusplus)
123}
124#endif
125
126static Image *ReadURLImage(const ImageInfo *image_info,ExceptionInfo *exception)
127{
128#define MaxBufferExtent 8192
129
130 char
131 filename[MaxTextExtent];
132
133 FILE
134 *file;
135
136 Image
137 *image;
138
139 ImageInfo
140 *read_info;
141
142 int
143 unique_file;
144
145 image=(Image *) NULL;
146 read_info=CloneImageInfo(image_info);
147 SetImageInfoBlob(read_info,(void *) NULL,0);
148 file=(FILE *) NULL;
149 unique_file=AcquireUniqueFileResource(read_info->filename);
150 if (unique_file != -1)
151 file=fdopen(unique_file,"wb");
152 if ((unique_file == -1) || (file == (FILE *) NULL))
153 {
154 read_info=DestroyImageInfo(read_info);
155 (void) CopyMagickString(image->filename,read_info->filename,
156 MaxTextExtent);
157 ThrowFileException(exception,FileOpenError,"UnableToCreateTemporaryFile",
158 image->filename);
159 image=DestroyImageList(image);
160 return((Image *) NULL);
161 }
162 (void) CopyMagickString(filename,image_info->magick,MaxTextExtent);
163 (void) ConcatenateMagickString(filename,":",MaxTextExtent);
164 LocaleLower(filename);
165 (void) ConcatenateMagickString(filename,image_info->filename,MaxTextExtent);
166 if (LocaleCompare(read_info->magick,"file") == 0)
167 {
168 (void) RelinquishUniqueFileResource(read_info->filename);
169 unique_file=(-1);
170 (void) CopyMagickString(read_info->filename,image_info->filename+2,
171 MaxTextExtent);
172 }
173#if defined(MAGICKCORE_XML_DELEGATE) && defined(LIBXML_FTP_ENABLED)
174 if (LocaleCompare(read_info->magick,"ftp") == 0)
175 {
176 void
177 *context;
178
179 xmlNanoFTPInit();
180 context=xmlNanoFTPNewCtxt(filename);
181 if (context != (void *) NULL)
182 {
183 if (xmlNanoFTPConnect(context) >= 0)
184 (void) xmlNanoFTPGet(context,GetFTPData,(void *) file,
185 (char *) NULL);
186 (void) xmlNanoFTPClose(context);
187 }
188 }
189#endif
190#if defined(MAGICKCORE_XML_DELEGATE) && defined(LIBXML_HTTP_ENABLED)
191 if (LocaleCompare(read_info->magick,"http") == 0)
192 {
193 char
194 buffer[MaxBufferExtent],
195 *type;
196
197 int
198 bytes;
199
200 void
201 *context;
202
203 type=(char *) NULL;
204 context=xmlNanoHTTPMethod(filename,(const char *) NULL,
205 (const char *) NULL,&type,(const char *) NULL,0);
206 if (context != (void *) NULL)
207 {
208 ssize_t
209 count;
210
211 while ((bytes=xmlNanoHTTPRead(context,buffer,MaxBufferExtent)) > 0)
212 count=(ssize_t) fwrite(buffer,bytes,1,file);
213 xmlNanoHTTPClose(context);
214 xmlFree(type);
215 xmlNanoHTTPCleanup();
216 }
217 }
218#endif
219 (void) fclose(file);
220 *read_info->magick='\0';
221 image=ReadImage(read_info,exception);
222 if (unique_file != -1)
223 (void) RelinquishUniqueFileResource(read_info->filename);
224 read_info=DestroyImageInfo(read_info);
225 if (image == (Image *) NULL)
226 (void) ThrowMagickException(exception,GetMagickModule(),CoderError,
227 "NoDataReturned","`%s'",filename);
228 return(GetFirstImageInList(image));
229}
230
231/*
232%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
233% %
234% %
235% %
236% R e g i s t e r U R L I m a g e %
237% %
238% %
239% %
240%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
241%
242% RegisterURLImage() adds attributes for the URL 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 RegisterURLImage method is:
250%
251% unsigned long RegisterURLImage(void)
252%
253*/
254ModuleExport unsigned long RegisterURLImage(void)
255{
256 MagickInfo
257 *entry;
258
259 entry=SetMagickInfo("HTTP");
260#if defined(MAGICKCORE_XML_DELEGATE) && defined(LIBXML_HTTP_ENABLED)
261 entry->decoder=(DecodeImageHandler *) ReadURLImage;
262#endif
263 entry->description=ConstantString("Uniform Resource Locator (http://)");
264 entry->module=ConstantString("URL");
265 entry->stealth=MagickTrue;
266 (void) RegisterMagickInfo(entry);
267 entry=SetMagickInfo("FTP");
268#if defined(MAGICKCORE_XML_DELEGATE) && defined(LIBXML_FTP_ENABLED)
269 entry->decoder=(DecodeImageHandler *) ReadURLImage;
270#endif
271 entry->description=ConstantString("Uniform Resource Locator (ftp://)");
272 entry->module=ConstantString("URL");
273 entry->stealth=MagickTrue;
274 (void) RegisterMagickInfo(entry);
275 entry=SetMagickInfo("FILE");
276 entry->decoder=(DecodeImageHandler *) ReadURLImage;
277 entry->description=ConstantString("Uniform Resource Locator (file://)");
278 entry->module=ConstantString("URL");
279 entry->stealth=MagickTrue;
280 (void) RegisterMagickInfo(entry);
281 return(MagickImageCoderSignature);
282}
283
284/*
285%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
286% %
287% %
288% %
289% U n r e g i s t e r U R L I m a g e %
290% %
291% %
292% %
293%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
294%
295% UnregisterURLImage() removes format registrations made by the
296% URL module from the list of supported formats.
297%
298% The format of the UnregisterURLImage method is:
299%
300% UnregisterURLImage(void)
301%
302*/
303ModuleExport void UnregisterURLImage(void)
304{
305 (void) UnregisterMagickInfo("HTTP");
306 (void) UnregisterMagickInfo("FTP");
307 (void) UnregisterMagickInfo("FILE");
308}