1/* 2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3% % 4% % 5% % 6% PPPP W W PPPP % 7% P P W W P P % 8% PPPP W W PPPP % 9% P W W W P % 10% P W W P % 11% % 12% % 13% Read Seattle Film Works 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/constitute.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/monitor.h" 54#include "MagickCore/monitor-private.h" 55#include "MagickCore/resource_.h" 56#include "MagickCore/quantum-private.h" 57#include "MagickCore/static.h" 58#include "MagickCore/string_.h" 59#include "MagickCore/module.h" 60 61/* 62%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 63% % 64% % 65% % 66% I s P W P % 67% % 68% % 69% % 70%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 71% 72% IsPWP() returns MagickTrue if the image format type, identified by the 73% magick string, is PWP. 74% 75% The format of the IsPWP method is: 76% 77% MagickBooleanType IsPWP(const unsigned char *magick,const size_t length) 78% 79% A description of each parameter follows: 80% 81% o magick: compare image format pattern against these bytes. 82% 83% o length: Specifies the length of the magick string. 84% 85% 86*/ 87static MagickBooleanType IsPWP(const unsigned char *magick,const size_t length) 88{ 89 if (length < 5) 90 return(MagickFalse); 91 if (LocaleNCompare((char *) magick,"SFW95",5) == 0) 92 return(MagickTrue); 93 return(MagickFalse); 94} 95 96/* 97%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 98% % 99% % 100% % 101% R e a d P W P I m a g e % 102% % 103% % 104% % 105%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 106% 107% ReadPWPImage() reads a Seattle Film Works multi-image file and returns 108% it. It allocates the memory necessary for the new Image structure and 109% returns a pointer to the new image. 110% 111% The format of the ReadPWPImage method is: 112% 113% Image *ReadPWPImage(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 *ReadPWPImage(const ImageInfo *image_info,ExceptionInfo *exception) 123{ 124 FILE 125 *file; 126 127 Image 128 *image, 129 *next_image, 130 *pwp_image; 131 132 ImageInfo 133 *read_info; 134 135 int 136 c, 137 unique_file; 138 139 MagickBooleanType 140 status; 141 142 register Image 143 *p; 144 145 register ssize_t 146 i; 147 148 size_t 149 filesize, 150 length; 151 152 ssize_t 153 count; 154 155 unsigned char 156 magick[MagickPathExtent]; 157 158 /* 159 Open image file. 160 */ 161 assert(image_info != (const ImageInfo *) NULL); 162 assert(image_info->signature == MagickCoreSignature); 163 if (image_info->debug != MagickFalse) 164 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s", 165 image_info->filename); 166 assert(exception != (ExceptionInfo *) NULL); 167 assert(exception->signature == MagickCoreSignature); 168 pwp_image=AcquireImage(image_info,exception); 169 image=pwp_image; 170 status=OpenBlob(image_info,pwp_image,ReadBinaryBlobMode,exception); 171 if (status == MagickFalse) 172 return((Image *) NULL); 173 count=ReadBlob(pwp_image,5,magick); 174 if ((count != 5) || (LocaleNCompare((char *) magick,"SFW95",5) != 0)) 175 ThrowReaderException(CorruptImageError,"ImproperImageHeader"); 176 read_info=CloneImageInfo(image_info); 177 (void) SetImageInfoProgressMonitor(read_info,(MagickProgressMonitor) NULL, 178 (void *) NULL); 179 SetImageInfoBlob(read_info,(void *) NULL,0); 180 unique_file=AcquireUniqueFileResource(read_info->filename); 181 for ( ; ; ) 182 { 183 for (c=ReadBlobByte(pwp_image); c != EOF; c=ReadBlobByte(pwp_image)) 184 { 185 for (i=0; i < 17; i++) 186 magick[i]=magick[i+1]; 187 magick[17]=(unsigned char) c; 188 if (LocaleNCompare((char *) (magick+12),"SFW94A",6) == 0) 189 break; 190 } 191 if (c == EOF) 192 break; 193 if (LocaleNCompare((char *) (magick+12),"SFW94A",6) != 0) 194 { 195 (void) RelinquishUniqueFileResource(read_info->filename); 196 ThrowReaderException(CorruptImageError,"ImproperImageHeader"); 197 } 198 /* 199 Dump SFW image to a temporary file. 200 */ 201 file=(FILE *) NULL; 202 if (unique_file != -1) 203 file=fdopen(unique_file,"wb"); 204 if ((unique_file == -1) || (file == (FILE *) NULL)) 205 { 206 (void) RelinquishUniqueFileResource(read_info->filename); 207 ThrowFileException(exception,FileOpenError,"UnableToWriteFile", 208 image->filename); 209 image=DestroyImageList(image); 210 return((Image *) NULL); 211 } 212 length=fwrite("SFW94A",1,6,file); 213 (void) length; 214 filesize=65535UL*magick[2]+256L*magick[1]+magick[0]; 215 for (i=0; i < (ssize_t) filesize; i++) 216 { 217 c=ReadBlobByte(pwp_image); 218 (void) fputc(c,file); 219 } 220 (void) fclose(file); 221 next_image=ReadImage(read_info,exception); 222 if (next_image == (Image *) NULL) 223 break; 224 (void) FormatLocaleString(next_image->filename,MagickPathExtent, 225 "slide_%02ld.sfw",(long) next_image->scene); 226 if (image == (Image *) NULL) 227 image=next_image; 228 else 229 { 230 /* 231 Link image into image list. 232 */ 233 for (p=image; p->next != (Image *) NULL; p=GetNextImageInList(p)) ; 234 next_image->previous=p; 235 next_image->scene=p->scene+1; 236 p->next=next_image; 237 } 238 if (image_info->number_scenes != 0) 239 if (next_image->scene >= (image_info->scene+image_info->number_scenes-1)) 240 break; 241 status=SetImageProgress(image,LoadImagesTag,TellBlob(pwp_image), 242 GetBlobSize(pwp_image)); 243 if (status == MagickFalse) 244 break; 245 } 246 if (unique_file != -1) 247 (void) close(unique_file); 248 (void) RelinquishUniqueFileResource(read_info->filename); 249 read_info=DestroyImageInfo(read_info); 250 (void) CloseBlob(pwp_image); 251 pwp_image=DestroyImage(pwp_image); 252 if (EOFBlob(image) != MagickFalse) 253 { 254 char 255 *message; 256 257 message=GetExceptionMessage(errno); 258 (void) ThrowMagickException(exception,GetMagickModule(),CorruptImageError, 259 "UnexpectedEndOfFile","`%s': %s",image->filename,message); 260 message=DestroyString(message); 261 } 262 (void) CloseBlob(image); 263 return(GetFirstImageInList(image)); 264} 265 266/* 267%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 268% % 269% % 270% % 271% R e g i s t e r P W P I m a g e % 272% % 273% % 274% % 275%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 276% 277% RegisterPWPImage() adds attributes for the PWP image format to 278% the list of supported formats. The attributes include the image format 279% tag, a method to read and/or write the format, whether the format 280% supports the saving of more than one frame to the same file or blob, 281% whether the format supports native in-memory I/O, and a brief 282% description of the format. 283% 284% The format of the RegisterPWPImage method is: 285% 286% size_t RegisterPWPImage(void) 287% 288*/ 289ModuleExport size_t RegisterPWPImage(void) 290{ 291 MagickInfo 292 *entry; 293 294 entry=AcquireMagickInfo("PWP","PWP","Seattle Film Works"); 295 entry->decoder=(DecodeImageHandler *) ReadPWPImage; 296 entry->magick=(IsImageFormatHandler *) IsPWP; 297 (void) RegisterMagickInfo(entry); 298 return(MagickImageCoderSignature); 299} 300 301/* 302%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 303% % 304% % 305% % 306% U n r e g i s t e r P W P I m a g e % 307% % 308% % 309% % 310%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 311% 312% UnregisterPWPImage() removes format registrations made by the 313% PWP module from the list of supported formats. 314% 315% The format of the UnregisterPWPImage method is: 316% 317% UnregisterPWPImage(void) 318% 319*/ 320ModuleExport void UnregisterPWPImage(void) 321{ 322 (void) UnregisterMagickInfo("PWP"); 323} 324