/src/graphicsmagick/coders/pwp.c
Line | Count | Source |
1 | | /* |
2 | | % Copyright (C) 2003-2026 GraphicsMagick Group |
3 | | % Copyright (C) 2002 ImageMagick Studio |
4 | | % Copyright 1991-1999 E. I. du Pont de Nemours and Company |
5 | | % |
6 | | % This program is covered by multiple licenses, which are described in |
7 | | % Copyright.txt. You should have received a copy of Copyright.txt with this |
8 | | % package; otherwise see http://www.graphicsmagick.org/www/Copyright.html. |
9 | | % |
10 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
11 | | % % |
12 | | % % |
13 | | % % |
14 | | % PPPP W W PPPP % |
15 | | % P P W W P P % |
16 | | % PPPP W W PPPP % |
17 | | % P W W W P % |
18 | | % P W W P % |
19 | | % % |
20 | | % % |
21 | | % Read Seattle Film Works Image Format. % |
22 | | % % |
23 | | % % |
24 | | % Software Design % |
25 | | % John Cristy % |
26 | | % July 1992 % |
27 | | % % |
28 | | % % |
29 | | % % |
30 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
31 | | % |
32 | | % |
33 | | */ |
34 | | |
35 | | /* |
36 | | Include declarations. |
37 | | */ |
38 | | #include "magick/studio.h" |
39 | | #include "magick/blob.h" |
40 | | #include "magick/constitute.h" |
41 | | #include "magick/magick.h" |
42 | | #include "magick/monitor.h" |
43 | | #include "magick/tempfile.h" |
44 | | #include "magick/utility.h" |
45 | | #include "magick/static.h" |
46 | | |
47 | | /* |
48 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
49 | | % % |
50 | | % % |
51 | | % % |
52 | | % I s P W P % |
53 | | % % |
54 | | % % |
55 | | % % |
56 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
57 | | % |
58 | | % Method IsPWP returns True if the image format type, identified by the |
59 | | % magick string, is PWP. |
60 | | % |
61 | | % The format of the IsPWP method is: |
62 | | % |
63 | | % unsigned int IsPWP(const unsigned char *magick,const size_t length) |
64 | | % |
65 | | % A description of each parameter follows: |
66 | | % |
67 | | % o status: Method IsPWP returns True if the image format type is PWP. |
68 | | % |
69 | | % o magick: This string is generally the first few bytes of an image file |
70 | | % or blob. |
71 | | % |
72 | | % o length: Specifies the length of the magick string. |
73 | | % |
74 | | % |
75 | | */ |
76 | | static unsigned int IsPWP(const unsigned char *magick,const size_t length) |
77 | 0 | { |
78 | 0 | if (length < 5) |
79 | 0 | return(False); |
80 | 0 | if (LocaleNCompare((char *) magick,"SFW95",5) == 0) |
81 | 0 | return(True); |
82 | 0 | return(False); |
83 | 0 | } |
84 | | |
85 | | /* |
86 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
87 | | % % |
88 | | % % |
89 | | % % |
90 | | % R e a d P W P I m a g e % |
91 | | % % |
92 | | % % |
93 | | % % |
94 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
95 | | % |
96 | | % Method ReadPWPImage reads a Seattle Film Works multi-image file and returns |
97 | | % it. It allocates the memory necessary for the new Image structure and |
98 | | % returns a pointer to the new image. |
99 | | % |
100 | | % The format of the ReadPWPImage method is: |
101 | | % |
102 | | % Image *ReadPWPImage(const ImageInfo *image_info,ExceptionInfo *exception) |
103 | | % |
104 | | % A description of each parameter follows: |
105 | | % |
106 | | % o image: Method ReadPWPImage returns a pointer to the image after |
107 | | % reading. A null image is returned if there is a memory shortage or |
108 | | % if the image cannot be read. |
109 | | % |
110 | | % o image_info: Specifies a pointer to a ImageInfo structure. |
111 | | % |
112 | | % o exception: return any errors or warnings in this structure. |
113 | | % |
114 | | % |
115 | | */ |
116 | | static Image *ReadPWPImage(const ImageInfo *image_info,ExceptionInfo *exception) |
117 | 12.4k | { |
118 | 12.4k | FILE |
119 | 12.4k | *file; |
120 | | |
121 | 12.4k | Image |
122 | 12.4k | *image, |
123 | 12.4k | *next_image, |
124 | 12.4k | *pwp_image; |
125 | | |
126 | 12.4k | ImageInfo |
127 | 12.4k | *clone_info; |
128 | | |
129 | 12.4k | int |
130 | 12.4k | c; |
131 | | |
132 | 12.4k | MonitorHandler |
133 | 12.4k | handler; |
134 | | |
135 | 12.4k | register Image |
136 | 12.4k | *p; |
137 | | |
138 | 12.4k | register unsigned long |
139 | 12.4k | i; |
140 | | |
141 | 12.4k | size_t |
142 | 12.4k | count; |
143 | | |
144 | 12.4k | unsigned char |
145 | 12.4k | magick[MaxTextExtent]; |
146 | | |
147 | 12.4k | unsigned int |
148 | 12.4k | status; |
149 | | |
150 | 12.4k | unsigned long |
151 | 12.4k | filesize; |
152 | | |
153 | | /* |
154 | | Open image file. |
155 | | */ |
156 | 12.4k | assert(image_info != (const ImageInfo *) NULL); |
157 | 12.4k | assert(image_info->signature == MagickSignature); |
158 | 12.4k | assert(exception != (ExceptionInfo *) NULL); |
159 | 12.4k | assert(exception->signature == MagickSignature); |
160 | 12.4k | image=(Image *) NULL; |
161 | 12.4k | pwp_image=AllocateImage(image_info); |
162 | 12.4k | status=OpenBlob(image_info,pwp_image,ReadBinaryBlobMode,exception); |
163 | 12.4k | if (status == False) |
164 | 12.4k | ThrowReaderException(FileOpenError,UnableToOpenFile,pwp_image); |
165 | 12.4k | count=ReadBlob(pwp_image,5,(char *) magick); |
166 | 12.4k | if ((count != 5) || (LocaleNCompare((char *) magick,"SFW95",5) != 0)) |
167 | 12.4k | ThrowReaderException(CorruptImageError,ImproperImageHeader,pwp_image); |
168 | 12.4k | clone_info=CloneImageInfo(image_info); |
169 | 12.4k | clone_info->blob=(_BlobInfoPtr_) NULL; |
170 | 12.4k | clone_info->length=0; |
171 | 12.4k | for ( ; ; ) |
172 | 12.4k | { |
173 | 12.4k | (void) memset(magick,0,sizeof(magick)); |
174 | 3.93M | for (c=ReadBlobByte(pwp_image); c != EOF; c=ReadBlobByte(pwp_image)) |
175 | 3.93M | { |
176 | 70.7M | for (i=0; i < 17; i++) |
177 | 66.8M | magick[i]=magick[i+1]; |
178 | 3.93M | magick[17]=(unsigned char) c; |
179 | 3.93M | if (LocaleNCompare((char *) (magick+12),"SFW94A",6) == 0) |
180 | 9.55k | break; |
181 | 3.93M | } |
182 | 12.4k | if (c == EOF) |
183 | 2.86k | { |
184 | 2.86k | ThrowException(exception,CorruptImageError,UnexpectedEndOfFile, |
185 | 2.86k | clone_info->filename); |
186 | 2.86k | break; |
187 | 2.86k | } |
188 | 9.55k | if (LocaleNCompare((char *) (magick+12),"SFW94A",6) != 0) |
189 | 0 | { |
190 | 0 | ThrowException(exception,CorruptImageError,ImproperImageHeader, |
191 | 0 | clone_info->filename); |
192 | 0 | break; |
193 | 0 | } |
194 | | /* |
195 | | Dump SFW image to a temporary file. |
196 | | */ |
197 | 9.55k | { |
198 | 9.55k | char tmpfile[MaxTextExtent]; |
199 | 9.55k | file=AcquireTemporaryFileStream(tmpfile,BinaryFileIOMode); |
200 | 9.55k | if (file == (FILE *) NULL) |
201 | 0 | { |
202 | 0 | ThrowException(exception,FileOpenError,UnableToCreateTemporaryFile, |
203 | 0 | clone_info->filename); |
204 | 0 | break; |
205 | 0 | } |
206 | 9.55k | (void) strlcpy(clone_info->filename,"SFW:",sizeof(clone_info->filename)); |
207 | 9.55k | (void) strlcat(clone_info->filename,tmpfile,sizeof(clone_info->filename)); |
208 | 9.55k | } |
209 | 0 | (void) fwrite("SFW94A",1,6,file); |
210 | 9.55k | filesize=(65535L*magick[2]+256L*magick[1]+magick[0]) & 0xFFFFFFFF; |
211 | 30.7M | for (i=0; i < filesize; i++) |
212 | 30.6M | { |
213 | 30.6M | if ((c=ReadBlobByte(pwp_image)) == EOF) |
214 | 199 | break; |
215 | 30.6M | (void) fputc(c,file); |
216 | 30.6M | } |
217 | 9.55k | (void) fclose(file); |
218 | 9.55k | if (c == EOF) |
219 | 199 | { |
220 | 199 | ThrowException(exception,CorruptImageError,UnexpectedEndOfFile, |
221 | 199 | clone_info->filename); |
222 | 199 | break; |
223 | 199 | } |
224 | 9.35k | handler=SetMonitorHandler((MonitorHandler) NULL); |
225 | 9.35k | next_image=ReadImage(clone_info,exception); |
226 | 9.35k | (void) LiberateTemporaryFile(clone_info->filename); |
227 | 9.35k | (void) SetMonitorHandler(handler); |
228 | 9.35k | if (next_image == (Image *) NULL) |
229 | 7.38k | break; |
230 | 1.97k | StopTimer(&next_image->timer); |
231 | 1.97k | MagickFormatString(next_image->filename,sizeof(next_image->filename), |
232 | 1.97k | "slide_%02ld.sfw",next_image->scene); |
233 | 1.97k | if (image == (Image *) NULL) |
234 | 1.97k | image=next_image; |
235 | 0 | else |
236 | 0 | { |
237 | | /* |
238 | | Link image into image list. |
239 | | */ |
240 | 0 | for (p=image; p->next != (Image *) NULL; p=p->next); |
241 | 0 | next_image->previous=p; |
242 | 0 | next_image->scene=p->scene+1; |
243 | 0 | p->next=next_image; |
244 | 0 | } |
245 | 1.97k | if (image_info->subrange != 0) |
246 | 1.97k | if (next_image->scene >= (image_info->subimage+image_info->subrange-1)) |
247 | 1.97k | break; |
248 | 0 | if (!MagickMonitorFormatted(TellBlob(pwp_image),GetBlobSize(image), |
249 | 0 | &image->exception,LoadImagesText, |
250 | 0 | image->filename)) |
251 | 0 | break; |
252 | 0 | } |
253 | 12.4k | DestroyImageInfo(clone_info); |
254 | 12.4k | CloseBlob(pwp_image); |
255 | 12.4k | DestroyImage(pwp_image); |
256 | 12.4k | return(image); |
257 | 12.4k | } |
258 | | |
259 | | /* |
260 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
261 | | % % |
262 | | % % |
263 | | % % |
264 | | % R e g i s t e r P W P I m a g e % |
265 | | % % |
266 | | % % |
267 | | % % |
268 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
269 | | % |
270 | | % Method RegisterPWPImage adds attributes for the PWP image format to |
271 | | % the list of supported formats. The attributes include the image format |
272 | | % tag, a method to read and/or write the format, whether the format |
273 | | % supports the saving of more than one frame to the same file or blob, |
274 | | % whether the format supports native in-memory I/O, and a brief |
275 | | % description of the format. |
276 | | % |
277 | | % The format of the RegisterPWPImage method is: |
278 | | % |
279 | | % RegisterPWPImage(void) |
280 | | % |
281 | | */ |
282 | | ModuleExport void RegisterPWPImage(void) |
283 | 4 | { |
284 | 4 | MagickInfo |
285 | 4 | *entry; |
286 | | |
287 | 4 | entry=SetMagickInfo("PWP"); |
288 | 4 | entry->decoder=(DecoderHandler) ReadPWPImage; |
289 | 4 | entry->magick=(MagickHandler) IsPWP; |
290 | 4 | entry->description="Seattle Film Works"; |
291 | 4 | entry->module="PWP"; |
292 | 4 | entry->coder_class=UnstableCoderClass; |
293 | 4 | (void) RegisterMagickInfo(entry); |
294 | 4 | } |
295 | | |
296 | | /* |
297 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
298 | | % % |
299 | | % % |
300 | | % % |
301 | | % U n r e g i s t e r P W P I m a g e % |
302 | | % % |
303 | | % % |
304 | | % % |
305 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
306 | | % |
307 | | % Method UnregisterPWPImage removes format registrations made by the |
308 | | % PWP module from the list of supported formats. |
309 | | % |
310 | | % The format of the UnregisterPWPImage method is: |
311 | | % |
312 | | % UnregisterPWPImage(void) |
313 | | % |
314 | | */ |
315 | | ModuleExport void UnregisterPWPImage(void) |
316 | 0 | { |
317 | 0 | (void) UnregisterMagickInfo("PWP"); |
318 | 0 | } |