]> granicus.if.org Git - imagemagick/blob - coders/html.c
https://www.imagemagick.org/discourse-server/viewtopic.php?f=1&t=31265
[imagemagick] / coders / html.c
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-2017 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 %    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 \f
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 \f
64 /*
65   Forward declarations.
66 */
67 static MagickBooleanType
68   WriteHTMLImage(const ImageInfo *,Image *,ExceptionInfo *);
69 \f
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 {
97   if (length < 5)
98     return(MagickFalse);
99   if (LocaleNCompare((char *) magick,"<html",5) == 0)
100     return(MagickTrue);
101   return(MagickFalse);
102 }
103 \f
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 {
129   MagickInfo
130     *entry;
131
132   entry=AcquireMagickInfo("HTML","HTM",
133     "Hypertext Markup Language and a client-side image map");
134   entry->encoder=(EncodeImageHandler *) WriteHTMLImage;
135   entry->magick=(IsImageFormatHandler *) IsHTML;
136   entry->flags^=CoderAdjoinFlag;
137   (void) RegisterMagickInfo(entry);
138   entry=AcquireMagickInfo("HTML","HTML",
139     "Hypertext Markup Language and a client-side image map");
140   entry->encoder=(EncodeImageHandler *) WriteHTMLImage;
141   entry->magick=(IsImageFormatHandler *) IsHTML;
142   entry->flags^=CoderAdjoinFlag;
143   (void) RegisterMagickInfo(entry);
144   entry=AcquireMagickInfo("HTML","SHTML",
145     "Hypertext Markup Language and a client-side image map");
146   entry->encoder=(EncodeImageHandler *) WriteHTMLImage;
147   entry->magick=(IsImageFormatHandler *) IsHTML;
148   entry->flags^=CoderAdjoinFlag;
149   (void) RegisterMagickInfo(entry);
150   return(MagickImageCoderSignature);
151 }
152 \f
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 {
174   (void) UnregisterMagickInfo("HTM");
175   (void) UnregisterMagickInfo("HTML");
176   (void) UnregisterMagickInfo("SHTML");
177 }
178 \f
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 static MagickBooleanType WriteHTMLImage(const ImageInfo *image_info,
207   Image *image,ExceptionInfo *exception)
208 {
209   char
210     basename[MagickPathExtent],
211     buffer[MagickPathExtent],
212     filename[MagickPathExtent],
213     mapname[MagickPathExtent],
214     url[MagickPathExtent];
215
216   Image
217     *next;
218
219   ImageInfo
220     *write_info;
221
222   MagickBooleanType
223     status;
224
225   RectangleInfo
226     geometry;
227
228   register char
229     *p;
230
231   /*
232     Open image.
233   */
234   assert(image_info != (const ImageInfo *) NULL);
235   assert(image_info->signature == MagickCoreSignature);
236   assert(image != (Image *) NULL);
237   assert(image->signature == MagickCoreSignature);
238   if (image->debug != MagickFalse)
239     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
240       image_info->filename);
241   assert(exception != (ExceptionInfo *) NULL);
242   assert(exception->signature == MagickCoreSignature);
243   status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
244   if (status == MagickFalse)
245     return(status);
246   (void) CloseBlob(image);
247   (void) TransformImageColorspace(image,sRGBColorspace,exception);
248   *url='\0';
249   if ((LocaleCompare(image_info->magick,"FTP") == 0) ||
250       (LocaleCompare(image_info->magick,"HTTP") == 0))
251     {
252       /*
253         Extract URL base from filename.
254       */
255       p=strrchr(image->filename,'/');
256       if (p != (char *) NULL)
257         {
258           p++;
259           (void) CopyMagickString(url,image_info->magick,MagickPathExtent);
260           (void) ConcatenateMagickString(url,":",MagickPathExtent);
261           url[strlen(url)+p-image->filename]='\0';
262           (void) ConcatenateMagickString(url,image->filename,
263             p-image->filename+2);
264           (void) CopyMagickString(image->filename,p,MagickPathExtent);
265         }
266     }
267   /*
268     Refer to image map file.
269   */
270   (void) CopyMagickString(filename,image->filename,MagickPathExtent);
271   AppendImageFormat("map",filename);
272   GetPathComponent(filename,BasePath,basename);
273   (void) CopyMagickString(mapname,basename,MagickPathExtent);
274   (void) CopyMagickString(image->filename,image_info->filename,MagickPathExtent);
275   (void) CopyMagickString(filename,image->filename,MagickPathExtent);
276   write_info=CloneImageInfo(image_info);
277   *write_info->magick='\0';
278   write_info->adjoin=MagickTrue;
279   status=MagickTrue;
280   if (LocaleCompare(image_info->magick,"SHTML") != 0)
281     {
282       const char
283         *value;
284
285       /*
286         Open output image file.
287       */
288       assert(exception != (ExceptionInfo *) NULL);
289       status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
290       if (status == MagickFalse)
291         return(status);
292       /*
293         Write the HTML image file.
294       */
295       (void) WriteBlobString(image,"<?xml version=\"1.0\" "
296         "encoding=\"US-ASCII\"?>\n");
297       (void) WriteBlobString(image,"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML "
298         "1.0 Strict//EN\" "
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",exception);
303       if (value != (const char *) NULL)
304         (void) FormatLocaleString(buffer,MagickPathExtent,"<title>%s</title>\n",
305           value);
306       else
307         {
308           GetPathComponent(filename,BasePath,basename);
309           (void) FormatLocaleString(buffer,MagickPathExtent,
310             "<title>%s</title>\n",basename);
311         }
312       (void) WriteBlobString(image,buffer);
313       (void) WriteBlobString(image,"</head>\n");
314       (void) WriteBlobString(image,"<body style=\"text-align: center;\">\n");
315       (void) FormatLocaleString(buffer,MagickPathExtent,"<h1>%s</h1>\n",
316         image->filename);
317       (void) WriteBlobString(image,buffer);
318       (void) WriteBlobString(image,"<div>\n");
319       (void) CopyMagickString(filename,image->filename,MagickPathExtent);
320       AppendImageFormat("png",filename);
321       (void) FormatLocaleString(buffer,MagickPathExtent,"<img usemap=\"#%s\" "
322         "src=\"%s\" style=\"border: 0;\" alt=\"Image map\" />\n",mapname,
323         filename);
324       (void) WriteBlobString(image,buffer);
325       /*
326         Determine the size and location of each image tile.
327       */
328       SetGeometry(image,&geometry);
329       if (image->montage != (char *) NULL)
330         (void) ParseAbsoluteGeometry(image->montage,&geometry);
331       /*
332         Write an image map.
333       */
334       (void) FormatLocaleString(buffer,MagickPathExtent,
335         "<map id=\"%s\" name=\"%s\">\n",mapname,mapname);
336       (void) WriteBlobString(image,buffer);
337       (void) FormatLocaleString(buffer,MagickPathExtent,"  <area href=\"%s",url);
338       (void) WriteBlobString(image,buffer);
339       if (image->directory == (char *) NULL)
340         {
341           (void) FormatLocaleString(buffer,MagickPathExtent,
342             "%s\" shape=\"rect\" coords=\"0,0,%.20g,%.20g\" alt=\"\" />\n",
343             image->filename,(double) geometry.width-1,(double) geometry.height-
344             1);
345           (void) WriteBlobString(image,buffer);
346         }
347       else
348         for (p=image->directory; *p != '\0'; p++)
349           if (*p != '\n')
350             (void) WriteBlobByte(image,(unsigned char) *p);
351           else
352             {
353               (void) FormatLocaleString(buffer,MagickPathExtent,"\" shape="
354                 "\"rect\" coords=\"%.20g,%.20g,%.20g,%.20g\" alt=\"\" />\n",
355                 (double) geometry.x,(double) geometry.y,(double) (geometry.x+
356                 geometry.width-1),(double) (geometry.y+geometry.height-1));
357               (void) WriteBlobString(image,buffer);
358               if (*(p+1) != '\0')
359                 {
360                   (void) FormatLocaleString(buffer,MagickPathExtent,
361                     "  <area href=%s\"",url);
362                   (void) WriteBlobString(image,buffer);
363                 }
364               geometry.x+=(ssize_t) geometry.width;
365               if ((geometry.x+4) >= (ssize_t) image->columns)
366                 {
367                   geometry.x=0;
368                   geometry.y+=(ssize_t) geometry.height;
369                 }
370             }
371       (void) WriteBlobString(image,"</map>\n");
372       (void) CopyMagickString(filename,image->filename,MagickPathExtent);
373       (void) WriteBlobString(image,"</div>\n");
374       (void) WriteBlobString(image,"</body>\n");
375       (void) WriteBlobString(image,"</html>\n");
376       (void) CloseBlob(image);
377       /*
378         Write the image as PNG.
379       */
380       (void) CopyMagickString(image->filename,filename,MagickPathExtent);
381       AppendImageFormat("png",image->filename);
382       next=GetNextImageInList(image);
383       image->next=NewImageList();
384       (void) CopyMagickString(image->magick,"PNG",MagickPathExtent);
385       (void) WriteImage(write_info,image,exception);
386       image->next=next;
387       /*
388         Determine image map filename.
389       */
390       GetPathComponent(image->filename,BasePath,filename);
391       (void) ConcatenateMagickString(filename,"_map.shtml",MagickPathExtent);
392       (void) CopyMagickString(image->filename,filename,MagickPathExtent);
393     }
394   /*
395     Open image map.
396   */
397   status=OpenBlob(write_info,image,WriteBinaryBlobMode,exception);
398   if (status == MagickFalse)
399     return(status);
400   write_info=DestroyImageInfo(write_info);
401   /*
402     Determine the size and location of each image tile.
403   */
404   SetGeometry(image,&geometry);
405   if (image->montage != (char *) NULL)
406     (void) ParseAbsoluteGeometry(image->montage,&geometry);
407   /*
408     Write an image map.
409   */
410   (void) FormatLocaleString(buffer,MagickPathExtent,
411     "<map id=\"%s\" name=\"%s\">\n",mapname,mapname);
412   (void) WriteBlobString(image,buffer);
413   (void) FormatLocaleString(buffer,MagickPathExtent,"  <area href=\"%s",url);
414   (void) WriteBlobString(image,buffer);
415   if (image->directory == (char *) NULL)
416     {
417       (void) FormatLocaleString(buffer,MagickPathExtent,
418         "%s\" shape=\"rect\" coords=\"0,0,%.20g,%.20g\" alt=\"\" />\n",
419         image->filename,(double) geometry.width-1,(double) geometry.height-1);
420       (void) WriteBlobString(image,buffer);
421     }
422   else
423     for (p=image->directory; *p != '\0'; p++)
424       if (*p != '\n')
425         (void) WriteBlobByte(image,(unsigned char) *p);
426       else
427         {
428           (void) FormatLocaleString(buffer,MagickPathExtent,"\" shape=\"rect\""
429             " coords=\"%.20g,%.20g,%.20g,%.20g\" alt=\"\" />\n",
430             (double) geometry.x,(double) geometry.y,geometry.x+(double)
431             geometry.width-1,geometry.y+(double) geometry.height-1);
432           (void) WriteBlobString(image,buffer);
433           if (*(p+1) != '\0')
434             {
435               (void) FormatLocaleString(buffer,MagickPathExtent,
436                 "  <area href=%s\"",url);
437               (void) WriteBlobString(image,buffer);
438             }
439           geometry.x+=(ssize_t) geometry.width;
440           if ((geometry.x+4) >= (ssize_t) image->columns)
441             {
442               geometry.x=0;
443               geometry.y+=(ssize_t) geometry.height;
444             }
445         }
446   (void) WriteBlobString(image,"</map>\n");
447   (void) CloseBlob(image);
448   (void) CopyMagickString(image->filename,filename,MagickPathExtent);
449   return(status);
450 }