html.c revision d15e65928aec551b7388c2863de3e3e628e2e0dd
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project%                                                                             %
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project%                                                                             %
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project%                                                                             %
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project%                        H   H  TTTTT  M   M  L                               %
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project%                        H   H    T    MM MM  L                               %
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project%                        HHHHH    T    M M M  L                               %
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project%                        H   H    T    M   M  L                               %
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project%                        H   H    T    M   M  LLLLL                           %
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project%                                                                             %
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project%                                                                             %
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project%                  Write A Client-Side Image Map Using                        %
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project%                 Image Montage & Directory Information.                      %
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project%                                                                             %
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project%                              Software Design                                %
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project%                                John Cristy                                  %
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project%                                 July 1992                                   %
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project%                                                                             %
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project%                                                                             %
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project%  Copyright 1999-2011 ImageMagick Studio LLC, a non-profit organization      %
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project%  dedicated to making software imaging solutions freely available.           %
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project%                                                                             %
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project%  You may not use this file except in compliance with the License.  You may  %
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project%  obtain a copy of the License at                                            %
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project%                                                                             %
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project%    http://www.imagemagick.org/script/license.php                            %
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project%                                                                             %
29253ad40649242edae625d95e2ae415a1bf27b9fcPaul Duffin%  Unless required by applicable law or agreed to in writing, software        %
30253ad40649242edae625d95e2ae415a1bf27b9fcPaul Duffin%  distributed under the License is distributed on an "AS IS" BASIS,          %
31253ad40649242edae625d95e2ae415a1bf27b9fcPaul Duffin%  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project%  See the License for the specific language governing permissions and        %
33253ad40649242edae625d95e2ae415a1bf27b9fcPaul Duffin%  limitations under the License.                                             %
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project%                                                                             %
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project%
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project%
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project*/
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  Include declarations.
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project*/
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "MagickCore/studio.h"
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "MagickCore/blob.h"
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "MagickCore/blob-private.h"
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "MagickCore/color-private.h"
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "MagickCore/colorspace.h"
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "MagickCore/colorspace-private.h"
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "MagickCore/constitute.h"
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "MagickCore/exception.h"
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "MagickCore/exception-private.h"
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "MagickCore/geometry.h"
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "MagickCore/list.h"
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "MagickCore/magick.h"
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "MagickCore/memory_.h"
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "MagickCore/paint.h"
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "MagickCore/property.h"
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "MagickCore/quantum-private.h"
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "MagickCore/static.h"
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "MagickCore/string_.h"
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "MagickCore/module.h"
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "MagickCore/utility.h"
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  Forward declarations.
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project*/
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic MagickBooleanType
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  WriteHTMLImage(const ImageInfo *,Image *,ExceptionInfo *);
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project%                                                                             %
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project%                                                                             %
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project%                                                                             %
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project%   I s H T M L                                                               %
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project%                                                                             %
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project%                                                                             %
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project%                                                                             %
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project%
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project%  IsHTML() returns MagickTrue if the image format type, identified by the
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project%  magick string, is HTML.
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project%
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project%  The format of the IsHTML method is:
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project%
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project%      MagickBooleanType IsHTML(const unsigned char *magick,const size_t length)
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project%
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project%  A description of each parameter follows:
899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project%
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project%    o magick: compare image format pattern against these bytes.
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project%
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project%    o length: Specifies the length of the magick string.
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project%
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project*/
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic MagickBooleanType IsHTML(const unsigned char *magick,const size_t length)
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  if (length < 5)
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return(MagickFalse);
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  if (LocaleNCompare((char *) magick,"<html",5) == 0)
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return(MagickTrue);
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  return(MagickFalse);
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/*
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project%                                                                             %
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project%                                                                             %
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project%                                                                             %
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project%   R e g i s t e r H T M L I m a g e                                         %
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project%                                                                             %
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project%                                                                             %
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project%                                                                             %
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project%
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project%  RegisterHTMLImage() adds properties for the HTML image format to
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project%  the list of supported formats.  The properties include the image format
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project%  tag, a method to read and/or write the format, whether the format
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project%  supports the saving of more than one frame to the same file or blob,
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project%  whether the format supports native in-memory I/O, and a brief
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project%  description of the format.
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project%
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project%  The format of the RegisterHTMLImage method is:
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project%
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project%      size_t RegisterHTMLImage(void)
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project%
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project*/
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectModuleExport size_t RegisterHTMLImage(void)
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  MagickInfo
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    *entry;
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  entry=SetMagickInfo("HTM");
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  entry->encoder=(EncodeImageHandler *) WriteHTMLImage;
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  entry->magick=(IsImageFormatHandler *) IsHTML;
1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  entry->adjoin=MagickFalse;
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  entry->description=ConstantString(
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    "Hypertext Markup Language and a client-side image map");
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  entry->module=ConstantString("HTML");
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  (void) RegisterMagickInfo(entry);
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  entry=SetMagickInfo("HTML");
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  entry->encoder=(EncodeImageHandler *) WriteHTMLImage;
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  entry->magick=(IsImageFormatHandler *) IsHTML;
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  entry->adjoin=MagickFalse;
1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  entry->description=ConstantString(
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    "Hypertext Markup Language and a client-side image map");
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  entry->module=ConstantString("HTML");
1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  (void) RegisterMagickInfo(entry);
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  entry=SetMagickInfo("SHTML");
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  entry->encoder=(EncodeImageHandler *) WriteHTMLImage;
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project  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);
157}
158
159/*
160%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
161%                                                                             %
162%                                                                             %
163%                                                                             %
164%   U n r e g i s t e r H T M L I m a g e                                     %
165%                                                                             %
166%                                                                             %
167%                                                                             %
168%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
169%
170%  UnregisterHTMLImage() removes format registrations made by the
171%  HTML module from the list of supported formats.
172%
173%  The format of the UnregisterHTMLImage method is:
174%
175%      UnregisterHTMLImage(void)
176%
177*/
178ModuleExport void UnregisterHTMLImage(void)
179{
180  (void) UnregisterMagickInfo("HTM");
181  (void) UnregisterMagickInfo("HTML");
182  (void) UnregisterMagickInfo("SHTML");
183}
184
185/*
186%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
187%                                                                             %
188%                                                                             %
189%                                                                             %
190%   W r i t e H T M L I m a g e                                               %
191%                                                                             %
192%                                                                             %
193%                                                                             %
194%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
195%
196%  WriteHTMLImage() writes an image in the HTML encoded image format.
197%
198%  The format of the WriteHTMLImage method is:
199%
200%      MagickBooleanType WriteHTMLImage(const ImageInfo *image_info,
201%        Image *image,ExceptionInfo *exception)
202%
203%  A description of each parameter follows.
204%
205%    o image_info: the image info.
206%
207%    o image:  The image.
208%
209%    o exception: return any errors or warnings in this structure.
210%
211*/
212static MagickBooleanType WriteHTMLImage(const ImageInfo *image_info,
213  Image *image,ExceptionInfo *exception)
214{
215  char
216    basename[MaxTextExtent],
217    buffer[MaxTextExtent],
218    filename[MaxTextExtent],
219    mapname[MaxTextExtent],
220    url[MaxTextExtent];
221
222  Image
223    *next;
224
225  ImageInfo
226    *write_info;
227
228  MagickBooleanType
229    status;
230
231  RectangleInfo
232    geometry;
233
234  register char
235    *p;
236
237  /*
238    Open image.
239  */
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)
251    return(status);
252  (void) CloseBlob(image);
253  if (IsRGBColorspace(image->colorspace) == MagickFalse)
254    (void) TransformImageColorspace(image,RGBColorspace);
255  *url='\0';
256  if ((LocaleCompare(image_info->magick,"FTP") == 0) ||
257      (LocaleCompare(image_info->magick,"HTTP") == 0))
258    {
259      /*
260        Extract URL base from filename.
261      */
262      p=strrchr(image->filename,'/');
263      if (p != (char *) NULL)
264        {
265          p++;
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);
272        }
273    }
274  /*
275    Refer to image map file.
276  */
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;
285  status=MagickTrue;
286  if (LocaleCompare(image_info->magick,"SHTML") != 0)
287    {
288      const char
289        *value;
290
291      /*
292        Open output image file.
293      */
294      assert(exception != (ExceptionInfo *) NULL);
295      if (status == MagickFalse)
296        return(status);
297      /*
298        Write the HTML image file.
299      */
300      (void) WriteBlobString(image,"<?xml version=\"1.0\" "
301        "encoding=\"US-ASCII\"?>\n");
302      (void) WriteBlobString(image,"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML "
303        "1.0 Strict//EN\" "
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",
310          value);
311      else
312        {
313          GetPathComponent(filename,BasePath,basename);
314          (void) FormatLocaleString(buffer,MaxTextExtent,
315            "<title>%s</title>\n",basename);
316        }
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",
321        image->filename);
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,
328        filename);
329      (void) WriteBlobString(image,buffer);
330      /*
331        Determine the size and location of each image tile.
332      */
333      SetGeometry(image,&geometry);
334      if (image->montage != (char *) NULL)
335        (void) ParseAbsoluteGeometry(image->montage,&geometry);
336      /*
337        Write an image map.
338      */
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",
343        url);
344      (void) WriteBlobString(image,buffer);
345      if (image->directory == (char *) NULL)
346        {
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-
350            1);
351          (void) WriteBlobString(image,buffer);
352        }
353      else
354        for (p=image->directory; *p != '\0'; p++)
355          if (*p != '\n')
356            (void) WriteBlobByte(image,(unsigned char) *p);
357          else
358            {
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);
364              if (*(p+1) != '\0')
365                {
366                  (void) FormatLocaleString(buffer,MaxTextExtent,
367                    "  <area href=%s\"",url);
368                  (void) WriteBlobString(image,buffer);
369                }
370              geometry.x+=(ssize_t) geometry.width;
371              if ((geometry.x+4) >= (ssize_t) image->columns)
372                {
373                  geometry.x=0;
374                  geometry.y+=(ssize_t) geometry.height;
375                }
376            }
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);
383      /*
384        Write the image as PNG.
385      */
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);
392      image->next=next;
393      /*
394        Determine image map filename.
395      */
396      GetPathComponent(image->filename,BasePath,filename);
397      (void) ConcatenateMagickString(filename,"_map.shtml",MaxTextExtent);
398      (void) CopyMagickString(image->filename,filename,MaxTextExtent);
399    }
400  /*
401    Open image map.
402  */
403  status=OpenBlob(write_info,image,WriteBinaryBlobMode,exception);
404  if (status == MagickFalse)
405    return(status);
406  write_info=DestroyImageInfo(write_info);
407  /*
408    Determine the size and location of each image tile.
409  */
410  SetGeometry(image,&geometry);
411  if (image->montage != (char *) NULL)
412    (void) ParseAbsoluteGeometry(image->montage,&geometry);
413  /*
414    Write an image map.
415  */
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)
422    {
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);
427    }
428  else
429    for (p=image->directory; *p != '\0'; p++)
430      if (*p != '\n')
431        (void) WriteBlobByte(image,(unsigned char) *p);
432      else
433        {
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);
439          if (*(p+1) != '\0')
440            {
441              (void) FormatLocaleString(buffer,MaxTextExtent,
442                "  <area href=%s\"",url);
443              (void) WriteBlobString(image,buffer);
444            }
445          geometry.x+=(ssize_t) geometry.width;
446          if ((geometry.x+4) >= (ssize_t) image->columns)
447            {
448              geometry.x=0;
449              geometry.y+=(ssize_t) geometry.height;
450            }
451        }
452  (void) WriteBlobString(image,"</map>\n");
453  (void) CloseBlob(image);
454  (void) CopyMagickString(image->filename,filename,MaxTextExtent);
455  return(status);
456}
457