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