1 /* 2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3 % % 4 % % 5 % % 6 % PPPP IIIII X X % 7 % P P I X X % 8 % PPPP I X % 9 % P I X X % 10 % P IIIII X X % 11 % % 12 % % 13 % Read Alias/Wavefront RLE Image 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/blob.h" 45 #include "MagickCore/blob-private.h" 46 #include "MagickCore/cache.h" 47 #include "MagickCore/colormap.h" 48 #include "MagickCore/exception.h" 49 #include "MagickCore/exception-private.h" 50 #include "MagickCore/image.h" 51 #include "MagickCore/image-private.h" 52 #include "MagickCore/list.h" 53 #include "MagickCore/magick.h" 54 #include "MagickCore/memory_.h" 55 #include "MagickCore/monitor.h" 56 #include "MagickCore/monitor-private.h" 57 #include "MagickCore/pixel-accessor.h" 58 #include "MagickCore/quantum-private.h" 59 #include "MagickCore/static.h" 60 #include "MagickCore/string_.h" 61 #include "MagickCore/module.h" 62 63 /* 65 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 66 % % 67 % % 68 % % 69 % R e a d P I X I m a g e % 70 % % 71 % % 72 % % 73 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 74 % 75 % ReadPIXImage() reads a Alias/Wavefront RLE image file and returns it. 76 % It allocates the memory necessary for the new Image structure and returns a 77 % pointer to the new image. 78 % 79 % The format of the ReadPIXImage method is: 80 % 81 % Image *ReadPIXImage(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 % 90 */ 91 static Image *ReadPIXImage(const ImageInfo *image_info,ExceptionInfo *exception) 92 { 93 Image 94 *image; 95 96 MagickBooleanType 97 status; 98 99 Quantum 100 blue, 101 green, 102 index, 103 red; 104 105 register ssize_t 106 x; 107 108 register Quantum 109 *q; 110 111 size_t 112 bits_per_pixel, 113 height, 114 length, 115 width; 116 117 ssize_t 118 y; 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 PIX image. 139 */ 140 width=ReadBlobMSBShort(image); 141 height=ReadBlobMSBShort(image); 142 (void) ReadBlobMSBShort(image); /* x-offset */ 143 (void) ReadBlobMSBShort(image); /* y-offset */ 144 bits_per_pixel=ReadBlobMSBShort(image); 145 if ((width == 0UL) || (height == 0UL) || ((bits_per_pixel != 8) && 146 (bits_per_pixel != 24))) 147 ThrowReaderException(CorruptImageError,"ImproperImageHeader"); 148 do 149 { 150 /* 151 Initialize image structure. 152 */ 153 image->columns=width; 154 image->rows=height; 155 if (bits_per_pixel == 8) 156 if (AcquireImageColormap(image,256,exception) == MagickFalse) 157 ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); 158 if ((image_info->ping != MagickFalse) && (image_info->number_scenes != 0)) 159 if (image->scene >= (image_info->scene+image_info->number_scenes-1)) 160 break; 161 status=SetImageExtent(image,image->columns,image->rows,exception); 162 if (status == MagickFalse) 163 return(DestroyImageList(image)); 164 /* 165 Convert PIX raster image to pixel packets. 166 */ 167 red=(Quantum) 0; 168 green=(Quantum) 0; 169 blue=(Quantum) 0; 170 index=0; 171 length=0; 172 for (y=0; y < (ssize_t) image->rows; y++) 173 { 174 q=QueueAuthenticPixels(image,0,y,image->columns,1,exception); 175 if (q == (Quantum *) NULL) 176 break; 177 for (x=0; x < (ssize_t) image->columns; x++) 178 { 179 if (length == 0) 180 { 181 length=(size_t) ReadBlobByte(image); 182 if (bits_per_pixel == 8) 183 index=ScaleCharToQuantum((unsigned char) ReadBlobByte(image)); 184 else 185 { 186 blue=ScaleCharToQuantum((unsigned char) ReadBlobByte(image)); 187 green=ScaleCharToQuantum((unsigned char) ReadBlobByte(image)); 188 red=ScaleCharToQuantum((unsigned char) ReadBlobByte(image)); 189 } 190 } 191 if (image->storage_class == PseudoClass) 192 SetPixelIndex(image,index,q); 193 SetPixelBlue(image,blue,q); 194 SetPixelGreen(image,green,q); 195 SetPixelRed(image,red,q); 196 length--; 197 q+=GetPixelChannels(image); 198 } 199 if (SyncAuthenticPixels(image,exception) == MagickFalse) 200 break; 201 if (image->previous == (Image *) NULL) 202 { 203 status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y, 204 image->rows); 205 if (status == MagickFalse) 206 break; 207 } 208 } 209 if (image->storage_class == PseudoClass) 210 (void) SyncImage(image,exception); 211 if (EOFBlob(image) != MagickFalse) 212 { 213 ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile", 214 image->filename); 215 break; 216 } 217 /* 218 Proceed to next image. 219 */ 220 if (image_info->number_scenes != 0) 221 if (image->scene >= (image_info->scene+image_info->number_scenes-1)) 222 break; 223 width=ReadBlobMSBLong(image); 224 height=ReadBlobMSBLong(image); 225 (void) ReadBlobMSBShort(image); 226 (void) ReadBlobMSBShort(image); 227 bits_per_pixel=ReadBlobMSBShort(image); 228 status=(width != 0UL) && (height == 0UL) && ((bits_per_pixel == 8) || 229 (bits_per_pixel == 24)) ? MagickTrue : MagickFalse; 230 if (status != MagickFalse) 231 { 232 /* 233 Allocate next image structure. 234 */ 235 AcquireNextImage(image_info,image,exception); 236 if (GetNextImageInList(image) == (Image *) NULL) 237 { 238 image=DestroyImageList(image); 239 return((Image *) NULL); 240 } 241 image=SyncNextImageInList(image); 242 status=SetImageProgress(image,LoadImagesTag,TellBlob(image), 243 GetBlobSize(image)); 244 if (status == MagickFalse) 245 break; 246 } 247 } while (status != MagickFalse); 248 (void) CloseBlob(image); 249 return(GetFirstImageInList(image)); 250 } 251 252 /* 254 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 255 % % 256 % % 257 % % 258 % R e g i s t e r P I X I m a g e % 259 % % 260 % % 261 % % 262 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 263 % 264 % RegisterPIXImage() adds attributes for the PIX image format to 265 % the list of supported formats. The attributes include the image format 266 % tag, a method to read and/or write the format, whether the format 267 % supports the saving of more than one frame to the same file or blob, 268 % whether the format supports native in-memory I/O, and a brief 269 % description of the format. 270 % 271 % The format of the RegisterPIXImage method is: 272 % 273 % size_t RegisterPIXImage(void) 274 % 275 */ 276 ModuleExport size_t RegisterPIXImage(void) 277 { 278 MagickInfo 279 *entry; 280 281 entry=AcquireMagickInfo("PIX","PIX","Alias/Wavefront RLE image format"); 282 entry->decoder=(DecodeImageHandler *) ReadPIXImage; 283 (void) RegisterMagickInfo(entry); 284 return(MagickImageCoderSignature); 285 } 286 287 /* 289 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 290 % % 291 % % 292 % % 293 % U n r e g i s t e r P I X I m a g e % 294 % % 295 % % 296 % % 297 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 298 % 299 % UnregisterPIXImage() removes format registrations made by the 300 % PIX module from the list of supported formats. 301 % 302 % The format of the UnregisterPIXImage method is: 303 % 304 % UnregisterPIXImage(void) 305 % 306 */ 307 ModuleExport void UnregisterPIXImage(void) 308 { 309 (void) UnregisterMagickInfo("PIX"); 310 } 311