blob: bfd92a4cc92df9f001080dc6a39b580ff4d03fc2 [file] [log] [blame]
cristy3ed852e2009-09-05 21:47:34 +00001/*
2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3% %
4% %
5% %
6% AAA RRRR TTTTT %
7% A A R R T %
8% AAAAA RRRR T %
9% A A R R T %
10% A A R R T %
11% %
12% %
13% Support PFS: 1st Publisher Clip Art Format %
14% %
15% Software Design %
16% John Cristy %
17% July 1992 %
18% %
19% %
cristy7e41fe82010-12-04 23:12:08 +000020% Copyright 1999-2011 ImageMagick Studio LLC, a non-profit organization %
cristy3ed852e2009-09-05 21:47:34 +000021% 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/blob.h"
44#include "magick/blob-private.h"
45#include "magick/cache.h"
46#include "magick/color-private.h"
cristye7e40552010-04-24 21:34:22 +000047#include "magick/colormap.h"
cristy3ed852e2009-09-05 21:47:34 +000048#include "magick/colorspace.h"
49#include "magick/exception.h"
50#include "magick/exception-private.h"
51#include "magick/image.h"
52#include "magick/image-private.h"
53#include "magick/list.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/quantum-private.h"
59#include "magick/static.h"
60#include "magick/string_.h"
61#include "magick/module.h"
62
63/*
64 Forward declarations.
65*/
66static MagickBooleanType
67 WriteARTImage(const ImageInfo *,Image *);
68
69/*
70%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
71% %
72% %
73% %
74% R e a d A R T I m a g e %
75% %
76% %
77% %
78%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
79%
80% ReadARTImage() reads an image of raw bits in LSB order and returns it.
81% It allocates the memory necessary for the new Image structure and returns
82% a pointer to the new image.
83%
84% The format of the ReadARTImage method is:
85%
86% Image *ReadARTImage(const ImageInfo *image_info,
87% ExceptionInfo *exception)
88%
89% A description of each parameter follows:
90%
91% o image_info: the image info.
92%
93% o exception: return any errors or warnings in this structure.
94%
95*/
96static Image *ReadARTImage(const ImageInfo *image_info,ExceptionInfo *exception)
97{
98 Image
99 *image;
100
cristybb503372010-05-27 20:51:26 +0000101 ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000102 y;
103
104 QuantumInfo
105 *quantum_info;
106
107 QuantumType
108 quantum_type;
109
110 MagickBooleanType
111 status;
112
113 ssize_t
114 count;
115
116 size_t
117 length;
118
119 unsigned char
120 *pixels;
121
122 /*
123 Open image file.
124 */
125 assert(image_info != (const ImageInfo *) NULL);
126 assert(image_info->signature == MagickSignature);
127 if (image_info->debug != MagickFalse)
128 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
129 image_info->filename);
130 assert(exception != (ExceptionInfo *) NULL);
131 assert(exception->signature == MagickSignature);
132 image=AcquireImage(image_info);
133 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
134 if (status == MagickFalse)
135 {
136 image=DestroyImageList(image);
137 return((Image *) NULL);
138 }
139 image->depth=1;
140 image->endian=MSBEndian;
141 (void) ReadBlobLSBShort(image);
cristybb503372010-05-27 20:51:26 +0000142 image->columns=(size_t) ReadBlobLSBShort(image);
cristy3ed852e2009-09-05 21:47:34 +0000143 (void) ReadBlobLSBShort(image);
cristybb503372010-05-27 20:51:26 +0000144 image->rows=(size_t) ReadBlobLSBShort(image);
cristy3ed852e2009-09-05 21:47:34 +0000145 /*
146 Initialize image colormap.
147 */
148 if (AcquireImageColormap(image,2) == MagickFalse)
149 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
150 if (image_info->ping != MagickFalse)
151 {
152 (void) CloseBlob(image);
153 return(GetFirstImageInList(image));
154 }
155 /*
156 Convert bi-level image to pixel packets.
157 */
158 quantum_type=IndexQuantum;
159 quantum_info=AcquireQuantumInfo(image_info,image);
160 if (quantum_info == (QuantumInfo *) NULL)
161 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
162 pixels=GetQuantumPixels(quantum_info);
163 length=GetQuantumExtent(image,quantum_info,quantum_type);
cristybb503372010-05-27 20:51:26 +0000164 for (y=0; y < (ssize_t) image->rows; y++)
cristy3ed852e2009-09-05 21:47:34 +0000165 {
166 register PixelPacket
cristyc47d1f82009-11-26 01:44:43 +0000167 *restrict q;
cristy3ed852e2009-09-05 21:47:34 +0000168
169 q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
170 if (q == (PixelPacket *) NULL)
171 break;
172 count=ReadBlob(image,length,pixels);
173 if (count != (ssize_t) length)
174 ThrowReaderException(CorruptImageError,"UnableToReadImageData");
175 (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info,
176 quantum_type,pixels,exception);
177 count=ReadBlob(image,(size_t) (-(ssize_t) length) & 0x01,pixels);
178 if (SyncAuthenticPixels(image,exception) == MagickFalse)
179 break;
180 if (SetImageProgress(image,LoadImageTag,y,image->rows) == MagickFalse)
181 break;
182 }
183 SetQuantumImageType(image,quantum_type);
184 quantum_info=DestroyQuantumInfo(quantum_info);
185 if (EOFBlob(image) != MagickFalse)
186 ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
187 image->filename);
188 (void) CloseBlob(image);
189 return(GetFirstImageInList(image));
190}
191
192/*
193%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
194% %
195% %
196% %
197% R e g i s t e r A R T I m a g e %
198% %
199% %
200% %
201%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
202%
203% RegisterARTImage() adds attributes for the ART image format to
204% the list of supported formats. The attributes include the image format
205% tag, a method to read and/or write the format, whether the format
206% supports the saving of more than one frame to the same file or blob,
207% whether the format supports native in-memory I/O, and a brief
208% description of the format.
209%
210% The format of the RegisterARTImage method is:
211%
cristybb503372010-05-27 20:51:26 +0000212% size_t RegisterARTImage(void)
cristy3ed852e2009-09-05 21:47:34 +0000213%
214*/
cristybb503372010-05-27 20:51:26 +0000215ModuleExport size_t RegisterARTImage(void)
cristy3ed852e2009-09-05 21:47:34 +0000216{
217 MagickInfo
218 *entry;
219
220 entry=SetMagickInfo("ART");
221 entry->decoder=(DecodeImageHandler *) ReadARTImage;
222 entry->encoder=(EncodeImageHandler *) WriteARTImage;
223 entry->raw=MagickTrue;
224 entry->adjoin=MagickFalse;
225 entry->description=ConstantString("PFS: 1st Publisher Clip Art");
226 entry->module=ConstantString("ART");
227 (void) RegisterMagickInfo(entry);
228 return(MagickImageCoderSignature);
229}
230
231/*
232%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
233% %
234% %
235% %
236% U n r e g i s t e r A R T I m a g e %
237% %
238% %
239% %
240%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
241%
242% UnregisterARTImage() removes format registrations made by the
243% ART module from the list of supported formats.
244%
245% The format of the UnregisterARTImage method is:
246%
247% UnregisterARTImage(void)
248%
249*/
250ModuleExport void UnregisterARTImage(void)
251{
252 (void) UnregisterMagickInfo("ART");
253}
254
255/*
256%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
257% %
258% %
259% %
260% W r i t e A R T I m a g e %
261% %
262% %
263% %
264%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
265%
266% WriteARTImage() writes an image of raw bits in LSB order to a file.
267%
268% The format of the WriteARTImage method is:
269%
270% MagickBooleanType WriteARTImage(const ImageInfo *image_info,Image *image)
271%
272% A description of each parameter follows.
273%
274% o image_info: the image info.
275%
276% o image: The image.
277%
278*/
279static MagickBooleanType WriteARTImage(const ImageInfo *image_info,Image *image)
280{
cristybb503372010-05-27 20:51:26 +0000281 ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000282 y;
283
284 MagickBooleanType
285 status;
286
287 QuantumInfo
288 *quantum_info;
289
290 register const PixelPacket
291 *p;
292
293 ssize_t
294 count;
295
296 size_t
297 length;
298
299 unsigned char
300 *pixels;
301
302 /*
303 Open output image file.
304 */
305 assert(image_info != (const ImageInfo *) NULL);
306 assert(image_info->signature == MagickSignature);
307 assert(image != (Image *) NULL);
308 assert(image->signature == MagickSignature);
309 if (image->debug != MagickFalse)
310 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
311 status=OpenBlob(image_info,image,WriteBinaryBlobMode,&image->exception);
312 if (status == MagickFalse)
313 return(status);
314 if ((image->columns > 65535UL) || (image->rows > 65535UL))
315 ThrowWriterException(ImageError,"WidthOrHeightExceedsLimit");
316 image->endian=MSBEndian;
317 image->depth=1;
318 (void) WriteBlobLSBShort(image,0);
319 (void) WriteBlobLSBShort(image,(unsigned short) image->columns);
320 (void) WriteBlobLSBShort(image,0);
321 (void) WriteBlobLSBShort(image,(unsigned short) image->rows);
322 if (image->colorspace != RGBColorspace)
323 (void) TransformImageColorspace(image,RGBColorspace);
324 length=(image->columns+7)/8;
325 pixels=(unsigned char *) AcquireQuantumMemory(length,sizeof(*pixels));
326 if (pixels == (unsigned char *) NULL)
327 ThrowWriterException(ResourceLimitError,"MemoryAllocationFailed");
328 /*
329 Convert image to a bi-level image.
330 */
331 (void) SetImageType(image,BilevelType);
332 quantum_info=AcquireQuantumInfo(image_info,image);
cristybb503372010-05-27 20:51:26 +0000333 for (y=0; y < (ssize_t) image->rows; y++)
cristy3ed852e2009-09-05 21:47:34 +0000334 {
335 p=GetVirtualPixels(image,0,y,image->columns,1,&image->exception);
336 if (p == (const PixelPacket *) NULL)
337 break;
338 (void) ExportQuantumPixels(image,(const CacheView *) NULL,quantum_info,
339 GrayQuantum,pixels,&image->exception);
340 count=WriteBlob(image,length,pixels);
341 if (count != (ssize_t) length)
342 ThrowWriterException(CorruptImageError,"UnableToWriteImageData");
343 count=WriteBlob(image,(size_t) (-(ssize_t) length) & 0x01,pixels);
cristycee97112010-05-28 00:44:52 +0000344 if (SetImageProgress(image,SaveImageTag,(MagickOffsetType) y,image->rows) == MagickFalse)
cristy3ed852e2009-09-05 21:47:34 +0000345 break;
346 }
347 quantum_info=DestroyQuantumInfo(quantum_info);
348 pixels=(unsigned char *) RelinquishMagickMemory(pixels);
349 (void) CloseBlob(image);
350 return(MagickTrue);
351}