]> granicus.if.org Git - imagemagick/blob - coders/inline.c
...
[imagemagick] / coders / inline.c
1 /*
2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 %                                                                             %
4 %                                                                             %
5 %                                                                             %
6 %                  IIIII  N   N  L      IIIII  N   N  EEEEE                   %
7 %                    I    NN  N  L        I    NN  N  E                       %
8 %                    I    N N N  L        I    N N N  EEE                     %
9 %                    I    N  NN  L        I    N  NN  E                       %
10 %                  IIIII  N   N  LLLLL  IIIII  N   N  EEEEE                   %
11 %                                                                             %
12 %                                                                             %
13 %                            Read Inline Images                               %
14 %                                                                             %
15 %                              Software Design                                %
16 %                                   Cristy                                    %
17 %                                 July 1992                                   %
18 %                                                                             %
19 %                                                                             %
20 %  Copyright 1999-2018 ImageMagick Studio LLC, a non-profit organization      %
21 %  dedicated to making software imaging solutions freely available.           %
22 %                                                                             %
23 %  You may not use this file except in compliance with the License.  You may  %
24 %  obtain a copy of the License at                                            %
25 %                                                                             %
26 %    https://www.imagemagick.org/script/license.php                           %
27 %                                                                             %
28 %  Unless required by applicable law or agreed to in writing, software        %
29 %  distributed under the License is distributed on an "AS IS" BASIS,          %
30 %  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
31 %  See the License for the specific language governing permissions and        %
32 %  limitations under the License.                                             %
33 %                                                                             %
34 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
35 %
36 %
37 */
38 \f
39 /*
40   Include declarations.
41 */
42 #include "MagickCore/studio.h"
43 #include "MagickCore/blob.h"
44 #include "MagickCore/blob-private.h"
45 #include "MagickCore/client.h"
46 #include "MagickCore/constitute.h"
47 #include "MagickCore/display.h"
48 #include "MagickCore/exception.h"
49 #include "MagickCore/exception-private.h"
50 #include "MagickCore/image.h"
51 #include "MagickCore/image-private.h"
52 #include "MagickCore/list.h"
53 #include "MagickCore/magick.h"
54 #include "MagickCore/memory_.h"
55 #include "MagickCore/option.h"
56 #include "MagickCore/quantum-private.h"
57 #include "MagickCore/static.h"
58 #include "MagickCore/string_.h"
59 #include "MagickCore/module.h"
60 #include "MagickCore/utility.h"
61 #include "MagickCore/xwindow.h"
62 #include "MagickCore/xwindow-private.h"
63 \f
64 /*
65   Forward declarations.
66 */
67 static MagickBooleanType
68   WriteINLINEImage(const ImageInfo *,Image *,ExceptionInfo *);
69 \f
70 /*
71 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
72 %                                                                             %
73 %                                                                             %
74 %                                                                             %
75 %   R e a d I N L I N E I m a g e                                             %
76 %                                                                             %
77 %                                                                             %
78 %                                                                             %
79 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
80 %
81 %  ReadINLINEImage() reads base64-encoded inlines images.
82 %
83 %  The format of the ReadINLINEImage method is:
84 %
85 %      Image *ReadINLINEImage(const ImageInfo *image_info,
86 %        ExceptionInfo *exception)
87 %
88 %  A description of each parameter follows:
89 %
90 %    o image_info: the image info.
91 %
92 %    o exception: return any errors or warnings in this structure.
93 %
94 */
95 static Image *ReadINLINEImage(const ImageInfo *image_info,
96   ExceptionInfo *exception)
97 {
98   Image
99     *image;
100
101   MagickBooleanType
102     status;
103
104   register size_t
105     i;
106
107   size_t
108     quantum;
109
110   ssize_t
111     count;
112
113   unsigned char
114     *inline_image;
115
116   /*
117     Open image file.
118   */
119   assert(image_info != (const ImageInfo *) NULL);
120   assert(image_info->signature == MagickCoreSignature);
121   if (image_info->debug != MagickFalse)
122     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
123       image_info->filename);
124   assert(exception != (ExceptionInfo *) NULL);
125   assert(exception->signature == MagickCoreSignature);
126   if (LocaleNCompare(image_info->filename,"data:",5) == 0)
127     {
128       char
129         *filename;
130
131       Image
132         *data_image;
133
134       filename=AcquireString("data:");
135       (void) ConcatenateMagickString(filename,image_info->filename,
136         MagickPathExtent);
137       data_image=ReadInlineImage(image_info,filename,exception);
138       filename=DestroyString(filename);
139       return(data_image);
140     }
141   image=AcquireImage(image_info,exception);
142   status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
143   if (status == MagickFalse)
144     {
145       image=DestroyImageList(image);
146       return((Image *) NULL);
147     }
148   quantum=MagickMin((size_t) GetBlobSize(image),MagickMaxBufferExtent);
149   if (quantum == 0)
150     quantum=MagickMaxBufferExtent;
151   inline_image=(unsigned char *) AcquireQuantumMemory(quantum,
152     sizeof(*inline_image));
153   count=0;
154   for (i=0; inline_image != (unsigned char *) NULL; i+=count)
155   {
156     count=(ssize_t) ReadBlob(image,quantum,inline_image+i);
157     if (count <= 0)
158       {
159         count=0;
160         if (errno != EINTR)
161           break;
162       }
163     if (~((size_t) i) < (quantum+1))
164       {
165         inline_image=(unsigned char *) RelinquishMagickMemory(inline_image);
166         break;
167       }
168     inline_image=(unsigned char *) ResizeQuantumMemory(inline_image,i+count+
169       quantum+1,sizeof(*inline_image));
170   }
171   if (inline_image == (unsigned char *) NULL)
172     {
173       (void) ThrowMagickException(exception,GetMagickModule(),
174         ResourceLimitError,"MemoryAllocationFailed","`%s'",image->filename);
175       return((Image *) NULL);
176     }
177   inline_image[i+count]='\0';
178   image=DestroyImageList(image);
179   image=ReadInlineImage(image_info,(char *) inline_image,exception);
180   inline_image=(unsigned char *) RelinquishMagickMemory(inline_image);
181   return(image);
182 }
183 \f
184 /*
185 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
186 %                                                                             %
187 %                                                                             %
188 %                                                                             %
189 %   R e g i s t e r I N L I N E I m a g e                                     %
190 %                                                                             %
191 %                                                                             %
192 %                                                                             %
193 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
194 %
195 %  RegisterINLINEImage() adds attributes for the INLINE image format to
196 %  the list of supported formats.  The attributes include the image format
197 %  tag, a method to read and/or write the format, whether the format
198 %  supports the saving of more than one frame to the same file or blob,
199 %  whether the format supports native in-memory I/O, and a brief
200 %  description of the format.
201 %
202 %  The format of the RegisterINLINEImage method is:
203 %
204 %      size_t RegisterINLINEImage(void)
205 %
206 */
207 ModuleExport size_t RegisterINLINEImage(void)
208 {
209   MagickInfo
210     *entry;
211
212   entry=AcquireMagickInfo("DATA","INLINE","Base64-encoded inline images");
213   entry->decoder=(DecodeImageHandler *) ReadINLINEImage;
214   entry->encoder=(EncodeImageHandler *) WriteINLINEImage;
215   entry->format_type=ImplicitFormatType;
216   (void) RegisterMagickInfo(entry);
217   entry=AcquireMagickInfo("INLINE","INLINE","Base64-encoded inline images");
218   entry->decoder=(DecodeImageHandler *) ReadINLINEImage;
219   entry->encoder=(EncodeImageHandler *) WriteINLINEImage;
220   entry->format_type=ImplicitFormatType;
221   (void) RegisterMagickInfo(entry);
222   return(MagickImageCoderSignature);
223 }
224 \f
225 /*
226 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
227 %                                                                             %
228 %                                                                             %
229 %                                                                             %
230 %   U n r e g i s t e r I N L I N E I m a g e                                 %
231 %                                                                             %
232 %                                                                             %
233 %                                                                             %
234 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
235 %
236 %  UnregisterINLINEImage() removes format registrations made by the
237 %  INLINE module from the list of supported formats.
238 %
239 %  The format of the UnregisterINLINEImage method is:
240 %
241 %      UnregisterINLINEImage(void)
242 %
243 */
244 ModuleExport void UnregisterINLINEImage(void)
245 {
246   (void) UnregisterMagickInfo("INLINE");
247   (void) UnregisterMagickInfo("DATA");
248 }
249 \f
250 /*
251 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
252 %                                                                             %
253 %                                                                             %
254 %                                                                             %
255 %   W r i t e I N L I N E I m a g e                                           %
256 %                                                                             %
257 %                                                                             %
258 %                                                                             %
259 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
260 %
261 %  WriteINLINEImage() writes an image to a file in INLINE format (Base64).
262 %
263 %  The format of the WriteINLINEImage method is:
264 %
265 %      MagickBooleanType WriteINLINEImage(const ImageInfo *image_info,
266 %        Image *image,ExceptionInfo *exception)
267 %
268 %  A description of each parameter follows.
269 %
270 %    o image_info: the image info.
271 %
272 %    o image:  The image.
273 %
274 %    o exception: return any errors or warnings in this structure.
275 %
276 */
277 static MagickBooleanType WriteINLINEImage(const ImageInfo *image_info,
278   Image *image,ExceptionInfo *exception)
279 {
280   char
281     *base64,
282     message[MagickPathExtent];
283
284   const MagickInfo
285     *magick_info;
286
287   Image
288     *write_image;
289
290   ImageInfo
291     *write_info;
292
293   MagickBooleanType
294     status;
295
296   size_t
297     blob_length,
298     encode_length;
299
300   unsigned char
301     *blob;
302
303   /*
304     Convert image to base64-encoding.
305   */
306   assert(image_info != (const ImageInfo *) NULL);
307   assert(image_info->signature == MagickCoreSignature);
308   assert(image != (Image *) NULL);
309   assert(image->signature == MagickCoreSignature);
310   if (image->debug != MagickFalse)
311     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
312   write_info=CloneImageInfo(image_info);
313   (void) SetImageInfo(write_info,1,exception);
314   if (LocaleCompare(write_info->magick,"INLINE") == 0)
315     (void) CopyMagickString(write_info->magick,image->magick,MagickPathExtent);
316   magick_info=GetMagickInfo(write_info->magick,exception);
317   if ((magick_info == (const MagickInfo *) NULL) ||
318       (GetMagickMimeType(magick_info) == (const char *) NULL))
319     {
320       write_info=DestroyImageInfo(write_info);
321       ThrowWriterException(CorruptImageError,"ImageTypeNotSupported");
322     }
323   (void) CopyMagickString(image->filename,write_info->filename,
324     MagickPathExtent);
325   blob_length=2048;
326   write_image=CloneImage(image,0,0,MagickTrue,exception);
327   if (write_image == (Image *) NULL)
328     {
329       write_info=DestroyImageInfo(write_info);
330       return(MagickTrue);
331     }
332   blob=(unsigned char *) ImageToBlob(write_info,write_image,&blob_length,
333     exception);
334   write_image=DestroyImage(write_image);
335   write_info=DestroyImageInfo(write_info);
336   if (blob == (unsigned char *) NULL)
337     return(MagickFalse);
338   encode_length=0;
339   base64=Base64Encode(blob,blob_length,&encode_length);
340   blob=(unsigned char *) RelinquishMagickMemory(blob);
341   if (base64 == (char *) NULL)
342     ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
343   /*
344     Write base64-encoded image.
345   */
346   status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception);
347   if (status == MagickFalse)
348     {
349       base64=DestroyString(base64);
350       return(status);
351     }
352   (void) FormatLocaleString(message,MagickPathExtent,"data:%s;base64,",
353     GetMagickMimeType(magick_info));
354   (void) WriteBlobString(image,message);
355   (void) WriteBlobString(image,base64);
356   base64=DestroyString(base64);
357   return(MagickTrue);
358 }