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