1/*
2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3%                                                                             %
4%                                                                             %
5%                                                                             %
6%                            PPPP   EEEEE  SSSSS                              %
7%                            P   P  E      SS                                 %
8%                            PPPP   EEE     SSS                               %
9%                            P      E         SS                              %
10%                            P      EEEEE  SSSSS                              %
11%                                                                             %
12%                                                                             %
13%                     Read/Write Brother PES Image Format                     %
14%                                                                             %
15%                              Software Design                                %
16%                                   Cristy                                    %
17%                                 July 2009                                   %
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%  The PES format was derived from Robert Heel's PHP script (see
37%  http://bobosch.dyndns.org/embroidery/showFile.php?pes.php) and pesconvert
38%  (see http://torvalds-family.blogspot.com/2010/01/embroidery-gaah.html).
39%
40*/
41
42/*
43  Include declarations.
44*/
45#include "MagickCore/studio.h"
46#include "MagickCore/property.h"
47#include "MagickCore/blob.h"
48#include "MagickCore/blob-private.h"
49#include "MagickCore/cache.h"
50#include "MagickCore/client.h"
51#include "MagickCore/colorspace.h"
52#include "MagickCore/constitute.h"
53#include "MagickCore/decorate.h"
54#include "MagickCore/exception.h"
55#include "MagickCore/exception-private.h"
56#include "MagickCore/gem.h"
57#include "MagickCore/geometry.h"
58#include "MagickCore/image.h"
59#include "MagickCore/image-private.h"
60#include "MagickCore/list.h"
61#include "MagickCore/magick.h"
62#include "MagickCore/memory_.h"
63#include "MagickCore/monitor.h"
64#include "MagickCore/monitor-private.h"
65#include "MagickCore/montage.h"
66#include "MagickCore/resize.h"
67#include "MagickCore/shear.h"
68#include "MagickCore/quantum-private.h"
69#include "MagickCore/static.h"
70#include "MagickCore/string_.h"
71#include "MagickCore/module.h"
72#include "MagickCore/resource_.h"
73#include "MagickCore/transform.h"
74#include "MagickCore/utility.h"
75
76/*
77  Typedef declarations.
78*/
79typedef struct _PESColorInfo
80{
81  const unsigned char
82    red,
83    green,
84    blue,
85    alpha;
86} PESColorInfo;
87
88typedef struct _PESBlockInfo
89{
90  const PESColorInfo
91    *color;
92
93  ssize_t
94    offset;
95} PESBlockInfo;
96
97/*
98  PES Colors.
99*/
100static const PESColorInfo
101  PESColor[256] =
102  {
103    {   0,   0,   0, 1 },
104    {  14,  31, 124, 1 },
105    {  10,  85, 163, 1 },
106    {  48, 135, 119, 1 },
107    {  75, 107, 175, 1 },
108    { 237,  23,  31, 1 },
109    { 209,  92,   0, 1 },
110    { 145,  54, 151, 1 },
111    { 228, 154, 203, 1 },
112    { 145,  95, 172, 1 },
113    { 157, 214, 125, 1 },
114    { 232, 169,   0, 1 },
115    { 254, 186,  53, 1 },
116    { 255, 255,   0, 1 },
117    { 112, 188,  31, 1 },
118    { 192, 148,   0, 1 },
119    { 168, 168, 168, 1 },
120    { 123, 111,   0, 1 },
121    { 255, 255, 179, 1 },
122    {  79,  85,  86, 1 },
123    {   0,   0,   0, 1 },
124    {  11,  61, 145, 1 },
125    { 119,   1, 118, 1 },
126    {  41,  49,  51, 1 },
127    {  42,  19,   1, 1 },
128    { 246,  74, 138, 1 },
129    { 178, 118,  36, 1 },
130    { 252, 187, 196, 1 },
131    { 254,  55,  15, 1 },
132    { 240, 240, 240, 1 },
133    { 106,  28, 138, 1 },
134    { 168, 221, 196, 1 },
135    {  37, 132, 187, 1 },
136    { 254, 179,  67, 1 },
137    { 255, 240, 141, 1 },
138    { 208, 166,  96, 1 },
139    { 209,  84,   0, 1 },
140    { 102, 186,  73, 1 },
141    {  19,  74,  70, 1 },
142    { 135, 135, 135, 1 },
143    { 216, 202, 198, 1 },
144    {  67,  86,   7, 1 },
145    { 254, 227, 197, 1 },
146    { 249, 147, 188, 1 },
147    {   0,  56,  34, 1 },
148    { 178, 175, 212, 1 },
149    { 104, 106, 176, 1 },
150    { 239, 227, 185, 1 },
151    { 247,  56, 102, 1 },
152    { 181,  76, 100, 1 },
153    {  19,  43,  26, 1 },
154    { 199,   1,  85, 1 },
155    { 254, 158,  50, 1 },
156    { 168, 222, 235, 1 },
157    {   0, 103,  26, 1 },
158    {  78,  41, 144, 1 },
159    {  47, 126,  32, 1 },
160    { 253, 217, 222, 1 },
161    { 255, 217,  17, 1 },
162    {   9,  91, 166, 1 },
163    { 240, 249, 112, 1 },
164    { 227, 243,  91, 1 },
165    { 255, 200, 100, 1 },
166    { 255, 200, 150, 1 },
167    { 255, 200, 200, 1 },
168    {   0,   0,   0, 1 },
169    {   0,   0,   0, 1 },
170    {   0,   0,   0, 1 },
171    {   0,   0,   0, 1 },
172    {   0,   0,   0, 1 },
173    {   0,   0,   0, 1 },
174    {   0,   0,   0, 1 },
175    {   0,   0,   0, 1 },
176    {   0,   0,   0, 1 },
177    {   0,   0,   0, 1 },
178    {   0,   0,   0, 1 },
179    {   0,   0,   0, 1 },
180    {   0,   0,   0, 1 },
181    {   0,   0,   0, 1 },
182    {   0,   0,   0, 1 },
183    {   0,   0,   0, 1 },
184    {   0,   0,   0, 1 },
185    {   0,   0,   0, 1 },
186    {   0,   0,   0, 1 },
187    {   0,   0,   0, 1 },
188    {   0,   0,   0, 1 },
189    {   0,   0,   0, 1 },
190    {   0,   0,   0, 1 },
191    {   0,   0,   0, 1 },
192    {   0,   0,   0, 1 },
193    {   0,   0,   0, 1 },
194    {   0,   0,   0, 1 },
195    {   0,   0,   0, 1 },
196    {   0,   0,   0, 1 },
197    {   0,   0,   0, 1 },
198    {   0,   0,   0, 1 },
199    {   0,   0,   0, 1 },
200    {   0,   0,   0, 1 },
201    {   0,   0,   0, 1 },
202    {   0,   0,   0, 1 },
203    {   0,   0,   0, 1 },
204    {   0,   0,   0, 1 },
205    {   0,   0,   0, 1 },
206    {   0,   0,   0, 1 },
207    {   0,   0,   0, 1 },
208    {   0,   0,   0, 1 },
209    {   0,   0,   0, 1 },
210    {   0,   0,   0, 1 },
211    {   0,   0,   0, 1 },
212    {   0,   0,   0, 1 },
213    {   0,   0,   0, 1 },
214    {   0,   0,   0, 1 },
215    {   0,   0,   0, 1 },
216    {   0,   0,   0, 1 },
217    {   0,   0,   0, 1 },
218    {   0,   0,   0, 1 },
219    {   0,   0,   0, 1 },
220    {   0,   0,   0, 1 },
221    {   0,   0,   0, 1 },
222    {   0,   0,   0, 1 },
223    {   0,   0,   0, 1 },
224    {   0,   0,   0, 1 },
225    {   0,   0,   0, 1 },
226    {   0,   0,   0, 1 },
227    {   0,   0,   0, 1 },
228    {   0,   0,   0, 1 },
229    {   0,   0,   0, 1 },
230    {   0,   0,   0, 1 },
231    {   0,   0,   0, 1 },
232    {   0,   0,   0, 1 },
233    {   0,   0,   0, 1 },
234    {   0,   0,   0, 1 },
235    {   0,   0,   0, 1 },
236    {   0,   0,   0, 1 },
237    {   0,   0,   0, 1 },
238    {   0,   0,   0, 1 },
239    {   0,   0,   0, 1 },
240    {   0,   0,   0, 1 },
241    {   0,   0,   0, 1 },
242    {   0,   0,   0, 1 },
243    {   0,   0,   0, 1 },
244    {   0,   0,   0, 1 },
245    {   0,   0,   0, 1 },
246    {   0,   0,   0, 1 },
247    {   0,   0,   0, 1 },
248    {   0,   0,   0, 1 },
249    {   0,   0,   0, 1 },
250    {   0,   0,   0, 1 },
251    {   0,   0,   0, 1 },
252    {   0,   0,   0, 1 },
253    {   0,   0,   0, 1 },
254    {   0,   0,   0, 1 },
255    {   0,   0,   0, 1 },
256    {   0,   0,   0, 1 },
257    {   0,   0,   0, 1 },
258    {   0,   0,   0, 1 },
259    {   0,   0,   0, 1 },
260    {   0,   0,   0, 1 },
261    {   0,   0,   0, 1 },
262    {   0,   0,   0, 1 },
263    {   0,   0,   0, 1 },
264    {   0,   0,   0, 1 },
265    {   0,   0,   0, 1 },
266    {   0,   0,   0, 1 },
267    {   0,   0,   0, 1 },
268    {   0,   0,   0, 1 },
269    {   0,   0,   0, 1 },
270    {   0,   0,   0, 1 },
271    {   0,   0,   0, 1 },
272    {   0,   0,   0, 1 },
273    {   0,   0,   0, 1 },
274    {   0,   0,   0, 1 },
275    {   0,   0,   0, 1 },
276    {   0,   0,   0, 1 },
277    {   0,   0,   0, 1 },
278    {   0,   0,   0, 1 },
279    {   0,   0,   0, 1 },
280    {   0,   0,   0, 1 },
281    {   0,   0,   0, 1 },
282    {   0,   0,   0, 1 },
283    {   0,   0,   0, 1 },
284    {   0,   0,   0, 1 },
285    {   0,   0,   0, 1 },
286    {   0,   0,   0, 1 },
287    {   0,   0,   0, 1 },
288    {   0,   0,   0, 1 },
289    {   0,   0,   0, 1 },
290    {   0,   0,   0, 1 },
291    {   0,   0,   0, 1 },
292    {   0,   0,   0, 1 },
293    {   0,   0,   0, 1 },
294    {   0,   0,   0, 1 },
295    {   0,   0,   0, 1 },
296    {   0,   0,   0, 1 },
297    {   0,   0,   0, 1 },
298    {   0,   0,   0, 1 },
299    {   0,   0,   0, 1 },
300    {   0,   0,   0, 1 },
301    {   0,   0,   0, 1 },
302    {   0,   0,   0, 1 },
303    {   0,   0,   0, 1 },
304    {   0,   0,   0, 1 },
305    {   0,   0,   0, 1 },
306    {   0,   0,   0, 1 },
307    {   0,   0,   0, 1 },
308    {   0,   0,   0, 1 },
309    {   0,   0,   0, 1 },
310    {   0,   0,   0, 1 },
311    {   0,   0,   0, 1 },
312    {   0,   0,   0, 1 },
313    {   0,   0,   0, 1 },
314    {   0,   0,   0, 1 },
315    {   0,   0,   0, 1 },
316    {   0,   0,   0, 1 },
317    {   0,   0,   0, 1 },
318    {   0,   0,   0, 1 },
319    {   0,   0,   0, 1 },
320    {   0,   0,   0, 1 },
321    {   0,   0,   0, 1 },
322    {   0,   0,   0, 1 },
323    {   0,   0,   0, 1 },
324    {   0,   0,   0, 1 },
325    {   0,   0,   0, 1 },
326    {   0,   0,   0, 1 },
327    {   0,   0,   0, 1 },
328    {   0,   0,   0, 1 },
329    {   0,   0,   0, 1 },
330    {   0,   0,   0, 1 },
331    {   0,   0,   0, 1 },
332    {   0,   0,   0, 1 },
333    {   0,   0,   0, 1 },
334    {   0,   0,   0, 1 },
335    {   0,   0,   0, 1 },
336    {   0,   0,   0, 1 },
337    {   0,   0,   0, 1 },
338    {   0,   0,   0, 1 },
339    {   0,   0,   0, 1 },
340    {   0,   0,   0, 1 },
341    {   0,   0,   0, 1 },
342    {   0,   0,   0, 1 },
343    {   0,   0,   0, 1 },
344    {   0,   0,   0, 1 },
345    {   0,   0,   0, 1 },
346    {   0,   0,   0, 1 },
347    {   0,   0,   0, 1 },
348    {   0,   0,   0, 1 },
349    {   0,   0,   0, 1 },
350    {   0,   0,   0, 1 },
351    {   0,   0,   0, 1 },
352    {   0,   0,   0, 1 },
353    {   0,   0,   0, 1 },
354    {   0,   0,   0, 1 },
355    {   0,   0,   0, 1 },
356    {   0,   0,   0, 1 },
357    {   0,   0,   0, 1 },
358    {   0,   0,   0, 1 }
359  };
360
361/*
362%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
363%                                                                             %
364%                                                                             %
365%                                                                             %
366%   I s P E S                                                                 %
367%                                                                             %
368%                                                                             %
369%                                                                             %
370%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
371%
372%  IsPES() returns MagickTrue if the image format type, identified by the
373%  magick string, is PES.
374%
375%  The format of the IsPES method is:
376%
377%      MagickBooleanType IsPES(const unsigned char *magick,const size_t length)
378%
379%  A description of each parameter follows:
380%
381%    o magick: compare image format pattern against these bytes.
382%
383%    o length: Specifies the length of the magick string.
384%
385*/
386static MagickBooleanType IsPES(const unsigned char *magick,const size_t length)
387{
388  if (length < 4)
389    return(MagickFalse);
390  if (LocaleNCompare((const char *) magick,"#PES",4) == 0)
391    return(MagickTrue);
392  return(MagickFalse);
393}
394
395/*
396%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
397%                                                                             %
398%                                                                             %
399%                                                                             %
400%   R e a d P E S I m a g e                                                   %
401%                                                                             %
402%                                                                             %
403%                                                                             %
404%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
405%
406%  ReadPESImage() reads a Brother PES image file and returns it.  It allocates
407%  the memory necessary for the new Image structure and returns a pointer to
408%  the new image.
409%
410%  The format of the ReadPESImage method is:
411%
412%      image=ReadPESImage(image_info)
413%
414%  A description of each parameter follows:
415%
416%    o image_info: the image info.
417%
418%    o exception: return any errors or warnings in this structure.
419%
420*/
421static Image *ReadPESImage(const ImageInfo *image_info,ExceptionInfo *exception)
422{
423  char
424    filename[MagickPathExtent];
425
426  FILE
427    *file;
428
429  Image
430    *image;
431
432  ImageInfo
433    *read_info;
434
435  int
436    delta_x,
437    delta_y,
438    j,
439    unique_file,
440    x,
441    y;
442
443  MagickBooleanType
444    status;
445
446  PESBlockInfo
447    blocks[256];
448
449  PointInfo
450    *stitches;
451
452  SegmentInfo
453    bounds;
454
455  register ssize_t
456    i;
457
458  size_t
459    number_blocks,
460    number_colors,
461    number_stitches;
462
463  ssize_t
464    count,
465    offset;
466
467  unsigned char
468    magick[4],
469    version[4];
470
471  /*
472    Open image file.
473  */
474  assert(image_info != (const ImageInfo *) NULL);
475  assert(image_info->signature == MagickCoreSignature);
476  if (image_info->debug != MagickFalse)
477    (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
478      image_info->filename);
479  assert(exception != (ExceptionInfo *) NULL);
480  assert(exception->signature == MagickCoreSignature);
481  image=AcquireImage(image_info,exception);
482  status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
483  if (status == MagickFalse)
484    {
485      image=DestroyImageList(image);
486      return((Image *) NULL);
487    }
488  /*
489    Verify PES identifier.
490  */
491  count=ReadBlob(image,4,magick);
492  if ((count != 4) || (LocaleNCompare((char *) magick,"#PES",4) != 0))
493    ThrowReaderException(CorruptImageError,"ImproperImageHeader");
494  count=ReadBlob(image,4,version);
495  offset=ReadBlobLSBSignedLong(image);
496  if (DiscardBlobBytes(image,offset+36) == MagickFalse)
497    ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
498      image->filename);
499  if (EOFBlob(image) != MagickFalse)
500    ThrowReaderException(CorruptImageError,"UnexpectedEndOfFile");
501  /*
502    Get PES colors.
503  */
504  number_colors=(size_t) ReadBlobByte(image)+1;
505  for (i=0; i < (ssize_t) number_colors; i++)
506  {
507    j=ReadBlobByte(image);
508    blocks[i].color=PESColor+(j < 0 ? 0 : j);
509    blocks[i].offset=0;
510  }
511  for ( ; i < 256L; i++)
512  {
513    blocks[i].offset=0;
514    blocks[i].color=PESColor;
515  }
516  if (DiscardBlobBytes(image,532L-number_colors-21) == MagickFalse)
517    ThrowFileException(exception,CorruptImageError,"UnexpectedEndOfFile",
518      image->filename);
519  if (EOFBlob(image) != MagickFalse)
520    ThrowReaderException(CorruptImageError,"UnexpectedEndOfFile");
521  /*
522    Stitch away.
523  */
524  number_stitches=64;
525  stitches=(PointInfo *) AcquireQuantumMemory(number_stitches,
526    sizeof(*stitches));
527  if (stitches == (PointInfo *) NULL)
528    ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
529  bounds.x1=65535.0;
530  bounds.y1=65535.0;
531  bounds.x2=(-65535.0);
532  bounds.y2=(-65535.0);
533  i=0;
534  j=0;
535  delta_x=0;
536  delta_y=0;
537  while (EOFBlob(image) != EOF)
538  {
539    x=ReadBlobByte(image);
540    y=ReadBlobByte(image);
541    if ((x == 0xff) && (y == 0))
542      break;
543    if ((x == 254) && (y == 176))
544      {
545        /*
546          Start a new stitch block.
547        */
548        j++;
549        blocks[j].offset=(ssize_t) i;
550        if (j >= 256)
551          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
552        (void) ReadBlobByte(image);
553        continue;
554      }
555    if ((x & 0x80) == 0)
556      {
557        /*
558          Normal stitch.
559        */
560        if ((x & 0x40) != 0)
561          x-=0x80;
562      }
563    else
564      {
565        /*
566          Jump stitch.
567        */
568        x=((x & 0x0f) << 8)+y;
569        if ((x & 0x800) != 0)
570          x-=0x1000;
571        y=ReadBlobByte(image);
572      }
573    if ((y & 0x80) == 0)
574      {
575        /*
576          Normal stitch.
577        */
578        if ((y & 0x40) != 0)
579          y-=0x80;
580      }
581    else
582      {
583        /*
584          Jump stitch.
585        */
586        y=((y & 0x0f) << 8)+ReadBlobByte(image);
587        if ((y & 0x800) != 0)
588          y-=0x1000;
589      }
590    /*
591      Note stitch (x,y).
592    */
593    x+=delta_x;
594    y+=delta_y;
595    delta_x=x;
596    delta_y=y;
597    stitches[i].x=(double) x;
598    stitches[i].y=(double) y;
599    if ((double) x < bounds.x1)
600      bounds.x1=(double) x;
601    if ((double) x > bounds.x2)
602      bounds.x2=(double) x;
603    if ((double) y < bounds.y1)
604      bounds.y1=(double) y;
605    if ((double) y > bounds.y2)
606      bounds.y2=(double) y;
607    i++;
608    if (i >= (ssize_t) number_stitches)
609      {
610        /*
611          Make room for more stitches.
612        */
613        number_stitches<<=1;
614        stitches=(PointInfo *)  ResizeQuantumMemory(stitches,(size_t)
615          number_stitches,sizeof(*stitches));
616        if (stitches == (PointInfo *) NULL)
617          ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed");
618     }
619  }
620  j++;
621  blocks[j].offset=(ssize_t) i;
622  number_blocks=(size_t) j;
623  /*
624    Write stitches as SVG file.
625  */
626  file=(FILE *) NULL;
627  unique_file=AcquireUniqueFileResource(filename);
628  if (unique_file != -1)
629    file=fdopen(unique_file,"wb");
630  if ((unique_file == -1) || (file == (FILE *) NULL))
631    ThrowImageException(FileOpenError,"UnableToCreateTemporaryFile");
632  (void) FormatLocaleFile(file,"<?xml version=\"1.0\"?>\n");
633  (void) FormatLocaleFile(file,"<svg xmlns=\"http://www.w3.org/2000/svg\" "
634    "xlink=\"http://www.w3.org/1999/xlink\" "
635    "ev=\"http://www.w3.org/2001/xml-events\" version=\"1.1\" "
636    "baseProfile=\"full\" width=\"%g\" height=\"%g\">\n",bounds.x2-bounds.x1,
637    bounds.y2-bounds.y1);
638  for (i=0; i < (ssize_t) number_blocks; i++)
639  {
640    offset=blocks[i].offset;
641    (void) FormatLocaleFile(file,"  <path stroke=\"#%02x%02x%02x\" "
642      "fill=\"none\" d=\"M %g %g",blocks[i].color->red,blocks[i].color->green,
643      blocks[i].color->blue,stitches[offset].x-bounds.x1,
644      stitches[offset].y-bounds.y1);
645    for (j=1; j < (ssize_t) (blocks[i+1].offset-offset); j++)
646      (void) FormatLocaleFile(file," L %g %g",stitches[offset+j].x-bounds.x1,
647        stitches[offset+j].y-bounds.y1);
648    (void) FormatLocaleFile(file,"\"/>\n");
649  }
650  (void) FormatLocaleFile(file,"</svg>\n");
651  (void) fclose(file);
652  (void) CloseBlob(image);
653  image=DestroyImage(image);
654  /*
655    Read SVG file.
656  */
657  read_info=CloneImageInfo(image_info);
658  SetImageInfoBlob(read_info,(void *) NULL,0);
659  (void) FormatLocaleString(read_info->filename,MagickPathExtent,"svg:%s",
660    filename);
661  image=ReadImage(read_info,exception);
662  if (image != (Image *) NULL)
663    {
664      (void) CopyMagickString(image->filename,image_info->filename,
665        MagickPathExtent);
666      (void) CopyMagickString(image->magick_filename,image_info->filename,
667        MagickPathExtent);
668      (void) CopyMagickString(image->magick,"PES",MagickPathExtent);
669    }
670  read_info=DestroyImageInfo(read_info);
671  (void) RelinquishUniqueFileResource(filename);
672  return(GetFirstImageInList(image));
673}
674
675/*
676%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
677%                                                                             %
678%                                                                             %
679%                                                                             %
680%   R e g i s t e r P E S I m a g e                                           %
681%                                                                             %
682%                                                                             %
683%                                                                             %
684%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
685%
686%  RegisterPESImage() adds attributes for the PES image format to
687%  the list of supported formats.  The attributes include the image format
688%  tag, a method to read and/or write the format, whether the format
689%  supports the saving of more than one frame to the same file or blob,
690%  whether the format supports native in-memory I/O, and a brief
691%  description of the format.
692%
693%  The format of the RegisterPESImage method is:
694%
695%      size_t RegisterPESImage(void)
696%
697*/
698ModuleExport size_t RegisterPESImage(void)
699{
700  MagickInfo
701    *entry;
702
703  entry=AcquireMagickInfo("PES","PES","Embrid Embroidery Format");
704  entry->decoder=(DecodeImageHandler *) ReadPESImage;
705  entry->magick=(IsImageFormatHandler *) IsPES;
706  (void) RegisterMagickInfo(entry);
707  return(MagickImageCoderSignature);
708}
709
710/*
711%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
712%                                                                             %
713%                                                                             %
714%                                                                             %
715%   U n r e g i s t e r P E S I m a g e                                       %
716%                                                                             %
717%                                                                             %
718%                                                                             %
719%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
720%
721%  UnregisterPESImage() removes format registrations made by the
722%  PES module from the list of supported formats.
723%
724%  The format of the UnregisterPESImage method is:
725%
726%      UnregisterPESImage(void)
727%
728*/
729ModuleExport void UnregisterPESImage(void)
730{
731  (void) UnregisterMagickInfo("PES");
732}
733