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