blob: 97cf1685575c7c9f86a8c6c694423e4b2e9adee4 [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% %
cristy1454be72011-12-19 01:52:48 +000021% Copyright 1999-2012 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*/
cristy4c08aed2011-07-01 19:47:50 +000043#include "MagickCore/studio.h"
44#include "MagickCore/blob.h"
45#include "MagickCore/blob-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/magick.h"
53#include "MagickCore/memory_.h"
54#include "MagickCore/module.h"
55#include "MagickCore/quantum-private.h"
56#include "MagickCore/static.h"
57#include "MagickCore/resource_.h"
58#include "MagickCore/string_.h"
59#include "MagickCore/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
cristy7ff4c442012-04-03 18:02:50 +0000231 {
232 (void) ThrowMagickException(exception,GetMagickModule(),CoderError,
233 "NoDataReturned","`%s'",filename);
234 return((Image *) NULL);
235 }
cristy3ed852e2009-09-05 21:47:34 +0000236 return(GetFirstImageInList(image));
237}
238
239/*
240%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
241% %
242% %
243% %
244% R e g i s t e r U R L I m a g e %
245% %
246% %
247% %
248%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
249%
250% RegisterURLImage() adds attributes for the URL image format to
251% the list of supported formats. The attributes include the image format
252% tag, a method to read and/or write the format, whether the format
253% supports the saving of more than one frame to the same file or blob,
254% whether the format supports native in-memory I/O, and a brief
255% description of the format.
256%
257% The format of the RegisterURLImage method is:
258%
cristybb503372010-05-27 20:51:26 +0000259% size_t RegisterURLImage(void)
cristy3ed852e2009-09-05 21:47:34 +0000260%
261*/
cristybb503372010-05-27 20:51:26 +0000262ModuleExport size_t RegisterURLImage(void)
cristy3ed852e2009-09-05 21:47:34 +0000263{
264 MagickInfo
265 *entry;
266
267 entry=SetMagickInfo("HTTP");
268#if defined(MAGICKCORE_XML_DELEGATE) && defined(LIBXML_HTTP_ENABLED)
269 entry->decoder=(DecodeImageHandler *) ReadURLImage;
270#endif
271 entry->description=ConstantString("Uniform Resource Locator (http://)");
272 entry->module=ConstantString("URL");
273 entry->stealth=MagickTrue;
274 (void) RegisterMagickInfo(entry);
275 entry=SetMagickInfo("FTP");
276#if defined(MAGICKCORE_XML_DELEGATE) && defined(LIBXML_FTP_ENABLED)
277 entry->decoder=(DecodeImageHandler *) ReadURLImage;
278#endif
279 entry->description=ConstantString("Uniform Resource Locator (ftp://)");
280 entry->module=ConstantString("URL");
281 entry->stealth=MagickTrue;
282 (void) RegisterMagickInfo(entry);
283 entry=SetMagickInfo("FILE");
284 entry->decoder=(DecodeImageHandler *) ReadURLImage;
285 entry->description=ConstantString("Uniform Resource Locator (file://)");
286 entry->module=ConstantString("URL");
287 entry->stealth=MagickTrue;
288 (void) RegisterMagickInfo(entry);
289 return(MagickImageCoderSignature);
290}
291
292/*
293%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
294% %
295% %
296% %
297% U n r e g i s t e r U R L I m a g e %
298% %
299% %
300% %
301%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
302%
303% UnregisterURLImage() removes format registrations made by the
304% URL module from the list of supported formats.
305%
306% The format of the UnregisterURLImage method is:
307%
308% UnregisterURLImage(void)
309%
310*/
311ModuleExport void UnregisterURLImage(void)
312{
313 (void) UnregisterMagickInfo("HTTP");
314 (void) UnregisterMagickInfo("FTP");
315 (void) UnregisterMagickInfo("FILE");
316}