blob: 6871e0dbc7f7e02bf0e8e484c1cef3f28945b51f [file] [log] [blame]
cristyae29c4f2010-12-28 14:45:29 +00001/*
2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3% %
4% %
5% %
6% %
7% M M AAA CCCC %
8% MM MM A A C %
9% M M M AAAAA C %
10% M M A A C %
11% M M A A CCCC %
12% %
13% %
14% Read MacPaint Image Format %
15% %
16% Software Design %
cristyde984cd2013-12-01 14:49:27 +000017% Cristy %
cristyae29c4f2010-12-28 14:45:29 +000018% July 1992 %
19% %
20% %
Cristy7ce65e72015-12-12 18:03:16 -050021% Copyright 1999-2016 ImageMagick Studio LLC, a non-profit organization %
cristyae29c4f2010-12-28 14:45:29 +000022% 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
40/*
41 Include declarations.
42*/
cristy4c08aed2011-07-01 19:47:50 +000043#include "MagickCore/studio.h"
44#include "MagickCore/blob.h"
45#include "MagickCore/blob-private.h"
46#include "MagickCore/cache.h"
47#include "MagickCore/colormap.h"
48#include "MagickCore/colorspace.h"
49#include "MagickCore/exception.h"
50#include "MagickCore/exception-private.h"
51#include "MagickCore/image.h"
52#include "MagickCore/image-private.h"
53#include "MagickCore/list.h"
54#include "MagickCore/magick.h"
55#include "MagickCore/memory_.h"
56#include "MagickCore/monitor.h"
57#include "MagickCore/monitor-private.h"
58#include "MagickCore/pixel-accessor.h"
59#include "MagickCore/quantum-private.h"
60#include "MagickCore/static.h"
61#include "MagickCore/string_.h"
62#include "MagickCore/module.h"
cristyae29c4f2010-12-28 14:45:29 +000063
64/*
65%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
66% %
67% %
68% %
69% R e a d M A C I m a g e %
70% %
71% %
72% %
73%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
74%
75% ReadMACImage() reads an MacPaint image file and returns it. It
76% allocates the memory necessary for the new Image structure and returns a
77% pointer to the new image.
78%
79% The format of the ReadMACImage method is:
80%
81% Image *ReadMACImage(const ImageInfo *image_info,ExceptionInfo *exception)
82%
83% A description of each parameter follows:
84%
85% o image_info: the image info.
86%
87% o exception: return any errors or warnings in this structure.
88%
89*/
90static Image *ReadMACImage(const ImageInfo *image_info,ExceptionInfo *exception)
91{
92 Image
93 *image;
94
95 MagickBooleanType
96 status;
97
cristy4c08aed2011-07-01 19:47:50 +000098 register Quantum
cristyae29c4f2010-12-28 14:45:29 +000099 *q;
100
cristybf1ebd52010-12-28 18:48:29 +0000101 register ssize_t
102 x;
103
cristyae29c4f2010-12-28 14:45:29 +0000104 register unsigned char
105 *p;
106
107 size_t
cristybf1ebd52010-12-28 18:48:29 +0000108 length;
cristyae29c4f2010-12-28 14:45:29 +0000109
110 ssize_t
cristybf1ebd52010-12-28 18:48:29 +0000111 offset,
cristyae29c4f2010-12-28 14:45:29 +0000112 y;
113
114 unsigned char
cristybf1ebd52010-12-28 18:48:29 +0000115 count,
116 bit,
117 byte,
cristyae29c4f2010-12-28 14:45:29 +0000118 *pixels;
119
120 /*
121 Open image file.
122 */
123 assert(image_info != (const ImageInfo *) NULL);
cristye1c94d92015-06-28 12:16:33 +0000124 assert(image_info->signature == MagickCoreSignature);
cristyae29c4f2010-12-28 14:45:29 +0000125 if (image_info->debug != MagickFalse)
126 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
127 image_info->filename);
128 assert(exception != (ExceptionInfo *) NULL);
cristye1c94d92015-06-28 12:16:33 +0000129 assert(exception->signature == MagickCoreSignature);
cristy9950d572011-10-01 18:22:35 +0000130 image=AcquireImage(image_info,exception);
cristyae29c4f2010-12-28 14:45:29 +0000131 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
132 if (status == MagickFalse)
133 {
134 image=DestroyImageList(image);
135 return((Image *) NULL);
136 }
137 /*
138 Read MAC X image.
139 */
cristybf1ebd52010-12-28 18:48:29 +0000140 length=ReadBlobLSBShort(image);
141 if ((length & 0xff) != 0)
142 ThrowReaderException(CorruptImageError,"CorruptImage");
143 for (x=0; x < (ssize_t) 638; x++)
144 if (ReadBlobByte(image) == EOF)
145 ThrowReaderException(CorruptImageError,"CorruptImage");
146 image->columns=576;
147 image->rows=720;
148 image->depth=1;
cristy018f07f2011-09-04 21:15:19 +0000149 if (AcquireImageColormap(image,2,exception) == MagickFalse)
cristybf1ebd52010-12-28 18:48:29 +0000150 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
151 if (image_info->ping != MagickFalse)
cristyae29c4f2010-12-28 14:45:29 +0000152 {
cristybf1ebd52010-12-28 18:48:29 +0000153 (void) CloseBlob(image);
154 return(GetFirstImageInList(image));
cristyae29c4f2010-12-28 14:45:29 +0000155 }
cristyacabb842014-12-14 23:36:33 +0000156 status=SetImageExtent(image,image->columns,image->rows,exception);
157 if (status == MagickFalse)
158 return(DestroyImageList(image));
cristybf1ebd52010-12-28 18:48:29 +0000159 /*
160 Convert MAC raster image to pixel packets.
161 */
162 length=(image->columns+7)/8;
163 pixels=(unsigned char *) AcquireQuantumMemory(length+1,sizeof(*pixels));
164 if (pixels == (unsigned char *) NULL)
165 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
166 p=pixels;
167 offset=0;
168 for (y=0; y < (ssize_t) image->rows; )
169 {
170 count=(unsigned char) ReadBlobByte(image);
cristyae29c4f2010-12-28 14:45:29 +0000171 if (EOFBlob(image) != MagickFalse)
cristybf1ebd52010-12-28 18:48:29 +0000172 break;
173 if ((count <= 0) || (count >= 128))
cristyae29c4f2010-12-28 14:45:29 +0000174 {
cristybf1ebd52010-12-28 18:48:29 +0000175 byte=(unsigned char) (~ReadBlobByte(image));
176 count=(~count)+2;
177 while (count != 0)
178 {
179 *p++=byte;
180 offset++;
181 count--;
182 if (offset >= (ssize_t) length)
183 {
184 q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
cristyacd2ed22011-08-30 01:44:23 +0000185 if (q == (Quantum *) NULL)
cristybf1ebd52010-12-28 18:48:29 +0000186 break;
cristybf1ebd52010-12-28 18:48:29 +0000187 p=pixels;
188 bit=0;
189 byte=0;
190 for (x=0; x < (ssize_t) image->columns; x++)
191 {
192 if (bit == 0)
193 byte=(*p++);
cristy4c08aed2011-07-01 19:47:50 +0000194 SetPixelIndex(image,((byte & 0x80) != 0 ? 0x01 : 0x00),q);
cristybf1ebd52010-12-28 18:48:29 +0000195 bit++;
196 byte<<=1;
197 if (bit == 8)
198 bit=0;
cristyed231572011-07-14 02:18:59 +0000199 q+=GetPixelChannels(image);
cristybf1ebd52010-12-28 18:48:29 +0000200 }
201 if (SyncAuthenticPixels(image,exception) == MagickFalse)
202 break;
203 offset=0;
204 p=pixels;
205 y++;
206 }
207 }
208 continue;
cristyae29c4f2010-12-28 14:45:29 +0000209 }
cristybf1ebd52010-12-28 18:48:29 +0000210 count++;
211 while (count != 0)
212 {
213 byte=(unsigned char) (~ReadBlobByte(image));
214 *p++=byte;
215 offset++;
216 count--;
217 if (offset >= (ssize_t) length)
218 {
219 q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
cristyacd2ed22011-08-30 01:44:23 +0000220 if (q == (Quantum *) NULL)
cristybf1ebd52010-12-28 18:48:29 +0000221 break;
cristybf1ebd52010-12-28 18:48:29 +0000222 p=pixels;
223 bit=0;
224 byte=0;
225 for (x=0; x < (ssize_t) image->columns; x++)
cristyae29c4f2010-12-28 14:45:29 +0000226 {
cristybf1ebd52010-12-28 18:48:29 +0000227 if (bit == 0)
228 byte=(*p++);
cristy4c08aed2011-07-01 19:47:50 +0000229 SetPixelIndex(image,((byte & 0x80) != 0 ? 0x01 : 0x00),q);
cristybf1ebd52010-12-28 18:48:29 +0000230 bit++;
231 byte<<=1;
232 if (bit == 8)
233 bit=0;
cristyed231572011-07-14 02:18:59 +0000234 q+=GetPixelChannels(image);
cristyae29c4f2010-12-28 14:45:29 +0000235 }
cristybf1ebd52010-12-28 18:48:29 +0000236 if (SyncAuthenticPixels(image,exception) == MagickFalse)
237 break;
238 offset=0;
239 p=pixels;
240 y++;
241 }
242 }
243 }
244 pixels=(unsigned char *) RelinquishMagickMemory(pixels);
cristy30841e62014-05-19 00:45:15 +0000245 (void) SyncImage(image,exception);
cristyae29c4f2010-12-28 14:45:29 +0000246 (void) CloseBlob(image);
247 return(GetFirstImageInList(image));
248}
249
250/*
251%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
252% %
253% %
254% %
255% R e g i s t e r M A C I m a g e %
256% %
257% %
258% %
259%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
260%
261% RegisterMACImage() adds attributes for the MAC X image format to the list
262% of supported formats. The attributes include the image format tag, a
263% method to read and/or write the format, whether the format supports the
264% saving of more than one frame to the same file or blob, whether the format
265% supports native in-memory I/O, and a brief description of the format.
266%
267% The format of the RegisterMACImage method is:
268%
269% size_t RegisterMACImage(void)
270%
271*/
272ModuleExport size_t RegisterMACImage(void)
273{
274 MagickInfo
275 *entry;
276
dirk06b627a2015-04-06 18:59:17 +0000277 entry=AcquireMagickInfo("MAC","MAC","MAC Paint");
cristyae29c4f2010-12-28 14:45:29 +0000278 entry->decoder=(DecodeImageHandler *) ReadMACImage;
cristyae29c4f2010-12-28 14:45:29 +0000279 (void) RegisterMagickInfo(entry);
280 return(MagickImageCoderSignature);
281}
282
283/*
284%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
285% %
286% %
287% %
288% U n r e g i s t e r M A C I m a g e %
289% %
290% %
291% %
292%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
293%
294% UnregisterMACImage() removes format registrations made by the
295% MAC module from the list of supported formats.
296%
297% The format of the UnregisterMACImage method is:
298%
299% UnregisterMACImage(void)
300%
301*/
302ModuleExport void UnregisterMACImage(void)
303{
304 (void) UnregisterMagickInfo("MAC");
305}