Coverage Report

Created: 2026-06-30 07:12

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/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
7.05k
{
125
7.05k
  char
126
7.05k
    filename[MagickPathExtent];
127
128
7.05k
  FILE
129
7.05k
    *file;
130
131
7.05k
  Image
132
7.05k
    *image,
133
7.05k
    *next_image,
134
7.05k
    *pwp_image;
135
136
7.05k
  ImageInfo
137
7.05k
    *read_info;
138
139
7.05k
  int
140
7.05k
    c,
141
7.05k
    unique_file;
142
143
7.05k
  MagickBooleanType
144
7.05k
    status;
145
146
7.05k
  Image
147
7.05k
    *p;
148
149
7.05k
  ssize_t
150
7.05k
    i;
151
152
7.05k
  size_t
153
7.05k
    filesize,
154
7.05k
    length;
155
156
7.05k
  ssize_t
157
7.05k
    count;
158
159
7.05k
  unsigned char
160
7.05k
    magick[MagickPathExtent];
161
162
  /*
163
    Open image file.
164
  */
165
7.05k
  assert(image_info != (const ImageInfo *) NULL);
166
7.05k
  assert(image_info->signature == MagickCoreSignature);
167
7.05k
  if (IsEventLogging() != MagickFalse)
168
0
    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
169
0
      image_info->filename);
170
7.05k
  assert(exception != (ExceptionInfo *) NULL);
171
7.05k
  assert(exception->signature == MagickCoreSignature);
172
7.05k
  image=AcquireImage(image_info,exception);
173
7.05k
  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
174
7.05k
  if (status == MagickFalse)
175
0
    {
176
0
      image=DestroyImage(image);
177
0
      return((Image *) NULL);
178
0
    }
179
7.05k
  pwp_image=image;
180
7.05k
  memset(magick,0,sizeof(magick));
181
7.05k
  count=ReadBlob(pwp_image,5,magick);
182
7.05k
  if ((count != 5) || (LocaleNCompare((char *) magick,"SFW95",5) != 0))
183
7.01k
    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
184
7.01k
  read_info=CloneImageInfo(image_info);
185
7.01k
  (void) SetImageInfoProgressMonitor(read_info,(MagickProgressMonitor) NULL,
186
7.01k
    (void *) NULL);
187
7.01k
  SetImageInfoBlob(read_info,(void *) NULL,0);
188
7.01k
  unique_file=AcquireUniqueFileResource(filename);
189
7.01k
  (void) FormatLocaleString(read_info->filename,MagickPathExtent,"sfw:%s",
190
7.01k
    filename);
191
7.01k
  for ( ; ; )
192
11.4k
  {
193
11.4k
    (void) memset(magick,0,sizeof(magick));
194
175k
    for (c=ReadBlobByte(pwp_image); c != EOF; c=ReadBlobByte(pwp_image))
195
170k
    {
196
3.07M
      for (i=0; i < 17; i++)
197
2.90M
        magick[i]=magick[i+1];
198
170k
      magick[17]=(unsigned char) c;
199
170k
      if (LocaleNCompare((char *) (magick+12),"SFW94A",6) == 0)
200
6.95k
        break;
201
170k
    }
202
11.4k
    if (c == EOF)
203
4.52k
      {
204
4.52k
        (void) RelinquishUniqueFileResource(filename);
205
4.52k
        read_info=DestroyImageInfo(read_info);
206
4.52k
        ThrowReaderException(CorruptImageError,"UnexpectedEndOfFile");
207
0
      }
208
6.95k
    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
6.95k
    file=(FILE *) NULL;
218
6.95k
    if (unique_file != -1)
219
6.95k
      file=fdopen(unique_file,"wb");
220
6.95k
    if ((unique_file == -1) || (file == (FILE *) NULL))
221
11
      {
222
11
        (void) RelinquishUniqueFileResource(filename);
223
11
        read_info=DestroyImageInfo(read_info);
224
11
        ThrowFileException(exception,FileOpenError,"UnableToWriteFile",
225
11
          image->filename);
226
11
        image=DestroyImageList(image);
227
11
        return((Image *) NULL);
228
11
      }
229
6.94k
    length=fwrite("SFW94A",1,6,file);
230
6.94k
    (void) length;
231
6.94k
    filesize=65535*magick[2]+256L*magick[1]+magick[0];
232
4.31M
    for (i=0; i < (ssize_t) filesize; i++)
233
4.30M
    {
234
4.30M
      c=ReadBlobByte(pwp_image);
235
4.30M
      if (c == EOF)
236
53
        break;
237
4.30M
      if (fputc(c,file) != c)
238
0
        break;
239
4.30M
    }
240
6.94k
    (void) fclose(file);
241
6.94k
    if (c == EOF)
242
53
      {
243
53
        (void) RelinquishUniqueFileResource(filename);
244
53
        read_info=DestroyImageInfo(read_info);
245
53
        ThrowReaderException(CorruptImageError,"UnexpectedEndOfFile");
246
0
      }
247
6.89k
    next_image=ReadImage(read_info,exception);
248
6.89k
    if (next_image == (Image *) NULL)
249
2.42k
      break;
250
4.46k
    (void) FormatLocaleString(next_image->filename,MagickPathExtent,
251
4.46k
      "slide_%02ld.sfw",(long) next_image->scene);
252
4.46k
    if (image == (Image *) NULL)
253
0
      image=next_image;
254
4.46k
    else
255
4.46k
      {
256
        /*
257
          Link image into image list.
258
        */
259
4.46k
        for (p=image; p->next != (Image *) NULL; p=GetNextImageInList(p)) ;
260
4.46k
        next_image->previous=p;
261
4.46k
        next_image->scene=p->scene+1;
262
4.46k
        p->next=next_image;
263
4.46k
      }
264
4.46k
    if (image_info->number_scenes != 0)
265
0
      if (next_image->scene >= (image_info->scene+image_info->number_scenes-1))
266
0
        break;
267
4.46k
    status=SetImageProgress(image,LoadImagesTag,TellBlob(pwp_image),
268
4.46k
      GetBlobSize(pwp_image));
269
4.46k
    if (status == MagickFalse)
270
0
      break;
271
4.46k
  }
