Coverage Report

Created: 2026-05-24 07:45

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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
}