/src/graphicsmagick/coders/mac.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | % Copyright (C) 2010-2020 GraphicsMagick Group |
3 | | % |
4 | | % This program is covered by multiple licenses, which are described in |
5 | | % Copyright.txt. You should have received a copy of Copyright.txt with this |
6 | | % package; otherwise see http://www.graphicsmagick.org/www/Copyright.html. |
7 | | % |
8 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
9 | | % % |
10 | | % % |
11 | | % M M AAA CCC % |
12 | | % MM MM A A C % |
13 | | % M M M AAAAA C % |
14 | | % M M A A C % |
15 | | % M M A A CCC % |
16 | | % % |
17 | | % Read MAC: MacPaint Image Format. % |
18 | | % % |
19 | | % % |
20 | | % Software Design % |
21 | | % Jaroslav Fojtik % |
22 | | % 2010 % |
23 | | % % |
24 | | % % |
25 | | % % |
26 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
27 | | % |
28 | | % |
29 | | */ |
30 | | |
31 | | /* |
32 | | Include declarations. |
33 | | */ |
34 | | #include "magick/studio.h" |
35 | | #include "magick/blob.h" |
36 | | #include "magick/colormap.h" |
37 | | #include "magick/constitute.h" |
38 | | #include "magick/log.h" |
39 | | #include "magick/magick.h" |
40 | | #include "magick/monitor.h" |
41 | | #include "magick/pixel_cache.h" |
42 | | #include "magick/utility.h" |
43 | | |
44 | | |
45 | | /* |
46 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
47 | | % % |
48 | | % % |
49 | | % % |
50 | | % R e a d M A C I m a g e % |
51 | | % % |
52 | | % % |
53 | | % % |
54 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
55 | | % |
56 | | % Method ReadMACImage reads an MAC image file and returns it. It |
57 | | % allocates the memory necessary for the new Image structure and returns a |
58 | | % pointer to the new image. |
59 | | % |
60 | | % The format of the ReadMACImage method is: |
61 | | % |
62 | | % Image *ReadMACImage(const ImageInfo *image_info,ExceptionInfo *exception) |
63 | | % |
64 | | % A description of each parameter follows: |
65 | | % |
66 | | % o image: Method ReadMACImage returns a pointer to the image after |
67 | | % reading. A null image is returned if there is a memory shortage or if |
68 | | % the image cannot be read. |
69 | | % |
70 | | % o image_info: Specifies a pointer to a ImageInfo structure. |
71 | | % |
72 | | % o exception: return any errors or warnings in this structure. |
73 | | % |
74 | | % |
75 | | */ |
76 | | static Image *ReadMACImage(const ImageInfo *image_info,ExceptionInfo *exception) |
77 | 282 | { |
78 | 282 | Image *image; |
79 | 282 | unsigned int y; |
80 | 282 | unsigned char x8, rep, b; |
81 | 282 | size_t ldblk; |
82 | 282 | unsigned char *BImgBuff = NULL; |
83 | 282 | unsigned char *DataPtr; |
84 | 282 | unsigned int status; |
85 | 282 | const PixelPacket *q; |
86 | | |
87 | | /* Open image file. */ |
88 | 282 | assert(image_info != (const ImageInfo *) NULL); |
89 | 282 | assert(image_info->signature == MagickSignature); |
90 | 282 | assert(exception != (ExceptionInfo *) NULL); |
91 | 282 | assert(exception->signature == MagickSignature); |
92 | 282 | image = AllocateImage(image_info); |
93 | 282 | status = OpenBlob(image_info,image,ReadBinaryBlobMode,exception); |
94 | 282 | if (status == False) |
95 | 282 | ThrowReaderException(FileOpenError,UnableToOpenFile,image); |
96 | | |
97 | | /* Read MAC image. */ |
98 | 282 | ldblk = ReadBlobLSBShort(image); |
99 | 282 | if ((ldblk & 0xFF)!=0) |
100 | 261 | ThrowReaderException(CorruptImageError,ImproperImageHeader,image); |
101 | | |
102 | 261 | if (ldblk==0) /* ???? don't know why */ |
103 | 222 | SeekBlob(image,0x200,SEEK_SET); |
104 | 39 | else |
105 | 39 | SeekBlob(image,0x280,SEEK_SET); |
106 | | |
107 | 261 | image->columns = 576; |
108 | 261 | image->rows = 720; |
109 | 261 | image->depth = 1; |
110 | 261 | image->colors = 1l << image->depth; |
111 | | |
112 | 261 | if (!AllocateImageColormap(image,image->colors)) goto NoMemory; |
113 | | |
114 | | /* If ping is true, then only set image size and colors without reading any image data. */ |
115 | 261 | if (image_info->ping) goto DONE_READING; |
116 | | |
117 | | /* ----- Load RLE compressed raster ----- */ |
118 | 261 | ldblk = (MagickArraySize(image->depth,image->columns)) /8; |
119 | 261 | BImgBuff = MagickAllocateResourceLimitedMemory(unsigned char *,ldblk); |
120 | 261 | if (BImgBuff==NULL) |
121 | 0 | NoMemory: |
122 | 261 | ThrowReaderException(ResourceLimitError,MemoryAllocationFailed,image); |
123 | | |
124 | 261 | DataPtr = BImgBuff; |
125 | 261 | x8=0; y=0; |
126 | | |
127 | 894k | while (y<image->rows) |
128 | 894k | { |
129 | 894k | rep = ReadBlobByte(image); |
130 | 894k | if(EOFBlob(image)) break; |
131 | | |
132 | 893k | if ( rep>=128 || rep<= 0) |
133 | 881k | { |
134 | 881k | b = ~ReadBlobByte(image);; |
135 | | |
136 | 881k | rep = ~rep + 2; |
137 | 5.15M | while (rep>0) |
138 | 4.27M | { |
139 | 4.27M | *DataPtr++ = b; |
140 | 4.27M | x8++; |
141 | 4.27M | rep--; |
142 | 4.27M | if(x8>=ldblk) |
143 | 59.1k | { |
144 | 59.1k | x8=0; |
145 | | |
146 | 59.1k | q = SetImagePixels(image,0,y,image->columns,1); |
147 | 59.1k | if (q == (PixelPacket *)NULL) break; |
148 | 59.1k | (void)ImportImagePixelArea(image,GrayQuantum,1,BImgBuff,NULL,0); |
149 | 59.1k | if (!SyncImagePixels(image)) break; |
150 | | |
151 | 59.1k | DataPtr = BImgBuff; |
152 | 59.1k | y++; |
153 | 59.1k | if ( y >= image->rows ) |
154 | 34 | { |
155 | 34 | break; |
156 | 34 | } |
157 | 59.1k | } |
158 | 4.27M | } |
159 | 881k | } |
160 | 12.2k | else |
161 | 12.2k | { |
162 | 12.2k | rep++; |
163 | 604k | while ( rep > 0 ) |
164 | 592k | { |
165 | 592k | b = ~ReadBlobByte(image); |
166 | 592k | *DataPtr++ = b; |
167 | 592k | x8++; |
168 | 592k | rep--; |
169 | 592k | if ( x8>=ldblk ) |
170 | 8.39k | { |
171 | 8.39k | x8=0; |
172 | | |
173 | 8.39k | q = SetImagePixels(image,0,y,image->columns,1); |
174 | 8.39k | if (q == (PixelPacket *)NULL) break; |
175 | 8.39k | (void)ImportImagePixelArea(image,GrayQuantum,1,BImgBuff,NULL,0); |
176 | 8.39k | if (!SyncImagePixels(image)) break; |
177 | | |
178 | 8.39k | DataPtr = BImgBuff; |
179 | 8.39k | y++; |
180 | 8.39k | if ( y >= image->rows ) |
181 | 5 | { |
182 | 5 | break; |
183 | 5 | } |
184 | 8.39k | } |
185 | 592k | } |
186 | 12.2k | } |
187 | 893k | } |
188 | 261 | if (BImgBuff!=NULL) |
189 | 261 | MagickFreeResourceLimitedMemory(BImgBuff); |
190 | 261 | if (EOFBlob(image)) |
191 | 224 | ThrowException(exception,CorruptImageError,UnexpectedEndOfFile,image->filename); |
192 | | |
193 | 261 | DONE_READING: |
194 | 261 | CloseBlob(image); |
195 | 261 | StopTimer(&image->timer); |
196 | 261 | return(image); |
197 | 261 | } |
198 | | |
199 | | |
200 | | /* |
201 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
202 | | % % |
203 | | % % |
204 | | % % |
205 | | % R e g i s t e r M A C I m a g e % |
206 | | % % |
207 | | % % |
208 | | % % |
209 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
210 | | % |
211 | | % Method RegisterMACImage adds attributes for the MAC image format to |
212 | | % the list of supported formats. The attributes include the image format |
213 | | % tag, a method to read and/or write the format, whether the format |
214 | | % supports the saving of more than one frame to the same file or blob, |
215 | | % whether the format supports native in-memory I/O, and a brief |
216 | | % description of the format. |
217 | | % |
218 | | % The format of the RegisterMACImage method is: |
219 | | % |
220 | | % RegisterMACImage(void) |
221 | | */ |
222 | | ModuleExport void RegisterMACImage(void) |
223 | 1 | { |
224 | 1 | MagickInfo *entry; |
225 | | |
226 | 1 | entry=SetMagickInfo("MAC"); |
227 | 1 | entry->decoder = (DecoderHandler)ReadMACImage; |
228 | 1 | entry->description="Mac Paint"; |
229 | 1 | entry->seekable_stream = True; |
230 | 1 | entry->module="MAC"; |
231 | 1 | (void) RegisterMagickInfo(entry); |
232 | 1 | } |
233 | | |
234 | | /* |
235 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
236 | | % % |
237 | | % % |
238 | | % % |
239 | | % U n r e g i s t e r M A C I m a g e % |
240 | | % % |
241 | | % % |
242 | | % % |
243 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
244 | | % |
245 | | % Method UnregisterMACImage removes format registrations made by the |
246 | | % MAC module from the list of supported formats. |
247 | | % |
248 | | % The format of the UnregisterMACImage method is: |
249 | | % |
250 | | % UnregisterMACImage(void) |
251 | | % |
252 | | */ |
253 | | ModuleExport void UnregisterMACImage(void) |
254 | 0 | { |
255 | 0 | (void) UnregisterMagickInfo("MAC"); |
256 | 0 | } |