1 /* 2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3 % % 4 % % 5 % % 6 % SSSSS CCCC TTTTT % 7 % SS C T % 8 % SSS C T % 9 % SS C T % 10 % SSSSS CCCC T % 11 % % 12 % % 13 % Read Scitex HandShake 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/exception.h" 48 #include "MagickCore/exception-private.h" 49 #include "MagickCore/image.h" 50 #include "MagickCore/image-private.h" 51 #include "MagickCore/list.h" 52 #include "MagickCore/magick.h" 53 #include "MagickCore/memory_.h" 54 #include "MagickCore/module.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/string-private.h" 62 63 /* 65 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 66 % % 67 % % 68 % % 69 % I s S C T % 70 % % 71 % % 72 % % 73 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 74 % 75 % IsSCT() returns MagickTrue if the image format type, identified by the 76 % magick string, is SCT. 77 % 78 % The format of the IsSCT method is: 79 % 80 % MagickBooleanType IsSCT(const unsigned char *magick,const size_t length) 81 % 82 % A description of each parameter follows: 83 % 84 % o magick: compare image format pattern against these bytes. 85 % 86 % o length: Specifies the length of the magick string. 87 % 88 */ 89 static MagickBooleanType IsSCT(const unsigned char *magick,const size_t length) 90 { 91 if (length < 2) 92 return(MagickFalse); 93 if (LocaleNCompare((const char *) magick,"CT",2) == 0) 94 return(MagickTrue); 95 return(MagickFalse); 96 } 97 98 /* 100 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 101 % % 102 % % 103 % % 104 % R e a d S C T I m a g e % 105 % % 106 % % 107 % % 108 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 109 % 110 % ReadSCTImage() reads a Scitex image file and returns it. It allocates 111 % the memory necessary for the new Image structure and returns a pointer to 112 % the new image. 113 % 114 % The format of the ReadSCTImage method is: 115 % 116 % Image *ReadSCTImage(const ImageInfo *image_info,ExceptionInfo *exception) 117 % 118 % A description of each parameter follows: 119 % 120 % o image_info: the image info. 121 % 122 % o exception: return any errors or warnings in this structure. 123 % 124 */ 125 static Image *ReadSCTImage(const ImageInfo *image_info,ExceptionInfo *exception) 126 { 127 char 128 magick[2]; 129 130 Image 131 *image; 132 133 MagickBooleanType 134 status; 135 136 double 137 height, 138 width; 139 140 Quantum 141 pixel; 142 143 register ssize_t 144 i, 145 x; 146 147 register Quantum 148 *q; 149 150 ssize_t 151 count, 152 y; 153 154 unsigned char 155 buffer[768]; 156 157 size_t 158 separations, 159 separations_mask, 160 units; 161 162 /* 163 Open image file. 164 */ 165 assert(image_info != (const ImageInfo *) NULL); 166 assert(image_info->signature == MagickCoreSignature); 167 if (image_info->debug != MagickFalse) 168 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s", 169 image_info->filename); 170 assert(exception != (ExceptionInfo *) NULL); 171 assert(exception->signature == MagickCoreSignature); 172 image=AcquireImage(image_info,exception); 173 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception); 174 if (status == MagickFalse) 175 { 176 image=DestroyImageList(image); 177 return((Image *) NULL); 178 } 179 /* 180 Read control block. 181 */ 182 count=ReadBlob(image,80,buffer); 183 (void) count; 184 count=ReadBlob(image,2,(unsigned char *) magick); 185 if ((LocaleNCompare((char *) magick,"CT",2) != 0) && 186 (LocaleNCompare((char *) magick,"LW",2) != 0) && 187 (LocaleNCompare((char *) magick,"BM",2) != 0) && 188 (LocaleNCompare((char *) magick,"PG",2) != 0) && 189 (LocaleNCompare((char *) magick,"TX",2) != 0)) 190 ThrowReaderException(CorruptImageError,"ImproperImageHeader"); 191 if ((LocaleNCompare((char *) magick,"LW",2) == 0) || 192 (LocaleNCompare((char *) magick,"BM",2) == 0) || 193 (LocaleNCompare((char *) magick,"PG",2) == 0) || 194 (LocaleNCompare((char *) magick,"TX",2) == 0)) 195 ThrowReaderException(CoderError,"OnlyContinuousTonePictureSupported"); 196 count=ReadBlob(image,174,buffer); 197 count=ReadBlob(image,768,buffer); 198 /* 199 Read paramter block. 200 */ 201 units=1UL*ReadBlobByte(image); 202 if (units == 0) 203 image->units=PixelsPerCentimeterResolution; 204 separations=1UL*ReadBlobByte(image); 205 separations_mask=ReadBlobMSBShort(image); 206 count=ReadBlob(image,14,buffer); 207 buffer[14]='\0'; 208 height=StringToDouble((char *) buffer,(char **) NULL); 209 count=ReadBlob(image,14,buffer); 210 width=StringToDouble((char *) buffer,(char **) NULL); 211 count=ReadBlob(image,12,buffer); 212 buffer[12]='\0'; 213 image->rows=StringToUnsignedLong((char *) buffer); 214 count=ReadBlob(image,12,buffer); 215 image->columns=StringToUnsignedLong((char *) buffer); 216 count=ReadBlob(image,200,buffer); 217 count=ReadBlob(image,768,buffer); 218 if (separations_mask == 0x0f) 219 SetImageColorspace(image,CMYKColorspace,exception); 220 image->resolution.x=1.0*image->columns/width; 221 image->resolution.y=1.0*image->rows/height; 222 if (image_info->ping != MagickFalse) 223 { 224 (void) CloseBlob(image); 225 return(GetFirstImageInList(image)); 226 } 227 status=SetImageExtent(image,image->columns,image->rows,exception); 228 if (status == MagickFalse) 229 return(DestroyImageList(image)); 230 /* 231 Convert SCT raster image to pixel packets. 232 */ 233 for (y=0; y < (ssize_t) image->rows; y++) 234 { 235 for (i=0; i < (ssize_t) separations; i++) 236 { 237 q=GetAuthenticPixels(image,0,y,image->columns,1,exception); 238 if (q == (Quantum *) NULL) 239 break; 240 for (x=0; x < (ssize_t) image->columns; x++) 241 { 242 pixel=(Quantum) ScaleCharToQuantum((unsigned char) ReadBlobByte(image)); 243 if (image->colorspace == CMYKColorspace) 244 pixel=(Quantum) (QuantumRange-pixel); 245 switch (i) 246 { 247 case 0: 248 { 249 SetPixelRed(image,pixel,q); 250 SetPixelGreen(image,pixel,q); 251 SetPixelBlue(image,pixel,q); 252 break; 253 } 254 case 1: 255 { 256 SetPixelGreen(image,pixel,q); 257 break; 258 } 259 case 2: 260 { 261 SetPixelBlue(image,pixel,q); 262 break; 263 } 264 case 3: 265 { 266 if (image->colorspace == CMYKColorspace) 267 SetPixelBlack(image,pixel,q); 268 break; 269 } 270 } 271 q+=GetPixelChannels(image); 272 } 273 if (SyncAuthenticPixels(image,exception) == MagickFalse) 274 break; 275 if ((image->columns % 2) != 0) 276 (void) ReadBlobByte(image); /* pad */ 277 } 278 status=SetImageProgress(image,LoadImageTag,(MagickOffsetType) y, 279 image->rows); 280 if (status == MagickFalse) 281 break; 282 } 283 if (EOFBlob(image) != MagickFalse) 284 ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile", 285 image->filename); 286 (void) CloseBlob(image); 287 return(GetFirstImageInList(image)); 288 } 289 290 /* 292 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 293 % % 294 % % 295 % % 296 % R e g i s t e r S C T I m a g e % 297 % % 298 % % 299 % % 300 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 301 % 302 % RegisterSCTImage() adds attributes for the SCT image format to 303 % the list of supported formats. The attributes include the image format 304 % tag, a method to read and/or write the format, whether the format 305 % supports the saving of more than one frame to the same file or blob, 306 % whether the format supports native in-memory I/O, and a brief 307 % description of the format. 308 % 309 % The format of the RegisterSCTImage method is: 310 % 311 % size_t RegisterSCTImage(void) 312 % 313 */ 314 ModuleExport size_t RegisterSCTImage(void) 315 { 316 MagickInfo 317 *entry; 318 319 entry=AcquireMagickInfo("SCT","SCT","Scitex HandShake"); 320 entry->decoder=(DecodeImageHandler *) ReadSCTImage; 321 entry->magick=(IsImageFormatHandler *) IsSCT; 322 entry->flags^=CoderAdjoinFlag; 323 (void) RegisterMagickInfo(entry); 324 return(MagickImageCoderSignature); 325 } 326 327 /* 329 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 330 % % 331 % % 332 % % 333 % U n r e g i s t e r S C T I m a g e % 334 % % 335 % % 336 % % 337 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 338 % 339 % UnregisterSCTImage() removes format registrations made by the 340 % SCT module from the list of supported formats. 341 % 342 % The format of the UnregisterSCTImage method is: 343 % 344 % UnregisterSCTImage(void) 345 % 346 */ 347 ModuleExport void UnregisterSCTImage(void) 348 { 349 (void) UnregisterMagickInfo("SCT"); 350 } 351