2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
13 % Write A Client-Side Image Map Using %
14 % Image Montage & Directory Information. %
21 % Copyright 1999-2012 ImageMagick Studio LLC, a non-profit organization %
22 % dedicated to making software imaging solutions freely available. %
24 % You may not use this file except in compliance with the License. You may %
25 % obtain a copy of the License at %
27 % http://www.imagemagick.org/script/license.php %
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. %
35 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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"
67 static MagickBooleanType
68 WriteHTMLImage(const ImageInfo *,Image *,ExceptionInfo *);
71 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
79 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
81 % IsHTML() returns MagickTrue if the image format type, identified by the
82 % magick string, is HTML.
84 % The format of the IsHTML method is:
86 % MagickBooleanType IsHTML(const unsigned char *magick,const size_t length)
88 % A description of each parameter follows:
90 % o magick: compare image format pattern against these bytes.
92 % o length: Specifies the length of the magick string.
95 static MagickBooleanType IsHTML(const unsigned char *magick,const size_t length)
99 if (LocaleNCompare((char *) magick,"<html",5) == 0)
105 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
109 % R e g i s t e r H T M L I m a g e %
113 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
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.
122 % The format of the RegisterHTMLImage method is:
124 % size_t RegisterHTMLImage(void)
127 ModuleExport size_t RegisterHTMLImage(void)
132 entry=SetMagickInfo("HTM");
133 entry->encoder=(EncodeImageHandler *) WriteHTMLImage;
134 entry->magick=(IsImageFormatHandler *) IsHTML;
135 entry->adjoin=MagickFalse;
136 entry->description=ConstantString(
137 "Hypertext Markup Language and a client-side image map");
138 entry->module=ConstantString("HTML");
139 (void) RegisterMagickInfo(entry);
140 entry=SetMagickInfo("HTML");
141 entry->encoder=(EncodeImageHandler *) WriteHTMLImage;
142 entry->magick=(IsImageFormatHandler *) IsHTML;
143 entry->adjoin=MagickFalse;
144 entry->description=ConstantString(
145 "Hypertext Markup Language and a client-side image map");
146 entry->module=ConstantString("HTML");
147 (void) RegisterMagickInfo(entry);
148 entry=SetMagickInfo("SHTML");
149 entry->encoder=(EncodeImageHandler *) WriteHTMLImage;
150 entry->magick=(IsImageFormatHandler *) IsHTML;
151 entry->adjoin=MagickFalse;
152 entry->description=ConstantString(
153 "Hypertext Markup Language and a client-side image map");
154 entry->module=ConstantString("HTML");
155 (void) RegisterMagickInfo(entry);
156 return(MagickImageCoderSignature);
160 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
164 % U n r e g i s t e r H T M L I m a g e %
168 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
170 % UnregisterHTMLImage() removes format registrations made by the
171 % HTML module from the list of supported formats.
173 % The format of the UnregisterHTMLImage method is:
175 % UnregisterHTMLImage(void)
178 ModuleExport void UnregisterHTMLImage(void)
180 (void) UnregisterMagickInfo("HTM");
181 (void) UnregisterMagickInfo("HTML");
182 (void) UnregisterMagickInfo("SHTML");
186 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
190 % W r i t e H T M L I m a g e %
194 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
196 % WriteHTMLImage() writes an image in the HTML encoded image format.
198 % The format of the WriteHTMLImage method is:
200 % MagickBooleanType WriteHTMLImage(const ImageInfo *image_info,
201 % Image *image,ExceptionInfo *exception)
203 % A description of each parameter follows.
205 % o image_info: the image info.
207 % o image: The image.
209 % o exception: return any errors or warnings in this structure.
212 static MagickBooleanType WriteHTMLImage(const ImageInfo *image_info,
213 Image *image,ExceptionInfo *exception)
216 basename[MaxTextExtent],
217 buffer[MaxTextExtent],
218 filename[MaxTextExtent],
219 mapname[MaxTextExtent],
240 assert(image_info != (const ImageInfo *) NULL);
241 assert(image_info->signature == MagickSignature);
242 assert(image != (Image *) NULL);
243 assert(image->signature == MagickSignature);
244 if (image->debug != MagickFalse)
245 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
246 image_info->filename);
247 assert(exception != (ExceptionInfo *) NULL);
248 assert(exception->signature == MagickSignature);
249 status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
250 if (status == MagickFalse)
252 (void) CloseBlob(image);
253 if (IsRGBColorspace(image->colorspace) == MagickFalse)
254 (void) TransformImageColorspace(image,RGBColorspace,exception);
256 if ((LocaleCompare(image_info->magick,"FTP") == 0) ||
257 (LocaleCompare(image_info->magick,"HTTP") == 0))
260 Extract URL base from filename.
262 p=strrchr(image->filename,'/');
263 if (p != (char *) NULL)
266 (void) CopyMagickString(url,image_info->magick,MaxTextExtent);
267 (void) ConcatenateMagickString(url,":",MaxTextExtent);
268 url[strlen(url)+p-image->filename]='\0';
269 (void) ConcatenateMagickString(url,image->filename,
270 p-image->filename+2);
271 (void) CopyMagickString(image->filename,p,MaxTextExtent);
275 Refer to image map file.
277 (void) CopyMagickString(filename,image->filename,MaxTextExtent);
278 AppendImageFormat("map",filename);
279 GetPathComponent(filename,BasePath,basename);
280 (void) CopyMagickString(mapname,basename,MaxTextExtent);
281 (void) CopyMagickString(image->filename,image_info->filename,MaxTextExtent);
282 (void) CopyMagickString(filename,image->filename,MaxTextExtent);
283 write_info=CloneImageInfo(image_info);
284 write_info->adjoin=MagickTrue;
286 if (LocaleCompare(image_info->magick,"SHTML") != 0)
292 Open output image file.
294 assert(exception != (ExceptionInfo *) NULL);
295 if (status == MagickFalse)
298 Write the HTML image file.
300 (void) WriteBlobString(image,"<?xml version=\"1.0\" "
301 "encoding=\"US-ASCII\"?>\n");
302 (void) WriteBlobString(image,"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML "
304 "\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n");
305 (void) WriteBlobString(image,"<html>\n");
306 (void) WriteBlobString(image,"<head>\n");
307 value=GetImageProperty(image,"label",exception);
308 if (value != (const char *) NULL)
309 (void) FormatLocaleString(buffer,MaxTextExtent,"<title>%s</title>\n",
313 GetPathComponent(filename,BasePath,basename);
314 (void) FormatLocaleString(buffer,MaxTextExtent,
315 "<title>%s</title>\n",basename);
317 (void) WriteBlobString(image,buffer);
318 (void) WriteBlobString(image,"</head>\n");
319 (void) WriteBlobString(image,"<body style=\"text-align: center;\">\n");
320 (void) FormatLocaleString(buffer,MaxTextExtent,"<h1>%s</h1>\n",
322 (void) WriteBlobString(image,buffer);
323 (void) WriteBlobString(image,"<div>\n");
324 (void) CopyMagickString(filename,image->filename,MaxTextExtent);
325 AppendImageFormat("png",filename);
326 (void) FormatLocaleString(buffer,MaxTextExtent,"<img usemap=\"#%s\" "
327 "src=\"%s\" style=\"border: 0;\" alt=\"Image map\" />\n",mapname,
329 (void) WriteBlobString(image,buffer);
331 Determine the size and location of each image tile.
333 SetGeometry(image,&geometry);
334 if (image->montage != (char *) NULL)
335 (void) ParseAbsoluteGeometry(image->montage,&geometry);
339 (void) FormatLocaleString(buffer,MaxTextExtent,
340 "<map id=\"%s\" name=\"%s\">\n",mapname,mapname);
341 (void) WriteBlobString(image,buffer);
342 (void) FormatLocaleString(buffer,MaxTextExtent," <area href=\"%s",
344 (void) WriteBlobString(image,buffer);
345 if (image->directory == (char *) NULL)
347 (void) FormatLocaleString(buffer,MaxTextExtent,
348 "%s\" shape=\"rect\" coords=\"0,0,%.20g,%.20g\" alt=\"\" />\n",
349 image->filename,(double) geometry.width-1,(double) geometry.height-
351 (void) WriteBlobString(image,buffer);
354 for (p=image->directory; *p != '\0'; p++)
356 (void) WriteBlobByte(image,(unsigned char) *p);
359 (void) FormatLocaleString(buffer,MaxTextExtent,"\" shape="
360 "\"rect\" coords=\"%.20g,%.20g,%.20g,%.20g\" alt=\"\" />\n",
361 (double) geometry.x,(double) geometry.y,(double) (geometry.x+
362 geometry.width-1),(double) (geometry.y+geometry.height-1));
363 (void) WriteBlobString(image,buffer);
366 (void) FormatLocaleString(buffer,MaxTextExtent,
367 " <area href=%s\"",url);
368 (void) WriteBlobString(image,buffer);
370 geometry.x+=(ssize_t) geometry.width;
371 if ((geometry.x+4) >= (ssize_t) image->columns)
374 geometry.y+=(ssize_t) geometry.height;
377 (void) WriteBlobString(image,"</map>\n");
378 (void) CopyMagickString(filename,image->filename,MaxTextExtent);
379 (void) WriteBlobString(image,"</div>\n");
380 (void) WriteBlobString(image,"</body>\n");
381 (void) WriteBlobString(image,"</html>\n");
382 (void) CloseBlob(image);
384 Write the image as PNG.
386 (void) CopyMagickString(image->filename,filename,MaxTextExtent);
387 AppendImageFormat("png",image->filename);
388 next=GetNextImageInList(image);
389 image->next=NewImageList();
390 (void) CopyMagickString(image->magick,"PNG",MaxTextExtent);
391 (void) WriteImage(write_info,image,exception);
394 Determine image map filename.
396 GetPathComponent(image->filename,BasePath,filename);
397 (void) ConcatenateMagickString(filename,"_map.shtml",MaxTextExtent);
398 (void) CopyMagickString(image->filename,filename,MaxTextExtent);
403 status=OpenBlob(write_info,image,WriteBinaryBlobMode,exception);
404 if (status == MagickFalse)
406 write_info=DestroyImageInfo(write_info);
408 Determine the size and location of each image tile.
410 SetGeometry(image,&geometry);
411 if (image->montage != (char *) NULL)
412 (void) ParseAbsoluteGeometry(image->montage,&geometry);
416 (void) FormatLocaleString(buffer,MaxTextExtent,
417 "<map id=\"%s\" name=\"%s\">\n",mapname,mapname);
418 (void) WriteBlobString(image,buffer);
419 (void) FormatLocaleString(buffer,MaxTextExtent," <area href=\"%s",url);
420 (void) WriteBlobString(image,buffer);
421 if (image->directory == (char *) NULL)
423 (void) FormatLocaleString(buffer,MaxTextExtent,
424 "%s\" shape=\"rect\" coords=\"0,0,%.20g,%.20g\" alt=\"\" />\n",
425 image->filename,(double) geometry.width-1,(double) geometry.height-1);
426 (void) WriteBlobString(image,buffer);
429 for (p=image->directory; *p != '\0'; p++)
431 (void) WriteBlobByte(image,(unsigned char) *p);
434 (void) FormatLocaleString(buffer,MaxTextExtent,"\" shape=\"rect\""
435 " coords=\"%.20g,%.20g,%.20g,%.20g\" alt=\"\" />\n",
436 (double) geometry.x,(double) geometry.y,geometry.x+(double)
437 geometry.width-1,geometry.y+(double) geometry.height-1);
438 (void) WriteBlobString(image,buffer);
441 (void) FormatLocaleString(buffer,MaxTextExtent,
442 " <area href=%s\"",url);
443 (void) WriteBlobString(image,buffer);
445 geometry.x+=(ssize_t) geometry.width;
446 if ((geometry.x+4) >= (ssize_t) image->columns)
449 geometry.y+=(ssize_t) geometry.height;
452 (void) WriteBlobString(image,"</map>\n");
453 (void) CloseBlob(image);
454 (void) CopyMagickString(image->filename,filename,MaxTextExtent);