1 /* 2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3 % % 4 % % 5 % % 6 % AAA RRRR TTTTT % 7 % A A R R T % 8 % AAAAA RRRR T % 9 % A A R R T % 10 % A A R R T % 11 % % 12 % % 13 % Support PFS: 1st Publisher Clip Art Format % 14 % % 15 % Software Design % 16 % Cristy % 17 % July 1992 % 18 % % 19 % % 20 % Copyright 1999-2016 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 % http://www.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 /* 41 Include declarations. 42 */ 43 #include "MagickCore/studio.h" 44 #include "MagickCore/attribute.h" 45 #include "MagickCore/blob.h" 46 #include "MagickCore/blob-private.h" 47 #include "MagickCore/cache.h" 48 #include "MagickCore/color-private.h" 49 #include "MagickCore/colormap.h" 50 #include "MagickCore/colorspace.h" 51 #include "MagickCore/colorspace-private.h" 52 #include "MagickCore/exception.h" 53 #include "MagickCore/exception-private.h" 54 #include "MagickCore/image.h" 55 #include "MagickCore/image-private.h" 56 #include "MagickCore/list.h" 57 #include "MagickCore/magick.h" 58 #include "MagickCore/memory_.h" 59 #include "MagickCore/monitor.h" 60 #include "MagickCore/monitor-private.h" 61 #include "MagickCore/quantum-private.h" 62 #include "MagickCore/static.h" 63 #include "MagickCore/string_.h" 64 #include "MagickCore/module.h" 65 66 /* 68 Forward declarations. 69 */ 70 static MagickBooleanType 71 WriteARTImage(const ImageInfo *,Image *,ExceptionInfo *); 72 73 /* 75 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 76 % % 77 % % 78 % % 79 % R e a d A R T I m a g e % 80 % % 81 % % 82 % % 83 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 84 % 85 % ReadARTImage() reads an image of raw bits in LSB order and returns it. 86 % It allocates the memory necessary for the new Image structure and returns 87 % a pointer to the new image. 88 % 89 % The format of the ReadARTImage method is: 90 % 91 % Image *ReadARTImage(const ImageInfo *image_info, 92 % ExceptionInfo *exception) 93 % 94 % A description of each parameter follows: 95 % 96 % o image_info: the image info. 97 % 98 % o exception: return any errors or warnings in this structure. 99 % 100 */ 101 static Image *ReadARTImage(const ImageInfo *image_info,ExceptionInfo *exception) 102 { 103 const unsigned char 104 *pixels; 105 106 Image 107 *image; 108 109 QuantumInfo 110 *quantum_info; 111 112 MagickBooleanType 113 status; 114 115 size_t 116 length; 117 118 ssize_t 119 count, 120 y; 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 image->depth=1; 140 image->endian=MSBEndian; 141 (void) ReadBlobLSBShort(image); 142 image->columns=(size_t) ReadBlobLSBShort(image); 143 (void) ReadBlobLSBShort(image); 144 image->rows=(size_t) ReadBlobLSBShort(image); 145 if ((image->columns == 0) || (image->rows == 0)) 146 ThrowReaderException(CorruptImageError,"ImproperImageHeader"); 147 if (image_info->ping != MagickFalse) 148 { 149 (void) CloseBlob(image); 150 return(GetFirstImageInList(image)); 151 } 152 status=SetImageExtent(image,image->columns,image->rows,exception); 153 if (status == MagickFalse) 154 return(DestroyImageList(image)); 155 /* 156 Convert bi-level image to pixel packets. 157 */ 158 SetImageColorspace(image,GRAYColorspace,exception); 159 quantum_info=AcquireQuantumInfo(image_info,image); 160 if (quantum_info == (QuantumInfo *) NULL) 161 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); 162 length=GetQuantumExtent(image,quantum_info,GrayQuantum); 163 for (y=0; y < (ssize_t) image->rows; y++) 164 { 165 register Quantum 166 *magick_restrict q; 167 168 q=QueueAuthenticPixels(image,0,y,image->columns,1,exception); 169 if (q == (Quantum *) NULL) 170 break; 171 pixels=(const unsigned char *) ReadBlobStream(image,length, 172 GetQuantumPixels(quantum_info),&count); 173 if (count != (ssize_t) length) 174 ThrowReaderException(CorruptImageError,"UnableToReadImageData"); 175 (void) ImportQuantumPixels(image,(CacheView *) NULL,quantum_info, 176 GrayQuantum,pixels,exception); 177 pixels=(const unsigned char *) ReadBlobStream(image,(size_t) (-(ssize_t) 178 length) & 0x01,GetQuantumPixels(quantum_info),&count); 179 if (SyncAuthenticPixels(image,exception) == MagickFalse) 180 break; 181 if (SetImageProgress(image,LoadImageTag,y,image->rows) == MagickFalse) 182 break; 183 } 184 SetQuantumImageType(image,GrayQuantum); 185 quantum_info=DestroyQuantumInfo(quantum_info); 186 if (EOFBlob(image) != MagickFalse) 187 ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile", 188 image->filename); 189 (void) CloseBlob(image); 190 return(GetFirstImageInList(image)); 191 } 192 193 /* 195 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 196 % % 197 % % 198 % % 199 % R e g i s t e r A R T I m a g e % 200 % % 201 % % 202 % % 203 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 204 % 205 % RegisterARTImage() adds attributes for the ART image format to 206 % the list of supported formats. The attributes include the image format 207 % tag, a method to read and/or write the format, whether the format 208 % supports the saving of more than one frame to the same file or blob, 209 % whether the format supports native in-memory I/O, and a brief 210 % description of the format. 211 % 212 % The format of the RegisterARTImage method is: 213 % 214 % size_t RegisterARTImage(void) 215 % 216 */ 217 ModuleExport size_t RegisterARTImage(void) 218 { 219 MagickInfo 220 *entry; 221 222 entry=AcquireMagickInfo("ART","ART","PFS: 1st Publisher Clip Art"); 223 entry->decoder=(DecodeImageHandler *) ReadARTImage; 224 entry->encoder=(EncodeImageHandler *) WriteARTImage; 225 entry->flags|=CoderRawSupportFlag; 226 entry->flags^=CoderAdjoinFlag; 227 (void) RegisterMagickInfo(entry); 228 return(MagickImageCoderSignature); 229 } 230 231 /* 233 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 234 % % 235 % % 236 % % 237 % U n r e g i s t e r A R T I m a g e % 238 % % 239 % % 240 % % 241 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 242 % 243 % UnregisterARTImage() removes format registrations made by the 244 % ART module from the list of supported formats. 245 % 246 % The format of the UnregisterARTImage method is: 247 % 248 % UnregisterARTImage(void) 249 % 250 */ 251 ModuleExport void UnregisterARTImage(void) 252 { 253 (void) UnregisterMagickInfo("ART"); 254 } 255 256 /* 258 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 259 % % 260 % % 261 % % 262 % W r i t e A R T I m a g e % 263 % % 264 % % 265 % % 266 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 267 % 268 % WriteARTImage() writes an image of raw bits in LSB order to a file. 269 % 270 % The format of the WriteARTImage method is: 271 % 272 % MagickBooleanType WriteARTImage(const ImageInfo *image_info, 273 % Image *image,ExceptionInfo *exception) 274 % 275 % A description of each parameter follows. 276 % 277 % o image_info: the image info. 278 % 279 % o image: The image. 280 % 281 % o exception: return any errors or warnings in this structure. 282 % 283 */ 284 static MagickBooleanType WriteARTImage(const ImageInfo *image_info,Image *image, 285 ExceptionInfo *exception) 286 { 287 MagickBooleanType 288 status; 289 290 QuantumInfo 291 *quantum_info; 292 293 register const Quantum 294 *p; 295 296 size_t 297 length; 298 299 ssize_t 300 count, 301 y; 302 303 unsigned char 304 *pixels; 305 306 /* 307 Open output image file. 308 */ 309 assert(image_info != (const ImageInfo *) NULL); 310 assert(image_info->signature == MagickCoreSignature); 311 assert(image != (Image *) NULL); 312 assert(image->signature == MagickCoreSignature); 313 if (image->debug != MagickFalse) 314 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 315 assert(exception != (ExceptionInfo *) NULL); 316 assert(exception->signature == MagickCoreSignature); 317 status=OpenBlob(image_info,image,WriteBinaryBlobMode,exception); 318 if (status == MagickFalse) 319 return(status); 320 if ((image->columns > 65535UL) || (image->rows > 65535UL)) 321 ThrowWriterException(ImageError,"WidthOrHeightExceedsLimit"); 322 (void) TransformImageColorspace(image,sRGBColorspace,exception); 323 (void) SetImageType(image,BilevelType,exception); 324 image->endian=MSBEndian; 325 image->depth=1; 326 (void) WriteBlobLSBShort(image,0); 327 (void) WriteBlobLSBShort(image,(unsigned short) image->columns); 328 (void) WriteBlobLSBShort(image,0); 329 (void) WriteBlobLSBShort(image,(unsigned short) image->rows); 330 quantum_info=AcquireQuantumInfo(image_info,image); 331 pixels=(unsigned char *) GetQuantumPixels(quantum_info); 332 for (y=0; y < (ssize_t) image->rows; y++) 333 { 334 p=GetVirtualPixels(image,0,y,image->columns,1,exception); 335 if (p == (const Quantum *) NULL) 336 break; 337 length=ExportQuantumPixels(image,(CacheView *) NULL,quantum_info, 338 GrayQuantum,pixels,exception); 339 count=WriteBlob(image,length,pixels); 340 if (count != (ssize_t) length) 341 ThrowWriterException(CorruptImageError,"UnableToWriteImageData"); 342 count=WriteBlob(image,(size_t) (-(ssize_t) length) & 0x01,pixels); 343 status=SetImageProgress(image,SaveImageTag,(MagickOffsetType) y, 344 image->rows); 345 if (status == MagickFalse) 346 break; 347 } 348 quantum_info=DestroyQuantumInfo(quantum_info); 349 (void) CloseBlob(image); 350 return(status); 351 } 352