2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
13 % Write A Client-Side Image Map Using %
14 % Image Montage & Directory Information. %
21 % Copyright 1999-2010 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 "magick/studio.h"
44 #include "magick/blob.h"
45 #include "magick/blob-private.h"
46 #include "magick/color-private.h"
47 #include "magick/colorspace.h"
48 #include "magick/constitute.h"
49 #include "magick/exception.h"
50 #include "magick/exception-private.h"
51 #include "magick/geometry.h"
52 #include "magick/list.h"
53 #include "magick/magick.h"
54 #include "magick/memory_.h"
55 #include "magick/paint.h"
56 #include "magick/property.h"
57 #include "magick/quantum-private.h"
58 #include "magick/static.h"
59 #include "magick/string_.h"
60 #include "magick/module.h"
61 #include "magick/utility.h"
66 static MagickBooleanType
67 WriteHTMLImage(const ImageInfo *,Image *);
70 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
78 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
80 % IsHTML() returns MagickTrue if the image format type, identified by the
81 % magick string, is HTML.
83 % The format of the IsHTML method is:
85 % MagickBooleanType IsHTML(const unsigned char *magick,const size_t length)
87 % A description of each parameter follows:
89 % o magick: compare image format pattern against these bytes.
91 % o length: Specifies the length of the magick string.
94 static MagickBooleanType IsHTML(const unsigned char *magick,const size_t length)
98 if (LocaleNCompare((char *) magick,"<html",5) == 0)
104 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
108 % R e g i s t e r H T M L I m a g e %
112 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
114 % RegisterHTMLImage() adds properties for the HTML image format to
115 % the list of supported formats. The properties include the image format
116 % tag, a method to read and/or write the format, whether the format
117 % supports the saving of more than one frame to the same file or blob,
118 % whether the format supports native in-memory I/O, and a brief
119 % description of the format.
121 % The format of the RegisterHTMLImage method is:
123 % unsigned long RegisterHTMLImage(void)
126 ModuleExport unsigned long RegisterHTMLImage(void)
131 entry=SetMagickInfo("HTM");
132 entry->encoder=(EncodeImageHandler *) WriteHTMLImage;
133 entry->magick=(IsImageFormatHandler *) IsHTML;
134 entry->adjoin=MagickFalse;
135 entry->description=ConstantString(
136 "Hypertext Markup Language and a client-side image map");
137 entry->module=ConstantString("HTML");
138 (void) RegisterMagickInfo(entry);
139 entry=SetMagickInfo("HTML");
140 entry->encoder=(EncodeImageHandler *) WriteHTMLImage;
141 entry->magick=(IsImageFormatHandler *) IsHTML;
142 entry->adjoin=MagickFalse;
143 entry->description=ConstantString(
144 "Hypertext Markup Language and a client-side image map");
145 entry->module=ConstantString("HTML");
146 (void) RegisterMagickInfo(entry);
147 entry=SetMagickInfo("SHTML");
148 entry->encoder=(EncodeImageHandler *) WriteHTMLImage;
149 entry->magick=(IsImageFormatHandler *) IsHTML;
150 entry->adjoin=MagickFalse;
151 entry->description=ConstantString(
152 "Hypertext Markup Language and a client-side image map");
153 entry->module=ConstantString("HTML");
154 (void) RegisterMagickInfo(entry);
155 return(MagickImageCoderSignature);
159 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
163 % U n r e g i s t e r H T M L I m a g e %
167 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
169 % UnregisterHTMLImage() removes format registrations made by the
170 % HTML module from the list of supported formats.
172 % The format of the UnregisterHTMLImage method is:
174 % UnregisterHTMLImage(void)
177 ModuleExport void UnregisterHTMLImage(void)
179 (void) UnregisterMagickInfo("HTM");
180 (void) UnregisterMagickInfo("HTML");
181 (void) UnregisterMagickInfo("SHTML");
185 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
189 % W r i t e H T M L I m a g e %
193 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
195 % WriteHTMLImage() writes an image in the HTML encoded image format.
197 % The format of the WriteHTMLImage method is:
199 % MagickBooleanType WriteHTMLImage(const ImageInfo *image_info,Image *image)
201 % A description of each parameter follows.
203 % o image_info: the image info.
205 % o image: The image.
209 static MagickBooleanType WriteHTMLImage(const ImageInfo *image_info,
213 basename[MaxTextExtent],
214 buffer[MaxTextExtent],
215 filename[MaxTextExtent],
216 mapname[MaxTextExtent],
237 assert(image_info != (const ImageInfo *) NULL);
238 assert(image_info->signature == MagickSignature);
239 assert(image != (Image *) NULL);
240 assert(image->signature == MagickSignature);
241 if (image->debug != MagickFalse)
242 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
243 image_info->filename);
244 status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
245 if (status == MagickFalse)
247 (void) CloseBlob(image);
248 if (image->colorspace != RGBColorspace)
249 (void) TransformImageColorspace(image,RGBColorspace);
251 if ((LocaleCompare(image_info->magick,"FTP") == 0) ||
252 (LocaleCompare(image_info->magick,"HTTP") == 0))
255 Extract URL base from filename.
257 p=strrchr(image->filename,'/');
261 (void) CopyMagickString(url,image_info->magick,MaxTextExtent);
262 (void) ConcatenateMagickString(url,":",MaxTextExtent);
263 url[strlen(url)+p-image->filename]='\0';
264 (void) ConcatenateMagickString(url,image->filename,
265 p-image->filename+2);
266 (void) CopyMagickString(image->filename,p,MaxTextExtent);
270 Refer to image map file.
272 (void) CopyMagickString(filename,image->filename,MaxTextExtent);
273 AppendImageFormat("map",filename);
274 GetPathComponent(filename,BasePath,basename);
275 (void) CopyMagickString(mapname,basename,MaxTextExtent);
276 (void) CopyMagickString(image->filename,image_info->filename,MaxTextExtent);
277 (void) CopyMagickString(filename,image->filename,MaxTextExtent);
278 write_info=CloneImageInfo(image_info);
279 write_info->adjoin=MagickTrue;
281 if (LocaleCompare(image_info->magick,"SHTML") != 0)
287 Open output image file.
289 status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
290 if (status == MagickFalse)
293 Write the HTML image file.
295 (void) WriteBlobString(image,"<?xml version=\"1.0\" "
296 "encoding=\"US-ASCII\"?>\n");
297 (void) WriteBlobString(image,"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML "
299 "\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n");
300 (void) WriteBlobString(image,"<html>\n");
301 (void) WriteBlobString(image,"<head>\n");
302 value=GetImageProperty(image,"label");
303 if (value != (const char *) NULL)
304 (void) FormatMagickString(buffer,MaxTextExtent,"<title>%s</title>\n",
308 GetPathComponent(filename,BasePath,basename);
309 (void) FormatMagickString(buffer,MaxTextExtent,
310 "<title>%s</title>\n",basename);
312 (void) WriteBlobString(image,buffer);
313 (void) WriteBlobString(image,"</head>\n");
314 (void) WriteBlobString(image,"<body style=\"text-align: center;\">\n");
315 (void) FormatMagickString(buffer,MaxTextExtent,"<h1>%s</h1>\n",
317 (void) WriteBlobString(image,buffer);
318 (void) WriteBlobString(image,"<div>\n");
319 (void) CopyMagickString(filename,image->filename,MaxTextExtent);
320 AppendImageFormat("png",filename);
321 (void) FormatMagickString(buffer,MaxTextExtent,"<img usemap=\"#%s\" "
322 "src=\"%s\" style=\"border: 0;\" alt=\"Image map\" />\n",mapname,
324 (void) WriteBlobString(image,buffer);
326 Determine the size and location of each image tile.
328 SetGeometry(image,&geometry);
329 if (image->montage != (char *) NULL)
330 (void) ParseAbsoluteGeometry(image->montage,&geometry);
334 (void) FormatMagickString(buffer,MaxTextExtent,
335 "<map id=\"%s\" name=\"%s\">\n",mapname,mapname);
336 (void) WriteBlobString(image,buffer);
337 (void) FormatMagickString(buffer,MaxTextExtent," <area href=\"%s",
339 (void) WriteBlobString(image,buffer);
340 if (image->directory == (char *) NULL)
342 (void) FormatMagickString(buffer,MaxTextExtent,
343 "%s\" shape=\"rect\" coords=\"0,0,%lu,%lu\" alt=\"\" />\n",
344 image->filename,geometry.width-1,geometry.height-1);
345 (void) WriteBlobString(image,buffer);
348 for (p=image->directory; *p != '\0'; p++)
350 (void) WriteBlobByte(image,(unsigned char) *p);
353 (void) FormatMagickString(buffer,MaxTextExtent,
354 "\" shape=\"rect\" coords=\"%ld,%ld,%ld,%ld\" alt=\"\" />\n",
355 geometry.x,geometry.y,geometry.x+(long) geometry.width-1,
356 geometry.y+(long) geometry.height-1);
357 (void) WriteBlobString(image,buffer);
360 (void) FormatMagickString(buffer,MaxTextExtent,
361 " <area href=%s\"",url);
362 (void) WriteBlobString(image,buffer);
364 geometry.x+=geometry.width;
365 if ((geometry.x+4) >= (long) image->columns)
368 geometry.y+=geometry.height;
371 (void) WriteBlobString(image,"</map>\n");
372 (void) CopyMagickString(filename,image->filename,MaxTextExtent);
373 (void) WriteBlobString(image,"</div>\n");
374 (void) WriteBlobString(image,"</body>\n");
375 (void) WriteBlobString(image,"</html>\n");
376 (void) CloseBlob(image);
378 Write the image as PNG.
380 (void) CopyMagickString(image->filename,filename,MaxTextExtent);
381 AppendImageFormat("png",image->filename);
382 next=GetNextImageInList(image);
383 image->next=NewImageList();
384 (void) CopyMagickString(image->magick,"PNG",MaxTextExtent);
385 (void) WriteImage(write_info,image);
388 Determine image map filename.
390 GetPathComponent(image->filename,BasePath,filename);
391 (void) ConcatenateMagickString(filename,"_map.shtml",MaxTextExtent);
392 (void) CopyMagickString(image->filename,filename,MaxTextExtent);
397 status=OpenBlob(write_info,image,WriteBinaryBlobMode,&image->exception);
398 if (status == MagickFalse)
400 write_info=DestroyImageInfo(write_info);
402 Determine the size and location of each image tile.
404 SetGeometry(image,&geometry);
405 if (image->montage != (char *) NULL)
406 (void) ParseAbsoluteGeometry(image->montage,&geometry);
410 (void) FormatMagickString(buffer,MaxTextExtent,
411 "<map id=\"%s\" name=\"%s\">\n",mapname,mapname);
412 (void) WriteBlobString(image,buffer);
413 (void) FormatMagickString(buffer,MaxTextExtent," <area href=\"%s",url);
414 (void) WriteBlobString(image,buffer);
415 if (image->directory == (char *) NULL)
417 (void) FormatMagickString(buffer,MaxTextExtent,
418 "%s\" shape=\"rect\" coords=\"0,0,%lu,%lu\" alt=\"\" />\n",
419 image->filename,geometry.width-1,geometry.height-1);
420 (void) WriteBlobString(image,buffer);
423 for (p=image->directory; *p != '\0'; p++)
425 (void) WriteBlobByte(image,(unsigned char) *p);
428 (void) FormatMagickString(buffer,MaxTextExtent,
429 "\" shape=\"rect\" coords=\"%ld,%ld,%ld,%ld\" alt=\"\" />\n",
430 geometry.x,geometry.y,geometry.x+(long) geometry.width-1,
431 geometry.y+(long) geometry.height-1);
432 (void) WriteBlobString(image,buffer);
435 (void) FormatMagickString(buffer,MaxTextExtent,
436 " <area href=%s\"",url);
437 (void) WriteBlobString(image,buffer);
439 geometry.x+=geometry.width;
440 if ((geometry.x+4) >= (long) image->columns)
443 geometry.y+=geometry.height;
446 (void) WriteBlobString(image,"</map>\n");
447 (void) CloseBlob(image);
448 (void) CopyMagickString(image->filename,filename,MaxTextExtent);