blob: 690f29da746ed6bcc3a1548f2c250bd02e95af82 [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% %
cristyfe676ee2013-11-18 13:03:38 +000021% Copyright 1999-2014 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);
124 assert(image_info->signature == MagickSignature);
125 if (image_info->debug != MagickFalse)
126 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
127 image_info->filename);
128 assert(exception != (ExceptionInfo *) NULL);
129 assert(exception->signature == MagickSignature);
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 }
cristybf1ebd52010-12-28 18:48:29 +0000156 /*
157 Convert MAC raster image to pixel packets.
158 */
159 length=(image->columns+7)/8;
160 pixels=(unsigned char *) AcquireQuantumMemory(length+1,sizeof(*pixels));
161 if (pixels == (unsigned char *) NULL)
162 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
163 p=pixels;
164 offset=0;
165 for (y=0; y < (ssize_t) image->rows; )
166 {
167 count=(unsigned char) ReadBlobByte(image);
cristyae29c4f2010-12-28 14:45:29 +0000168 if (EOFBlob(image) != MagickFalse)
cristybf1ebd52010-12-28 18:48:29 +0000169 break;
170 if ((count <= 0) || (count >= 128))
cristyae29c4f2010-12-28 14:45:29 +0000171 {
cristybf1ebd52010-12-28 18:48:29 +0000172 byte=(unsigned char) (~ReadBlobByte(image));
173 count=(~count)+2;
174 while (count != 0)
175 {
176 *p++=byte;
177 offset++;
178 count--;
179 if (offset >= (ssize_t) length)
180 {
181 q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
cristyacd2ed22011-08-30 01:44:23 +0000182 if (q == (Quantum *) NULL)
cristybf1ebd52010-12-28 18:48:29 +0000183 break;
cristybf1ebd52010-12-28 18:48:29 +0000184 p=pixels;
185 bit=0;
186 byte=0;
187 for (x=0; x < (ssize_t) image->columns; x++)
188 {
189 if (bit == 0)
190 byte=(*p++);
cristy4c08aed2011-07-01 19:47:50 +0000191 SetPixelIndex(image,((byte & 0x80) != 0 ? 0x01 : 0x00),q);
cristybf1ebd52010-12-28 18:48:29 +0000192 bit++;
193 byte<<=1;
194 if (bit == 8)
195 bit=0;
cristyed231572011-07-14 02:18:59 +0000196 q+=GetPixelChannels(image);
cristybf1ebd52010-12-28 18:48:29 +0000197 }
198 if (SyncAuthenticPixels(image,exception) == MagickFalse)
199 break;
200 offset=0;
201 p=pixels;
202 y++;
203 }
204 }
205 continue;
cristyae29c4f2010-12-28 14:45:29 +0000206 }
cristybf1ebd52010-12-28 18:48:29 +0000207 count++;
208 while (count != 0)
209 {
210 byte=(unsigned char) (~ReadBlobByte(image));
211 *p++=byte;
212 offset++;
213 count--;
214 if (offset >= (ssize_t) length)
215 {
216 q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
cristyacd2ed22011-08-30 01:44:23 +0000217 if (q == (Quantum *) NULL)
cristybf1ebd52010-12-28 18:48:29 +0000218 break;
cristybf1ebd52010-12-28 18:48:29 +0000219 p=pixels;
220 bit=0;
221 byte=0;
222 for (x=0; x < (ssize_t) image->columns; x++)
cristyae29c4f2010-12-28 14:45:29 +0000223 {
cristybf1ebd52010-12-28 18:48:29 +0000224 if (bit == 0)
225 byte=(*p++);
cristy4c08aed2011-07-01 19:47:50 +0000226 SetPixelIndex(image,((byte & 0x80) != 0 ? 0x01 : 0x00),q);
cristybf1ebd52010-12-28 18:48:29 +0000227 bit++;
228 byte<<=1;
229 if (bit == 8)
230 bit=0;
cristyed231572011-07-14 02:18:59 +0000231 q+=GetPixelChannels(image);
cristyae29c4f2010-12-28 14:45:29 +0000232 }
cristybf1ebd52010-12-28 18:48:29 +0000233 if (SyncAuthenticPixels(image,exception) == MagickFalse)
234 break;
235 offset=0;
236 p=pixels;
237 y++;
238 }
239 }
240 }
241 pixels=(unsigned char *) RelinquishMagickMemory(pixels);
cristy30841e62014-05-19 00:45:15 +0000242 (void) SyncImage(image,exception);
cristyae29c4f2010-12-28 14:45:29 +0000243 (void) CloseBlob(image);
244 return(GetFirstImageInList(image));
245}
246
247/*
248%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
249% %
250% %
251% %
252% R e g i s t e r M A C I m a g e %
253% %
254% %
255% %
256%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
257%
258% RegisterMACImage() adds attributes for the MAC X image format to the list
259% of supported formats. The attributes include the image format tag, a
260% method to read and/or write the format, whether the format supports the
261% saving of more than one frame to the same file or blob, whether the format
262% supports native in-memory I/O, and a brief description of the format.
263%
264% The format of the RegisterMACImage method is:
265%
266% size_t RegisterMACImage(void)
267%
268*/
269ModuleExport size_t RegisterMACImage(void)
270{
271 MagickInfo
272 *entry;
273
274 entry=SetMagickInfo("MAC");
275 entry->decoder=(DecodeImageHandler *) ReadMACImage;
276 entry->description=ConstantString("MAC Paint");
277 entry->module=ConstantString("MAC");
278 (void) RegisterMagickInfo(entry);
279 return(MagickImageCoderSignature);
280}
281
282/*
283%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
284% %
285% %
286% %
287% U n r e g i s t e r M A C I m a g e %
288% %
289% %
290% %
291%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
292%
293% UnregisterMACImage() removes format registrations made by the
294% MAC module from the list of supported formats.
295%
296% The format of the UnregisterMACImage method is:
297%
298% UnregisterMACImage(void)
299%
300*/
301ModuleExport void UnregisterMACImage(void)
302{
303 (void) UnregisterMagickInfo("MAC");
304}