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/* 41 Include declarations. 42*/ 43#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" 63 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 98 register Quantum 99 *q; 100 101 register ssize_t 102 x; 103 104 register unsigned char 105 *p; 106 107 size_t 108 length; 109 110 ssize_t 111 offset, 112 y; 113 114 unsigned char 115 count, 116 bit, 117 byte, 118 *pixels; 119 120 /* 121 Open image file. 122 */ 123 assert(image_info != (const ImageInfo *) NULL); 124 assert(image_info->signature == MagickCoreSignature); 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 == MagickCoreSignature); 130 image=AcquireImage(image_info,exception); 131 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 */ 140 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; 149 if (AcquireImageColormap(image,2,exception) == MagickFalse) 150 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); 151 if (image_info->ping != MagickFalse) 152 { 153 (void) CloseBlob(image); 154 return(GetFirstImageInList(image)); 155 } 156 status=SetImageExtent(image,image->columns,image->rows,exception); 157 if (status == MagickFalse) 158 return(DestroyImageList(image)); 159 /* 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); 171 if (EOFBlob(image) != MagickFalse) 172 break; 173 if ((count <= 0) || (count >= 128)) 174 { 175 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); 185 if (q == (Quantum *) NULL) 186 break; 187 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++); 194 SetPixelIndex(image,((byte & 0x80) != 0 ? 0x01 : 0x00),q); 195 bit++; 196 byte<<=1; 197 if (bit == 8) 198 bit=0; 199 q+=GetPixelChannels(image); 200 } 201 if (SyncAuthenticPixels(image,exception) == MagickFalse) 202 break; 203 offset=0; 204 p=pixels; 205 y++; 206 } 207 } 208 continue; 209 } 210 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); 220 if (q == (Quantum *) NULL) 221 break; 222 p=pixels; 223 bit=0; 224 byte=0; 225 for (x=0; x < (ssize_t) image->columns; x++) 226 { 227 if (bit == 0) 228 byte=(*p++); 229 SetPixelIndex(image,((byte & 0x80) != 0 ? 0x01 : 0x00),q); 230 bit++; 231 byte<<=1; 232 if (bit == 8) 233 bit=0; 234 q+=GetPixelChannels(image); 235 } 236 if (SyncAuthenticPixels(image,exception) == MagickFalse) 237 break; 238 offset=0; 239 p=pixels; 240 y++; 241 } 242 } 243 } 244 pixels=(unsigned char *) RelinquishMagickMemory(pixels); 245 (void) SyncImage(image,exception); 246 (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 277 entry=AcquireMagickInfo("MAC","MAC","MAC Paint"); 278 entry->decoder=(DecodeImageHandler *) ReadMACImage; 279 (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} 306