/src/imagemagick/coders/html.c
Line | Count | Source |
1 | | /* |
2 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
3 | | % % |
4 | | % % |
5 | | % % |
6 | | % H H TTTTT M M L % |
7 | | % H H T MM MM L % |
8 | | % HHHHH T M M M L % |
9 | | % H H T M M L % |
10 | | % H H T M M LLLLL % |
11 | | % % |
12 | | % % |
13 | | % Write A Client-Side Image Map Using % |
14 | | % Image Montage & Directory Information. % |
15 | | % % |
16 | | % Software Design % |
17 | | % Cristy % |
18 | | % July 1992 % |
19 | | % % |
20 | | % % |
21 | | % Copyright @ 1999 ImageMagick Studio LLC, a non-profit organization % |
22 | | % 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 | | % https://imagemagick.org/license/ % |
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 "MagickCore/studio.h" |
44 | | #include "MagickCore/blob.h" |
45 | | #include "MagickCore/blob-private.h" |
46 | | #include "MagickCore/color-private.h" |
47 | | #include "MagickCore/colorspace.h" |
48 | | #include "MagickCore/colorspace-private.h" |
49 | | #include "MagickCore/constitute.h" |
50 | | #include "MagickCore/exception.h" |
51 | | #include "MagickCore/exception-private.h" |
52 | | #include "MagickCore/geometry.h" |
53 | | #include "MagickCore/list.h" |
54 | | #include "MagickCore/magick.h" |
55 | | #include "MagickCore/memory_.h" |
56 | | #include "MagickCore/paint.h" |
57 | | #include "MagickCore/property.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/utility.h" |
63 | | |
64 | | /* |
65 | | Forward declarations. |
66 | | */ |
67 | | static MagickBooleanType |
68 | | WriteHTMLImage(const ImageInfo *,Image *,ExceptionInfo *); |
69 | | |
70 | | /* |
71 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
72 | | % % |
73 | | % % |
74 | | % % |
75 | | % I s H T M L % |
76 | | % % |
77 | | % % |
78 | | % % |
79 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
80 | | % |
81 | | % IsHTML() returns MagickTrue if the image format type, identified by the |
82 | | % magick string, is HTML. |
83 | | % |
84 | | % The format of the IsHTML method is: |
85 | | % |
86 | | % MagickBooleanType IsHTML(const unsigned char *magick,const size_t length) |
87 | | % |
88 | | % A description of each parameter follows: |
89 | | % |
90 | | % o magick: compare image format pattern against these bytes. |
91 | | % |
92 | | % o length: Specifies the length of the magick string. |
93 | | % |
94 | | */ |
95 | | static MagickBooleanType IsHTML(const unsigned char *magick,const size_t length) |
96 | 0 | { |
97 | 0 | if (length < 6) |
98 | 0 | return(MagickFalse); |
99 | 0 | if (LocaleNCompare((char *) magick+1,"html",5) == 0) |
100 | 0 | return(MagickTrue); |
101 | 0 | return(MagickFalse); |
102 | 0 | } |
103 | | |
104 | | /* |
105 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
106 | | % % |
107 | | % % |
108 | | % % |
109 | | % R e g i s t e r H T M L I m a g e % |
110 | | % % |
111 | | % % |
112 | | % % |
113 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
114 | | % |
115 | | % RegisterHTMLImage() adds properties for the HTML image format to |
116 | | % the list of supported formats. The properties include the image format |
117 | | % tag, a method to read and/or write the format, whether the format |
118 | | % supports the saving of more than one frame to the same file or blob, |
119 | | % whether the format supports native in-memory I/O, and a brief |
120 | | % description of the format. |
121 | | % |
122 | | % The format of the RegisterHTMLImage method is: |
123 | | % |
124 | | % size_t RegisterHTMLImage(void) |
125 | | % |
126 | | */ |
127 | | ModuleExport size_t RegisterHTMLImage(void) |
128 | 7 | { |
129 | 7 | MagickInfo |
130 | 7 | *entry; |
131 | | |
132 | 7 | entry=AcquireMagickInfo("HTML","HTM", |
133 | 7 | "Hypertext Markup Language and a client-side image map"); |
134 | 7 | entry->encoder=(EncodeImageHandler *) WriteHTMLImage; |
135 | 7 | entry->magick=(IsImageFormatHandler *) IsHTML; |
136 | 7 | entry->flags^=CoderAdjoinFlag; |
137 | 7 | (void) RegisterMagickInfo(entry); |
138 | 7 | entry=AcquireMagickInfo("HTML","HTML", |
139 | 7 | "Hypertext Markup Language and a client-side image map"); |
140 | 7 | entry->encoder=(EncodeImageHandler *) WriteHTMLImage; |
141 | 7 | entry->magick=(IsImageFormatHandler *) IsHTML; |
142 | 7 | entry->flags^=CoderAdjoinFlag; |
143 | 7 | (void) RegisterMagickInfo(entry); |
144 | 7 | entry=AcquireMagickInfo("HTML","SHTML", |
145 | 7 | "Hypertext Markup Language and a client-side image map"); |
146 | 7 | entry->encoder=(EncodeImageHandler *) WriteHTMLImage; |
147 | 7 | entry->magick=(IsImageFormatHandler *) IsHTML; |
148 | 7 | entry->flags^=CoderAdjoinFlag; |
149 | 7 | (void) RegisterMagickInfo(entry); |
150 | 7 | return(MagickImageCoderSignature); |
151 | 7 | } |
152 | | |
153 | | /* |
154 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
155 | | % % |
156 | | % % |
157 | | % % |
158 | | % U n r e g i s t e r H T M L I m a g e % |
159 | | % % |
160 | | % % |
161 | | % % |
162 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
163 | | % |
164 | | % UnregisterHTMLImage() removes format registrations made by the |
165 | | % HTML module from the list of supported formats. |
166 | | % |
167 | | % The format of the UnregisterHTMLImage method is: |
168 | | % |
169 | | % UnregisterHTMLImage(void) |
170 | | % |
171 | | */ |
172 | | ModuleExport void UnregisterHTMLImage(void) |
173 | 0 | { |
174 | 0 | (void) UnregisterMagickInfo("HTM"); |
175 | 0 | (void) UnregisterMagickInfo("HTML"); |
176 | 0 | (void) UnregisterMagickInfo("SHTML"); |
177 | 0 | } |
178 | | |
179 | | /* |
180 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
181 | | % % |
182 | | % % |
183 | | % % |
184 | | % W r i t e H T M L I m a g e % |
185 | | % % |
186 | | % % |
187 | | % % |
188 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
189 | | % |
190 | | % WriteHTMLImage() writes an image in the HTML encoded image format. |
191 | | % |
192 | | % The format of the WriteHTMLImage method is: |
193 | | % |
194 | | % MagickBooleanType WriteHTMLImage(const ImageInfo *image_info, |
195 | | % Image *image,ExceptionInfo *exception) |
196 | | % |
197 | | % A description of each parameter follows. |
198 | | % |
199 | | % o image_info: the image info. |
200 | | % |
201 | | % o image: The image. |
202 | | % |
203 | | % o exception: return any errors or warnings in this structure. |
204 | | % |
205 | | */ |
206 | | |
207 | | static void WriteHtmlEncodedString(Image *image,const char* value) |
208 | 0 | { |
209 | 0 | char |
210 | 0 | *encoded_value; |
211 | |
|
212 | 0 | encoded_value=AcquireString(value); |
213 | 0 | (void) SubstituteString(&encoded_value,"<","<"); |
214 | 0 | (void) SubstituteString(&encoded_value,">",">"); |
215 | 0 | (void) SubstituteString(&encoded_value,"&","&"); |
216 | 0 | (void) SubstituteString(&encoded_value,"\"","""); |
217 | 0 | (void) SubstituteString(&encoded_value,"'","'"); |
218 | 0 | WriteBlobString(image,encoded_value); |
219 | 0 | encoded_value=DestroyString(encoded_value); |
220 | 0 | } |
221 | | |
222 | | static ssize_t WriteURLComponent(Image *image,const int c) |
223 | 0 | { |
224 | 0 | char |
225 | 0 | encoding[MagickPathExtent], |
226 | 0 | html5; |
227 | | |
228 | 0 | html5=isalnum(c) != 0 || (c == '-') || (c == '_') || (c == '.') || |
229 | 0 | (c == '!') || (c == '~') || (c == '*') || (c == '\'') || (c == '(') || |
230 | 0 | (c == ')') ? (char) c : 0; |
231 | 0 | if (html5 != 0) |
232 | 0 | (void) FormatLocaleString(encoding,MagickPathExtent,"%c",html5); |
233 | 0 | else |
234 | 0 | (void) FormatLocaleString(encoding,MagickPathExtent,"%%%02X",c); |
235 | 0 | return(WriteBlobString(image,encoding)); |
236 | 0 | } |
237 | | |
238 | | static MagickBooleanType WriteHTMLImage(const ImageInfo *image_info, |
239 | | Image *image,ExceptionInfo *exception) |
240 | 0 | { |
241 | 0 | char |
242 | 0 | basename[MagickPathExtent], |
243 | 0 | buffer[MagickPathExtent], |
244 | 0 | filename[MagickPathExtent], |
245 | 0 | mapname[MagickPathExtent], |
246 | 0 | url[MagickPathExtent]; |
247 | |
|
248 | 0 | Image |
249 | 0 | *next; |
250 | |
|
251 | 0 | ImageInfo |
252 | 0 | *write_info; |
253 | |
|
254 | 0 | MagickBooleanType |
255 | 0 | status; |
256 | |
|
257 | 0 | RectangleInfo |
258 | 0 | geometry; |
259 | |
|
260 | 0 | char |
261 | 0 | *p; |
262 | | |
263 | | /* |
264 | | Open image. |
265 | | */ |
266 | 0 | assert(image_info != (const ImageInfo *) NULL); |
267 | 0 | assert(image_info->signature == MagickCoreSignature); |
268 | 0 | assert(image != (Image *) NULL); |
269 | 0 | assert(image->signature == MagickCoreSignature); |
270 | 0 | assert(exception != (ExceptionInfo *) NULL); |
271 | 0 | assert(exception->signature == MagickCoreSignature); |
272 | 0 | if (IsEventLogging() != MagickFalse) |
273 | 0 | (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s", |
274 | 0 | image_info->filename); |
275 | 0 | status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception); |
276 | 0 | if (status == MagickFalse) |
277 | 0 | return(status); |
278 | 0 | (void) CloseBlob(image); |
279 | 0 | if (IssRGBCompatibleColorspace(image->colorspace) == MagickFalse) |
280 | 0 | (void) TransformImageColorspace(image,sRGBColorspace,exception); |
281 | 0 | *url='\0'; |
282 | 0 | if ((LocaleCompare(image_info->magick,"FTP") == 0) || |
283 | 0 | (LocaleCompare(image_info->magick,"HTTP") == 0)) |
284 | 0 | { |
285 | | /* |
286 | | Extract URL base from filename. |
287 | | */ |
288 | 0 | p=strrchr(image->filename,'/'); |
289 | 0 | if (p != (char *) NULL) |
290 | 0 | { |
291 | 0 | p++; |
292 | 0 | (void) CopyMagickString(url,image_info->magick,MagickPathExtent); |
293 | 0 | (void) ConcatenateMagickString(url,":",MagickPathExtent); |
294 | 0 | url[strlen(url)+p-image->filename]='\0'; |
295 | 0 | (void) ConcatenateMagickString(url,image->filename,(size_t) |
296 | 0 | (p-image->filename+2)); |
297 | 0 | (void) CopyMagickString(image->filename,p,MagickPathExtent); |
298 | 0 | } |
299 | 0 | } |
300 | | /* |
301 | | Refer to image map file. |
302 | | */ |
303 | 0 | (void) CopyMagickString(filename,image->filename,MagickPathExtent); |
304 | 0 | AppendImageFormat("map",filename); |
305 | 0 | GetPathComponent(filename,BasePath,basename); |
306 | 0 | (void) CopyMagickString(mapname,basename,MagickPathExtent); |
307 | 0 | (void) CopyMagickString(image->filename,image_info->filename, |
308 | 0 | MagickPathExtent); |
309 | 0 | (void) CopyMagickString(filename,image->filename,MagickPathExtent); |
310 | 0 | write_info=CloneImageInfo(image_info); |
311 | 0 | *write_info->magick='\0'; |
312 | 0 | write_info->adjoin=MagickTrue; |
313 | 0 | status=MagickTrue; |
314 | 0 | if (LocaleCompare(image_info->magick,"SHTML") != 0) |
315 | 0 | { |
316 | 0 | const char |
317 | 0 | *value; |
318 | | |
319 | | /* |
320 | | Open output image file. |
321 | | */ |
322 | 0 | assert(exception != (ExceptionInfo *) NULL); |
323 | 0 | status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception); |
324 | 0 | if (status == MagickFalse) |
325 | 0 | return(status); |
326 | | /* |
327 | | Write the HTML image file. |
328 | | */ |
329 | 0 | (void) WriteBlobString(image,"<?xml version=\"1.0\" " |
330 | 0 | "encoding=\"UTF-8\"?>\n"); |
331 | 0 | (void) WriteBlobString(image,"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML " |
332 | 0 | "1.0 Strict//EN\" " |
333 | 0 | "\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n"); |
334 | 0 | (void) WriteBlobString(image,"<html>\n"); |
335 | 0 | (void) WriteBlobString(image,"<head>\n"); |
336 | 0 | (void) WriteBlobString(image,"<title>"); |
337 | 0 | value=GetImageProperty(image,"label",exception); |
338 | 0 | if (value != (const char *) NULL) |
339 | 0 | WriteHtmlEncodedString(image,value); |
340 | 0 | else |
341 | 0 | { |
342 | 0 | GetPathComponent(filename,BasePath,basename); |
343 | 0 | WriteHtmlEncodedString(image,basename); |
344 | 0 | } |
345 | 0 | (void) WriteBlobString(image,"</title>\n"); |
346 | 0 | (void) WriteBlobString(image,"</head>\n"); |
347 | 0 | (void) WriteBlobString(image,"<body style=\"text-align: center;\">\n"); |
348 | 0 | (void) WriteBlobString(image,"<h1>"); |
349 | 0 | WriteHtmlEncodedString(image,image->filename); |
350 | 0 | (void) WriteBlobString(image,"</h1>"); |
351 | 0 | (void) WriteBlobString(image,"<div>\n"); |
352 | 0 | (void) CopyMagickString(filename,image->filename,MagickPathExtent); |
353 | 0 | AppendImageFormat("png",filename); |
354 | 0 | (void) WriteBlobString(image,"<img usemap=\"#"); |
355 | 0 | WriteHtmlEncodedString(image,mapname); |
356 | 0 | (void) WriteBlobString(image,"\" src=\""); |
357 | 0 | WriteHtmlEncodedString(image,filename); |
358 | 0 | (void) WriteBlobString(image,"\" style=\"border: 0;\" alt=\"Image map\" />\n"); |
359 | | /* |
360 | | Determine the size and location of each image tile. |
361 | | */ |
362 | 0 | SetGeometry(image,&geometry); |
363 | 0 | if (image->montage != (char *) NULL) |
364 | 0 | (void) ParseAbsoluteGeometry(image->montage,&geometry); |
365 | | /* |
366 | | Write an image map. |
367 | | */ |
368 | 0 | (void) WriteBlobString(image,"<map id=\""); |
369 | 0 | WriteHtmlEncodedString(image,mapname); |
370 | 0 | (void) WriteBlobString(image,"\" name=\""); |
371 | 0 | WriteHtmlEncodedString(image,mapname); |
372 | 0 | (void) WriteBlobString(image,"\">\n<area href=\""); |
373 | 0 | WriteHtmlEncodedString(image,url); |
374 | 0 | if (image->directory == (char *) NULL) |
375 | 0 | { |
376 | 0 | WriteHtmlEncodedString(image,image->filename); |
377 | 0 | (void) FormatLocaleString(buffer,MagickPathExtent, |
378 | 0 | "\" shape=\"rect\" coords=\"0,0,%.20g,%.20g\" alt=\"\" />\n", |
379 | 0 | (double) geometry.width-1,(double) geometry.height-1); |
380 | 0 | (void) WriteBlobString(image,buffer); |
381 | 0 | } |
382 | 0 | else |
383 | 0 | for (p=image->directory; *p != '\0'; p++) |
384 | 0 | if (*p != '\xff') |
385 | 0 | (void) WriteURLComponent(image,(unsigned char) *p); |
386 | 0 | else |
387 | 0 | { |
388 | 0 | (void) FormatLocaleString(buffer,MagickPathExtent,"\" shape=" |
389 | 0 | "\"rect\" coords=\"%.20g,%.20g,%.20g,%.20g\" alt=\"\" />\n", |
390 | 0 | (double) geometry.x,(double) geometry.y,(double) (geometry.x+ |
391 | 0 | (ssize_t) geometry.width-1),(double) (geometry.y+(ssize_t) |
392 | 0 | geometry.height-1)); |
393 | 0 | (void) WriteBlobString(image,buffer); |
394 | 0 | if (*(p+1) != '\0') |
395 | 0 | { |
396 | 0 | (void) WriteBlobString(image," <area href=\""); |
397 | 0 | WriteHtmlEncodedString(image,url); |
398 | 0 | (void) WriteBlobString(image,"\""); |
399 | 0 | } |
400 | 0 | geometry.x+=(ssize_t) geometry.width; |
401 | 0 | if ((geometry.x+4) >= (ssize_t) image->columns) |
402 | 0 | { |
403 | 0 | geometry.x=0; |
404 | 0 | geometry.y+=(ssize_t) geometry.height; |
405 | 0 | } |
406 | 0 | } |
407 | 0 | (void) WriteBlobString(image,"</map>\n"); |
408 | 0 | (void) WriteBlobString(image,"</div>\n"); |
409 | 0 | (void) WriteBlobString(image,"</body>\n"); |
410 | 0 | (void) WriteBlobString(image,"</html>\n"); |
411 | 0 | (void) CloseBlob(image); |
412 | | /* |
413 | | Write the image as PNG. |
414 | | */ |
415 | 0 | AppendImageFormat("png",image->filename); |
416 | 0 | next=GetNextImageInList(image); |
417 | 0 | image->next=NewImageList(); |
418 | 0 | (void) CopyMagickString(image->magick,"PNG",MagickPathExtent); |
419 | 0 | (void) WriteImage(write_info,image,exception); |
420 | 0 | image->next=next; |
421 | | /* |
422 | | Determine image map filename. |
423 | | */ |
424 | 0 | GetPathComponent(image->filename,BasePath,filename); |
425 | 0 | (void) ConcatenateMagickString(filename,"_map.shtml",MagickPathExtent); |
426 | 0 | (void) CopyMagickString(image->filename,filename,MagickPathExtent); |
427 | 0 | } |
428 | | /* |
429 | | Open image map. |
430 | | */ |
431 | 0 | status=OpenBlob(write_info,image,WriteBinaryBlobMode,exception); |
432 | 0 | if (status == MagickFalse) |
433 | 0 | return(status); |
434 | 0 | write_info=DestroyImageInfo(write_info); |
435 | | /* |
436 | | Determine the size and location of each image tile. |
437 | | */ |
438 | 0 | SetGeometry(image,&geometry); |
439 | 0 | if (image->montage != (char *) NULL) |
440 | 0 | (void) ParseAbsoluteGeometry(image->montage,&geometry); |
441 | | /* |
442 | | Write an image map. |
443 | | */ |
444 | 0 | (void) FormatLocaleString(buffer,MagickPathExtent, |
445 | 0 | "<map id=\"%s\" name=\"%s\">\n",mapname,mapname); |
446 | 0 | (void) WriteBlobString(image,buffer); |
447 | 0 | (void) FormatLocaleString(buffer,MagickPathExtent," <area href=\"%s",url); |
448 | 0 | (void) WriteBlobString(image,buffer); |
449 | 0 | if (image->directory == (char *) NULL) |
450 | 0 | { |
451 | 0 | (void) FormatLocaleString(buffer,MagickPathExtent, |
452 | 0 | "%s\" shape=\"rect\" coords=\"0,0,%.20g,%.20g\" alt=\"\" />\n", |
453 | 0 | image->filename,(double) geometry.width-1,(double) geometry.height-1); |
454 | 0 | (void) WriteBlobString(image,buffer); |
455 | 0 | } |
456 | 0 | else |
457 | 0 | for (p=image->directory; *p != '\0'; p++) |
458 | 0 | if (*p != '\xff') |
459 | 0 | (void) WriteURLComponent(image,(unsigned char) *p); |
460 | 0 | else |
461 | 0 | { |
462 | 0 | (void) FormatLocaleString(buffer,MagickPathExtent,"\" shape=\"rect\"" |
463 | 0 | " coords=\"%.20g,%.20g,%.20g,%.20g\" alt=\"\" />\n", |
464 | 0 | (double) geometry.x,(double) geometry.y,geometry.x+(double) |
465 | 0 | geometry.width-1,geometry.y+(double) geometry.height-1); |
466 | 0 | (void) WriteBlobString(image,buffer); |
467 | 0 | if (*(p+1) != '\0') |
468 | 0 | { |
469 | 0 | (void) FormatLocaleString(buffer,MagickPathExtent, |
470 | 0 | " <area href=%s\"",url); |
471 | 0 | (void) WriteBlobString(image,buffer); |
472 | 0 | } |
473 | 0 | geometry.x+=(ssize_t) geometry.width; |
474 | 0 | if ((geometry.x+4) >= (ssize_t) image->columns) |
475 | 0 | { |
476 | 0 | geometry.x=0; |
477 | 0 | geometry.y+=(ssize_t) geometry.height; |
478 | 0 | } |
479 | 0 | } |
480 | 0 | (void) WriteBlobString(image,"</map>\n"); |
481 | 0 | (void) CloseBlob(image); |
482 | 0 | (void) CopyMagickString(image->filename,filename,MagickPathExtent); |
483 | 0 | return(status); |
484 | 0 | } |