272
2.42k
  if (unique_file != -1)
273
2.42k
    (void) close_utf8(unique_file);
274
2.42k
  (void) RelinquishUniqueFileResource(filename);
275
2.42k
  read_info=DestroyImageInfo(read_info);
276
2.42k
  if (image != (Image *) NULL)
277
2.42k
    {
278
2.42k
      if (EOFBlob(image) != MagickFalse)
279
0
        {
280
0
          char
281
0
            *message;
282
283
0
          message=GetExceptionMessage(errno);
284
0
          (void) ThrowMagickException(exception,GetMagickModule(),
285
0
            CorruptImageError,"UnexpectedEndOfFile","`%s': %s",image->filename,
286
0
            message);
287
0
          message=DestroyString(message);
288
0
        }
289
2.42k
      (void) CloseBlob(image);
290
2.42k
    }
291
2.42k
  return(GetFirstImageInList(image));
292
7.01k
}
293

294
/*
295
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
296
%                                                                             %
297
%                                                                             %
298
%                                                                             %
299
%   R e g i s t e r P W P I m a g e                                           %
300
%                                                                             %
301
%                                                                             %
302
%                                                                             %
303
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
304
%
305
%  RegisterPWPImage() adds attributes for the PWP image format to
306
%  the list of supported formats.  The attributes include the image format
307
%  tag, a method to read and/or write the format, whether the format
308
%  supports the saving of more than one frame to the same file or blob,
309
%  whether the format supports native in-memory I/O, and a brief
310
%  description of the format.
311
%
312
%  The format of the RegisterPWPImage method is:
313
%
314
%      size_t RegisterPWPImage(void)
315
%
316
*/
317
ModuleExport size_t RegisterPWPImage(void)
318
10
{
319
10
  MagickInfo
320
10
    *entry;
321
322
10
  entry=AcquireMagickInfo("PWP","PWP","Seattle Film Works");
323
10
  entry->decoder=(DecodeImageHandler *) ReadPWPImage;
324
10
  entry->magick=(IsImageFormatHandler *) IsPWP;
325
10
  (void) RegisterMagickInfo(entry);
326
10
  return(MagickImageCoderSignature);
327
10
}
328

329
/*
330
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
331
%                                                                             %
332
%                                                                             %
333
%                                                                             %
334
%   U n r e g i s t e r P W P I m a g e                                       %
335
%                                                                             %
336
%                                                                             %
337
%                                                                             %
338
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
339
%
340
%  UnregisterPWPImage() removes format registrations made by the
341
%  PWP module from the list of supported formats.
342
%
343
%  The format of the UnregisterPWPImage method is:
344
%
345
%      UnregisterPWPImage(void)
346
%
347
*/
348
ModuleExport void UnregisterPWPImage(void)
349
0
{
350
0
  (void) UnregisterMagickInfo("PWP");
351
0
}