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