From: cristy Date: Mon, 25 Jan 2010 01:44:27 +0000 (+0000) Subject: (no commit message) X-Git-Tag: 7.0.1-0~10060 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=85256d123fadd574aa9c4db6af1e1b2f392a25c0;p=imagemagick --- diff --git a/coders/pes.c b/coders/pes.c index c09d3fb68..20a3701a2 100644 --- a/coders/pes.c +++ b/coders/pes.c @@ -33,7 +33,7 @@ % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % -% The PES coders is derived from Robert Heel's PHP script (see +% The PES format was derived from Robert Heel's PHP script (see % http://bobosch.dyndns.org/embroidery/showFile.php?pes.php) and pesconvert % (see http://torvalds-family.blogspot.com/2010/01/embroidery-gaah.html). % @@ -69,26 +69,38 @@ #include "magick/static.h" #include "magick/string_.h" #include "magick/module.h" +#include "magick/resource_.h" #include "magick/transform.h" #include "magick/utility.h" /* - PES Colors. + Typedef declarations. */ - typedef struct _PESColorInfo { - unsigned char + const unsigned char red, green, blue, alpha; } PESColorInfo; +typedef struct _PESBlockInfo +{ + const PESColorInfo + *color; + + ssize_t + offset; +} PESBlockInfo; + +/* + PES Colors. +*/ static const PESColorInfo PESColor[256] = { - { 0, 0, 0, 0 }, + { 0, 0, 0, 1 }, { 14, 31, 124, 1 }, { 10, 85, 163, 1 }, { 48, 135, 119, 1 }, @@ -152,7 +164,198 @@ static const PESColorInfo { 227, 243, 91, 1 }, { 255, 200, 100, 1 }, { 255, 200, 150, 1 }, - { 255, 200, 200, 1 } + { 255, 200, 200, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 }, + { 0, 0, 0, 1 } }; /* @@ -217,30 +420,53 @@ static MagickBooleanType IsPES(const unsigned char *magick,const size_t length) */ static Image *ReadPESImage(const ImageInfo *image_info,ExceptionInfo *exception) { + char + filename[MaxTextExtent]; + + FILE + *file; + Image *image; + ImageInfo + *read_info; + + int + delta_x, + delta_y, + j, + unique_file, + x, + y; + MagickBooleanType status; - PESColorInfo - colors[256]; + PESBlockInfo + blocks[256]; + + PointInfo + *stitches; + + SegmentInfo + bounds; register long i; ssize_t - count; - - size_t - length; + count, + offset; unsigned char magick[4], version[4]; unsigned long - number_colors; + number_blocks, + number_colors, + number_stitches; /* Open image file. @@ -266,8 +492,8 @@ static Image *ReadPESImage(const ImageInfo *image_info,ExceptionInfo *exception) if ((count != 4) || (LocaleNCompare((char *) magick,"#PES",4) != 0)) ThrowReaderException(CorruptImageError,"ImproperImageHeader"); count=ReadBlob(image,4,version); - length=(size_t) ReadBlobLSBLong(image); - for (i=0; i < 37; i++) + offset=(ssize_t) ReadBlobLSBLong(image); + for (i=0; i < (offset+36); i++) if (ReadBlobByte(image) == EOF) break; if (EOFBlob(image) != MagickFalse) @@ -275,14 +501,171 @@ static Image *ReadPESImage(const ImageInfo *image_info,ExceptionInfo *exception) /* Get PES colors. */ - number_colors=ReadBlobByte(image)+1; + number_colors=(unsigned long) ReadBlobByte(image)+1; for (i=0; i < (long) number_colors; i++) - colors[i]=PESColor[ReadBlobByte(image)]; - for (i=0; i < (532L-number_colors-49L); i++) + { + j=(int) ReadBlobByte(image); + blocks[i].color=PESColor+j; + blocks[i].offset=0; + } + for ( ; i < 256L; i++) + blocks[i].offset=0; + for (i=0; i < (long) (532L-number_colors-21); i++) if (ReadBlobByte(image) == EOF) break; if (EOFBlob(image) != MagickFalse) ThrowReaderException(CorruptImageError,"UnexpectedEndOfFile"); + /* + Stitch away. + */ + number_stitches=64; + stitches=(PointInfo *) AcquireQuantumMemory(number_stitches, + sizeof(*stitches)); + if (stitches == (PointInfo *) NULL) + ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); + bounds.x1=65535.0; + bounds.y1=65535.0; + bounds.x2=(-65535.0); + bounds.y2=(-65535.0); + i=0; + j=0; + delta_x=0; + delta_y=0; + while (EOFBlob(image) != EOF) + { + x=(int) ReadBlobByte(image); + y=(int) ReadBlobByte(image); + if ((x == 0xff) && (y == 0)) + break; + if ((x == 254) && (y == 176)) + { + /* + Start a new stitch block. + */ + j++; + blocks[j].offset=(ssize_t) i; + if (j >= 256) + ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); + (void) ReadBlobByte(image); + continue; + } + if ((x & 0x80) == 0) + { + /* + Normal stitch. + */ + if ((x & 0x40) != 0) + x-=0x80; + } + else + { + /* + Jump stitch. + */ + x=((x & 0x0f) << 8)+y; + if ((x & 0x800) != 0) + x-=0x1000; + y=ReadBlobByte(image); + } + if ((y & 0x80) == 0) + { + /* + Normal stitch. + */ + if ((y & 0x40) != 0) + y-=0x80; + } + else + { + /* + Jump stitch. + */ + y=((y & 0x0f) << 8)+ReadBlobByte(image); + if ((y & 0x800) != 0) + y-=0x1000; + } + /* + Note stitch (x,y). + */ + x+=delta_x; + y+=delta_y; + delta_x=x; + delta_y=y; + stitches[i].x=(double) x; + stitches[i].y=(double) y; + if ((double) x < bounds.x1) + bounds.x1=(double) x; + if ((double) x > bounds.x2) + bounds.x2=(double) x; + if ((double) y < bounds.y1) + bounds.y1=(double) y; + if ((double) y > bounds.y2) + bounds.y2=(double) y; + i++; + if (i >= (long) number_stitches) + { + /* + Make room for more stitches. + */ + number_stitches<<=1; + stitches=(PointInfo *) ResizeQuantumMemory(stitches,(size_t) + number_stitches,sizeof(*stitches)); + if (stitches == (PointInfo *) NULL) + ThrowReaderException(ResourceLimitError,"MemoryAllocationFailed"); + } + } + j++; + blocks[j].offset=(ssize_t) i; + number_blocks=(unsigned long) j; + /* + Write stitches as SVG file. + */ + file=(FILE *) NULL; + unique_file=AcquireUniqueFileResource(filename); + if (unique_file != -1) + file=fdopen(unique_file,"wb"); + if ((unique_file == -1) || (file == (FILE *) NULL)) + ThrowImageException(FileOpenError,"UnableToCreateTemporaryFile"); + (void) fprintf(file,"\n"); + (void) fprintf(file,"\n",bounds.x2-bounds.x1, + bounds.y2-bounds.y1); + for (i=0; i < (long) number_blocks; i++) + { + offset=blocks[i].offset; + (void) fprintf(file," red,blocks[i].color->green, + blocks[i].color->blue,stitches[offset].x-bounds.x1, + stitches[offset].y-bounds.y1); + for (j=1; j < (long) (blocks[i+1].offset-offset); j++) + (void) fprintf(file," L %g %g",stitches[offset+j].x-bounds.x1, + stitches[offset+j].y-bounds.y1); + (void) fprintf(file,"\"/>\n"); + } + (void) fprintf(file,"\n"); + (void) fclose(file); + (void) CloseBlob(image); + image=DestroyImage(image); + /* + Read SVG file. + */ + read_info=CloneImageInfo(image_info); + SetImageInfoBlob(read_info,(void *) NULL,0); + (void) FormatMagickString(read_info->filename,MaxTextExtent,"svg:%.1024s", + filename); + image=ReadImage(read_info,exception); + if (image != (Image *) NULL) + { + (void) CopyMagickString(image->filename,image_info->filename, + MaxTextExtent); + (void) CopyMagickString(image->magick_filename,image_info->filename, + MaxTextExtent); + (void) CopyMagickString(image->magick,"PES",MaxTextExtent); + } + read_info=DestroyImageInfo(read_info); + (void) RelinquishUniqueFileResource(filename); return(GetFirstImageInList(image)); }