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