/src/imagemagick/coders/mac.c
Line | Count | Source |
1 | | /* |
2 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
3 | | % % |
4 | | % % |
5 | | % % |
6 | | % M M AAA CCCC % |
7 | | % MM MM A A C % |
8 | | % M M M AAAAA C % |
9 | | % M M A A C % |
10 | | % M M A A CCCC % |
11 | | % % |
12 | | % % |
13 | | % Read MacPaint Image Format % |
14 | | % % |
15 | | % Software Design % |
16 | | % Cristy % |
17 | | % July 1992 % |
18 | | % % |
19 | | % % |
20 | | % Copyright @ 1999 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://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 "MagickCore/studio.h" |
43 | | #include "MagickCore/blob.h" |
44 | | #include "MagickCore/blob-private.h" |
45 | | #include "MagickCore/cache.h" |
46 | | #include "MagickCore/colormap.h" |
47 | | #include "MagickCore/colorspace.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/monitor.h" |
56 | | #include "MagickCore/monitor-private.h" |
57 | | #include "MagickCore/pixel-accessor.h" |
58 | | #include "MagickCore/quantum-private.h" |
59 | | #include "MagickCore/static.h" |
60 | | #include "MagickCore/string_.h" |
61 | | #include "MagickCore/module.h" |
62 | | |
63 | | /* |
64 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
65 | | % % |
66 | | % % |
67 | | % % |
68 | | % R e a d M A C I m a g e % |
69 | | % % |
70 | | % % |
71 | | % % |
72 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
73 | | % |
74 | | % ReadMACImage() reads an MacPaint image file and returns it. It |
75 | | % allocates the memory necessary for the new Image structure and returns a |
76 | | % pointer to the new image. |
77 | | % |
78 | | % The format of the ReadMACImage method is: |
79 | | % |
80 | | % Image *ReadMACImage(const ImageInfo *image_info,ExceptionInfo *exception) |
81 | | % |
82 | | % A description of each parameter follows: |
83 | | % |
84 | | % o image_info: the image info. |
85 | | % |
86 | | % o exception: return any errors or warnings in this structure. |
87 | | % |
88 | | */ |
89 | | static Image *ReadMACImage(const ImageInfo *image_info,ExceptionInfo *exception) |
90 | 309 | { |
91 | 309 | Image |
92 | 309 | *image; |
93 | | |
94 | 309 | MagickBooleanType |
95 | 309 | status; |
96 | | |
97 | 309 | Quantum |
98 | 309 | *q; |
99 | | |
100 | 309 | ssize_t |
101 | 309 | x; |
102 | | |
103 | 309 | unsigned char |
104 | 309 | *p; |
105 | | |
106 | 309 | size_t |
107 | 309 | length; |
108 | | |
109 | 309 | ssize_t |
110 | 309 | offset, |
111 | 309 | y; |
112 | | |
113 | 309 | unsigned char |
114 | 309 | count, |
115 | 309 | bit, |
116 | 309 | byte, |
117 | 309 | *pixels; |
118 | | |
119 | | /* |
120 | | Open image file. |
121 | | */ |
122 | 309 | assert(image_info != (const ImageInfo *) NULL); |
123 | 309 | assert(image_info->signature == MagickCoreSignature); |
124 | 309 | assert(exception != (ExceptionInfo *) NULL); |
125 | 309 | assert(exception->signature == MagickCoreSignature); |
126 | 309 | if (IsEventLogging() != MagickFalse) |
127 | 0 | (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s", |
128 | 0 | image_info->filename); |
129 | 309 | image=AcquireImage(image_info,exception); |
130 | 309 | status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception); |
131 | 309 | if (status == MagickFalse) |
132 | 51 | { |
133 | 51 | image=DestroyImageList(image); |
134 | 51 | return((Image *) NULL); |
135 | 51 | } |
136 | | /* |
137 | | Read MAC X image. |
138 | | */ |
139 | 258 | length=ReadBlobLSBShort(image); |
140 | 258 | if ((length & 0xff) != 0) |
141 | 245 | ThrowReaderException(CorruptImageError,"CorruptImage"); |
142 | 245 | if (length == 0) |
143 | 210 | { |
144 | 70.6k | for (x=0; x < (ssize_t) 510; x++) |
145 | 70.5k | if (ReadBlobByte(image) == EOF) |
146 | 134 | ThrowReaderException(CorruptImageError,"CorruptImage"); |
147 | 134 | } |
148 | 35 | else |
149 | 2.62k | for (x=0; x < (ssize_t) 638; x++) |
150 | 2.62k | if (ReadBlobByte(image) == EOF) |
151 | 137 | ThrowReaderException(CorruptImageError,"CorruptImage"); |
152 | 137 | image->columns=576; |
153 | 137 | image->rows=720; |
154 | 137 | image->depth=1; |
155 | 137 | if (AcquireImageColormap(image,2,exception) == MagickFalse) |
156 | 137 | ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); |
157 | 137 | if (image_info->ping != MagickFalse) |
158 | 0 | { |
159 | 0 | (void) CloseBlob(image); |
160 | 0 | return(GetFirstImageInList(image)); |
161 | 0 | } |
162 | 137 | status=SetImageExtent(image,image->columns,image->rows,exception); |
163 | 137 | if (status == MagickFalse) |
164 | 0 | return(DestroyImageList(image)); |
165 | 137 | status=ResetImagePixels(image,exception); |
166 | 137 | if (status == MagickFalse) |
167 | 0 | return(DestroyImageList(image)); |
168 | | /* |
169 | | Convert MAC raster image to pixel packets. |
170 | | */ |
171 | 137 | length=(image->columns+7)/8; |
172 | 137 | pixels=(unsigned char *) AcquireQuantumMemory(length+257,sizeof(*pixels)); |
173 | 137 | if (pixels == (unsigned char *) NULL) |
174 | 137 | ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); |
175 | 137 | (void) memset(pixels,0,(length+257)*sizeof(*pixels)); |
176 | 137 | p=pixels; |
177 | 137 | offset=0; |
178 | 21.5k | for (y=0; y < (ssize_t) image->rows; ) |
179 | 21.5k | { |
180 | 21.5k | count=(unsigned char) ReadBlobByte(image); |
181 | 21.5k | if (EOFBlob(image) != MagickFalse) |
182 | 125 | break; |
183 | 21.4k | if ((count <= 0) || (count >= 128)) |
184 | 18.2k | { |
185 | 18.2k | byte=(unsigned char) (~ReadBlobByte(image)); |
186 | 18.2k | count=(~count)+2; |
187 | 1.24M | while (count != 0) |
188 | 1.22M | { |
189 | 1.22M | *p++=byte; |
190 | 1.22M | offset++; |
191 | 1.22M | count--; |
192 | 1.22M | if (offset >= (ssize_t) length) |
193 | 16.2k | { |
194 | 16.2k | q=QueueAuthenticPixels(image,0,y,image->columns,1,exception); |
195 | 16.2k | if (q == (Quantum *) NULL) |
196 | 4 | break; |
197 | 16.2k | p=pixels; |
198 | 16.2k | bit=0; |
199 | 16.2k | byte=0; |
200 | 9.34M | for (x=0; x < (ssize_t) image->columns; x++) |
201 | 9.33M | { |
202 | 9.33M | if (bit == 0) |
203 | 1.16M | byte=(*p++); |
204 | 9.33M | SetPixelIndex(image,(Quantum) ((byte & 0x80) != 0 ? 0x01 : 0x00),q); |
205 | 9.33M | bit++; |
206 | 9.33M | byte<<=1; |
207 | 9.33M | if (bit == 8) |
208 | 1.16M | bit=0; |
209 | 9.33M | q+=(ptrdiff_t) GetPixelChannels(image); |
210 | 9.33M | } |
211 | 16.2k | if (SyncAuthenticPixels(image,exception) == MagickFalse) |
212 | 0 | break; |
213 | 16.2k | offset=0; |
214 | 16.2k | p=pixels; |
215 | 16.2k | y++; |
216 | 16.2k | } |
217 | 1.22M | } |
218 | 18.2k | continue; |
219 | 18.2k | } |
220 | 3.22k | count++; |
221 | 71.0k | while (count != 0) |
222 | 67.7k | { |
223 | 67.7k | byte=(unsigned char) (~ReadBlobByte(image)); |
224 | 67.7k | *p++=byte; |
225 | 67.7k | offset++; |
226 | 67.7k | count--; |
227 | 67.7k | if (offset >= (ssize_t) length) |
228 | 1.76k | { |
229 | 1.76k | q=QueueAuthenticPixels(image,0,y,image->columns,1,exception); |
230 | 1.76k | if (q == (Quantum *) NULL) |
231 | 2 | break; |
232 | 1.76k | p=pixels; |
233 | 1.76k | bit=0; |
234 | 1.76k | byte=0; |
235 | 1.01M | for (x=0; x < (ssize_t) image->columns; x++) |
236 | 1.01M | { |
237 | 1.01M | if (bit == 0) |
238 | 126k | byte=(*p++); |
239 | 1.01M | SetPixelIndex(image,(Quantum) ((byte & 0x80) != 0 ? 0x01 : 0x00),q); |
240 | 1.01M | bit++; |
241 | 1.01M | byte<<=1; |
242 | 1.01M | if (bit == 8) |
243 | 126k | bit=0; |
244 | 1.01M | q+=(ptrdiff_t) GetPixelChannels(image); |
245 | 1.01M | } |
246 | 1.76k | if (SyncAuthenticPixels(image,exception) == MagickFalse) |
247 | 0 | break; |
248 | 1.76k | offset=0; |
249 | 1.76k | p=pixels; |
250 | 1.76k | y++; |
251 | 1.76k | } |
252 | 67.7k | } |
253 | 3.22k | } |
254 | 137 | pixels=(unsigned char *) RelinquishMagickMemory(pixels); |
255 | 137 | (void) SyncImage(image,exception); |
256 | 137 | if (CloseBlob(image) == MagickFalse) |
257 | 0 | status=MagickFalse; |
258 | 137 | if (status == MagickFalse) |
259 | 0 | return(DestroyImageList(image)); |
260 | 137 | return(GetFirstImageInList(image)); |
261 | 137 | } |
262 | | |
263 | | /* |
264 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
265 | | % % |
266 | | % % |
267 | | % % |
268 | | % R e g i s t e r M A C I m a g e % |
269 | | % % |
270 | | % % |
271 | | % % |
272 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
273 | | % |
274 | | % RegisterMACImage() adds attributes for the MAC X image format to the list |
275 | | % of supported formats. The attributes include the image format tag, a |
276 | | % method to read and/or write the format, whether the format supports the |
277 | | % saving of more than one frame to the same file or blob, whether the format |
278 | | % supports native in-memory I/O, and a brief description of the format. |
279 | | % |
280 | | % The format of the RegisterMACImage method is: |
281 | | % |
282 | | % size_t RegisterMACImage(void) |
283 | | % |
284 | | */ |
285 | | ModuleExport size_t RegisterMACImage(void) |
286 | 8 | { |
287 | 8 | MagickInfo |
288 | 8 | *entry; |
289 | | |
290 | 8 | entry=AcquireMagickInfo("MAC","MAC","MAC Paint"); |
291 | 8 | entry->decoder=(DecodeImageHandler *) ReadMACImage; |
292 | 8 | (void) RegisterMagickInfo(entry); |
293 | 8 | return(MagickImageCoderSignature); |
294 | 8 | } |
295 | | |
296 | | /* |
297 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
298 | | % % |
299 | | % % |
300 | | % % |
301 | | % U n r e g i s t e r M A C I m a g e % |
302 | | % % |
303 | | % % |
304 | | % % |
305 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
306 | | % |
307 | | % UnregisterMACImage() removes format registrations made by the |
308 | | % MAC module from the list of supported formats. |
309 | | % |
310 | | % The format of the UnregisterMACImage method is: |
311 | | % |
312 | | % UnregisterMACImage(void) |
313 | | % |
314 | | */ |
315 | | ModuleExport void UnregisterMACImage(void) |
316 | 0 | { |
317 | 0 | (void) UnregisterMagickInfo("MAC"); |
318 | 0 | } |