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