vid.c revision 7e41fe84a841d7b9d7b36b245b65e9dcb3314943
1/*
2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3%                                                                             %
4%                                                                             %
5%                                                                             %
6%                            V   V  IIIII  DDDD                               %
7%                            V   V    I    D   D                              %
8%                            V   V    I    D   D                              %
9%                             V V     I    D   D                              %
10%                              V    IIIII  DDDD                               %
11%                                                                             %
12%                                                                             %
13%             Return a Visual Image Directory for matching images.            %
14%                                                                             %
15%                              Software Design                                %
16%                                John Cristy                                  %
17%                                 July 1992                                   %
18%                                                                             %
19%                                                                             %
20%  Copyright 1999-2011 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%    http://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
39/*
40  Include declarations.
41*/
42#include "magick/studio.h"
43#include "magick/property.h"
44#include "magick/blob.h"
45#include "magick/blob-private.h"
46#include "magick/constitute.h"
47#include "magick/exception.h"
48#include "magick/exception-private.h"
49#include "magick/geometry.h"
50#include "magick/image.h"
51#include "magick/image-private.h"
52#include "magick/list.h"
53#include "magick/log.h"
54#include "magick/magick.h"
55#include "magick/memory_.h"
56#include "magick/monitor.h"
57#include "magick/monitor-private.h"
58#include "magick/montage.h"
59#include "magick/quantum-private.h"
60#include "magick/resize.h"
61#include "magick/static.h"
62#include "magick/string_.h"
63#include "magick/module.h"
64#include "magick/utility.h"
65
66/*
67  Forward declarations.
68*/
69static MagickBooleanType
70  WriteVIDImage(const ImageInfo *,Image *);
71
72/*
73%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
74%                                                                             %
75%                                                                             %
76%                                                                             %
77%   R e a d V I D I m a g e                                                   %
78%                                                                             %
79%                                                                             %
80%                                                                             %
81%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
82%
83%  ReadVIDImage reads one of more images and creates a Visual Image
84%  Directory file.  It allocates the memory necessary for the new Image
85%  structure and returns a pointer to the new image.
86%
87%  The format of the ReadVIDImage method is:
88%
89%      Image *ReadVIDImage(const ImageInfo *image_info,ExceptionInfo *exception)
90%
91%  A description of each parameter follows:
92%
93%    o image_info: the image info.
94%
95%    o exception: return any errors or warnings in this structure.
96%
97*/
98static Image *ReadVIDImage(const ImageInfo *image_info,ExceptionInfo *exception)
99{
100#define ClientName  "montage"
101
102  char
103    **filelist,
104    *label;
105
106  Image
107    *image,
108    *images,
109    *montage_image,
110    *next_image,
111    *thumbnail_image;
112
113  ImageInfo
114    *read_info;
115
116  int
117    number_files;
118
119  MagickBooleanType
120    status;
121
122  MontageInfo
123    *montage_info;
124
125  RectangleInfo
126    geometry;
127
128  register ssize_t
129    i;
130
131  /*
132    Expand the filename.
133  */
134  assert(image_info != (const ImageInfo *) NULL);
135  assert(image_info->signature == MagickSignature);
136  if (image_info->debug != MagickFalse)
137    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
138      image_info->filename);
139  assert(exception != (ExceptionInfo *) NULL);
140  assert(exception->signature == MagickSignature);
141  image=AcquireImage(image_info);
142  filelist=(char **) AcquireMagickMemory(sizeof(*filelist));
143  if (filelist == (char **) NULL)
144    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
145  filelist[0]=ConstantString(image_info->filename);
146  number_files=1;
147  status=ExpandFilenames(&number_files,&filelist);
148  if ((status == MagickFalse) || (number_files == 0))
149    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
150  image=DestroyImage(image);
151  /*
152    Read each image and convert them to a tile.
153  */
154  images=NewImageList();
155  read_info=CloneImageInfo(image_info);
156  SetImageInfoBlob(read_info,(void *) NULL,0);
157  (void) SetImageInfoProgressMonitor(read_info,(MagickProgressMonitor) NULL,
158    (void *) NULL);
159  if (read_info->size == (char *) NULL)
160    (void) CloneString(&read_info->size,DefaultTileGeometry);
161  for (i=0; i < (ssize_t) number_files; i++)
162  {
163    if (image_info->debug != MagickFalse)
164      (void) LogMagickEvent(CoderEvent,GetMagickModule(),"name: %s",
165        filelist[i]);
166    (void) CopyMagickString(read_info->filename,filelist[i],MaxTextExtent);
167    filelist[i]=DestroyString(filelist[i]);
168    *read_info->magick='\0';
169    next_image=ReadImage(read_info,exception);
170    CatchException(exception);
171    if (next_image == (Image *) NULL)
172      break;
173    label=InterpretImageProperties(image_info,next_image,DefaultTileLabel);
174    (void) SetImageProperty(next_image,"label",label);
175    label=DestroyString(label);
176    if (image_info->debug != MagickFalse)
177      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
178        "geometry: %.20gx%.20g",(double) next_image->columns,(double)
179        next_image->rows);
180    SetGeometry(next_image,&geometry);
181    (void) ParseMetaGeometry(read_info->size,&geometry.x,&geometry.y,
182      &geometry.width,&geometry.height);
183    thumbnail_image=ThumbnailImage(next_image,geometry.width,geometry.height,
184      exception);
185    if (thumbnail_image != (Image *) NULL)
186      {
187        next_image=DestroyImage(next_image);
188        next_image=thumbnail_image;
189      }
190    if (image_info->debug != MagickFalse)
191      (void) LogMagickEvent(CoderEvent,GetMagickModule(),
192        "thumbnail geometry: %.20gx%.20g",(double) next_image->columns,(double)
193        next_image->rows);
194    AppendImageToList(&images,next_image);
195    status=SetImageProgress(images,LoadImagesTag,i,number_files);
196    if (status == MagickFalse)
197      break;
198  }
199  read_info=DestroyImageInfo(read_info);
200  filelist=(char **) RelinquishMagickMemory(filelist);
201  if (images == (Image *) NULL)
202    ThrowReaderException(CorruptImageError,
203      "ImageFileDoesNotContainAnyImageData");
204  /*
205    Create the visual image directory.
206  */
207  montage_info=CloneMontageInfo(image_info,(MontageInfo *) NULL);
208  if (image_info->debug != MagickFalse)
209    (void) LogMagickEvent(CoderEvent,GetMagickModule(),"creating montage");
210  montage_image=MontageImageList(image_info,montage_info,
211    GetFirstImageInList(images),exception);
212  montage_info=DestroyMontageInfo(montage_info);
213  images=DestroyImageList(images);
214  return(montage_image);
215}
216
217/*
218%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
219%                                                                             %
220%                                                                             %
221%                                                                             %
222%   R e g i s t e r V I D I m a g e                                           %
223%                                                                             %
224%                                                                             %
225%                                                                             %
226%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
227%
228%  RegisterVIDImage() adds attributes for the VID image format to
229%  the list of supported formats.  The attributes include the image format
230%  tag, a method to read and/or write the format, whether the format
231%  supports the saving of more than one frame to the same file or blob,
232%  whether the format supports native in-memory I/O, and a brief
233%  description of the format.
234%
235%  The format of the RegisterVIDImage method is:
236%
237%      size_t RegisterVIDImage(void)
238%
239*/
240ModuleExport size_t RegisterVIDImage(void)
241{
242  MagickInfo
243    *entry;
244
245  entry=SetMagickInfo("VID");
246  entry->decoder=(DecodeImageHandler *) ReadVIDImage;
247  entry->encoder=(EncodeImageHandler *) WriteVIDImage;
248  entry->format_type=ImplicitFormatType;
249  entry->description=ConstantString("Visual Image Directory");
250  entry->module=ConstantString("VID");
251  (void) RegisterMagickInfo(entry);
252  return(MagickImageCoderSignature);
253}
254
255/*
256%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
257%                                                                             %
258%                                                                             %
259%                                                                             %
260%   U n r e g i s t e r V I D I m a g e                                       %
261%                                                                             %
262%                                                                             %
263%                                                                             %
264%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
265%
266%  UnregisterVIDImage() removes format registrations made by the
267%  VID module from the list of supported formats.
268%
269%  The format of the UnregisterVIDImage method is:
270%
271%      UnregisterVIDImage(void)
272%
273*/
274ModuleExport void UnregisterVIDImage(void)
275{
276  (void) UnregisterMagickInfo("VID");
277}
278
279/*
280%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
281%                                                                             %
282%                                                                             %
283%                                                                             %
284%   W r i t e V I D I m a g e                                                 %
285%                                                                             %
286%                                                                             %
287%                                                                             %
288%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
289%
290%  WriteVIDImage() writes an image to a file in VID X image format.
291%
292%  The format of the WriteVIDImage method is:
293%
294%      MagickBooleanType WriteVIDImage(const ImageInfo *image_info,Image *image)
295%
296%  A description of each parameter follows.
297%
298%    o image_info: the image info.
299%
300%    o image:  The image.
301%
302*/
303static MagickBooleanType WriteVIDImage(const ImageInfo *image_info,Image *image)
304{
305  Image
306    *montage_image;
307
308  ImageInfo
309    *write_info;
310
311  MagickBooleanType
312    status;
313
314  MontageInfo
315    *montage_info;
316
317  register Image
318    *p;
319
320  /*
321    Create the visual image directory.
322  */
323  for (p=image; p != (Image *) NULL; p=GetNextImageInList(p))
324    (void) SetImageProperty(p,"label",DefaultTileLabel);
325  montage_info=CloneMontageInfo(image_info,(MontageInfo *) NULL);
326  montage_image=MontageImageList(image_info,montage_info,image,
327    &image->exception);
328  montage_info=DestroyMontageInfo(montage_info);
329  if (montage_image == (Image *) NULL)
330    ThrowWriterException(CorruptImageError,image->exception.reason);
331  (void) CopyMagickString(montage_image->filename,image_info->filename,
332    MaxTextExtent);
333  write_info=CloneImageInfo(image_info);
334  (void) SetImageInfo(write_info,1,&image->exception);
335  if (LocaleCompare(write_info->magick,"VID") == 0)
336    (void) FormatMagickString(montage_image->filename,MaxTextExtent,
337      "miff:%s",write_info->filename);
338  status=WriteImage(write_info,montage_image);
339  montage_image=DestroyImage(montage_image);
340  write_info=DestroyImageInfo(write_info);
341  return(status);
342}
343