Libembroidery

The Low Level API: Libembroidery 1.0.0-alpha

API Reference

convert

(Under construction, please wait for v1.0 release.)

Libembroidery is a low-level library for reading, writing, and altering digital embroidery files in C. It is part of the Embroidermodder Project for open source machine embroidery.

Libembroidery is the underlying library that is used by Embroidermodder 2 and is developed by The Embroidermodder Team %ref{the-embroidermodder-team}. A full list of contributors to the project is maintained in the Embroidermodder 2 github (https://github.com/Embroidermodder/embroidermodder) in the file CREDITS.md. It handles over 45 different embroidery specific formats as well as several non-embroidery specific vector formats.

It also includes a CLI called embroider that allows for better automation of changes to embroidery files and will be more up-to date than the Embroidermodder 2 GUI.

Build Script

Documentation

Libembroidery is documented as part of this reference manual. If you need libembroidery for any non-trivial usage or want to contribute to the library we advise you read the appropriate design sections of the manual first. Copies of this manual will be shipped with the packaged version of libembroidery, but to build it we use the Doxyfile in url{https://github.com/Embroidermodder/embroidermodder} the Embroidermodder git repository.

For more basic usage, embroider should have some in-built help starting with:

$ embroider –help

License

Libembroidery is distributed under the permissive zlib licence, see the LICENCE file.

Demos

We’re currently trying out some fill techniques which will be demonstrated here and in the script texttt{qa_test.sh}.

Converts to:

Build

libembroidery and EmbroiderModder 2 use CMake builds so if you are building the project to use as a library we recommend you run:

#!/bin/bash

pacman -S gcc cmake git bash mingw-w64-SDL2

mingw-w64-SDL2_image mingw-w64-SDL2_ttf

git clone https://github.com/Embroidermodder/Embroidermodder cd Embroidermodder bash build.sh

This builds both the static and shared versions of the library as well as the command line program embroider.

citep{packard1992pcl} citep{linuxcncsrc} citep{linuxcnc} citep{adobe1990postscript} citep{postscript1999postscript} citep{eduTechDST} citep{cups} citep{millOperatorsManual} citep{oberg1914machinery} citep{dxf_reference} citep{embroidermodder_source_code} citep{libembroidery_source_code} citep{acatina} citep{kde_tajima} citep{wotsit_archive} citep{wotsit_siterip} citep{fineemb_dst} citep{edutechwiki_dst}

Libembroidery API

A library for reading, writing, altering and otherwise processing machine embroidery files and designs. The functions in this section consistitute the external API: that is, the functions described in src/embroidery.h.

Also, the core library supporting the Embroidermodder Project’s family of machine embroidery interfaces.

Only uses source from this directory or standard C libraries, not including POSIX headers like unistd since this library needs to support non-POSIX systems like Windows.

The source code is stored in the src/ directory, the other versions are considered hand-translations of this version. For example, the embedded/ directory has assembly macros that imitate the behaviour of these functions and are documented in the Assembly Macros section.

Note that all new defines start with EMB_, all functions with emb and all typedefs with Emb to protect against namespace pollution. (INCOMPLETE)

Version flags

label

value

EMB_LIB_VERSION_MAJOR

1

EMB_LIB_VERSION_MINOR

0

EMB_LIB_VERSION_PATCH

0

EMB_LIB_VERSION_TAG

“alpha”

Machine codes for stitch flags.

These all represent distinct bits as some of them can be combined on some machines.

begin{center} csvreader[tabular=l l l,

table head=hlinemulticolumn{3}{c}{bfseries Machine Code Flags}\hline

bfseries Label & bfseries Description & bfseries Value\hlinehline,

late after line=\hline]% {data/machine_code_flags.csv}{label=name,description=description,value=value}{%

texttt{name} & description & value

} end{center}

Missing change color?

Format identifiers

begin{verbatim} #define EMB_FORMAT_100 0 #define EMB_FORMAT_10O 1 #define EMB_FORMAT_ART 2 #define EMB_FORMAT_BMC 3 #define EMB_FORMAT_BRO 4 #define EMB_FORMAT_CND 5 #define EMB_FORMAT_COL 6 #define EMB_FORMAT_CSD 7 #define EMB_FORMAT_CSV 8 #define EMB_FORMAT_DAT 9 #define EMB_FORMAT_DEM 10 #define EMB_FORMAT_DSB 11 #define EMB_FORMAT_DST 12 #define EMB_FORMAT_DSZ 13 #define EMB_FORMAT_DXF 14 #define EMB_FORMAT_EDR 15 #define EMB_FORMAT_EMD 16 #define EMB_FORMAT_EXP 17 #define EMB_FORMAT_EXY 18 #define EMB_FORMAT_EYS 19 #define EMB_FORMAT_FXY 20 #define EMB_FORMAT_GC 21 #define EMB_FORMAT_GNC 22 #define EMB_FORMAT_GT 23 #define EMB_FORMAT_HUS 24 #define EMB_FORMAT_INB 25 #define EMB_FORMAT_INF 26 #define EMB_FORMAT_JEF 27 #define EMB_FORMAT_KSM 28 #define EMB_FORMAT_MAX 29 #define EMB_FORMAT_MIT 30 #define EMB_FORMAT_NEW 31 #define EMB_FORMAT_OFM 32 #define EMB_FORMAT_PCD 33 #define EMB_FORMAT_PCM 34 #define EMB_FORMAT_PCQ 35 #define EMB_FORMAT_PCS 36 #define EMB_FORMAT_PEC 37 #define EMB_FORMAT_PEL 38 #define EMB_FORMAT_PEM 39 #define EMB_FORMAT_PES 40 #define EMB_FORMAT_PHB 41 #define EMB_FORMAT_PHC 42 #define EMB_FORMAT_PLT 43 #define EMB_FORMAT_RGB 44 #define EMB_FORMAT_SEW 45 #define EMB_FORMAT_SHV 46 #define EMB_FORMAT_SST 47 #define EMB_FORMAT_STX 48 #define EMB_FORMAT_SVG 49 #define EMB_FORMAT_T01 50 #define EMB_FORMAT_T09 51 #define EMB_FORMAT_TAP 52 #define EMB_FORMAT_THR 53 #define EMB_FORMAT_TXT 54 #define EMB_FORMAT_U00 55 #define EMB_FORMAT_U01 56 #define EMB_FORMAT_VIP 57 #define EMB_FORMAT_VP3 58 #define EMB_FORMAT_XXX 59 #define EMB_FORMAT_ZSK 60 end{verbatim}

EmbGeometry types, should include all of the possible rendering types for EmbroiderModder and internal types for stitch processing (like fills).

begin{verbatim} #define EMB_ARRAY 0 #define EMB_ARC 1 #define EMB_CIRCLE 2 #define EMB_DIM_DIAMETER 3 #define EMB_DIM_LEADER 4 #define EMB_ELLIPSE 5 #define EMB_FLAG 6 #define EMB_LINE 7 #define EMB_IMAGE 8 #define EMB_PATH 9 #define EMB_POINT 10 #define EMB_POLYGON 11 #define EMB_POLYLINE 12 #define EMB_RECT 13 #define EMB_SPLINE 14 #define EMB_STITCH 15 #define EMB_TEXT_SINGLE 16 #define EMB_TEXT_MULTI 17 #define EMB_VECTOR 18 #define EMB_THREAD 19

#define EMBFORMAT_UNSUPPORTED 0 #define EMBFORMAT_STITCHONLY 1 #define EMBFORMAT_OBJECTONLY 2 #define EMBFORMAT_STCHANDOBJ 3 /* binary operation: 1+2=3 */

#define numberOfFormats 61

#define CHUNK_SIZE 128

#define EMB_MAX_LAYERS 10 #define MAX_THREADS 256 #define MAX_STRING_LENGTH 200 #define EMBFORMAT_MAXEXT 3 /* maximum length of extension without dot / #define EMBFORMAT_MAXDESC 50 / the longest possible description string length */ #define MAX_STITCHES 1000000

/* Libembroidery’s handling of integer types.

*/

#define EMB_BIG_ENDIAN 0 #define EMB_LITTLE_ENDIAN 1

/* Most machines are little endian (including the developer’s), so default to
  • that.

*/

#define ENDIAN_HOST EMB_LITTLE_ENDIAN

#define EMB_INT16_BIG 2 #define EMB_INT16_LITTLE 3 #define EMB_INT32_BIG 4 #define EMB_INT32_LITTLE 5

/* Identifiers for different PES versions. */ #define PES0001 0 #define PES0020 1 #define PES0022 2 #define PES0030 3 #define PES0040 4 #define PES0050 5 #define PES0055 6 #define PES0056 7 #define PES0060 8 #define PES0070 9 #define PES0080 10 #define PES0090 11 #define PES0100 12 #define N_PES_VERSIONS 13

/**
  • Type of sector

  • Compound File Sector (CFS)

*/

#define CompoundFileSector_MaxRegSector 0xFFFFFFFA #define CompoundFileSector_DIFAT_Sector 0xFFFFFFFC #define CompoundFileSector_FAT_Sector 0xFFFFFFFD #define CompoundFileSector_EndOfChain 0xFFFFFFFE #define CompoundFileSector_FreeSector 0xFFFFFFFF

/**
  • Type of directory object

*/

#define ObjectTypeUnknown 0x00 /!< Probably unallocated */ #define ObjectTypeStorage 0x01 /!< a directory type object / #define ObjectTypeStream 0x02 /!< a file type object / #define ObjectTypeRootEntry 0x05 /!< the root entry */

/**
  • Special values for Stream Identifiers

*/

#define CompoundFileStreamId_MaxRegularStreamId 0xFFFFFFFA /!< All real stream Ids are less than this */ #define CompoundFileStreamId_NoStream 0xFFFFFFFF /!< There is no valid stream Id */

#define ELEMENT_XML 0 #define ELEMENT_A 1 #define ELEMENT_ANIMATE 2 #define ELEMENT_ANIMATECOLOR 3 #define ELEMENT_ANIMATEMOTION 4 #define ELEMENT_ANIMATETRANSFORM 5 #define ELEMENT_ANIMATION 6 #define ELEMENT_AUDIO 7 #define ELEMENT_CIRCLE 8 #define ELEMENT_DEFS 9 #define ELEMENT_DESC 10 #define ELEMENT_DISCARD 11 #define ELEMENT_ELLIPSE 12 #define ELEMENT_FONT 13 #define ELEMENT_FONT_FACE 14 #define ELEMENT_FONT_FACE_SRC 15 #define ELEMENT_FONT_FACE_URI 16 #define ELEMENT_FOREIGN_OBJECT 17 #define ELEMENT_G 18 #define ELEMENT_GLYPH 19 #define ELEMENT_HANDLER 20 #define ELEMENT_HKERN 21 #define ELEMENT_IMAGE 22 #define ELEMENT_LINE 23 #define ELEMENT_LINEAR_GRADIENT 24 #define ELEMENT_LISTENER 25 #define ELEMENT_METADATA 26 #define ELEMENT_MISSING_GLYPH 27 #define ELEMENT_MPATH 28 #define ELEMENT_PATH 29 #define ELEMENT_POLYGON 30 #define ELEMENT_POLYLINE 31 #define ELEMENT_PREFETCH 32 #define ELEMENT_RADIAL_GRADIENT 33 #define ELEMENT_RECT 34 #define ELEMENT_SCRIPT 35 #define ELEMENT_SET 36 #define ELEMENT_SOLID_COLOR 37 #define ELEMENT_STOP 38 #define ELEMENT_SVG 39 #define ELEMENT_SWITCH 40 #define ELEMENT_TBREAK 41 #define ELEMENT_TEXT 42 #define ELEMENT_TEXT_AREA 43 #define ELEMENT_TITLE 44 #define ELEMENT_TSPAN 45 #define ELEMENT_USE 46 #define ELEMENT_VIDEO 47

#define HOOP_126X110 0 #define HOOP_110X110 1 #define HOOP_50X50 2 #define HOOP_140X200 3 #define HOOP_230X200 4

/* DXF Version Identifiers */ #define DXF_VERSION_R10 “AC1006” #define DXF_VERSION_R11 “AC1009” #define DXF_VERSION_R12 “AC1009” #define DXF_VERSION_R13 “AC1012” #define DXF_VERSION_R14 “AC1014” #define DXF_VERSION_R15 “AC1015” #define DXF_VERSION_R18 “AC1018” #define DXF_VERSION_R21 “AC1021” #define DXF_VERSION_R24 “AC1024” #define DXF_VERSION_R27 “AC1027”

#define DXF_VERSION_2000 “AC1015” #define DXF_VERSION_2002 “AC1015” #define DXF_VERSION_2004 “AC1018” #define DXF_VERSION_2006 “AC1018” #define DXF_VERSION_2007 “AC1021” #define DXF_VERSION_2009 “AC1021” #define DXF_VERSION_2010 “AC1024” #define DXF_VERSION_2013 “AC1027”

#define SVG_CREATOR_NULL 0 #define SVG_CREATOR_EMBROIDERMODDER 1 #define SVG_CREATOR_ILLUSTRATOR 2 #define SVG_CREATOR_INKSCAPE 3

#define SVG_EXPECT_NULL 0 #define SVG_EXPECT_ELEMENT 1 #define SVG_EXPECT_ATTRIBUTE 2 #define SVG_EXPECT_VALUE 3

/* SVG_TYPES

*/

#define SVG_NULL 0 #define SVG_ELEMENT 1 #define SVG_PROPERTY 2 #define SVG_MEDIA_PROPERTY 3 #define SVG_ATTRIBUTE 4 #define SVG_CATCH_ALL 5

/* path flag codes */ #define LINETO 0x000 #define MOVETO 0x001 #define BULGETOCONTROL 0x002 #define BULGETOEND 0x004 #define ELLIPSETORAD 0x008 #define ELLIPSETOEND 0x010 #define CUBICTOCONTROL1 0x020 #define CUBICTOCONTROL2 0x040 #define CUBICTOEND 0x080 #define QUADTOCONTROL 0x100 #define QUADTOEND 0x200

/* LANGUAGES */ #define LANG_SVG 0 #define LANG_PS 1 #define LANG_PROMPT 2

/* COMMANDS
  • These identifiers are subject to change since they are in alphabetical order

  • and the numbers are increasing.

  • Note that GUI-only commands are present here because this is for operations

  • available in all frontends.

  • The actuator uses

*/

#define EMB_CMD_ABOUT 0 #define EMB_CMD_ARC 1 #define EMB_CMD_CIRCLE 2 #define N_COMMANDS 3

/* Brand identifiers. */ #define EMB_BRAND_DXF 0 #define EMB_BRAND_HUS 1 #define EMB_BRAND_JEF 2 #define EMB_BRAND_SHV 3 #define EMB_BRAND_PCM 4 #define EMB_BRAND_PEC 5 #define EMB_BRAND_SVG 6

/* UTILITY MACROS

*/

#define EMB_MIN(A, B) (((A) < (B)) ? (A) : (B)) #define EMB_MAX(A, B) (((A) > (B)) ? (A) : (B))

/* COMPILATION SETTINGS

*/

#if defined(_WIN32) && !defined(WIN32) #define WIN32 #endif

/* When building a shared library, * use the proper export keyword depending on the compiler */ #define EMB_PUBLIC #if defined(LIBEMBROIDERY_SHARED)

#undef EMB_PUBLIC #if defined(__WIN32__) || defined(WIN32)

#define EMB_PUBLIC __declspec(dllexport)

#else

#define EMB_PUBLIC __attribute__ ((visibility(“default”)))

#endif

#endif end{verbatim}

subsection{Typedefs and Structs}

begin{verbatim} /* Should some platform need a different precision, this is typedef-ed

  • and used in place of all real types where possible.

*/

typedef float EmbReal;

/* EmbColor uses the light primaries: red, green, blue in that order. */ typedef struct EmbColor_ {

unsigned char r; unsigned char g; unsigned char b;

} EmbColor;

/* The basic type to represent points absolutely or represent directions.
  • Positive y is up, units are in mm.

*/

typedef struct EmbVector_ {

EmbReal x; EmbReal y;

} EmbVector;

/* . */ typedef struct EmbTime_ {

unsigned int year; unsigned int month; unsigned int day; unsigned int hour; unsigned int minute; unsigned int second;

} EmbTime;

/* For our internal string library.
  • Note that we cannot use this for any larger amount of data,

  • it’s to ensure that the cap on the size is fixed at 200.

*/

typedef char EmbString[200];

/* To help new developers understand why we use “void *”,
  • when it is widely not recommended within C++.

  • libembroidery is a low-level library: we need to do bit-level

  • and untyped calculations. Thinking “memory location” not

  • “untyped pointer” helped me (Robin).

*/

typedef void *EmbMem;

/* The basic array type. */ typedef struct EmbArray_ EmbArray;

/* double-indirection file allocation table references */ typedef struct _bcf_file_difat {

unsigned int fatSectorCount; unsigned int fatSectorEntries[109]; unsigned int sectorSize;

} bcf_file_difat;

/* . */ typedef struct _bcf_file_fat {

int fatEntryCount; unsigned int fatEntries[255]; /* maybe make this dynamic */ unsigned int numberOfEntriesInFatSector;

} bcf_file_fat;

/* . */ typedef struct _bcf_directory_entry {

char directoryEntryName[32]; unsigned short directoryEntryNameLength; unsigned char objectType; unsigned char colorFlag; unsigned int leftSiblingId; unsigned int rightSiblingId; unsigned int childId; unsigned char CLSID[16]; unsigned int stateBits; EmbTime creationTime; EmbTime modifiedTime; unsigned int startingSectorLocation; /* streamSize should be long long but in our case we shouldn’t need it,

  • and hard to support on c89 cross platform. */

unsigned long streamSize; /* Store the high int of streamsize. / unsigned int streamSizeHigh; struct _bcf_directory_entry next;

} bcf_directory_entry;

/* TODO: possibly add a directory tree in the future.

*/

typedef struct _bcf_directory {

bcf_directory_entry* dirEntries; unsigned int maxNumberOfDirectoryEntries;

} bcf_directory;

/* TODO: CLSID should be a separate type.

*/

typedef struct _bcf_file_header {

unsigned char signature[8]; unsigned char CLSID[16]; unsigned short minorVersion; unsigned short majorVersion; unsigned short byteOrder; unsigned short sectorShift; unsigned short miniSectorShift; unsigned short reserved1; unsigned int reserved2; unsigned int numberOfDirectorySectors; unsigned int numberOfFATSectors; unsigned int firstDirectorySectorLocation; unsigned int transactionSignatureNumber; unsigned int miniStreamCutoffSize; unsigned int firstMiniFATSectorLocation; unsigned int numberOfMiniFatSectors; unsigned int firstDifatSectorLocation; unsigned int numberOfDifatSectors;

} bcf_file_header;

/* . */ typedef struct _bcf_file {

bcf_file_header header; /! The header for the CompoundFile */ bcf_file_difat difat; /! The “Double Indirect FAT” for the CompoundFile */ bcf_file_fat fat; /! The File Allocation Table for the Compound File */ bcf_directory directory; /*! The directory for the CompoundFile */

} bcf_file;

/* . */ typedef struct _vp3Hoop {

int right; int bottom; int left; int top; int threadLength; char unknown2; unsigned char numberOfColors; unsigned short unknown3; int unknown4; int numberOfBytesRemaining;

int xOffset; int yOffset;

unsigned char byte1; unsigned char byte2; unsigned char byte3;

/* Centered hoop dimensions */ int right2; int left2; int bottom2; int top2;

int width; int height;

} vp3Hoop;

/* . / typedef struct ThredHeader_ / thred file header */ {

unsigned int sigVersion; /* signature and version / unsigned int length; / length of ThredHeader + length of stitch data / unsigned short numStiches; / number of stitches / unsigned short hoopSize; / size of hoop / unsigned short reserved[7]; / reserved for expansion */

} ThredHeader;

/* . / typedef struct ThredExtension_ / thred v1.0 file header extension */ {

float hoopX; /* hoop size x dimension in 1/6 mm units / float hoopY; / hoop size y dimension in 1/6 mm units / float stitchGranularity; / stitches per millimeter–not implemented / char creatorName[50]; / name of the file creator / char modifierName[50]; / name of last file modifier / char auxFormat; / auxiliary file format, 0=PCS,1=DST,2=PES / char reserved[31]; / reserved for expansion */

} ThredExtension;

/* . */ typedef struct SubDescriptor_ {

int someNum; /! todo better variable naming */ int someInt; /! todo better variable naming / int someOtherInt; /! todo better variable naming / char colorCode; char* colorName;

} SubDescriptor;

/* . */ typedef struct StxThread_ {

char* colorCode; char* colorName; char* sectionName; SubDescriptor* subDescriptors; EmbColor stxColor;

} StxThread;

/* . */ typedef struct VipHeader_ {

int magicCode; int numberOfStitches; int numberOfColors; short postitiveXHoopSize; short postitiveYHoopSize; short negativeXHoopSize; short negativeYHoopSize; int attributeOffset; int xOffset; int yOffset; unsigned char stringVal[8]; short unknown; int colorLength;

} VipHeader;

/* . */ typedef enum {

CSV_EXPECT_NULL, CSV_EXPECT_QUOTE1, CSV_EXPECT_QUOTE2, CSV_EXPECT_COMMA

} CSV_EXPECT;

/* . */ typedef enum {

CSV_MODE_NULL, CSV_MODE_COMMENT, CSV_MODE_VARIABLE, CSV_MODE_THREAD, CSV_MODE_STITCH

} CSV_MODE;

/* . */ typedef struct SvgAttribute_ {

char* name; char* value;

} SvgAttribute;

/* . */ typedef struct Huffman {

int default_value; int lengths[1000]; int nlengths; int table[1000]; int table_width; int ntable;

} huffman;

/* . */ typedef struct Compress {

int bit_position; char *input_data; int input_length; int bits_total; int block_elements; huffman character_length_huffman; huffman character_huffman; huffman distance_huffman;

} compress;

/* . */ typedef struct EmbImage_ {

EmbVector position; EmbVector dimensions; unsigned char* data; int width; int height; EmbString path; EmbString name;

} EmbImage;

/* . */ typedef struct EmbBlock_ {

EmbVector position;

} EmbBlock;

/* . */ typedef struct EmbAlignedDim_ {

EmbVector position;

} EmbAlignedDim;

/* . */ typedef struct EmbAngularDim_ {

EmbVector position;

} EmbAngularDim;

/* . */ typedef struct EmbArcLengthDim_ {

EmbVector position;

} EmbArcLengthDim;

/* . */ typedef struct EmbDiameterDim_ {

EmbVector position;

} EmbDiameterDim;

/* . */ typedef struct EmbLeaderDim_ {

EmbVector position;

} EmbLeaderDim;

/* . */ typedef struct EmbLinearDim_ {

EmbVector position;

} EmbLinearDim;

/* . */ typedef struct EmbOrdinateDim_ {

EmbVector position;

} EmbOrdinateDim;

/* . */ typedef struct EmbRadiusDim_ {

EmbVector position;

} EmbRadiusDim;

/* . */ typedef struct EmbInfiniteLine_ {

EmbVector position;

} EmbInfiniteLine;

/* . */ typedef struct EmbRay_ {

EmbVector position;

} EmbRay;

/* . */ typedef struct EmbTextMulti_ {

EmbVector position; EmbString text;

} EmbTextMulti;

/* . */ typedef struct EmbTextSingle_ {

EmbVector position; EmbString text;

} EmbTextSingle;

/* . */ typedef struct EmbPoint_ {

EmbVector position; int lineType; EmbColor color;

} EmbPoint;

/* . */ typedef struct EmbLine_ {

EmbVector start; EmbVector end; int lineType; EmbColor color;

} EmbLine;

/* . */ typedef struct EmbPath_ {

EmbArray* pointList; EmbArray* flagList; int lineType; EmbColor color;

} EmbPath;

/* . */ typedef struct EmbStitch_ {

int flags; /! uses codes defined above */ EmbReal x; /! absolute position (not relative) / EmbReal y; /! positive is up, units are in mm / int color; /! color number for this stitch / /! todo this should be called colorIndex since it is not an EmbColor */

} EmbStitch;

/* . */ typedef struct EmbThread_ {

EmbColor color; EmbString description; EmbString catalogNumber;

} EmbThread;

/* . */ typedef struct thread_color_ {

EmbString name; unsigned int hex_code; int manufacturer_code;

} thread_color;

/* absolute position (not relative) */ typedef struct EmbArc_ {

EmbVector start; EmbVector mid; EmbVector end;

} EmbArc;

/* . */ typedef struct EmbRect_ {

EmbReal x; EmbReal y; EmbReal w; EmbReal h; EmbReal rotation; EmbReal radius;

} EmbRect;

/* . */ typedef struct EmbCircle_ {

EmbVector center; EmbReal radius;

} EmbCircle;

/* . */ typedef EmbPath EmbPolygon;

/* . */ typedef EmbPath EmbPolyline;

/* . */ typedef int EmbFlag;

/* . */ typedef struct EmbSatinOutline_ {

int length; EmbArray* side1; EmbArray* side2;

} EmbSatinOutline;

/* . */ typedef struct EmbEllipse_ {

EmbVector center; EmbVector radius; EmbReal rotation;

} EmbEllipse;

/* . */ typedef struct EmbBezier_ {

EmbVector start; EmbVector control1; EmbVector control2; EmbVector end;

} EmbBezier;

/* . */ typedef struct EmbSpline_ {

EmbArray *beziers;

} EmbSpline;

/* . */ typedef struct LSYSTEM {

char axiom; char *alphabet; char *constants; char **rules;

} L_system;

/* . */ typedef struct EmbGeometry_ {

union {

EmbArc arc; EmbCircle circle; EmbColor color; EmbEllipse ellipse; EmbLine line; EmbPath path; EmbPoint point; EmbPolygon polygon; EmbPolyline polyline; EmbRect rect; EmbSpline spline; EmbVector vector;

} object; int flag; int type; int lineType; EmbColor color;

} EmbGeometry;

/* . */ struct EmbArray_ {

EmbGeometry *geometry; EmbStitch *stitch; EmbThread *thread; int count; int length; int type;

};

/* . */ typedef struct EmbLayer_ {

char name[100]; EmbArray *geometry;

} EmbLayer;

/* . */ typedef struct EmbPattern_ {

unsigned int dstJumpsPerTrim; EmbVector home; EmbReal hoop_width; EmbReal hoop_height; EmbArray *thread_list; EmbArray *stitch_list; EmbArray *geometry; EmbLayer layer[EMB_MAX_LAYERS]; int currentColorIndex;

} EmbPattern;

/* . */ typedef struct EmbFormatList_ {

EmbString extension; EmbString description; char reader_state; char writer_state; int type; int color_only; int check_for_color_file; int write_external_color_file;

} EmbFormatList;

/* Thread colors that are subject to change are loaded at runtime,
  • allowing us to update them as they change.

  • However, in-builts that use indicies like the DXF, SVG or HUS

  • tables are compiled in. This should help with embedded compatibility

  • in both cases.

*/

typedef struct BRAND {

thread_color *codes; int length; EmbString label;

} EmbBrand;

typedef struct EmbStackElement_ {

int data_type; int attribute; int i; float r; char s[100];

} EmbStackElement;

/* This uses about 100kb per instance because it’s not dynamic. */ typedef struct EmbStack_ {

EmbStackElement stack[1000]; int position;

} EmbStack;

/* Function Declarations *************************************************************************/ EMB_PUBLIC int lindenmayer_system(L_system L, char* state, int iteration, int complete); EMB_PUBLIC int hilbert_curve(EmbPattern *pattern, int iterations);

EMB_PUBLIC int emb_identify_format(const char *ending); EMB_PUBLIC int convert(const char *inf, const char *outf);

EMB_PUBLIC EmbVector emb_vector(EmbReal x, EmbReal y);

EMB_PUBLIC void emb_processor(char *state, const char *program, int program_length); EMB_PUBLIC int emb_compiler(const char *program, int language, char *compiled_program); EMB_PUBLIC void emb_actuator(const char *program, int language);

EMB_PUBLIC EmbColor embColor_make(unsigned char r, unsigned char g, unsigned char b); EMB_PUBLIC EmbColor embColor_fromHexStr(char* val); EMB_PUBLIC int embColor_distance(EmbColor a, EmbColor b);

EMB_PUBLIC EmbArray* emb_array_create(int type); EMB_PUBLIC int emb_array_resize(EmbArray g); EMB_PUBLIC void emb_array_copy(EmbArray *dst, EmbArray *src); EMB_PUBLIC int emb_array_add_geometry(EmbArray *a, EmbGeometry g); EMB_PUBLIC int emb_array_add_arc(EmbArray g, EmbArc arc); EMB_PUBLIC int emb_array_add_circle(EmbArray* g, EmbCircle circle); EMB_PUBLIC int emb_array_add_ellipse(EmbArray* g, EmbEllipse ellipse); EMB_PUBLIC int emb_array_add_flag(EmbArray* g, int flag); EMB_PUBLIC int emb_array_addLine(EmbArray* g, EmbLine line); EMB_PUBLIC int emb_array_addRect(EmbArray* g, EmbRect rect); EMB_PUBLIC int emb_array_addPath(EmbArray* g, EmbPath p); EMB_PUBLIC int emb_array_addPoint(EmbArray* g, EmbPoint p); EMB_PUBLIC int emb_array_addPolygon(EmbArray* g, EmbPolygon p); EMB_PUBLIC int emb_array_addPolyline(EmbArray* g, EmbPolyline p); /* EMB_PUBLIC int emb_array_addSpline(EmbArray* g, EmbSpline p); / EMB_PUBLIC int emb_array_addStitch(EmbArray g, EmbStitch st); EMB_PUBLIC int emb_array_addThread(EmbArray* g, EmbThread p); EMB_PUBLIC int emb_array_addVector(EmbArray* g, EmbVector); EMB_PUBLIC void emb_array_free(EmbArray* p);

EMB_PUBLIC EmbLine emb_line_make(EmbReal x1, EmbReal y1, EmbReal x2, EmbReal y2);

EMB_PUBLIC EmbVector emb_line_normalVector(EmbLine line, int clockwise); EMB_PUBLIC EmbVector emb_line_intersectionPoint(EmbLine line1, EmbLine line2, int *error_code);

EMB_PUBLIC int emb_find_nearest_color(EmbColor color, EmbColor* colors, int n_colors); EMB_PUBLIC int emb_find_nearest_thread(EmbColor color, EmbThread* threads, int n_threads); EMB_PUBLIC EmbThread emb_get_random_thread(void);

EMB_PUBLIC EmbVector emb_vector_normalize(EmbVector vector); EMB_PUBLIC EmbVector emb_vector_scale(EmbVector vector, EmbReal magnitude); EMB_PUBLIC EmbVector emb_vector_add(EmbVector v1, EmbVector v2); EMB_PUBLIC EmbVector emb_vector_average(EmbVector v1, EmbVector v2); EMB_PUBLIC EmbVector emb_vector_subtract(EmbVector v1, EmbVector v2); EMB_PUBLIC EmbReal emb_vector_dot(EmbVector v1, EmbVector v2); EMB_PUBLIC EmbReal emb_vector_cross(EmbVector v1, EmbVector v2); EMB_PUBLIC EmbVector emb_vector_transpose_product(EmbVector v1, EmbVector v2); EMB_PUBLIC EmbReal emb_vector_length(EmbVector vector); EMB_PUBLIC EmbReal emb_vector_relativeX(EmbVector a1, EmbVector a2, EmbVector a3); EMB_PUBLIC EmbReal emb_vector_relativeY(EmbVector a1, EmbVector a2, EmbVector a3); EMB_PUBLIC EmbReal emb_vector_angle(EmbVector v); EMB_PUBLIC EmbReal emb_vector_distance(EmbVector a, EmbVector b); EMB_PUBLIC EmbVector emb_vector_unit(EmbReal angle);

EMB_PUBLIC EmbGeometry emb_arc(EmbReal, EmbReal, EmbReal, EmbReal, EmbReal, EmbReal); EMB_PUBLIC char emb_arc_clockwise(EmbGeometry arc); EMB_PUBLIC EmbVector emb_arc_center(EmbGeometry arc); EMB_PUBLIC EmbReal emb_arc_radius(EmbGeometry arc); EMB_PUBLIC EmbReal emb_arc_diameter(EmbGeometry arc); EMB_PUBLIC EmbVector emb_arc_chordMid(EmbGeometry arc); EMB_PUBLIC EmbReal emb_arc_sagitta(EmbGeometry arc); EMB_PUBLIC EmbReal emb_arc_apothem(EmbGeometry arc); EMB_PUBLIC EmbReal emb_arc_incAngle(EmbGeometry arc); EMB_PUBLIC EmbReal emb_arc_bulge(EmbGeometry arc);

EMB_PUBLIC EmbGeometry emb_circle(EmbReal x, EmbReal y, EmbReal r); EMB_PUBLIC int getCircleCircleIntersections(

EmbCircle c0, EmbCircle c1, EmbVector *v0, EmbVector *v1);

EMB_PUBLIC int getCircleTangentPoints(

EmbCircle c, EmbVector p, EmbVector *v0, EmbVector *v1);

EMB_PUBLIC EmbEllipse embEllipse_init(void); EMB_PUBLIC EmbEllipse embEllipse_make(EmbReal cx, EmbReal cy, EmbReal rx, EmbReal ry); EMB_PUBLIC EmbReal embEllipse_diameterX(EmbEllipse ellipse); EMB_PUBLIC EmbReal embEllipse_diameterY(EmbEllipse ellipse); EMB_PUBLIC EmbReal embEllipse_area(EmbEllipse ellipse); EMB_PUBLIC EmbReal embEllipse_perimeter(EmbEllipse ellipse);

EMB_PUBLIC EmbImage embImage_create(int, int); EMB_PUBLIC void embImage_read(EmbImage *image, char *fname); EMB_PUBLIC int embImage_write(EmbImage *image, char *fname); EMB_PUBLIC void embImage_free(EmbImage *image);

EMB_PUBLIC EmbRect emb_rect(EmbReal, EmbReal, EmbReal, EmbReal); EMB_PUBLIC EmbReal embRect_area(EmbRect);

EMB_PUBLIC int threadColor(const char*, int brand); EMB_PUBLIC int threadColorNum(unsigned int color, int brand); EMB_PUBLIC const char* threadColorName(unsigned int color, int brand);

EMB_PUBLIC void embTime_initNow(EmbTime* t); EMB_PUBLIC EmbTime embTime_time(EmbTime* t);

EMB_PUBLIC int emb_generate_satin_outline(EmbArray* lines,

EmbReal thickness, EmbSatinOutline* result);

EMB_PUBLIC EmbArray* emb_satin_outline_render(EmbSatinOutline* result,

EmbReal density);

EMB_PUBLIC EmbGeometry *emb_geometry_init(int type_in); EMB_PUBLIC void emb_geometry_free(EmbGeometry *obj); EMB_PUBLIC void emb_geometry_move(EmbGeometry *obj, EmbVector delta); EMB_PUBLIC EmbRect embGeometry_boundingRect(EmbGeometry *obj); EMB_PUBLIC void emb_vulcanize(EmbGeometry *obj);

EMB_PUBLIC EmbPattern* emb_pattern_create(void); EMB_PUBLIC void emb_pattern_hideStitchesOverLength(EmbPattern* p, int length); EMB_PUBLIC void emb_pattern_fixColorCount(EmbPattern* p); EMB_PUBLIC int emb_pattern_addThread(EmbPattern* p, EmbThread thread); EMB_PUBLIC void emb_pattern_addStitchAbs(EmbPattern* p, EmbReal x, EmbReal y,

int flags, int isAutoColorIndex);

EMB_PUBLIC void emb_pattern_addStitchRel(EmbPattern* p, EmbReal dx, EmbReal dy, int flags, int isAutoColorIndex); EMB_PUBLIC void emb_pattern_changeColor(EmbPattern* p, int index); EMB_PUBLIC void emb_pattern_free(EmbPattern* p); EMB_PUBLIC void emb_pattern_scale(EmbPattern* p, EmbReal scale); EMB_PUBLIC EmbReal emb_pattern_totalStitchLength(EmbPattern pattern); EMB_PUBLIC EmbReal emb_pattern_minimumStitchLength(EmbPattern *pattern); EMB_PUBLIC EmbReal emb_pattern_maximumStitchLength(EmbPattern *pattern); EMB_PUBLIC void emb_pattern_lengthHistogram(EmbPattern *pattern, int *bin, int NUMBINS); EMB_PUBLIC int emb_pattern_realStitches(EmbPattern *pattern); EMB_PUBLIC int emb_pattern_jumpStitches(EmbPattern *pattern); EMB_PUBLIC int emb_pattern_trimStitches(EmbPattern *pattern); EMB_PUBLIC EmbRect emb_pattern_calcBoundingBox(EmbPattern p); EMB_PUBLIC void emb_pattern_flipHorizontal(EmbPattern* p); EMB_PUBLIC void emb_pattern_flipVertical(EmbPattern* p); EMB_PUBLIC void emb_pattern_flip(EmbPattern* p, int horz, int vert); EMB_PUBLIC void emb_pattern_combineJumpStitches(EmbPattern* p); EMB_PUBLIC void emb_pattern_correctForMaxStitchLength(EmbPattern* p, EmbReal maxStitchLength, EmbReal maxJumpLength); EMB_PUBLIC void emb_pattern_center(EmbPattern* p); EMB_PUBLIC void emb_pattern_loadExternalColorFile(EmbPattern* p, const char* fileName); EMB_PUBLIC void emb_pattern_convertGeometry(EmbPattern* p); EMB_PUBLIC void emb_pattern_designDetails(EmbPattern p); EMB_PUBLIC EmbPattern *emb_pattern_combine(EmbPattern *p1, EmbPattern *p2); EMB_PUBLIC int emb_pattern_color_count(EmbPattern *pattern, EmbColor startColor); EMB_PUBLIC void emb_pattern_end(EmbPattern p); EMB_PUBLIC void emb_pattern_crossstitch(EmbPattern *pattern, EmbImage *, int threshhold); EMB_PUBLIC void emb_pattern_horizontal_fill(EmbPattern *pattern, EmbImage *, int threshhold); EMB_PUBLIC int emb_pattern_render(EmbPattern *pattern, char *fname); EMB_PUBLIC int emb_pattern_simulate(EmbPattern *pattern, char *fname);

EMB_PUBLIC void emb_add_circle(EmbPattern* p, EmbCircle obj); EMB_PUBLIC void emb_add_ellipse(EmbPattern* p, EmbEllipse obj); EMB_PUBLIC void emb_add_line(EmbPattern* p, EmbLine obj); EMB_PUBLIC void emb_add_path(EmbPattern* p, EmbPath obj); EMB_PUBLIC void emb_pattern_addPointAbs(EmbPattern* p, EmbPoint obj); EMB_PUBLIC void emb_pattern_addPolygonAbs(EmbPattern* p, EmbPolygon obj); EMB_PUBLIC void emb_pattern_addPolylineAbs(EmbPattern* p, EmbPolyline obj); EMB_PUBLIC void emb_pattern_addRectAbs(EmbPattern* p, EmbRect obj);

EMB_PUBLIC void emb_copy_stitches_to_polylines(EmbPattern* pattern); EMB_PUBLIC void emb_copy_polylines_to_stitches(EmbPattern* pattern); EMB_PUBLIC void emb_move_stitches_to_polylines(EmbPattern* pattern); EMB_PUBLIC void emb_move_polylines_to_stitches(EmbPattern* pattern);

EMB_PUBLIC char emb_pattern_read(EmbPattern pattern, const char fileName, int format); EMB_PUBLIC char emb_pattern_write(EmbPattern pattern, const char fileName, int format);

EMB_PUBLIC char emb_pattern_readAuto(EmbPattern pattern, const char fileName); EMB_PUBLIC char emb_pattern_writeAuto(EmbPattern pattern, const char fileName);

EMB_PUBLIC int emb_round(EmbReal x); EMB_PUBLIC EmbReal radians(EmbReal degree); EMB_PUBLIC EmbReal degrees(EmbReal radian);

/* ———————————- Geometry —————————– */

EMB_PUBLIC int emb_pattern_real_count(EmbPattern *pattern); EMB_PUBLIC int emb_pattern_count_type(EmbPattern *pattern, int flags); EMB_PUBLIC double emb_pattern_shortest_stitch(EmbPattern *pattern); EMB_PUBLIC double emb_pattern_longest_stitch(EmbPattern *pattern); EMB_PUBLIC void emb_color_histogram(EmbPattern *pattern, int **bins); EMB_PUBLIC void emb_length_histogram(EmbPattern *pattern, int *bins); EMB_PUBLIC double emb_total_thread_length(EmbPattern *pattern); EMB_PUBLIC double emb_total_thread_of_color(EmbPattern *pattern, int thread_index);

EMB_PUBLIC int emb_approx(EmbVector point1, EmbVector point2);

EMB_PUBLIC EmbVector scale_and_rotate(EmbVector v, double angle, double scale);

EMB_PUBLIC double emb_width(EmbGeometry *geometry); EMB_PUBLIC double emb_height(EmbGeometry *geometry); EMB_PUBLIC double emb_radius(EmbGeometry *geometry); EMB_PUBLIC double emb_radius_major(EmbGeometry *geometry); EMB_PUBLIC double emb_radius_minor(EmbGeometry *geometry); EMB_PUBLIC double emb_diameter(EmbGeometry *geometry); EMB_PUBLIC double emb_diameter_major(EmbGeometry *geometry); EMB_PUBLIC double emb_diameter_minor(EmbGeometry *geometry); EMB_PUBLIC EmbVector emb_quadrant(EmbGeometry *geometry, int degrees); EMB_PUBLIC double emb_angle(EmbGeometry *geometry); EMB_PUBLIC double emb_start_angle(EmbGeometry *geometry); EMB_PUBLIC double emb_end_angle(EmbGeometry *geometry); EMB_PUBLIC double emb_arc_length(EmbGeometry *geometry); EMB_PUBLIC double emb_area(EmbGeometry *geometry); EMB_PUBLIC double emb_chord(EmbGeometry *geometry); EMB_PUBLIC double emb_included_angle(EmbGeometry *geometry); EMB_PUBLIC char emb_clockwise(EmbGeometry *geometry); EMB_PUBLIC double emb_circumference(EmbGeometry *geometry);

EMB_PUBLIC void emb_set_start_angle(EmbGeometry *geometry, double angle); EMB_PUBLIC void emb_set_end_angle(EmbGeometry *geometry, double angle); EMB_PUBLIC void emb_set_start_point(EmbGeometry *geometry, EmbVector point); EMB_PUBLIC void emb_set_mid_point(EmbGeometry *geometry, EmbVector point); EMB_PUBLIC void emb_set_end_point(EmbGeometry *geometry, EmbVector point); EMB_PUBLIC void emb_set_diameter(EmbGeometry *geometry, double diameter); EMB_PUBLIC void emb_set_area(EmbGeometry *geometry, double area); EMB_PUBLIC void emb_set_circumference(EmbGeometry *geometry, double circumference); EMB_PUBLIC void emb_set_radius(EmbGeometry *geometry, double radius); EMB_PUBLIC void emb_set_radius_major(EmbGeometry *geometry, double radius); EMB_PUBLIC void emb_set_radius_minor(EmbGeometry *geometry, double radius); EMB_PUBLIC void emb_set_diameter_major(EmbGeometry *geometry, double diameter); EMB_PUBLIC void emb_set_diameter_minor(EmbGeometry *geometry, double diameter);

EMB_PUBLIC char *emb_get_svg_token(char *svg, char token[MAX_STRING_LENGTH]); EMB_PUBLIC char *emb_get_svg_vector(char *svg, EmbVector *v);

/* NON-MACRO CONSTANTS

**************************************************************************/

extern EmbFormatList formatTable[numberOfFormats]; extern const EmbReal embConstantPi; extern EmbBrand brand_codes[100]; extern EmbThread black_thread; extern int emb_verbose; extern const char *version_string; end{verbatim}

subsection{Vector Functions}

subsection{Encoding Functions}

subsection{String Management Functions}

section{Internal C Functions}

section{Assembly Macros}

section{Java API}

begin{lstlisting} const int NUMBINS = 10;

double epsilon = 0.000000001;

double emb_included_angle(EmbGeometry *geometry);

int emb_fread(void data, int length, FILE file_pointer) {

return fread((unsigned char )data, 1, length, (void)file_pointer);

}

int emb_fwrite(void data, int length, FILE file_pointer) {

return fwrite((unsigned char )data, 1, length, (void)file_pointer);

}

/* Internal function declarations.

*/

/* Utility Functions: merge first three with string library / int stringInArray(const char *s, const char **array); char *copy_trim(char const *s); char emb_optOut(EmbReal num, char* str); void safe_free(void *data);

int testMain(int);

/* DIFAT functions / unsigned int entriesInDifatSector(bcf_file_difat fat); bcf_file_fat* bcfFileFat_create(const unsigned int sectorSize); void loadFatFromSector(bcf_file_fat* fat, FILE* file); void bcf_file_fat_free(bcf_file_fat** fat); bcf_directory* CompoundFileDirectory(const unsigned int maxNumberOfDirectoryEntries); void bcf_directory_free(bcf_directory** dir); unsigned int numberOfEntriesInDifatSector(bcf_file_difat* fat); void bcf_file_difat_free(bcf_file_difat* difat); bcf_file_header bcfFileHeader_read(FILE* file); int bcfFileHeader_isValid(bcf_file_header header); void bcf_file_free(bcf_file* bcfFile);

static EmbPattern *focussed_pattern = NULL;

void printArcResults(

EmbReal bulge, EmbArc arc, EmbVector center, EmbReal radius, EmbReal diameter, EmbReal chord, EmbVector chordMid, EmbReal sagitta, EmbReal apothem, EmbReal incAngle, char clockwise);

int testTangentPoints(EmbCircle c, EmbVector p, EmbVector *t0, EmbVector *t1); int create_test_file(int test_file, int format);

/* Encoding/decoding and compression functions. / int hus_compress(char input, int size, char* output, int out_size); int hus_decompress(char input, int size, char* output, int *out_size);

void huffman_build_table(huffman *h); int *huffman_table_lookup(huffman *h, int byte_lookup, int *lengths);

int compress_get_bits(compress *c, int length); int compress_pop(compress *c, int bit_count); int compress_read_variable_length(compress *c); void compress_load_character_length_huffman(compress *c); void compress_load_character_huffman(compress *c); void compress_load_distance_huffman(compress *c); void compress_load_block(compress *c); int compress_get_token(compress *c); int compress_get_position(compress *c);

EmbReal pfaffDecode(unsigned char a1, unsigned char a2, unsigned char a3);

int decodeNewStitch(unsigned char value);

unsigned char mitEncodeStitch(EmbReal value); int mitDecodeStitch(unsigned char value);

void encode_t01_record(unsigned char b[3], int x, int y, int flags); int decode_t01_record(unsigned char b[3], int *x, int *y, int *flags);

int encode_tajima_ternary(unsigned char b[3], int x, int y); void decode_tajima_ternary(unsigned char b[3], int *x, int *y);

/*
  • Note that this file only has to exist because we cannot necessary include

  • any of the C standard library on all platforms. For example, “void *” and

  • “printf” aren’t universal. See the “Supported Platforms” section of

  • the reference manual.

*/

/* Function Declarations / void readPecStitches(EmbPattern pattern, FILE* file); void writePecStitches(EmbPattern* pattern, FILE* file, const char* filename);

void pfaffEncode(FILE* file, int x, int y, int flags);

void readPESHeaderV5(FILE* file, EmbPattern* pattern); void readPESHeaderV6(FILE* file, EmbPattern* pattern); void readPESHeaderV7(FILE* file, EmbPattern* pattern); void readPESHeaderV8(FILE* file, EmbPattern* pattern); void readPESHeaderV9(FILE* file, EmbPattern* pattern); void readPESHeaderV10(FILE* file, EmbPattern* pattern);

void readDescriptions(FILE* file, EmbPattern* pattern); void readHoopName(FILE* file, EmbPattern* pattern); void readImageString(FILE* file, EmbPattern* pattern); void readProgrammableFills(FILE* file, EmbPattern* pattern); void readMotifPatterns(FILE* file, EmbPattern* pattern); void readFeatherPatterns(FILE* file, EmbPattern* pattern); void readThreads(FILE* file, EmbPattern* pattern);

int bcfFile_read(FILE* file, bcf_file* bcfFile); void* GetFile(bcf_file* bcfFile, FILE* file, char* fileToFind);

void binaryReadString(FILE* file, char buffer, int maxLength); void binaryReadUnicodeString(FILE file, char *buffer, const int stringLength);

void fpad(FILE* f, char c, int n);

void write_24bit(FILE* file, int); int check_header_present(FILE* file, int minimum_header_length);

int emb_readline(FILE* file, char *line, int maxLength);

int16_t emb_read_i16(FILE* f); uint16_t emb_read_u16(FILE* f); int32_t emb_read_i32(FILE* f); uint32_t emb_read_u32(FILE* f); int16_t emb_read_i16be(FILE* f); uint16_t emb_read_u16be(FILE* f); int32_t emb_read_i32be(FILE* f); uint32_t emb_read_u32be(FILE* f);

void emb_write_i16(FILE* f, int16_t data); void emb_write_u16(FILE* f, uint16_t data); void emb_write_i32(FILE* f, int32_t data); void emb_write_u32(FILE* f, uint32_t data); void emb_write_i16BE(FILE* f, int16_t data); void emb_write_u16BE(FILE* f, uint16_t data); void emb_write_i32be(FILE* f, int32_t data); void emb_write_u32be(FILE* f, uint32_t data);

bcf_file_difat* bcf_difat_create(FILE* file, unsigned int fatSectors, const unsigned int sectorSize); unsigned int readFullSector(FILE* file, bcf_file_difat* bcfFile, unsigned int* numberOfDifatEntriesStillToRead); bcf_directory_entry* CompoundFileDirectoryEntry(FILE* file); void readNextSector(FILE* file, bcf_directory* dir);

void embColor_read(void *f, EmbColor *c, int toRead); void embColor_write(void *f, EmbColor c, int toWrite);

unsigned char toyota_position_encode(EmbReal a); EmbReal toyota_position_decode(unsigned char a);

void toyota_100_encode(EmbVector *position, EmbStitch *st, unsigned char *b); void toyota_100_decode(EmbVector *position, EmbStitch *st, unsigned char *b); void toyota_10o_encode(EmbVector *position, EmbStitch *st, unsigned char *b); void toyota_10o_decode(EmbVector *position, EmbStitch *st, unsigned char *b); void bernina_art_encode(EmbVector *position, EmbStitch *st, unsigned char *b); void bernina_art_decode(EmbVector *position, EmbStitch *st, unsigned char *b);

char read_stitch_block(

EmbPattern , FILE file, void (*stitch_encoder)(EmbVector *, EmbStitch *, unsigned char *), int stitch_data_size, int mode

); char write_stitch_block(

EmbPattern , FILE file, void (*stitch_encoder)(EmbVector *, EmbStitch *, unsigned char *), int stitch_data_size, int mode

);

char readBmc(EmbPattern pattern, FILE file); char writeBmc(EmbPattern pattern, FILE file); char readBro(EmbPattern pattern, FILE file); char writeBro(EmbPattern pattern, FILE file); char readCnd(EmbPattern pattern, FILE file); char writeCnd(EmbPattern pattern, FILE file); char readCol(EmbPattern pattern, FILE file); char writeCol(EmbPattern pattern, FILE file); char readCsd(EmbPattern pattern, FILE file); char writeCsd(EmbPattern pattern, FILE file); char readCsv(EmbPattern pattern, FILE file); char writeCsv(EmbPattern pattern, FILE file); char readDat(EmbPattern pattern, FILE file); char writeDat(EmbPattern pattern, FILE file); char readDem(EmbPattern pattern, FILE file); char writeDem(EmbPattern pattern, FILE file); char readDsb(EmbPattern pattern, FILE file); char writeDsb(EmbPattern pattern, FILE file); char readDst(EmbPattern pattern, FILE file); char writeDst(EmbPattern pattern, FILE file); char readDsz(EmbPattern pattern, FILE file); char writeDsz(EmbPattern pattern, FILE file); char readDxf(EmbPattern pattern, FILE file); char writeDxf(EmbPattern pattern, FILE file); char readEdr(EmbPattern pattern, FILE file); char writeEdr(EmbPattern pattern, FILE file); char readEmd(EmbPattern pattern, FILE file); char writeEmd(EmbPattern pattern, FILE file); char readExp(EmbPattern pattern, FILE file); char writeExp(EmbPattern pattern, FILE file); char readExy(EmbPattern pattern, FILE file); char writeExy(EmbPattern pattern, FILE file); char readEys(EmbPattern pattern, FILE file); char writeEys(EmbPattern pattern, FILE file); char readFxy(EmbPattern pattern, FILE file); char writeFxy(EmbPattern pattern, FILE file); char readGc(EmbPattern pattern, FILE file); char writeGc(EmbPattern pattern, FILE file); char readGnc(EmbPattern pattern, FILE file); char writeGnc(EmbPattern pattern, FILE file); char readGt(EmbPattern pattern, FILE file); char writeGt(EmbPattern pattern, FILE file); char readHus(EmbPattern pattern, FILE file); char writeHus(EmbPattern pattern, FILE file); char readInb(EmbPattern pattern, FILE file); char writeInb(EmbPattern pattern, FILE file); char readInf(EmbPattern pattern, FILE file); char writeInf(EmbPattern pattern, FILE file); char readJef(EmbPattern pattern, FILE file); char writeJef(EmbPattern pattern, FILE file); char readKsm(EmbPattern pattern, FILE file); char writeKsm(EmbPattern pattern, FILE file); char readMax(EmbPattern pattern, FILE file); char writeMax(EmbPattern pattern, FILE file); char readMit(EmbPattern pattern, FILE file); char writeMit(EmbPattern pattern, FILE file); char readNew(EmbPattern pattern, FILE file); char writeNew(EmbPattern pattern, FILE file); char readOfm(EmbPattern pattern, FILE file); char writeOfm(EmbPattern pattern, FILE file); char readPcd(EmbPattern pattern, const char *fileName, FILE file); char writePcd(EmbPattern pattern, FILE file); char readPcm(EmbPattern pattern, FILE file); char writePcm(EmbPattern pattern, FILE file); char readPcq(EmbPattern pattern, const char *fileName, FILE file); char writePcq(EmbPattern pattern, FILE file); char readPcs(EmbPattern pattern, const char *fileName, FILE file); char writePcs(EmbPattern pattern, FILE file); char readPec(EmbPattern pattern, const char *fileName, FILE file); char writePec(EmbPattern pattern, const char *fileName, FILE file); char readPel(EmbPattern pattern, FILE file); char writePel(EmbPattern pattern, FILE file); char readPem(EmbPattern pattern, FILE file); char writePem(EmbPattern pattern, FILE file); char readPes(EmbPattern pattern, const char *fileName, FILE file); char writePes(EmbPattern pattern, const char *fileName, FILE file); char readPhb(EmbPattern pattern, FILE file); char writePhb(EmbPattern pattern, FILE file); char readPhc(EmbPattern pattern, FILE file); char writePhc(EmbPattern pattern, FILE file); char readPlt(EmbPattern pattern, FILE file); char writePlt(EmbPattern pattern, FILE file); char readRgb(EmbPattern pattern, FILE file); char writeRgb(EmbPattern pattern, FILE file); char readSew(EmbPattern pattern, FILE file); char writeSew(EmbPattern pattern, FILE file); char readShv(EmbPattern pattern, FILE file); char writeShv(EmbPattern pattern, FILE file); char readSst(EmbPattern pattern, FILE file); char writeSst(EmbPattern pattern, FILE file); char readStx(EmbPattern pattern, FILE file); char writeStx(EmbPattern pattern, FILE file); char readSvg(EmbPattern pattern, FILE file); char writeSvg(EmbPattern pattern, FILE file); char readT01(EmbPattern pattern, FILE file); char writeT01(EmbPattern pattern, FILE file); char readT09(EmbPattern pattern, FILE file); char writeT09(EmbPattern pattern, FILE file); char readTap(EmbPattern pattern, FILE file); char writeTap(EmbPattern pattern, FILE file); char readThr(EmbPattern pattern, FILE file); char writeThr(EmbPattern pattern, FILE file); char readTxt(EmbPattern pattern, FILE file); char writeTxt(EmbPattern pattern, FILE file); char readU00(EmbPattern pattern, FILE file); char writeU00(EmbPattern pattern, FILE file); char readU01(EmbPattern pattern, FILE file); char writeU01(EmbPattern pattern, FILE file); char readVip(EmbPattern pattern, FILE file); char writeVip(EmbPattern pattern, FILE file); char readVp3(EmbPattern pattern, FILE file); char writeVp3(EmbPattern pattern, FILE file); char readXxx(EmbPattern pattern, FILE file); char writeXxx(EmbPattern pattern, FILE file); char readZsk(EmbPattern pattern, FILE file); char writeZsk(EmbPattern pattern, FILE file);

void write_24bit(FILE* file, int);

/* Replacing functions that compilers complain about.
  • In some cases, this is due to valid concerns about

  • functions not returning (like a string without null-termination).

  • We don’t use size_t because it’s system-specific.

  • IDEA: don’t rely on “sizeof” because it’s system and

  • compiler-specific, depending on how the struct is packed.

  • We could manually pack out structs and then know exactly

  • how much space they need.

  • TODO: UTF-8 support.

*/

void string_copy(char *dst, const char *src); int string_equals(const char *s1, const char *s2); int string_len(const char *src); void string_cat(char *dst, const char *src); int string_rchar(const char *s1, char c); void char_ptr_to_string(char *dst, char *src); void memory_copy(void *dst, const void *src, int n); char memory_cmp(void *dst, const void *src, int n);

/* Internal Data
  • This file contains all the read and write functions for the

  • library.

  • This list needs reviewed in case some stitch

  • formats also can contain object data (EMBFORMAT_STCHANDOBJ). *

*/

EmbFormatList formatTable[numberOfFormats] = {

{“.10o”, “Toyota Embroidery Format”, ‘U’, ‘ ‘, EMBFORMAT_STITCHONLY, 0, 1, 0}, {“.100”, “Toyota Embroidery Format”, ‘U’, ‘ ‘, EMBFORMAT_STITCHONLY, 0, 1, 0}, {“.art”, “Bernina Embroidery Format”, ‘ ‘, ‘ ‘, EMBFORMAT_STITCHONLY, 0, 0, 0}, {“.bmc”, “Bitmap Cache Embroidery Format”, ‘ ‘, ‘ ‘, EMBFORMAT_STITCHONLY, 0, 0, 0}, {“.bro”, “Bits & Volts Embroidery Format”, ‘U’, ‘ ‘, EMBFORMAT_STITCHONLY, 0, 1, 0}, {“.cnd”, “Melco Embroidery Format”, ‘ ‘, ‘ ‘, EMBFORMAT_STITCHONLY, 0, 0, 0}, {“.col”, “Embroidery Thread Color Format”, ‘U’, ‘U’, EMBFORMAT_STITCHONLY, 1, 0, 0}, {“.csd”, “Singer Embroidery Format”, ‘U’, ‘ ‘, EMBFORMAT_STITCHONLY, 0, 0, 0}, {“.csv”, “Comma Separated Values Format”, ‘U’, ‘U’, EMBFORMAT_STITCHONLY, 0, 0, 0}, {“.dat”, “Barudan Embroidery Format”, ‘U’, ‘ ‘, EMBFORMAT_STITCHONLY, 0, 1, 0}, {“.dem”, “Melco Embroidery Format”, ‘ ‘, ‘ ‘, EMBFORMAT_STITCHONLY, 0, 0, 0}, {“.dsb”, “Barudan Embroidery Format”, ‘U’, ‘ ‘, EMBFORMAT_STITCHONLY, 0, 1, 0}, {“.dst”, “Tajima Embroidery Format”, ‘U’, ‘U’, EMBFORMAT_STITCHONLY, 0, 1, 0}, {“.dsz”, “ZSK USA Embroidery Format”, ‘U’, ‘ ‘, EMBFORMAT_STITCHONLY, 0, 1, 0}, {“.dxf”, “Drawing Exchange Format”, ‘ ‘, ‘ ‘, EMBFORMAT_OBJECTONLY, 0, 0, 0}, {“.edr”, “Embird Embroidery Format”, ‘U’, ‘U’, EMBFORMAT_STITCHONLY, 1, 0, 0}, {“.emd”, “Elna Embroidery Format”, ‘U’, ‘ ‘, EMBFORMAT_STITCHONLY, 0, 1, 0}, {“.exp”, “Melco Embroidery Format”, ‘U’, ‘U’, EMBFORMAT_STITCHONLY, 0, 1, 0}, {“.exy”, “Eltac Embroidery Format”, ‘U’, ‘ ‘, EMBFORMAT_STITCHONLY, 0, 1, 0}, {“.eys”, “Sierra Expanded Embroidery Format”, ‘ ‘, ‘ ‘, EMBFORMAT_STITCHONLY, 0, 0, 0}, {“.fxy”, “Fortron Embroidery Format”, ‘U’, ‘ ‘, EMBFORMAT_STITCHONLY, 0, 1, 0}, {“.gc”, “Smoothie G-Code Format”, ‘ ‘, ‘ ‘, EMBFORMAT_STITCHONLY, 0, 0, 0}, {“.gnc”, “Great Notions Embroidery Format”, ‘ ‘, ‘ ‘, EMBFORMAT_STITCHONLY, 0, 0, 0}, {“.gt”, “Gold Thread Embroidery Format”, ‘U’, ‘ ‘, EMBFORMAT_STITCHONLY, 0, 1, 0}, {“.hus”, “Husqvarna Viking Embroidery Format”, ‘U’, ‘U’, EMBFORMAT_STITCHONLY, 0, 0, 0}, {“.inb”, “Inbro Embroidery Format”, ‘U’, ‘ ‘, EMBFORMAT_STITCHONLY, 0, 1, 0}, {“.inf”, “Embroidery Color Format”, ‘U’, ‘U’, EMBFORMAT_STITCHONLY, 1, 0, 0}, {“.jef”, “Janome Embroidery Format”, ‘U’, ‘U’, EMBFORMAT_STITCHONLY, 0, 0, 0}, {“.ksm”, “Pfaff Embroidery Format”, ‘U’, ‘U’, EMBFORMAT_STITCHONLY, 0, 0, 0}, {“.max”, “Pfaff Embroidery Format”, ‘U’, ‘U’, EMBFORMAT_STITCHONLY, 0, 0, 0}, {“.mit”, “Mitsubishi Embroidery Format”, ‘U’, ‘ ‘, EMBFORMAT_STITCHONLY, 0, 1, 0}, {“.new”, “Ameco Embroidery Format”, ‘U’, ‘ ‘, EMBFORMAT_STITCHONLY, 0, 1, 0}, {“.ofm”, “Melco Embroidery Format”, ‘U’, ‘ ‘, EMBFORMAT_STITCHONLY, 0, 0, 0}, {“.pcd”, “Pfaff Embroidery Format”, ‘U’, ‘U’, EMBFORMAT_STITCHONLY, 0, 0, 0}, {“.pcm”, “Pfaff Embroidery Format”, ‘U’, ‘ ‘, EMBFORMAT_STITCHONLY, 0, 0, 0}, {“.pcq”, “Pfaff Embroidery Format”, ‘U’, ‘U’, EMBFORMAT_STITCHONLY, 0, 0, 0}, {“.pcs”, “Pfaff Embroidery Format”, ‘U’, ‘U’, EMBFORMAT_STITCHONLY, 0, 0, 0}, {“.pec”, “Brother Embroidery Format”, ‘U’, ‘U’, EMBFORMAT_STITCHONLY, 0, 0, 0}, {“.pel”, “Brother Embroidery Format”, ‘ ‘, ‘ ‘, EMBFORMAT_STITCHONLY, 0, 0, 0}, {“.pem”, “Brother Embroidery Format”, ‘ ‘, ‘ ‘, EMBFORMAT_STITCHONLY, 0, 0, 0}, {“.pes”, “Brother Embroidery Format”, ‘U’, ‘U’, EMBFORMAT_STITCHONLY, 0, 0, 0}, {“.phb”, “Brother Embroidery Format”, ‘U’, ‘ ‘, EMBFORMAT_STITCHONLY, 0, 0, 0}, {“.phc”, “Brother Embroidery Format”, ‘U’, ‘ ‘, EMBFORMAT_STITCHONLY, 0, 0, 0}, {“.plt”, “AutoCAD Plot Drawing Format”, ‘U’, ‘U’, EMBFORMAT_STITCHONLY, 0, 1, 0}, {“.rgb”, “RGB Embroidery Format”, ‘U’, ‘U’, EMBFORMAT_STITCHONLY, 1, 0, 0}, {“.sew”, “Janome Embroidery Format”, ‘U’, ‘U’, EMBFORMAT_STITCHONLY, 0, 0, 0}, {“.shv”, “Husqvarna Viking Embroidery Format”, ‘U’, ‘ ‘, EMBFORMAT_STITCHONLY, 0, 0, 0}, {“.sst”, “Sunstar Embroidery Format”, ‘U’, ‘ ‘, EMBFORMAT_STITCHONLY, 0, 1, 0}, {“.stx”, “Data Stitch Embroidery Format”, ‘U’, ‘ ‘, EMBFORMAT_STITCHONLY, 0, 0, 0}, {“.svg”, “Scalable Vector Graphics”, ‘U’, ‘U’, EMBFORMAT_OBJECTONLY, 0, 0, 0}, {“.t01”, “Pfaff Embroidery Format”, ‘U’, ‘ ‘, EMBFORMAT_STITCHONLY, 0, 1, 0}, {“.t09”, “Pfaff Embroidery Format”, ‘U’, ‘ ‘, EMBFORMAT_STITCHONLY, 0, 0, 0}, {“.tap”, “Happy Embroidery Format”, ‘U’, ‘U’, EMBFORMAT_STITCHONLY, 0, 1, 0}, {“.thr”, “ThredWorks Embroidery Format”, ‘U’, ‘U’, EMBFORMAT_STITCHONLY, 1, 0, 0}, {“.txt”, “Text File”, ‘ ‘, ‘U’, EMBFORMAT_STITCHONLY, 0, 0, 0}, {“.u00”, “Barudan Embroidery Format”, ‘U’, ‘ ‘, EMBFORMAT_STITCHONLY, 0, 0, 0}, {“.u01”, “Barudan Embroidery Format”, ‘ ‘, ‘ ‘, EMBFORMAT_STITCHONLY, 0, 0, 0}, {“.vip”, “Pfaff Embroidery Format”, ‘U’, ‘ ‘, EMBFORMAT_STITCHONLY, 0, 0, 0}, {“.vp3”, “Pfaff Embroidery Format”, ‘U’, ‘U’, EMBFORMAT_STITCHONLY, 0, 0, 0}, {“.xxx”, “Singer Embroidery Format”, ‘U’, ‘U’, EMBFORMAT_STITCHONLY, 0, 0, 0}, {“.zsk”, “ZSK USA Embroidery Format”, ‘U’, ‘ ‘, EMBFORMAT_STITCHONLY, 0, 0, 0}

};

const char *version_string = “embroider v0.1”;

EmbThread black_thread = { { 0, 0, 0 }, “Black”, “Black” }; int emb_verbose = 0;

const EmbReal embConstantPi = 3.1415926535;

/* Constant representing the number of EmbReal Indirect FAT
  • entries in a single header */

const unsigned int difatEntriesInHeader = 109; const unsigned int sizeOfFatEntry = sizeof(unsigned int); const unsigned int sizeOfDifatEntry = 4; const unsigned int sizeOfChainingEntryAtEndOfDifatSector = 4; const unsigned int sizeOfDirectoryEntry = 128; /* const int supportedMinorVersion = 0x003E; const int littleEndianByteOrderMark = 0xFFFE; */

/* Based on the DraftSight color table. It doesn’t appear to be authoratitive

*/

const unsigned char _dxfColorTable[][3] = { };

/* HUS Colors */ const EmbThread husThreads[] = { };

const EmbThread jefThreads[] = { };

/* SHV Colors */ const int shvThreadCount = 42; const EmbThread shvThreads[] = { };

const EmbThread pcmThreads[] = { };

const int pecThreadCount = 65; const EmbThread pecThreads[] = { };

/* Converted from the table at:

*/

thread_color svg_color_codes[200] = { };

EmbBrand brand_codes[100] = {

{svg_color_codes, 100, “DXF”}, {svg_color_codes, 100, “HUS”}, {svg_color_codes, 100, “JEF”}, {svg_color_codes, 100, “SHV”}, {svg_color_codes, 100, “PCM”}, {svg_color_codes, 100, “PEC”}, {svg_color_codes, 200, “Scalable Vector Graphics”}

};

/* Internally, we use fixed-point arithmetic because it can be made more
  • consistent.

  • The maximum integer value is 32767, so with a place value of 0.1 the

  • maximum distance is 3276.7 mm which is around 3 metres. In longer

  • calculations this means that we can have stacked errors that cause issues.

  • However, since 2 byte, fixed-point real types are appropriate for most

  • scenarios: if this is a issue for a specific calculation then we recommend

  • that authors scale up then scale down what they’re working on. If it

  • continues to be an issue please describe your use case, along with a

  • description of your art, to us at the issues page on:

  • https://github.com/embroidermodder/libembroidery

*/

#define DEFAULT_PLACE_VALUE (0.1)

/* INTERNAL POSTSCRIPT-COMPATIBLE INTERPRETER
  • Eventually we want all dependencies of libembroidery to be only c standard

  • libraries and we also need the interpreter to integrate well with our

  • own virtual machine. So this experiment is to establish that this works.

  • I am using the PostScript Reference Manual for a description of how the

  • langauge works. It is being held in an environment where it cannot

  • effect the disk directly and can only edit a pattern loaded into memory.

  • This should reduce the potential damage of a malicious postscript file,

  • because it will only have access to the files that we explicitly give it

  • access to (assuming there are no memory leaks).

*/

/* PostScript data types */ #define STRING_TYPE 0 #define ARRAY_TYPE 1 #define REAL_TYPE 2 #define INT_TYPE 3 #define BOOL_TYPE 4 #define NAME_TYPE 5 #define DICTIONARY_TYPE 6

static char postscript_data_type[][20] = {

“string”, “array”, “real”, “int”, “bool”, “name”, “dictionary”

};

/* Attributes */ #define LITERAL_ATTR 0 #define EXEC_ATTR 1

/* PostScript’s built-in identifiers
  • (See the in_built_functions string table below.)

*/

/* 3.6.1 Stack / #define PS_FUNC_DUP 0 #define PS_FUNC_EXCH 1 #define PS_FUNC_POP 2 #define PS_FUNC_COPY 3 #define PS_FUNC_ROLL 4 #define PS_FUNC_INDEX 5 #define PS_FUNC_MARK 6 #define PS_FUNC_CLEAR 7 #define PS_FUNC_COUNT 8 #define PS_FUNC_COUNTTOMARK 9 / 3.6.2 Mathematical / #define PS_FUNC_ADD 10 #define PS_FUNC_SUB 11 #define PS_FUNC_MUL 12 #define PS_FUNC_DIV 13 #define PS_FUNC_IDIV 14 #define PS_FUNC_MOD 15 #define PS_FUNC_ABS 16 #define PS_FUNC_NEG 17 #define PS_FUNC_CEILING 18 #define PS_FUNC_FLOOR 19 #define PS_FUNC_ROUND 20 #define PS_FUNC_TRUNCATE 21 #define PS_FUNC_SQRT 22 #define PS_FUNC_EXP 23 #define PS_FUNC_LN 24 #define PS_FUNC_LOG 25 #define PS_FUNC_sin 26 #define PS_FUNC_cos 27 #define PS_FUNC_atan 28 #define PS_FUNC_rand 29 #define PS_FUNC_srand 30 #define PS_FUNC_rrand 31 / 3.6.3 Array, Dictionary, String / #define PS_FUNC_get 32 #define PS_FUNC_put 33 #define PS_FUNC_copy 34 #define PS_FUNC_length 35 #define PS_FUNC_getinterval 36 #define PS_FUNC_putinterval 37 / Array-specific / #define PS_FUNC_aload 38 #define PS_FUNC_astore 39 #define PS_FUNC_OPEN_SQ 40 #define PS_FUNC_CLOSE_SQ 41 #define PS_FUNC_setpacking 42 #define PS_FUNC_currentpacking 43 / Dictionary-specific / #define PS_FUNC_begin 44 #define PS_FUNC_end 45 #define PS_FUNC_def 46 #define PS_FUNC_store 47 #define PS_FUNC_load 48 #define PS_FUNC_where 49 #define PS_FUNC_countdictstack 50 #define PS_FUNC_cleardictstack 51 #define PS_FUNC_dictstack 52 #define PS_FUNC_known 53 #define PS_FUNC_maxlength 54 #define PS_FUNC_undef 55 / Level 2 / #define PS_FUNC_left_arrow 56 / Level 2 / #define PS_FUNC_right_arrow 57 / Level 2 / / String-specific / #define PS_FUNC_search 58 #define PS_FUNC_anchorsearch 59 #define PS_FUNC_token 60 / 3.6.4 Boolean / #define PS_FUNC_eq 61 #define PS_FUNC_ne 62 #define PS_FUNC_gt 63 #define PS_FUNC_ge 64 #define PS_FUNC_le 65 #define PS_FUNC_lt 66 #define PS_FUNC_and 67 #define PS_FUNC_or 68 #define PS_FUNC_xor 69 #define PS_FUNC_true 70 #define PS_FUNC_false 71 #define PS_FUNC_not 72 / 3.6.5 Control / #define PS_FUNC_if 73 #define PS_FUNC_ifelse 74 #define PS_FUNC_exec 75 #define PS_FUNC_for 76 #define PS_FUNC_repeat 77 #define PS_FUNC_loop 78 #define PS_FUNC_forall 79 #define PS_FUNC_exit 80 #define PS_FUNC_countexecstack 81 #define PS_FUNC_execstack 82 #define PS_FUNC_stop 83 / 3.6.6 Type / #define PS_FUNC_type 84 #define PS_FUNC_xcheck 85 #define PS_FUNC_rcheck 86 #define PS_FUNC_wcheck 87 #define PS_FUNC_cvlit 88 #define PS_FUNC_cvx 89 #define PS_FUNC_readonly 90 #define PS_FUNC_executeonly 91 #define PS_FUNC_noaccess 92 #define PS_FUNC_cvi 93 #define PS_FUNC_cvr 94 #define PS_FUNC_cvn 95 #define PS_FUNC_cvs 96 #define PS_FUNC_cvrs 97 / 3.7.1 Memory / #define PS_FUNC_array 98 #define PS_FUNC_packedarray 99 #define PS_FUNC_dict 100 #define PS_FUNC_string 101 #define PS_FUNC_gstate 102 / 3.7.2 VM */ #define PS_FUNC_save 103 #define PS_FUNC_restore 104 #define PS_FUNC_userdict 105 #define PS_FUNC_gcheck 106

int emb_repl(void); void execute_postscript(EmbStack *stack, char line[200]); void analyse_stack(EmbStack *stack);

/* The PostScript Reference Manual (second edition) lists these commands and
  • specifically requests that authors credit them as the copyright holder

  • in order to protect their ownership of the language and de-facto interpreter.

  • We reproduce it here in order to make our own filters and graphics features

  • compatible with those found in graphic design for modern printers and

  • scanners.

  • The in_built_functions string table here is credited to:

  • Adobe Systems Incorporated “The PostScript(R) Reference Manual” (1990)

  • (Second Edition) Addison Wesley

*/

static char in_built_functions[][20];

/* .

*/

void analyse_stack(EmbStack *stack)

/* .

*/

int stack_push(EmbStack *stack, char token[200])

/* .

*/

EmbStackElement stack_pop(EmbStack *stack)

/* .

*/

int queue_token(EmbStack *stack, char token[200])

/* .

*/

void queue_token_list(EmbStack *stack, char line[200])

int token_is_int(EmbStackElement arg)

/* . */ int get_int_tokens(EmbStack *stack, EmbStackElement *args, int n_tokens)

/* .

*/

int process_stack_head(EmbStack *stack)

/* .

*/

void execute_postscript(EmbStack *stack, char line[200])

/* .

*/

int emb_repl(void)

static int emb_int_from_bytes(const char *program, int i)

static EmbReal emb_real_from_bytes(const char *program, int i)

static EmbVector emb_vector_from_bytes(const char *program, int i)

/* Our virtual machine
  • Program state is altered via this function, all other functions

  • pass the program state back and forth to keep it thread-safe.

  • Variables are packed into and removed from this state, the stack is embedded

  • into it. To manage memory each stack item names its successor, or is a negative

  • number indicating that the stack terminates there.

  • DATA TYPE FLAG

  • STRING (any value <=100): which is also the length of the string.

  • INT (101): integer in the range (-32767, 32767).

  • REAL (102): fixed-point real number in the range (-3276.7, 3276.7).

  • FUNCTION (103): interpret the data as an index in the predefined function

  • table.

  • VARIABLE (104): reference to memory location outside of the stack.

  • EXAMPLE STACK

  • Stack element 0:

  • description: (3, BYTE, “a”)

  • literally: {3, , 97}

  • Stack element 1:

  • description: (6, BYTE, 0)

  • literally: {6, 0, 0}

  • Stack element 2:

  • description: (10, REAL, 21.1)

  • literally: {10, 1, 0, 211}

  • Stack element 3:

  • description: (-1, REAL, 32.1)

  • literally: {-1, 1, 1, 55}

  • Altogether, this stack is: (“a”, 21.1, 32.1)

  • Literally: {3, 0, 97, 6, 0, 0

  • In order to ensure that the processor is running correctly, each processor

  • call can be alternated with a full stack analysis printout that looks like

  • this.

*/

void emb_processor(char *state, const char *program, int program_length)

/*

*/

void emb_postscript_compiler(const char *program, char *compiled_program)

/* The actuator works by creating an on-the-fly EmbProgramState so external
  • callers don’t have to manage memory over longer sessions.

  • It also compiles down our command line arguments, postscript and SVG

  • defines etc. into a common “machine code” like program.

*/

int emb_compiler(const char *program, int language, char *compiled_program)

/* Calls the compiler, then runs the compiled program. */ void emb_actuator(const char *program, int language)

/*

*/

void string_copy(char *dst, const char *src)

/* Finds the location of the first non-whitespace character
  • in the string and returns it.

*/

int string_whitespace(const char *s)

/* Note that our version of strlen can tell us that
  • the string is not null-terminated by returning -1.

*/

int string_len(const char *src)

/* Replacement for strcat that is only to be used for
  • short strings, otherwise use memory_copy.

*/

void string_cat(char *dst, const char *src)

/*

*/

int string_equals(const char *s1, const char *s2)

/*

*/

int string_rchar(const char *s, char c)

/* Replacement for memcpy. To allow us to take out
  • “string.h” entirely.

*/

void memory_copy(void *dst, const void *src, int n)

/* Replacement for memcmp. To allow us to take out
  • “string.h” entirely.

*/

char memory_cmp(void *dst, const void *src, int n)

/* Replacement for memset. To allow us to take out
  • “string.h” entirely.

*/

char memory_set(void *dst, char value, int n)

/* ENCODING SECTION
  • The functions in this section are grouped together to aid the developer’s

  • understanding of the similarities between the file formats. This also helps

  • reduce errors between reimplementation of the same idea.

  • For example: the Tajima ternary encoding of positions is used by at least 4

  • formats and the only part that changes is the flag encoding.

  • Converts a 6 digit hex string (I.E. “00FF00”)

  • into an EmbColor and returns it.

  • a val 6 byte code describing the color as a hex string, doesn’t require null termination.

  • Returns EmbColor the same color as our internal type.

*/

EmbColor embColor_fromHexStr(char* val)

EmbColor embColor_make(unsigned char red, unsigned char green, unsigned char blue)

/* Swap two bytes’ positions. */ void emb_swap(char *a, int i, int j)

/* Deal with endianness of the host machine. */ void fix_endian(char *a, int bytes, int endian)

/* Read a little-endian signed 16-bit integer. / int16_t emb_read_i16(FILE f)

/* Read a little-endian unsigned 16-bit integer. / uint16_t emb_read_u16(FILE f)

/* Read a little-endian signed 32-bit integer. / int32_t emb_read_i32(FILE f)

/* Read a little-endian unsigned 32-bit integer. / uint32_t emb_read_u32(FILE f)

/* Read a big-endian signed 16-bit integer. / int16_t emb_read_i16be(FILE f)

/* Read a big-endian unsigned 16-bit integer. / uint16_t emb_read_u16be(FILE f)

/* Read a big-endian signed 32-bit integer. / int32_t emb_read_i32be(FILE f)

/* Read a big-endian unsigned 32-bit integer. / uint32_t emb_read_u32be(FILE f)

/* a b a x a y a flags .
  • todo remove the unused return argument.

*/

int decode_t01_record(unsigned char b[3], int *x, int *y, int *flags)

/* Encode into bytes a b the values of the x-position a x,
  • y-position a y and the a flags.

*/

void encode_t01_record(unsigned char b[3], int x, int y, int flags)

/* Encode the signed ternary of the tajima format into
  • a b the position values a x and a y.

  • If the values of a x or a y fall outside of the

  • valid range of -121 and +121 then it returns 0 and

*/

int encode_tajima_ternary(unsigned char b[3], int x, int y)

/* Decode the signed ternary of the tajima format from
  • a b to the position values a x and a y.

  • There is no return argument.

*/

void decode_tajima_ternary(unsigned char b[3], int *x, int *y)

/* a file a dx a dy a flags

*/

void pfaffEncode(FILE* file, int dx, int dy, int flags)

/* Decode the bytes a a1, a a2 and a a3 .
  • Returns the EmbReal floating-point value.

*/

EmbReal pfaffDecode(unsigned char a1, unsigned char a2, unsigned char a3)

/* * a value
  • Returns unsigned char

*/

unsigned char mitEncodeStitch(EmbReal value)

/* * a value
  • Returns int

*/

int mitDecodeStitch(unsigned char value)

/* * a value
  • Returns int

*/

int decodeNewStitch(unsigned char value)

/* Read and write system for multiple byte types.
  • The caller passes the function to read/write from, the

  • memory location as a void pointer and a mode identifier that describes

  • the type. This way we can abstract out the endianness of the

  • system running the library and don’t have to maintain many functions,

  • just two.

  • TODO: This is being replaced by the simpler system above.

*/

void emb_read(void* f, void *b, int mode)

/* . / void fpad(FILE file, char c, int n)

/* . / void emb_write_i16(FILE f, int16_t data)

/* . / void emb_write_u16(FILE f, uint16_t data)

/* . / void emb_write_i16be(FILE f, int16_t data)

/* . / void emb_write_u16BE(FILE f, uint16_t data)

/* . / void emb_write_i32(FILE f, int32_t data)

/* . / void emb_write_u32(FILE f, uint32_t data)

void emb_write_i32be(FILE* f, int32_t data)

void emb_write_u32be(FILE* f, uint32_t data)

/* end of encoding section. */ end{lstlisting}

section{Compression}

This is section on compression is a work in progress.

Thanks to Jason Weiler for describing the binary formats of the HUS and VIP formats at: hyperref{http://www.jasonweiler.com/HUSandVIPFileFormatInfo.html}.

Further thanks to github user texttt{tatarize} for solving the mystery of the compression in: hyperref{https://github.com/EmbroidePy/pyembroidery}. with a description of that work here: hyperref{https://stackoverflow.com/questions/7852670/greenleaf-archive-library}

This is based on their work.

begin{lstlisting} int huffman_lookup_data[2];

/* Compress data “data” of length “length” to “output” with length “output_length”.
  • Returns whether it was successful as an int.

  • This avoids the now unnecessary compression by placing a

  • minimal header of 6 bytes and using only literals in the

  • huffman compressed part (see the sources above).

*/

int hus_compress(char *data, int length, char *output, int *output_length)

/* These next 2 functions represent the Huffman class in tartarize’s code.

*/

void huffman_build_table(huffman *h)

/* Lookup a byte_lookup in huffman table a h return result
  • as two bytes using the memory huffman_lookup_data.

*/

int *huffman_lookup(huffman h, int byte_lookup)

/* These functions represent the EmbCompress class. */ void compress_init()

/* Return bits from compress struct pointed to by “c” of length “length”. */ int compress_get_bits(compress *c, int length)

/* a c a bit_count . Returns.

*/

int compress_pop(compress *c, int bit_count)

/* a c a bit_count. Returns.

*/

int compress_peek(compress *c, int bit_count)

/* a c. Returns.

*/

int compress_read_variable_length(compress *c)

/* a c . Returns.

*/

void compress_load_character_length_huffman(compress *c)

/* Load character table to compress struct a c. Returns nothing.

*/

void compress_load_character_huffman(compress *c)

/* a c . Returns nothing.

*/

void compress_load_distance_huffman(compress *c)

/* a c . Returns nothing.

*/

void compress_load_block(compress *c)

/* a c . Returns the token as an int.

*/

int compress_get_token(compress *c)

/* a c . Returns the position as an int.

*/

int compress_get_position(compress *c)

/* a data a length a output a output_length .
  • Returns whether the decompression was successful.

*/

int hus_decompress(char *data, int length, char *output, int *output_length)

/* End of compression section. */

/* The array management for libembroidery’s arrays.

*/

/* Allocates memory for an EmbArray of the type determined by
  • the argument a type.

*/

EmbArray* emb_array_create(int type)

/* Resizes the array a a to be CHUNK_SIZE entries longer
  • if and only if the amount of room left is less than

  • 3 entries.

*/

int emb_array_resize(EmbArray *a)

/* Copies all entries in the EmbArray struct from a src to a dst.

*/

void emb_array_copy(EmbArray *dst, EmbArray *src)

/* Add a circle a b to the EmbArray a a and it returns if the
  • element was successfully added.

*/

int emb_array_add_circle(EmbArray *a, EmbCircle b)

/* Add an ellipse a b to the EmbArray a a and it returns if the
  • element was successfully added.

*/

int emb_array_add_ellipse(EmbArray *a, EmbEllipse b)

/* Add a flag a b to the EmbArray a a and it returns if the
  • element was successfully added.

*/

int emb_array_add_flag(EmbArray *a, EmbFlag b)

/* Add a line a b to the EmbArray a a and it returns if the
  • element was successfully added.

*/

int emb_array_addLine(EmbArray *a, EmbLine b)

/* Add a path a b to the EmbArray a a and it returns if the
  • element was successfully added.

*/

int emb_array_addPath(EmbArray *a, EmbPath b)

/* Add a point a b to the EmbArray a a and it returns if the
  • element was successfully added.

*/

int emb_array_addPoint(EmbArray *a, EmbPoint b)

/* Add a polyline a b to the EmbArray a a and it returns if the
  • element was successfully added.

*/

int emb_array_addPolyline(EmbArray *a, EmbPolyline b)

/* Add a polygon a b to the EmbArray a a and it returns if the
  • element was successfully added.

*/

int emb_array_addPolygon(EmbArray *a, EmbPolygon b)

/* Add a rectangle a b to the EmbArray a a and it returns if the
  • element was successfully added.

*/

int emb_array_addRect(EmbArray *a, EmbRect b)

/* Add a stitch a b to the EmbArray a a and it returns if the
  • element was successfully added.

*/

int emb_array_addStitch(EmbArray *a, EmbStitch b)

/* Add a generic geometry to the EmbArray a a and it returns if the
  • element was successfully added.

*/

int emb_array_add_geometry(EmbArray *a, EmbGeometry g)

/* Add a vector a b to the EmbArray a a and it returns if the
  • element was successfully added.

*/

int emb_array_addVector(EmbArray *a, EmbVector b)

/* Free the memory of EmbArray a a, recursively if necessary.

*/

void emb_array_free(EmbArray* a)

/* Print the vector “v2 with the name “label”. */ void emb_vector_print(EmbVector v, char *label)

/* Print the arc “arc”. */ void emb_arc_print(EmbArc arc)

/* Checks that there are enough bytes to interpret the header,
  • stops possible segfaults when reading in the header bytes.

  • Returns 0 if there aren’t enough, or the length of the file

  • if there are.

*/

int check_header_present(FILE* file, int minimum_header_length)

/* sectorSize based on the bcfFile version. / unsigned int sectorSize(bcf_file bcfFile)

/* . / int haveExtraDIFATSectors(bcf_file file)

/* . / int seekToSector(bcf_file bcfFile, FILE* file, const unsigned int sector)

/* . / void parseDIFATSectors(FILE file, bcf_file* bcfFile)

/* . / int bcfFile_read(FILE file, bcf_file* bcfFile)

/* Get the File object. / void GetFile(bcf_file* bcfFile, FILE* file, char* fileToFind)

/* . / void bcf_file_free(bcf_file bcfFile)

/* . / bcf_file_difat bcf_difat_create(FILE* file, unsigned int fatSectors, const unsigned int sectorSize)

/* . / unsigned int entriesInDifatSector(bcf_file_difat fat)

/* . */ unsigned int readFullSector(

FILE* file, bcf_file_difat* bcfFile, unsigned int* difatEntriesToRead)

/* . / void parseDirectoryEntryName(FILE file, bcf_directory_entry* dir)

/* . / bcf_directory CompoundFileDirectory(const unsigned int maxNumberOfDirectoryEntries)

/* . / EmbTime parseTime(FILE file)

/* . / bcf_directory_entry CompoundFileDirectoryEntry(FILE* file)

/* . / void readNextSector(FILE file, bcf_directory* dir)

/* . / void bcf_directory_free(bcf_directory* dir)

/* . / bcf_file_fat bcfFileFat_create(const unsigned int sectorSize)

/* . / void loadFatFromSector(bcf_file_fat fat, FILE* file)

/* . / bcf_file_header bcfFileHeader_read(FILE file)

/* . / int emb_generate_satin_outline(EmbArray *lines, EmbReal thickness, EmbSatinOutline result)

/* . / EmbArray emb_satin_outline_render(EmbSatinOutline* result, EmbReal density)

/* . / void write_24bit(FILE file, int x)

/* . */ int embColor_distance(EmbColor a, EmbColor b)

/* . */ void embColor_read(void *f, EmbColor *c, int toRead)

/* . */ void embColor_write(void *f, EmbColor c, int toWrite)

/* Returns the closest color to the required color based on
  • a list of available threads. The algorithm is a simple least

  • squares search against the list. If the (square of) Euclidean 3-dimensional

  • distance between the points in (red, green, blue) space is smaller

  • then the index is saved and the remaining index is returned to the

  • caller.

  • a color The EmbColor color to match.

  • a colors The EmbThreadList pointer to start the search at.

  • a mode Is the argument an array of threads (0) or colors (1)?

  • Returns closestIndex The entry in the ThreadList that matches.

*/

int emb_find_nearest_color(EmbColor color, EmbColor *color_list, int n_colors)

/* . */ int emb_find_nearest_thread(EmbColor color, EmbThread *thread_list, int n_threads)

/*
  • Returns a random thread color, useful in filling in cases where the

  • actual color of the thread doesn’t matter but one needs to be declared

  • to test or render a pattern.

  • Returns c The resulting color.

*/

EmbThread emb_get_random_thread(void)

/* . / void binaryReadString(FILE file, char* buffer, int maxLength)

/* . / void binaryReadUnicodeString(FILE file, char *buffer, const int stringLength)

/*
  • Tests for the presence of a string a s in the supplied

  • a array.

  • The end of the array is marked by an empty string.

  • Returns 0 if not present 1 if present.

*/

int stringInArray(const char *s, const char **array)

/* . / int emb_readline(FILE file, char *line, int maxLength)

/* TODO: description */

/* Get the trim bounds object. */ void get_trim_bounds(char const *s, char const **firstWord, char const **trailingSpace)

/* . / char copy_trim(char const *s)

/* Optimizes the number (a num) for output to a text file and returns
  • it as a string (a str).

*/

char* emb_optOut(EmbReal num, char* str)

/* . / void embTime_initNow(EmbTime t)

/* . / EmbTime embTime_time(EmbTime t)

/* Currently just crash testing.

*/

int test_convert(int test_case, int from, int to)

/* . */ int testMain(int test_index)

/* . */ int testTangentPoints(EmbCircle c, EmbVector p, EmbVector *t0, EmbVector *t1)

/* . */ void printArcResults(

EmbReal bulge, EmbArc arc, EmbVector center, EmbReal radius, EmbReal diameter, EmbReal chord, EmbVector chordMid, EmbReal sagitta, EmbReal apothem, EmbReal incAngle, char clockwise)

/* Create a test file 1 object. */ int create_test_file(int test_file, int format)

/* . */ void formats(void)

/* . */ void to_flag(char **argv, int argc, int i)

/* FILL ALGORITHMS

*/

const char *rules[] = {“+BF-AFA-FB+”, “-AF+BFB+FA-“};

L_system hilbert_curve_l_system = {

‘A’, “AB”, “F+-”, (char**)rules

};

/* a L a state a iterations a complete
  • Returns int

  • This is a slow generation algorithm.

*/

int lindenmayer_system(L_system L, char *state, int iterations, int complete) {

/* We know that the full length of the curve has to fit within
  • the number of stitches and we can cancel consecutive +-, -+

  • etc.

Potential reference:

@book{Prusinkiewicz1996Mar,

author = {Prusinkiewicz, Przemyslaw and Lindenmayer, Aristid and Hanan, J. S. and Fracchia, F. D. and Fowler, D. R. and de Boer, M. J. M. and Mercer, L.}, title = {{The Algorithmic Beauty of Plants (The Virtual Laboratory)}}, year = {1996}, month = {Mar}, publisher = {Springer}

}

*/

/* a points a n_points a width a tolerence
  • Remove points that lie in the middle of two short stitches that could

  • be one longer stitch. Repeat until none are found.

*/

static void join_short_stitches(int *points, int *n_points, int width, int tolerence)

/* a image a n_points a subsample_width a subsample_height
  • a threshold

  • Returns int*

  • Identify darker pixels to put stitches in.

*/

static int * threshold_method(EmbImage *image, int *n_points,

int subsample_width, int subsample_height, int threshold)

/* a points a n_points a width a bias
  • Greedy Algorithm

  • For each point in the list find the shortest distance to

  • any possible neighbour, then perform a swap to make that

  • neighbour the next item in the list.

  • To make the stitches lie more on one axis than the other

  • bias the distance operator to prefer horizontal direction.

*/

static void greedy_algorithm(int *points, int n_points, int width, EmbReal bias)

/* a pattern a points a n_points
  • a scale a width a height

*/

static void save_points_to_pattern(

EmbPattern *pattern, int *points, int n_points, EmbReal scale, int width, int height)

/* a pattern a image a threshhold
  • Uses a threshhold method to determine where to put

  • lines in the fill.

  • Needs to pass a “donut test”, i.e. an image with black pixels where:

  • 10 < x*x + y*y < 20

  • over the area (-30, 30) x (-30, 30).

  • Use render then image difference to see how well it passes.

*/

void emb_pattern_horizontal_fill(EmbPattern *pattern, EmbImage *image, int threshhold)

/* a pattern a image a threshhold
  • Uses a threshhold method to determine where to put

  • crosses in the fill.

  • To improve this, we can remove the vertical stitches when two crosses

  • neighbour. Currently the simple way to do this is to chain crosses

  • that are neighbours exactly one ahead.

*/

void emb_pattern_crossstitch(EmbPattern *pattern, EmbImage *image, int threshhold)

/* a pattern a iterations

*/

int hilbert_curve(EmbPattern *pattern, int iterations)

/* a state a iterations
  • using the “paper folding” method

  • todo find citation for paper folding method

*/

void generate_dragon_curve(char *state, int iterations)

/* Create the dragon curve for a iterations.
  • Returns 0 if the number of iterations is greater than 10

  • and 1 otherwise.

*/

int dragon_curve(int iterations)

/* a pattern
  • Returns StitchBlock*

*/

StitchBlock* BreakIntoColorBlocks(EmbPattern *pattern)

/* a blocks
  • Returns StitchBlock*

*/

StitchBlock * BreakIntoSeparateObjects(EmbStitchBlock* blocks)

/* a stitchData
  • Returns StitchObject*

*/

StitchObject * FindOutline(EmbStitchBlock* stitchData)

/* a p
  • Returns EmbPattern

*/

EmbPattern DrawGraphics(EmbPattern p)

/* a pattern
  • Returns EmbPattern

*/

EmbPattern SimplifyOutline(EmbPattern pattern)

bool[] _usePt; EmbReal _distanceTolerance;

/* Removes all collinear points on the polygon.
  • a vertices

  • a collinearityTolerance

  • Returns Vertices

*/

Vertices CollinearSimplify(Vertices vertices, float collinearityTolerance)

/* vertices
  • Returns Vertices

  • Removes all collinear points on the polygon. Has a default bias of 0.

  • param vertices: The polygon that needs simplification.

  • returns: A simplified polygon.

*/

Vertices CollinearSimplify(Vertices vertices)

/* vertices
  • a distanceTolerance

  • Returns Vertices

  • Ramer-Douglas-Peucker polygon simplification algorithm.

  • This is the general recursive version that does not use the

  • speed-up technique by using the Melkman convex hull.

  • If you pass in 0, it will remove all collinear points.

  • todo Ramer-Douglas-Peucker citation

*/

Vertices DouglasPeuckerSimplify(Vertices vertices, float distanceTolerance)

/* vertices a i a j */ void SimplifySection(Vertices vertices, int i, int j)

/* p a a a b
  • Returns EmbReal

*/

EmbReal DistancePointLine(EmbVector p, EmbVector a, EmbVector b)

/* vertices a areaTolerance
  • Returns public

  • From physics2d.net.

*/

public Vertices ReduceByArea(Vertices vertices, float areaTolerance)

/* vertices a tolerance
  • From Eric Jordan’s convex decomposition library.

  • Merges all parallel edges in the list of vertices.

*/

void MergeParallelEdges(EmbArray *vertices, float tolerance)

void embPolygon_reduceByDistance(EmbArray *vertices, EmbArray *simplified, float distance); void embPolygon_reduceByNth(EmbArray *vertices, EmbArray *out, int nth);

/* vertices a simplified a distance
  • Reduces the polygon by distance.

  • This is a non-destructive function, so the caller is responsible for

  • freeing “vertices” if they choose to keep “simplified”.

*/

void embPolygon_reduceByDistance(EmbArray *vertices, EmbArray *simplified, float distance)

/* vertices a out a nth
  • Reduces the polygon by removing the Nth vertex in the vertices list.

  • This is a non-destructive function, so the caller is responsible for

  • freeing vertices if they choose to keep out.

*/

void embPolygon_reduceByNth(EmbArray *vertices, EmbArray *out, int nth)

/* p1 a p2
  • Returns EmbPattern*

*/

EmbPattern * emb_pattern_combine(EmbPattern *p1, EmbPattern *p2)

/* p a arc a thread_index a style

*/

void emb_pattern_stitchArc(EmbPattern *p, EmbArc arc, int thread_index, int style)

/* p a circle a thread_index a style
  • style determines:

  • stitch density

  • fill pattern

  • outline or fill

  • For now it’s a straight fill of 1000 stitches of the whole object by

  • default.

  • Consider the intersection of a line in direction “d” that passes through

  • the disc with center “c”, radius “r”. The start and end points are:

  • $(c-r(d/|d|), c + r(d/|d|))$

  • Lines that are above and below this with an even seperation $s$ can be

  • found by taking the point on the line to be c+sn where the $n$ is the

  • unit normal vector to $d$ and the vector to be $d$ again. The

  • intersection points are therefore a right angled triangle, with one side

  • r, another s and the third the length to be solved, by Pythagoras we

  • have:

  • $(c + sn - sqrt{r^2-s^2}(d/|d|), c + sn + sqrt{r^2-s^2}(d/|d|))$

  • repeating this process gives us all the end points and the fill only

  • alters these lines by splitting the ones longer than some tolerence.

*/

void emb_pattern_stitchCircle(EmbPattern *p, EmbCircle circle, int thread_index, int style)

/* a p a ellipse a thread_index a style
  • todo finish stitchEllipse

*/

void emb_pattern_stitchEllipse(EmbPattern *p, EmbEllipse ellipse, int thread_index, int style)

/*a p a rect a thread_index a style
  • todo finish stitch path

*/

void emb_pattern_stitchPath(EmbPattern *p, EmbPath path, int thread_index, int style)

/*a p a rect a thread_index a style
  • todo finish stitch polygon

*/

void emb_pattern_stitchPolygon(EmbPattern *p, EmbPolygon polygon, int thread_index, int style)

/* a p a rect a thread_index a style
  • todo finish stitch polyline

*/

void emb_pattern_stitchPolyline(EmbPattern *p, EmbPolyline polyline, int thread_index, int style)

/* a p a rect a thread_index a style
  • Here we just stitch the rectangle in the direction of it’s longer side.

*/

void emb_pattern_stitchRect(EmbPattern *p, EmbRect rect, int thread_index, int style)

/* a p a rect a thread_index a style

*/

void emb_pattern_stitchText(EmbPattern *p, EmbRect rect, int thread_index, int style)

/* a p

*/

void emb_pattern_convertGeometry(EmbPattern* p)

/*
  • Frame for PES formats

*/

const char imageWithFrame[38][48];

/* Check that the pointer isn’t NULL before freeing. */ void safe_free(void *data)

unsigned char char_to_lower(unsigned char a)

/* Get extension from file name. */ int emb_fname_extension(const char *fileName, char ending[5])

/* Identify format from the file name. */ int emb_identify_format(const char *fileName)

/* . / char emb_pattern_read(EmbPattern pattern, const char *fileName, int format)

/* . / char emb_pattern_write(EmbPattern pattern, const char *fileName, int format)

/* . / char emb_pattern_readAuto(EmbPattern pattern, const char* fileName)

/* . / char emb_pattern_writeAuto(EmbPattern pattern, const char* fileName)

/*
  • TO DO: NEEDS ERROR REPORTING.

*/

unsigned char toyota_position_encode(EmbReal x)

/*
  • .

*/

EmbReal toyota_position_decode(unsigned char a)

/* The Toyota 100 format is a stitch-only format that uses an external color
  • file.

  • The stitch encoding is in 4 byte chunks.

*/

void toyota_100_encode(EmbVector *head_position, EmbStitch *st, unsigned char *b)

void toyota_100_decode(EmbVector *head_position, EmbStitch *st, unsigned char *b)

/* The Toyota 10o format is a stitch-only format that uses an external color
  • file.

  • The stitch encoding is in 3 byte chunks.

*/

void toyota_10o_encode(EmbVector *head_position, EmbStitch *st, unsigned char *b)

void toyota_10o_decode(EmbVector *head_position, EmbStitch *st, unsigned char *b)

/* The Bernina Embroidery Format (.art)
  • We don’t know much about this format. todo Find a source.

*/

void bernina_art_encode(EmbVector *position, EmbStitch *st, unsigned char *b)

void bernina_art_decode(EmbVector *position, EmbStitch *st, unsigned char *b)

/* A generic reader loop for any format that uses a binary block representing
  • an array of stitches.

*/

char read_stitch_block(

EmbPattern pattern, FILE file, void (*stitch_decoder)(EmbVector *, EmbStitch *, unsigned char *), int stitch_data_size, int mode

)

/* A generic writer loop for any format that uses a binary block representing
  • an array of stitches.

*/

char write_stitch_block(

EmbPattern pattern, FILE file, void (*stitch_encoder)(EmbVector *, EmbStitch *, unsigned char *), int stitch_data_size, int mode

)

/* The Bitmap Cache Embroidery Format (.bmc)
  • We don’t know much about this format. todo Find a source.

*/

char readBmc(EmbPattern* pattern, FILE* file)

char writeBmc(EmbPattern* pattern, FILE* file)

/* The Bits and Volts Embroidery Format (.bro)
  • The Bits and Volts bro format is a stitch-only format that

  • uses an external color file.

  • The header is 256 bytes.

  • There’s a series of unknown variables in the header.

  • The stitch list uses a variable length encoding which is

  • 2 bytes for any stitch.

*/

char readBro(EmbPattern* pattern, FILE* file)

char writeBro(EmbPattern* pattern, FILE* file)

/* The Melco Embroidery Format (.cnd)
  • The Melco cnd format is a stitch-only format.

  • We don’t know much about this format.

  • todo Find a source.

*/

char readCnd(EmbPattern* pattern, FILE* file)

char writeCnd(EmbPattern* pattern, FILE* file)

/* The Embroidery Thread Color Format (.col)
  • An external color file format for formats that do not record

  • their own colors.

  • It is a human-readable format that has a header that is

  • a single line containing only the number of threads in decimal

  • followed by the windows line break `textbackslash{}rtextbackslash{}n}.

  • Then the rest of the file is a comma seperated value list of

  • all threads with 4 values per line: the index of the thread

  • then the red, green and blue channels of the color in that order.

  • subsubsection col-example Example

  • If we had a pattern called “example” with four colors:

  • black, red, magenta and cyan in that order then the file is

  • (with the white space written out):

  • example.col

  • 4rn

  • 0,0,0,0rn

  • 1,255,0,0rn

  • 2,0,255,0rn

  • 3,0,0,255rn

*/

char readCol(EmbPattern* pattern, FILE* file)

char writeCol(EmbPattern* pattern, FILE* file)

/* The Singer Embroidery Format (.csd)
  • Stitch Only Format.

*/

#define CsdSubMaskSize 479 #define CsdXorMaskSize 501

char _subMask[CsdSubMaskSize]; char _xorMask[CsdXorMaskSize];

const unsigned char csd_decryptArray[];

void BuildDecryptionTable(int seed)

unsigned char DecodeCsdByte(long fileOffset, unsigned char val, int type)

char readCsd(EmbPattern* pattern, FILE* file)

char writeCsd(EmbPattern* pattern, FILE* file)

/* Comma Separated Values (.csv)
  • Comma Seperated Values files aren’t a universal system, here we aim to

  • offer a broad support. The dialect is detected based on the opening lines,

  • as each manufacturer should label their CSV files there.

  • ## Embroidermodder 2.0 CSV Dialect

  • Our own version has the identifier comment line:

  • Control Symbol | Type | Description |
  • |---|—|

  • # | COMMENT | |
  • > | VARIABLE | To store records of a pattern’s width, height etc. This means that data stored in the header of say a .dst file is preserved. |
  • $ | THREAD | |
  • * | STITCH | |
  • * | JUMP | |
  • * | COLOR | To change a color: used for trim as well |
  • * | END | To end a pattern. |
  • * | UNKNOWN | For any feature that we can’t identify.
  • ## EmBird CSV Dialect

*/

char* csvStitchFlagToStr(int flags)

int csvStrToStitchFlag(const char* str)

char readCsv(EmbPattern* pattern, FILE* file)

char writeCsv(EmbPattern* pattern, FILE* file)

/* The Barudan Embroidery Format (.dat)
  • Stitch Only Format.

*/

char readDat(EmbPattern* pattern, FILE* file)

char writeDat(EmbPattern* pattern, FILE* file)

/* The Melco Embroidery Format (.dem)
  • Stitch Only Format

*/

char readDem(EmbPattern* pattern, FILE* file)

char writeDem(EmbPattern* pattern, FILE* file)

/* The Barudan Embroidery Format (.dsb)
  • Stitch Only Format.

  • [X] Basic Read Support

  • [o] Basic Write Support

  • [o] Well Tested Read

  • [o] Well Tested Write

*/

char readDsb(EmbPattern* pattern, FILE* file)

char writeDsb(EmbPattern* pattern, FILE* file)

/*
  • # Tajima Embroidery Format (.dst)

  • .DST (Tajima) embroidery file read/write routines

  • Format comments are thanks to tspilman@dalcoathletic.com who’s

  • notes appeared at http://www.wotsit.org under Tajima Format.

  • Stitch Only Format.

  • [X] Basic Read Support

  • [X] Basic Write Support

  • [ ] Well Tested Read

  • [ ] Well Tested Write

  • Other references: cite kde_tajima , cite acatina .

  • ## Header

  • The header contains general information about the design. It is in lines of ASCII, so

  • if you open a DST file as a text file, it’s the only part that’s easy to read. The

  • line ending symbol is `0x0D}. The header is necessary for the file to be read by

  • most softwares and hardwares.

  • The header is 125 bytes of data followed by padding spaces to make it 512 bytes

  • in total.

  • The lines are as follows.

  • Label | Size | Description | Example |
  • |----|—-|----|—-|

  • LA: | 17 | The design name with no path or extension. The space reserved is 16 characters, but the name must not be longer than 8 and be padded to 16 with spaces (0x20). | “LA:Star “ |
  • ST: | 8 | The stitch count. An integer in the format %07d, that is: a 7 digit number padded by leading zeros. This is the total accross all possible stitch flags. | |
  • CO: | 4 | The number of color changes (not to be confused with thread count, an all black design we would have the record textbf{000}). An integer in the format %03d, that is: a 3 digit number padded by leading zeros. | |
  • +X: | 6 | The extent of the pattern in the postitive x direction in millimeters. An integer in the format %05d, that is: a 5 digit number padded by leading zeros. | |
  • -X: | 6 | The extent of the pattern in the negative x direction in millimeters. An integer in the format %05d, that is: a 5 digit integer padded by leading zeros. | |
  • +Y: | 6 | The extent of the pattern in the postitive y direction in millimeters. An integer in the format %05d, that is: a 5 digit integer padded by leading zeros. | |
  • -Y: | 6 | The extent of the pattern in the negative y direction in millimeters. An integer in the format %05d, that is: a 5 digit integer padded by leading zeros. | |
  • AX: | 7 | The difference of the end from the start in the x direction in 0.1mm, the first char should be the sign, followed by an integer in the format %05d, that is: a 5 digit integer padded by leading zeros. | |
  • AY: | 7 | The difference of the end from the start in the y direction in 0.1mm, the first char should be the sign, followed by an integer in the format %05d, that is: a 5 digit integer padded by leading zeros. | |
  • MX: | 7 | The x co-ordinate of the last point in the previous file should the design span multiple files. Like AX, it is the sign, followed by a 5 digit integer. If we have a one file design set it to zero. | |
  • MY: | 7 | The y co-ordinate of the last point in the previous file should the design span multiple files. Like AY, it is the sign, followed by a 5 digit integer. If we have a one file design set it to zero. | |
  • PD: | 10 | Information about multivolume designs. | |
  • ### Stitch Data

  • Uses 3 byte per stitch encoding with the format as follows:

  • Bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
  • |-------|—–|-----|—–|-----|—–|-----|—–|-----|

  • Byte 0 | y+1 | y-1 | y+9 | y-9 | x-9 | x+9 | x-1 | x+1 |
  • Byte 1 | y+3 | y-3 | y+27 | y-27 | x-27 | x+27 | x-3 | x+3 |
  • Byte 2 | jump | color change | y+81 | y-81 | x-81 | x+81 | set | set |
  • T01 and Tap appear to use Tajima Ternary.

  • Where the stitch type is determined as:

    • Normal Stitch 0b00000011 0x03

    • Jump Stitch 0b10000011 0x83

    • Stop/Change Color 0b11000011 0xC3

    • End Design 0b11110011 0xF3

  • Inclusive or’ed with the last byte.

  • Note that the max stitch length is the largest sum of $1+3+9+27+81=121$

  • where the unit length is 0.1mm so 12.1mm. The coordinate system is right handed.

*/

int decode_record_flags(unsigned char b2)

/* TODO: review this then remove since emb-pattern.c has a similar function / void combine_jump_stitches(EmbPattern p, int jumpsPerTrim)

void encode_record(FILE* file, int x, int y, int flags)

/*convert 2 characters into 1 int for case statement */ /*#define cci(s) (s[0]*256+s[1]) */ #define cci(c1, c2) (c1*256+c2)

void set_dst_variable(EmbPattern* pattern, char* var, char* val)

/*
  • The header seems to contain information about the design.

  • Seems to be ASCII text delimited by 0x0D (carriage returns).

  • This must be in the file for most new software or hardware

  • to consider it a good file! This is much more important

  • than I originally believed. The header is 125 bytes in

  • length and padded out by 0x20 to 512 bytes total.

  • All entries in the header seem to be 2 ASCII characters

  • followed by a colon, then it’s value trailed by a carriage return.

  • char LA[16+1]; First is the ‘LA’ entry, which is the design name with no

  • path or extension information. The blank is 16 characters

  • in total, but the name must not be longer that 8 characters

  • and padded out with 0x20.

  • char ST[7+1]; Next is the stitch count ST, this is a 7 digit number

  • padded by leading zeros. This is the total stitch count

  • including color changes, jumps, nups, and special records.

  • char CO[3+1]; Next, is CO or colors, a 3 digit number padded by leading

  • zeros. This is the number of color change records in the file.

  • char POSX[5+1]; Next is +X or the positive X extent in centimeters, a 5

  • digit non-decimal number padded by leading zeros.

  • char NEGX[5+1]; Following is the -X or the negative X extent in millimeters,

  • a 5 digit non-decimal number padded by leading zeros.

  • char POSY[5+1]; Again, the +Y extents.

  • char NEGY[5+1]; Again, the -Y extents.

  • char AX[6+1]; AX and AY should express the relative coordinates of the

  • char AY[6+1]; last point from the start point in 0.1 mm. If the start

  • and last points are the same, the coordinates are (0,0).

  • char MX[6+1]; MX and MY should express coordinates of the last point of

  • char MY[6+1]; the previous file for a multi-volume design. A multi-

  • volume design means a design consisted of two or more files.

  • This was used for huge designs that can not be stored in a

  • single paper tape roll. It is not used so much (almost

  • never) nowadays.

  • char PD[9+1]; PD is also storing some information for multi-volume design.

*/

char readDst(EmbPattern* pattern, FILE* file)

char writeDst(EmbPattern* pattern, FILE* file)

/* ZSK USA Embroidery Format (.dsz)
  • The ZSK USA dsz format is stitch-only.

*/

char readDsz(EmbPattern* pattern, FILE* file)

/* WARNING: this is untested.
  • This is based on the readDsz function.

*/

char writeDsz(EmbPattern* pattern, FILE* file)

/* Drawing Exchange Format (.dxf)
  • Graphics format for drawing files designed and used by AudoDesk for their AutoCAD program. cite{dxf_reference}

*/

void readLine(FILE* file, char *str)

char readDxf(EmbPattern* pattern, FILE* file)

char writeDxf(EmbPattern* pattern, FILE* file)

/* Embird Embroidery Format (.edr)
  • Stitch Only Format

*/

char readEdr(EmbPattern* pattern, FILE* file)

char writeEdr(EmbPattern* pattern, FILE* file)

/* The Elna Embroidery Format (.emd)
  • Stitch Only Format.

*/

char emdDecode(unsigned char inputByte) {

char readEmd(EmbPattern* pattern, FILE* file) {

char writeEmd(EmbPattern* pattern, FILE* file) {

/* Melco Embroidery Format (.exp)
  • Stitch Only Format.

*/

char expDecode(unsigned char a1)

char readExp(EmbPattern* pattern, FILE* file)

char writeExp(EmbPattern* pattern, FILE* file)

/* Eltac Embroidery Format (.exy)
  • Stitch Only Format.

*/

int decode_exy_flags(unsigned char b2)

char readExy(EmbPattern* pattern, FILE* file)

char writeExy(EmbPattern* pattern, FILE* file)

/* Sierra Expanded Embroidery Format (.eys)
  • Stitch Only Format.

  • Smoothie G-Code Embroidery Format (.fxy)?

*/

char readEys(EmbPattern* pattern, FILE* file)

char writeEys(EmbPattern* pattern, FILE* file)

/* Fortron Embroidery Format (.fxy)
  • Stitch Only Format.

*/

char readFxy(EmbPattern* pattern, FILE* file)

char writeFxy(EmbPattern* pattern, FILE* file)

/*
  • Smoothie G-Code

  • Main Reference:

  • Machinery’s Handbook Guide

  • A Guide to Tables, Formulas, & More in the 31st Edition

  • by John Milton Amiss, Franklin D. Jones and Henry Ryffel

*/

char readGc(EmbPattern* pattern, FILE* file)

char writeGc(EmbPattern* pattern, FILE* file)

/*
  • Great Notions Embroidery Format (.gnc)

  • Stitch Only Format.

*/

/* TODO: finish readGnc / char readGnc(EmbPattern pattern, FILE* file)

/* TODO: finish writeGnc / char writeGnc(EmbPattern pattern, FILE* file)

/*
  • Gold Thread Embroidery Format (.gt)

  • Stitch Only Format.

*/

char readGt(EmbPattern* pattern, FILE* file)

char writeGt(EmbPattern* pattern, FILE* file)

/* Husqvarna Viking Embroidery Format (.hus)
  • Stitch Only Format.

*/

int husDecodeStitchType(unsigned char b)

unsigned char* husDecompressData(unsigned char* input, int compressedInputLength, int decompressedContentLength)

unsigned char* husCompressData(unsigned char* input, int decompressedInputSize, int* compressedSize)

int husDecodeByte(unsigned char b)

unsigned char husEncodeByte(EmbReal f)

unsigned char husEncodeStitchType(int st)

#define READ_RAW_BYTES(ptr, size, file)

char readHus(EmbPattern* pattern, FILE* file)

char writeHus(EmbPattern* pattern, FILE* file)

/*
  • Inbro Embroidery Format (.inb)

  • Stitch Only Format.

*/

char readInb(EmbPattern* pattern, FILE* file)

char writeInb(EmbPattern* pattern, FILE* file)

/*
  • Embroidery Color Format (.inf)

  • Stitch Only Format.

*/

char readInf(EmbPattern* pattern, FILE* file)

char writeInf(EmbPattern* pattern, FILE* file)

/*
  • Janome Embroidery Format (.jef)

  • Stitch Only Format.

*/

int jefGetHoopSize(int width, int height)

char jefDecode(unsigned char inputByte)

void jefSetHoopFromId(EmbPattern* pattern, int hoopCode)

struct hoop_padding {

int left; int right; int top; int bottom;

};

void read_hoop(FILE* file, struct hoop_padding *hoop, char *label)

char readJef(EmbPattern* pattern, FILE* file)

void jefEncode(unsigned char* b, char dx, char dy, int flags)

char writeJef(EmbPattern* pattern, FILE* file)

/* subsection pfaff-ksm-format Pfaff professional Design format (.ksm)

Stitch Only Format.

*/

void ksmEncode(unsigned char* b, char dx, char dy, int flags)

char readKsm(EmbPattern* pattern, FILE* file)

char writeKsm(EmbPattern* pattern, FILE* file)

/* Pfaff Embroidery Format (.max)
  • Stitch Only Format.

*/

const unsigned char max_header[] = {

/* —————————————————————- / / format max */

/* Pfaff MAX embroidery file format / char readMax(EmbPattern pattern, FILE* file)

char writeMax(EmbPattern* pattern, FILE* file)

/* subsection mitsubishi-mit-format Mitsubishi Embroidery Format (.mit)

Stitch Only Format.

*/

char readMit(EmbPattern* pattern, FILE* file)

char writeMit(EmbPattern* pattern, FILE* file)

/* subsection ameco-new-format Ameco Embroidery Format (.new)

Stitch Only Format.

*/

char readNew(EmbPattern* pattern, FILE* file)

char writeNew(EmbPattern* pattern, FILE* file)

/* subsection melco-ofm-format Melco Embroidery Format (.ofm)

Stitch Only Format.

*/

char* ofmReadLibrary(FILE* file)

static int ofmReadClass(FILE* file)

void ofmReadBlockHeader(FILE* file)

void ofmReadColorChange(FILE* file, EmbPattern* pattern)

void ofmReadThreads(FILE* file, EmbPattern* p)

EmbReal ofmDecode(unsigned char b1, unsigned char b2)

void ofmReadExpanded(FILE* file, EmbPattern* p)

char readOfm(EmbPattern* pattern, FILE* fileCompound)

char writeOfm(EmbPattern* pattern, FILE* file)

/*
  • ## Pfaff PCD File Format (.pcd)

  • Stitch Only Format.

  • The format uses a signed 3 byte-length number type.

  • See the description here ([5](5)) for the overview of the format.

  • For an example of the format see ([11](11)).

*/

char readPcd(EmbPattern* pattern, const char fileName, FILE file)

char writePcd(EmbPattern* pattern, FILE* file)

/*
  • Pfaff Embroidery Format (.pcm)

  • The Pfaff pcm format is stitch-only.

*/

char readPcm(EmbPattern* pattern, FILE* file)

char writePcm(EmbPattern* pattern, FILE* file)

/*
  • Pfaff Embroidery Format (.pcq)

  • The Pfaff pcq format is stitch-only.

*/

char readPcq(EmbPattern* pattern, const char* fileName, FILE* file)

char writePcq(EmbPattern* pattern, FILE* file)

/*
  • Pfaff Embroidery Format (.pcs)

  • The Pfaff pcs format is stitch-only.

*/

char readPcs(EmbPattern* pattern, const char* fileName, FILE* file)

char writePcs(EmbPattern* pattern, FILE* file)

/*
  • Brother Embroidery Format (.pec)

  • The Brother pec format is stitch-only.

*/

void readPecStitches(EmbPattern* pattern, FILE* file)

void pecEncodeJump(FILE* file, int x, int types)

void pecEncodeStop(FILE* file, unsigned char val)

char readPec(EmbPattern* pattern, const char fileName, FILE file)

void pecEncode(FILE* file, EmbPattern* p)

void writeImage(FILE* file, unsigned char image[][48]);

void writePecStitches(EmbPattern* pattern, FILE* file, const char *fileName)

char writePec(EmbPattern* pattern, const char* fileName, FILE* file)

/*
  • Brother Embroidery Format (.pel)

  • The Brother pel format is stitch-only.

*/

char readPel(EmbPattern pattern, FILE file)

char writePel(EmbPattern pattern, FILE file)

/*
  • Brother Embroidery Format (.pem)

  • The Brother pem format is stitch-only.

*/

char readPem(EmbPattern pattern, FILE file)

char writePem(EmbPattern pattern, FILE file)

/*
  • Brother Embroidery Format (.pes)

  • The Brother pes format is stitch-only.

*/

const char *pes_version_strings[];

/* format pes */

int pes_version = PES0001;

char readPes(EmbPattern* pattern, const char fileName, FILE file)

void readDescriptions(FILE* file, EmbPattern* pattern)

void readPESHeaderV5(FILE* file, EmbPattern* pattern)

void readPESHeaderV6(FILE* file, EmbPattern* pattern)

void readPESHeaderV7(FILE* file, EmbPattern* pattern)

void readPESHeaderV8(FILE* file, EmbPattern* pattern)

void readPESHeaderV9(FILE* file, EmbPattern* pattern)

void readPESHeaderV10(FILE* file, EmbPattern* pattern)

void readHoopName(FILE* file, EmbPattern* pattern)

void readImageString(FILE* file, EmbPattern* pattern)

void readProgrammableFills(FILE* file, EmbPattern* pattern) {

void readMotifPatterns(FILE* file, EmbPattern* pattern)

void readFeatherPatterns(FILE* file, EmbPattern* pattern)

void readThreads(FILE* file, EmbPattern* pattern)

void pesWriteSewSegSection(EmbPattern* pattern, FILE* file)

void pesWriteEmbOneSection(EmbPattern* pattern, FILE* file)

char writePes(EmbPattern* pattern, const char fileName, FILE file)

/*
  • Brother Embroidery Format (.phb)

  • The Brother phb format is stitch-only.

*/

char readPhb(EmbPattern* pattern, FILE* file)

char writePhb(EmbPattern* pattern, FILE* file)

/*
  • Brother Embroidery Format (.phc)

  • The Brother phc format is stitch-only.

*/

char readPhc(EmbPattern* pattern, FILE* file)

char writePhc(EmbPattern* pattern, FILE* file)

/*
  • AutoCAD Embroidery Format (.plt)

  • The AutoCAD plt format is stitch-only.

*/

char readPlt(EmbPattern* pattern, FILE* file)

char writePlt(EmbPattern* pattern, FILE* file)

/*
  • RGB Color File (.rgb)

  • The RGB format is a color-only format to act as an external color file for other formats.

*/

char readRgb(EmbPattern* pattern, FILE* file)

char writeRgb(EmbPattern* pattern, FILE* file)

/*
  • Janome Embroidery Format (.sew)

  • The Janome sew format is stitch-only.

*/

char sewDecode(unsigned char inputByte)

char readSew(EmbPattern* pattern, FILE* file)

char writeSew(EmbPattern* pattern, FILE* file)

/*
  • Husqvarna Viking Embroidery Format (.shv)

  • The Husqvarna Viking shv format is stitch-only.

*/

char shvDecode(unsigned char inputByte)

short shvDecodeShort(unsigned short inputByte)

char readShv(EmbPattern* pattern, FILE* file)

char writeShv(EmbPattern* pattern, FILE* file)

/*
  • Sunstar Embroidery Format (.sst)

  • The Sunstar sst format is stitch-only.

*/

char readSst(EmbPattern* pattern, FILE* file)

char writeSst(EmbPattern* pattern, FILE* file)

/*
  • Data Stitch Embroidery Format (.stx)

  • The Data Stitch stx format is stitch-only.

*/

int stxReadThread(StxThread* thread, FILE* file)

char readStx(EmbPattern* pattern, FILE* file)

char writeStx(EmbPattern* pattern, FILE* file)

/*
  • Scalable Vector Graphics (.svg)

  • The scalable vector graphics (SVG) format is a graphics format maintained by …

*/

int svgCreator;

int svgExpect; int svgMultiValue;

int current_element_id; SvgAttribute attributeList[1000]; int n_attributes = 0; char currentAttribute[1000]; char currentValue[1000];

int svg_identify_element(char *buff);

EmbColor svgColorToEmbColor(char* colorString)

int toUpper(char cmd)

int svgPathCmdToEmbPathFlag(char cmd)

char* svgAttribute_getValue(const char* name)

void parse_circle(EmbPattern *p)

void parse_ellipse(EmbPattern *p)

void parse_line(EmbPattern *p)

void parse_path(EmbPattern *p)

EmbArray * parse_pointlist(EmbPattern *p)

void parse_polygon(EmbPattern *p)

void parse_polyline(EmbPattern *p)

void parse_rect(EmbPattern *p)

void svgAddToPattern(EmbPattern* p)

int svg_identify_element(char *buff)

int svgIsElement(const char* buff)

int svgIsSvgAttribute(const char* buff)

void svgProcess(int c, const char* buff)

char readSvg(EmbPattern* pattern, FILE* file)

/*! Writes the data from a pattern to a file with the given a fileName.
  • Returns c true if successful, otherwise returns c false. */

char writeSvg(EmbPattern* pattern, FILE* file)

/*
  • Pfaff Embroidery Format (.t01)

  • The Pfaff t01 format is stitch-only.

*/

char readT01(EmbPattern* pattern, FILE* file)

char writeT01(EmbPattern* pattern, FILE* file)

/*
  • Pfaff Embroidery Format (.t09)

  • The Pfaff t09 format is stitch-only.

*/

char readT09(EmbPattern* pattern, FILE* file)

char writeT09(EmbPattern* pattern, FILE* file)

/*
  • Happy Embroidery Format (.tap)

  • The Happy tap format is stitch-only.

*/

void encode_tap_record(FILE* file, int x, int y, int flags)

int decode_tap_record_flags(unsigned char b2)

char readTap(EmbPattern* pattern, FILE* file)

char writeTap(EmbPattern* pattern, FILE* file)

/*
  • ThredWorks Embroidery Format (.thr)

  • The ThreadWorks thr format is stitch-only.

  • bit definitions for attributes of stitch

  • 0-3 stitch color

  • 4-14 form pointer

  • 15-18 spares

  • 19 not a form stitch

  • 20 center walk stitch

  • 21 edge walk stitch

  • 22 underlay stitch

  • 23 knot stitch

  • 24 feather stitch

  • 25-27 layer

  • 28 spare

  • 29-30 stitch type

  • 00=not a form stitch,

  • 01=form fill,

  • 10=form border fill,

  • 11=applique stitches

  • 31 set for user edited stitches

*/

char readThr(EmbPattern* pattern, FILE* file)

char writeThr(EmbPattern* pattern, FILE* file)

/*
  • Text File (.txt)

  • The txt format is stitch-only and isn’t associated with a specific company.

*/

char readTxt(EmbPattern* pattern, FILE* file)

char writeTxt(EmbPattern* pattern, FILE* file)

/*
  • Barudan Embroidery Format (.u00)

  • The Barudan u00 format is stitch-only.

*/

char readU00(EmbPattern* pattern, FILE* file)

char writeU00(EmbPattern* pattern, FILE* file)

/*
  • Barudan Embroidery Format (.u01)

  • The Barudan u01 format is stitch-only.

  • TODO: AFAIK this is a duplicate of U00. Review for differences and merge

  • files and handle accordingly.

*/

char readU01(EmbPattern* pattern, FILE* file)

char writeU01(EmbPattern* pattern, FILE* file)

/*
  • Pfaff Embroidery Format (.vip). The vip format is stitch-only.

*/

const unsigned char vipDecodingTable[];

int vipDecodeByte(unsigned char b)

int vipDecodeStitchType(unsigned char b)

unsigned char* vipDecompressData(unsigned char* input, int compressedInputLength, int decompressedContentLength)

char readVip(EmbPattern* pattern, FILE* file)

unsigned char* vipCompressData(unsigned char* input, int decompressedInputSize, int* compressedSize)

unsigned char vipEncodeByte(EmbReal f)

unsigned char vipEncodeStitchType(int st)

char writeVip(EmbPattern* pattern, FILE* file)

/*
  • VP3 FORMAT

  • Pfaff Embroidery Format (.vp3)

  • The Pfaff vp3 format is stitch-only.

*/

unsigned char* vp3ReadString(FILE* file)

int vp3Decode(unsigned char inputByte)

short vp3DecodeInt16(unsigned short inputByte)

vp3Hoop vp3ReadHoopSection(FILE* file)

char readVp3(EmbPattern* pattern, FILE* file)

void vp3WriteStringLen(FILE* file, const char* str, int len) {

emb_write_u16BE(file, len); emb_fwrite(str, len, file);

}

void vp3WriteString(FILE* file, const char* str)

void vp3PatchByteCount(FILE* file, int offset, int adjustment)

char writeVp3(EmbPattern* pattern, FILE* file)

/*
  • Singer Embroidery Format (.xxx)

  • The Singer xxx format is stitch-only.

*/

char xxxDecodeByte(unsigned char inputByte)

char readXxx(EmbPattern* pattern, FILE* file)

void xxxEncodeStop(FILE* file, EmbStitch s)

void xxxEncodeStitch(FILE* file, EmbReal deltaX, EmbReal deltaY, int flags)

void xxxEncodeDesign(FILE* file, EmbPattern* p)

char writeXxx(EmbPattern* pattern, FILE* file)

/*
  • ZSK FORMAT

  • The ZSK USA Embroidery Format (.zsk)

  • The ZSK USA zsk format is stitch-only.

*/

char readZsk(EmbPattern* pattern, FILE* file)

/* based on the readZsk function / char writeZsk(EmbPattern pattern, FILE* file)

/*
  • GEOMETRY

*/

/* Our generic object interface backends to each individual type.
  • The caller defines what the type is.

*/

EmbGeometry * embGeometry_init(int type_in)

/* Free the memory occupied by a non-stitch geometry object.
  • Pointer to geometry memory.

*/

void embGeometry_free(EmbGeometry *obj)

/* Translate a obj by the vector a delta.
  • obj A pointer to the geometry memory.

  • delta A vector in the 0.1mm scale to offset the geometry by.

*/

void emb_geometry_move(EmbGeometry *obj, EmbVector delta)

/* Calculate the bounding box of geometry a obj based on what kind of
  • geometric object it is.

  • obj A pointer to the geometry memory.

  • Returns an EmbRect, the bounding box in the same scale as the input geometry.

  • In the case of a failure the bounding box returned is always the unit square

  • with top left corner at (0, 0).

*/

EmbRect embGeometry_boundingRect(EmbGeometry *obj)

/*
  • ARC GEOMETRY

  • The EmbArc is implicitly an elliptical arc not a circular one

  • because of our need to cover all of the SVG spec. Note that

  • the circlar arcs are a subset of the elliptical arcs.

  • TODO: some of these formulae may assume that the arc is circular,

  • correct for elliptic versions.

  • Returns an EmbGeometry. It is created on the stack.

  • Note that the default arc is the semicircular arc of the circle of radius

  • arc.

*/

EmbGeometry emb_arc(EmbReal x1, EmbReal y1, EmbReal x2, EmbReal y2, EmbReal x3, EmbReal y3)

/* Calculus based approach at determining whether a polygon is clockwise or counterclockwise.
  • Returns true if arc is clockwise.

*/

char emb_arc_clockwise(EmbGeometry g)

/* Calculates the CenterPoint of the Arc */ EmbVector emb_arc_center(EmbGeometry g)

/* Calculate the Radius */ EmbReal emb_arc_radius(EmbGeometry g)

/* Calculate the Diameter */ EmbReal emb_arc_diameter(EmbGeometry g)

/* Calculate the Chord Angle (from arc.start to arc.end). */ EmbReal emb_arc_chordAngle(EmbGeometry g)

/* Calculate the Chord MidPoint. */ EmbVector emb_arc_chordMid(EmbGeometry g)

/* Calculate the Sagitta. */ EmbReal emb_arc_sagitta(EmbGeometry g)

/* Calculate the Apothem */ EmbReal emb_arc_apothem(EmbGeometry g)

/* Calculate the Included Angle. */ EmbReal emb_arc_incAngle(EmbGeometry g)

/* TODO: fixme */ EmbReal emb_arc_bulge(EmbGeometry g)

void emb_arc_setCenter(EmbGeometry *g, EmbVector point)

void emb_arc_setRadius(EmbGeometry *g, float radius)

EmbReal emb_arc_arcLength(EmbArc arc)

EmbReal emb_arc_includedAngle(EmbArc arc)

void set_object_color(EmbGeometry *obj, EmbColor color)

void embGeometry_setColorRGB(EmbGeometry *obj, unsigned int rgb)

void embGeometry_setLineType(EmbGeometry *obj, int lineType)

void embGeometry_setLineWeight(EmbGeometry *obj, float lineWeight)

EmbVector emb_base_rubber_point(EmbGeometry *obj, const char *key)

const char * emb_base_rubber_text(EmbGeometry *obj, const char *key)

void emb_circle_main()

void emb_circle_CircleObject(EmbVector center, float radius, unsigned int rgb)

void emb_circle_CircleObject(EmbCircle* obj)

void emb_circle_setDiameter(EmbCircle *circle, float diameter)

void emb_circle_setArea(EmbCircle *circle, float area)

void emb_circle_setCircumference(EmbCircle *circle, float circumference)

void dim_leader_init(EmbLine line, unsigned int rgb, int lineType)

void emb_dimleader_set_end_point_1(EmbVector endPt1)

void dimleader_setEndPoint2(EmbVector endPt2)

EmbVector dimleader_objectEndPoint1()

EmbVector dimleader_objectEndPoint2()

EmbVector dimleader_objectMidPoint()

float dimleader_objectAngle()

void dimleader_updateLeader()

void emb_ellipse_main()

void emb_ellipse(float centerX, float centerY, float width, float height, unsigned int rgb, QGraphicsItem* parent)

void emb_ellipse(EllipseObject* obj, QGraphicsItem* parent)

void image_init(EmbRect rect, unsigned int rgb, int lineType)

void image_setRect(float x, float y, float w, float h)

EmbVector image_objectTopLeft()

EmbVector image_objectTopRight()

EmbVector image_objectBottomLeft()

EmbVector image_objectBottomRight()

//Command: Line

float global = {}; //Required

void emb_line_init(void)

void emb_line_init(EmbLine line_in, unsigned int rgb, PenStyle lineType)

void emb_line_set_endpoint1(EmbVector point1)

void emb_line_set_endpoint2(EmbVector point1)

EmbVector emb_line_EndPoint2()

EmbVector emb_line_MidPoint()

float emb_line_Angle()

path_PathObject(float x, float y, const QPainterPath p, unsigned int rgb, QGraphicsItem* parent)

path_PathObject(PathObject* obj, QGraphicsItem* parent)

void path_init(float x, float y, const QPainterPath& p, unsigned int rgb, int lineType)

void point_init(float x, float y, unsigned int rgb, int lineType)

void emb_polygon(float x, float y, const QPainterPath& p, unsigned int rgb, QGraphicsItem* parent)

void polygon_PolygonObject(PolygonObject* obj, QGraphicsItem* parent)

void emb_polygon_init(float x, float y, const QPainterPath& p, unsigned int rgb, PenStyle lineType)

int polygon_findIndex(EmbVector point)

void emb_polyline(float x, float y, const QPainterPath& p, unsigned int rgb, QGraphicsItem* parent)

void emb_polyline(EmbPolyline* obj, QGraphicsItem* parent)

void embPolyline_init(float x, float y, QPainterPath *p, unsigned int rgb, int lineType)

int embPolyline_findIndex(const EmbVector& point)

void rect_init(EmbRect rect, unsigned int rgb, PenStyle lineType)

EmbVector rect_topLeft()

EmbVector rect_topRight()

EmbVector embRect_bottomLeft(EmbRect rect)

EmbVector embRect_bottomRight(EmbRect rect)

EmbGeometry emb_circle(EmbReal x, EmbReal y, EmbReal radius)

/*

*/

EmbReal emb_circle_area(EmbCircle circle)

/*

*/

EmbReal emb_circle_circumference(EmbCircle circle)

/* Computational Geometry for Circles */

/* Returns true if the circles intersect.
  • Returns false if the circles do not intersect.

*/

int getCircleCircleIntersections(EmbCircle c0, EmbCircle c1,

EmbVector *p0, EmbVector *p1)

{

EmbVector delta; EmbReal a, h, px2, py2, mx, my, d; /* Distance between centers */ delta = emb_vector_subtract(c1.center, c0.center); d = emb_vector_length(delta);

/*Circles share centers. This results in division by zero,

infinite solutions or one circle being contained within the other. */

if (d == 0.0) {

return 0;

} else if (d > (c0.radius + c1.radius)) {

/* Circles do not touch each other */ return 0;

} else if (d < (c0.radius - c1.radius)) {

/* One circle is contained within the other */ return 0;

} /*

  • Considering the two right triangles p0p2p3 and p1p2p3 we can write:

  • a^2 + h^2 = r0^2 and b^2 + h^2 = r1^2

  • BEGIN PROOF

  • Remove h^2 from the equation by setting them equal to themselves:

  • r0^2 - a^2 = r1^2 - b^2

  • Substitute b with (d - a) since it is proven that d = a + b:

  • r0^2 - a^2 = r1^2 - (d - a)^2

  • Complete the square:

  • r0^2 - a^2 = r1^2 - (d^2 -2da + a^2)

  • Subtract r1^2 from both sides:

  • r0^2 - r1^2 - a^2 = -(d^2 -2da + a^2)

  • Invert the signs:

  • r0^2 - r1^2 - a^2 = -d^2 + 2da - a^2

  • Adding a^2 to each side cancels them out:

  • r0^2 - r1^2 = -d^2 + 2da

  • Add d^2 to both sides to shift it to the other side:

  • r0^2 - r1^2 + d^2 = 2da

  • Divide by 2d to finally solve for a:

  • a = (r0^2 - r1^2 + d^2)/ (2d)

  • END PROOF

*/

a = ((c0.radius*c0.radius) - (c1.radius*c1.radius) + (d*d)) / (2.0 * d); /* Solve for h by substituting a into a^2 + h^2 = r0^2 */ h = sqrt((c0.radius*c0.radius) - (a*a));

/*Find point p2 by adding the a offset in relation to line d to point p0 */ px2 = c0.center.x + (delta.x * a/d); py2 = c0.center.y + (delta.y * a/d);

/* Tangent circles have only one intersection

TODO: using == in floating point arithmetic doesn’t account for the machine accuracy, having a stated (EmbReal) tolerance value would help.

*/ if (d == (c0.radius + c1.radius)) {

p0->x = px2; p0->y = py2; p1->x = px2; p1->y = py2; return 1;

}

/* Get the perpendicular slope by multiplying by the negative reciprocal
  • Then multiply by the h offset in relation to d to get the actual offsets */

mx = -(delta.y * h/d); my = (delta.x * h/d);

/* Add the offsets to point p2 to obtain the intersection points */ p0->x = px2 + mx; p0->y = py2 + my; p1->x = px2 - mx; p1->y = py2 - my;

return 1;

}

/* Returns true if the given point lies outside the circle.
  • Returns false if the given point is inside the circle.

*/

int getCircleTangentPoints(EmbCircle c, EmbVector point, EmbVector *t0, EmbVector *t1)

/* Distance to center of circle / / Point is inside the circle */

/* Point is lies on the circle, so there is only one tangent point */

/* Since the tangent lines are always perpendicular to the radius, so
  • we can use the Pythagorean theorem to solve for the missing side */

/*

*/

EmbEllipse emb_ellipse_init(void)

/* TODO: look up a formula. */ EmbReal emb_ellipse_area(EmbEllipse ellipse)

/* TODO: Use Ramanujan’s approximation here. */ EmbReal emb_ellipse_perimeter(EmbEllipse ellipse)

EmbReal emb_ellipse_diameterX(EmbEllipse ellipse)

EmbReal emb_ellipse_diameterY(EmbEllipse ellipse)

void emb_ellipse_init(EmbEllipse ellipse, unsigned int rgb, int lineType)

void emb_ellipse_setSize(float width, float height)

void emb_ellipse_setRadiusMajor(float radius)

void emb_ellipse_setRadiusMinor(float radius)

void emb_ellipse_setDiameterMajor(EmbEllipse *ellipse, float diameter)

void emb_ellipse_setDiameterMinor(EmbEllipse *ellipse, float diameter)

/*
  • BASIC FUNCTIONS

*/

/* round is C99 and we’re committed to C90 so here’s a replacement.

*/

int emb_round(EmbReal x)

EmbReal radians(EmbReal degree)

EmbReal degrees(EmbReal radian)

/* Finds the normalized vector perpendicular (clockwise) to the line
  • given by v1->v2 (normal to the line) */

EmbVector emb_line_normalVector(EmbLine line, int clockwise)

/* Returns the vector that is the same length as the line, in the same
  • direction.

*/

EmbVector emb_line_toVector(EmbLine line)

/*
  • Finds the intersection of two lines given by v1->v2 and v3->v4

  • and sets the value in the result variable.

*/

EmbVector emb_line_intersectionPoint(EmbLine line1, EmbLine line2, int *emb_error)

/* .

*/

EmbRect emb_rect(EmbReal x, EmbReal y, EmbReal w, EmbReal h)

//NOTE: This void should be used to interpret various object types and save them as polylines for stitchOnly formats. /* void save_to_polyline(EmbPattern* pattern, const EmbVector& objPos, const QPainterPath& objPath, const char* layer, const QColor& color, const char* lineType, const char* lineWeight)

void textSingle_TextSingleObject(const char* str, float x, float y, unsigned int rgb, QGraphicsItem* parent)

void textSingle_TextSingleObject(TextSingleObject* obj, QGraphicsItem* parent)

void textSingle_init(const char* str, float x, float y, unsigned int rgb, int lineType)

std::stringList text_single_objectTextJustifyList()

void textSingle_setText(const char* str)

void textSingle_setTextFont(const char *font)

void textSingle_setJustify(const char *justify)

void textSingle_setTextSize(float size)

void textSingle_setTextStyle(char bold, char italic, char under, char strike, char over)

void textSingle_setTextBold(char val) void textSingle_setTextItalic(char val)

void textSingle_setTextUnderline(char val)

void textSingle_setTextStrikeOut(char val)

void textSingle_setTextOverline(char val)

void textSingle_setTextBackward(char val)

void textSingle_setTextUpsideDown(char val)

/* . */ EmbVector emb_vector(EmbReal x, EmbReal y)

/* Finds the unit length vector a result in the same direction as a vector.
  • Equivalent to:

  • f[

  • mathbf{u} = frac{v}{|\mathbf{v}|}

  • f]

  • todo make result return argument.

*/

EmbVector emb_vector_normalize(EmbVector vector)

/* The scalar multiple a magnitude of a vector a vector. Returned as
  • a result.

  • todo make result return argument.

*/

EmbVector emb_vector_scale(EmbVector vector, EmbReal magnitude)

/* The sum of vectors a a and a b returned as a vector.
  • Equivalent to:

  • f[

  • mathbf{c} = mathbf{a} + mathbf{b}

  • = begin{pmatrix} a_{x} + b_{x} \ a_{y}+b_{y} end{pmatrix}

  • f]

*/

EmbVector emb_vector_add(EmbVector a, EmbVector b)

/* The average of vectors a v1 and a v2 returned as a vector.
  • Equivalent to:

  • f[

  • mathbf{c} = frac{mathbf{a} + mathbf{b}}{2}

  • = begin{pmatrix} frac{a_{x} + b_{x}}{2} \ frac{a_{y}+b_{y}}{2} end{pmatrix}

  • f]

*/

EmbVector emb_vector_average(EmbVector a, EmbVector b)

/* The difference between vectors a v1 and a v2 returned as a result.
  • Equivalent to:

  • f[

  • mathbf{c} = mathbf{a} - mathbf{b}

  • = begin{pmatrix} a_{x} - b_{x} \ a_{y}-b_{y} end{pmatrix}

  • f]

*/

EmbVector emb_vector_subtract(EmbVector v1, EmbVector v2)

/* The dot product as vectors a v1 and a v2 returned as a EmbReal.
  • Equivalent to:

  • f[

  • c = mathbf{a} cdot mathbf{b}

  • = a_x b_x + a_y b_y

  • f]

*/

EmbReal emb_vector_dot(EmbVector a, EmbVector b)

/* @brief The “cross product” as vectors a a and a b returned as a real value.
  • Technically, this is the magnitude of the cross product when the

  • embroidery is placed in the z=0 plane (since the cross product is defined for

  • 3-dimensional vectors). That is:

  • f[

  • |c| = left| begin{pmatrix} a_x \ a_y \ 0 end{pmatrix} times begin{pmatrix} b_x \ b_y \ 0 end{pmatrix}right|

  • = left| begin{pmatrix} 0 \ 0 \ a_x b_y - a_y b_x end{pmatrix} right|

  • = a_x b_y - a_y b_x

  • f]

*/

EmbReal emb_vector_cross(EmbVector a, EmbVector b)

/* Since we aren’t using full vector algebra here, all vectors are “vertical”.
  • so this is like the product v1^{T} I_{2} v2 for our vectors a v1 and v2

  • so a “component-wise product”. The result is stored at the pointer a result.

  • That is

  • (1 0) (a) = (xa)

  • (x y)(0 1) (b) (yb)

*/

EmbVector emb_vector_transpose_product(EmbVector v1, EmbVector v2)

/* The length or absolute value of the vector a vector.
  • Equivalent to:

  • f[

  • |v| = sqrt{v_{x}^{2} + v_{y}^{2}}

  • f]

*/

EmbReal emb_vector_length(EmbVector vector)

/* The x-component of the vector

*/

EmbReal emb_vector_relativeX(EmbVector a1, EmbVector a2, EmbVector a3)

/* The y-component of the vector

*/

EmbReal emb_vector_relativeY(EmbVector a1, EmbVector a2, EmbVector a3)

/* The angle, measured anti-clockwise from the x-axis, of a vector v.

*/

EmbReal emb_vector_angle(EmbVector v)

/* The unit vector in the direction a angle.
  • f[

  • mathbf{a}_{alpha} = begin{pmatrix} cos(alpha) \ sin(alpha) end{pmatrix}

  • f]

*/

EmbVector emb_vector_unit(EmbReal alpha)

/* The distance between a a and a b returned as a real value.
  • f[

  • d = left|mathbf{a}-mathbf{b}right|

  • = sqrt{(a_x-b_x)^{2} + (a_y-b_y)^{2}}

  • f]

*/

EmbReal emb_vector_distance(EmbVector a, EmbVector b)

/*
  • This file contains all the read and write functions for the

  • library.

  • file image.c

  • This backends to the stb libraries and nanosvg library.

  • Use Python PEP7 for coding style.

  • Write a PES embedded a image to the given a file pointer.

*/

void writeImage(FILE* file, unsigned char image[][48])

/* The distance between the arrays a a and a b of length
  • a size.

*/

float image_diff(unsigned char *a, unsigned char *b, int size)

/* Render the pattern a p to the file with name a fname.
  • Return whether it was successful as an int.

  • Basic Render

  • Backends rendering to nanosvg/stb_image.

  • The caller is responsible for the memory in p.

*/

int emb_pattern_render(EmbPattern *p, char *fname)

/* Simulate the stitching of a pattern, using the image for rendering
  • hints about how to represent the pattern.

*/

int emb_pattern_simulate(EmbPattern *pattern, char *fname)

/* . */ EmbImage embImage_create(int width, int height)

/* . */ void embImage_read(EmbImage *image, char *fname)

/* . */ int embImage_write(EmbImage *image, char *fname)

/* . */ void embImage_free(EmbImage *image)

/* The file is for the management of the main struct: EmbPattern.
  • Returns a pointer to an EmbPattern. It is created on the heap.

  • The caller is responsible for freeing the allocated memory with

  • emb_pattern_free().

  • Returns EmbPattern*

*/

EmbPattern* emb_pattern_create(void)

/* a p a length

*/

void emb_pattern_hideStitchesOverLength(EmbPattern* p, int length)

/* a pattern a thread
  • Returns int

*/

int emb_pattern_addThread(EmbPattern *pattern, EmbThread thread) {

if (pattern->thread_list->count + 1 > pattern->thread_list->length) {
if (!emb_array_resize(pattern->thread_list)) {

return 0;

}

} pattern->thread_list->thread[pattern->thread_list->count] = thread; pattern->thread_list->count++; return 1;

}

/* a p

*/

void emb_pattern_fixColorCount(EmbPattern* p)

/* Copies all of the Embstitch_list data to
  • EmbPolylineObjectList data for pattern (a p).

*/

void emb_pattern_copystitch_listToPolylines(EmbPattern* p)

/* Copies all of the EmbPolylineObjectList data to Embstitch_list
  • data for pattern (a p).

*/

void emb_pattern_copyPolylinesTostitch_list(EmbPattern* p)

/* Moves all of the Embstitch_list data to EmbPolylineObjectList
  • data for pattern (a p).

*/

void emb_pattern_movestitch_listToPolylines(EmbPattern* p)

/* Moves all of the EmbPolylineObjectList data to Embstitch_list
  • data for pattern (a p).

*/

void emb_pattern_movePolylinesTostitch_list(EmbPattern* p)

/* Adds a stitch to the pattern (a p) at the absolute position
  • (a x,a y). Positive y is up. Units are in millimeters.

*/

void emb_pattern_addStitchAbs(EmbPattern* p, EmbReal x, EmbReal y,

int flags, int isAutoColorIndex)

/* Adds a stitch to the pattern (a p) at the relative position
  • (a dx,a dy) to the previous stitch. Positive y is up.

  • Units are in millimeters.

*/

void emb_pattern_addStitchRel(EmbPattern* p, EmbReal dx, EmbReal dy,

int flags, int isAutoColorIndex)

/* Change the currentColorIndex of pattern a p to a index.

*/

void emb_pattern_changeColor(EmbPattern* p, int index)

/* Very simple scaling of the x and y axis for every point.
  • Doesn’t insert or delete stitches to preserve density.

*/

void emb_pattern_scale(EmbPattern* p, EmbReal scale)

/* Returns an EmbRect that encapsulates all stitches and objects in the
  • pattern (a p).

*/

EmbRect emb_pattern_calcBoundingBox(EmbPattern* p)

/* Flips the entire pattern (a p) horizontally about the y-axis.

*/

void emb_pattern_flipHorizontal(EmbPattern* p)

/* Flips the entire pattern (a p) vertically about the x-axis.

*/

void emb_pattern_flipVertical(EmbPattern* p)

/* Flips the entire pattern (a p) horizontally about the x-axis if (a horz) is true.
  • Flips the entire pattern (a p) vertically about the y-axis if (a vert) is true.

*/

void emb_pattern_flip(EmbPattern* p, int horz, int vert)

/* a p

*/

void emb_pattern_combineJumpStitches(EmbPattern* p)

/* todo The params determine the max XY movement rather than the length.
  • They need renamed or clarified further.

*/

void emb_pattern_correctForMaxStitchLength(EmbPattern* p,

EmbReal maxStitchLength, EmbReal maxJumpLength)

/* Center the pattern a p.

*/

void emb_pattern_center(EmbPattern* p)

/* TODO: Description needed.

*/

void emb_pattern_loadExternalColorFile(EmbPattern* p, const char* fileName)

/* Frees all memory allocated in the pattern (a p).

*/

void emb_pattern_free(EmbPattern* p)

/*

*/

void emb_add_geometry(EmbPattern* p, EmbGeometry g)

/* Adds a circle object to pattern (a p) with its center at the absolute
  • position (a cx,a cy) with a radius of (a r). Positive y is up.

  • Units are in millimeters.

*/

void emb_add_circle(EmbPattern* p, EmbCircle circle)

/* Adds an ellipse object to pattern (a p) with its center at the
  • absolute position (a cx,a cy) with radii of (a rx,a ry). Positive y is up.

  • Units are in millimeters.

*/

void emb_add_ellipse(EmbPattern* p, EmbEllipse ellipse)

/* Adds a line object to pattern (a p) starting at the absolute position
  • (a x1,a y1) and ending at the absolute position (a x2,a y2).

  • Positive y is up. Units are in millimeters.

*/

void emb_add_line(EmbPattern* p, EmbLine line)

/* .

*/

void emb_add_path(EmbPattern* p, EmbPath obj)

/! Adds a point object to pattern (a p) at the absolute position (a x,a y). Positive y is up. Units are in millimeters. */ void emb_pattern_addPointAbs(EmbPattern p, EmbPoint obj)

void emb_pattern_addPolygonAbs(EmbPattern* p, EmbPolygon obj)

void emb_pattern_addPolylineObjectAbs(EmbPattern* p, EmbPolyline obj)

/* Adds a rectangle object to pattern (a p) at the absolute position
  • (a x,a y) with a width of (a w) and a height of (a h).

  • Positive y is up. Units are in millimeters.

*/

void emb_pattern_addRectAbs(EmbPattern* p, EmbRect rect)

/* . */ void emb_pattern_end(EmbPattern *p)

int emb_pattern_color_count(EmbPattern *pattern, EmbColor startColor)

void emb_pattern_designDetails(EmbPattern *pattern)

int convert(const char *inf, const char *outf) end{lstlisting}

section{The Pattern Properties}

begin{lstlisting} /* a pattern

  • Returns float

*/

float emb_pattern_totalStitchLength(EmbPattern *pattern)

float emb_pattern_minimumStitchLength(EmbPattern *pattern)

float emb_pattern_maximumStitchLength(EmbPattern *pattern)

void emb_pattern_lengthHistogram(EmbPattern *pattern, int *bin, int NUMBINS)

int emb_pattern_realStitches(EmbPattern *pattern)

int emb_pattern_jumpStitches(EmbPattern *pattern)

int emb_pattern_trimStitches(EmbPattern *pattern) end{lstlisting}

section{The Thread Management System}

begin{lstlisting} int threadColor(const char *name, int brand)

int threadColorNum(unsigned int color, int brand)

const char* threadColorName(unsigned int color, int brand)

return “COLOR NOT FOUND”;

end{lstlisting}

section{The Geometry System}

TODO: error reporting for improper EmbGeometry type passing.

begin{lstlisting} int emb_approx(EmbVector point1, EmbVector point2)

/* FIXME */ double emb_width(EmbGeometry *g)

/* FIXME: finish all types. */ double emb_height(EmbGeometry *g)

/* FIXME: finish all types. */ double emb_radius(EmbGeometry *g)

/* FIXME */ double emb_radius_major(EmbGeometry *g)

/* FIXME */ double emb_radius_minor(EmbGeometry *g)

/* FIXME */ double emb_diameter_major(EmbGeometry *g)

/* FIXME */ double emb_diameter_minor(EmbGeometry *g)

/* FIXME */ double emb_diameter(EmbGeometry *g)

/* . */ EmbVector emb_quadrant(EmbGeometry *geometry, int degrees)

/* . */ double emb_angle(EmbGeometry *geometry)

/* . */ double emb_start_angle(EmbGeometry *geometry)

/* . */ double emb_end_angle(EmbGeometry *geometry)

/* . */ double emb_arc_length(EmbGeometry *geometry)

/* . */ double emb_area(EmbGeometry *g)

/* . */ double emb_chord(EmbGeometry *geometry)

/* . */ double emb_included_angle(EmbGeometry *geometry)

/* . */ char emb_clockwise(EmbGeometry *geometry)

/* . */ void emb_set_start_angle(EmbGeometry *geometry, double angle)

/* . */ void emb_set_end_angle(EmbGeometry *geometry, double angle)

/* . */ void emb_set_start_point(EmbGeometry *geometry, EmbVector point)

/* . */ void emb_set_mid_point(EmbGeometry *geometry, EmbVector point)

/* . */ void emb_set_end_point(EmbGeometry *geometry, EmbVector point)

/* . */ void emb_set_radius(EmbGeometry *geometry, double radius)

/* . */ void emb_set_diameter(EmbGeometry *geometry, double diameter)

/* . */ void emb_set_area(EmbGeometry *geometry, double area)

/* . */ void emb_set_circumference(EmbGeometry *geometry, double circumference)

/* . */ void emb_set_radius_major(EmbGeometry *geometry, double radius)

/* . */ void emb_set_radius_minor(EmbGeometry *geometry, double radius)

/* . */ void emb_set_diameter_major(EmbGeometry *geometry, double diameter)

/* . */ void emb_set_diameter_minor(EmbGeometry *geometry, double diameter)

/* . */ QColor emb_color(EmbGeometry *geometry)

/* . */ QRgb emb_color_rgb(EmbGeometry *geometry)

/* . */ Qt::PenStyle emb_line_type(EmbGeometry *geometry)

/* . */ double emb_line_weight(EmbGeometry *geometry)

/* . */ QPainterPath emb_path(EmbGeometry *geometry)

/* . */ EmbVector emb_rubber_point(EmbGeometry *geometry, const char *key)

/* . */ QString emb_rubber_text(EmbGeometry *geometry, const char *key)

/* . */ EmbVector emb_pos(EmbGeometry *geometry)

/* . */ double emb_x(EmbGeometry *geometry)

/* . */ double emb_y(EmbGeometry *geometry)

/* . */ EmbVector emb_center(EmbGeometry *geometry)

/* . */ double emb_center_x(EmbGeometry *geometry)

/* . */ double emb_center_y(EmbGeometry *geometry)

/* . */ double emb_radius(EmbGeometry *geometry)

/* . */ double emb_diameter(EmbGeometry *geometry)

/* . */ double emb_circumference(EmbGeometry *geometry)

/* . */ EmbVector emb_end_point_1(EmbGeometry *geometry)

/* . */ EmbVector emb_end_point_2(EmbGeometry *geometry)

/* . */ EmbVector emb_start_point(EmbGeometry *geometry)

/* . */ EmbVector emb_mid_point(EmbGeometry *geometry)

/* . */ EmbVector emb_end_point(EmbGeometry *geometry)

/* . */ EmbVector emb_delta(EmbGeometry *geometry)

/* . */ EmbVector top_left(EmbGeometry *geometry)

/* . */ EmbVector top_right(EmbGeometry *geometry)

/* . */ EmbVector bottom_left(EmbGeometry *geometry)

/* . */ EmbVector bottom_right(EmbGeometry *geometry)

/* . / void update_rubber(QPainter painter);

/* . */ void update_rubber_grip(QPainter *painter);

/* . */ void update_leader(EmbGeometry *geometry);

/* . */ void update_path(EmbGeometry *geometry);

/* . */ void update_path(const QPainterPath& p);

/* . */ void update_arc_rect(double radius);

/* . */ double emb_length(EmbGeometry *geometry)

/* . */ void emb_set_end_point_1(EmbGeometry *geometry, const QPointF& endPt1)

/* . */ void emb_set_end_point_1(EmbGeometry *geometry, double x1, double y1)

/* . */ void emb_set_end_point_2(EmbGeometry *geometry, QPointF endPt2)

/* . */ void emb_set_end_point_2(EmbGeometry *geometry, double x2, double y2)

/* . */ void emb_set_x1(double x)

/* . */ void emb_set_y1(double y)

/* . */ void emb_set_x2(double x)

/* . */ void emb_set_y2(double y)

/* . */ QRectF emb_rect(EmbGeometry *geometry)

/* . */ void emb_setRect(const QRectF& r)

/* . */ void emb_setRect(double x, double y, double w, double h)

/* . */ QLineF line(EmbGeometry *geometry)

void emb_setLine(const QLineF& li)

void emb_set_line(double x1, double y1, double x2, double y2)

void emb_set_pos(QPointF point)

void emb_set_pos(EmbGeometry *geometry, double x, double y)

/* . */ void emb_set_x(EmbGeometry *geometry, double x)

/* . */ void emb_set_y(EmbGeometry *geometry, double y)

/* . */ void emb_set_Rect(double x1, double y1, double x2, double y2)

/* . */ virtual QRectF boundingRect(EmbGeometry *geometry)

/* . */ virtual QPainterPath shape(EmbGeometry *geometry)

/* . */ void emb_set_Color(const QColor& color)

/* . */ void emb_set_ColorRGB(QRgb rgb)

/* . */ void emb_set_LineType(Qt::PenStyle lineType)

/* . */ void emb_set_LineWeight(double lineWeight)

/* . */ void emb_set_Path(const QPainterPath& p)

/* . */ void emb_set_rubber_mode(int mode)

/* . */ void emb_set_rubber_point(const QString& key, const QPointF& point)

/* . */ void emb_set_rubber_text(const QString& key, const QString& txt)

/* . / void draw_rubber_line(const QLineF& rubLine, QPainter painter = 0, const char* colorFromScene = 0)

/* . */ QPen lineWeightPen(EmbGeometry *geometry)

/* . / void emb_real_render(QPainter painter, const QPainterPath& renderPath)

/* . */ void emb_set_center(EmbVector point)

/* . */ void emb_set_center(const QPointF& center)

/* . */ void emb_set_center_x(EmbGeometry *geometry, double centerX)

/* . */ void emb_set_center_y(EmbGeometry *geometry, double centerY)

/* . */ void emb_calculate_data(EmbGeometry *geometry)

/* . */ void emb_set_size(EmbGeometry *geometry, double width, double height)

/* . */ QPainterPath emb_object_copy_path(EmbGeometry *geometry)

/* . */ QPainterPath emb_object_save_path(EmbGeometry *geometry)

/* . */ QList<QPainterPath> emb_object_save_path_list(EmbGeometry *geometry)

/* . */ QList<QPainterPath> emb_sub_path_list(EmbGeometry *geometry)

/* . */ EmbVector scale_and_rotate(EmbVector v, double scale, double angle)

/* Get the position as a vector from the stitch. */ EmbVector emb_st_pos(EmbStitch st)

/* Length of stitch starting of “prev_st” and ending at “st”. */ double emb_stitch_length(EmbStitch prev_st, EmbStitch st)

/* Returns the number of real stitches in a pattern.
  • We consider SEQUIN to be a real stitch in this count.

*/

int emb_pattern_real_count(EmbPattern *pattern)

/* The length of the longest stitch in the pattern. */ double emb_pattern_longest_stitch(EmbPattern *pattern)

/* The length of the shortest stitch in the pattern. */ double emb_pattern_shortest_stitch(EmbPattern *pattern) end{lstlisting}

apifunc{emb_pattern_count_type}

int emb_pattern_count_type(EmbPattern *pattern, int flag)

Returns the number of stitches in a pattern that are of any of the types or-ed together in “flag”. For example to count the total number of TRIM and STOP stitches use:

begin{lstlisting} emb_pattern_count_type(pattern, TRIM | STOP); end{lstlisting}

apifunc{emb_length_histogram}

void emb_length_histogram(EmbPattern *pattern, int *bins)

apifunc{emb_color_histogram}

texttt{void emb_color_histogram(EmbPattern *pattern, int **bins)}

apifunc{emb_total_thread_length}

Arguments: texttt{(EmbPattern *pattern)}, returns: texttt{double}.

Measure the total length of all threads within pattern texttt{pattern}. Returns total as a texttt{double}.

TODO: change return type to texttt{EmbReal}.

apifunc{emb_total_thread_of_color}

Arguments: (EmbPattern *pattern, int thread_index)

Measure the total length of the thread texttt{thread_index} within pattern texttt{pattern}. Returns total as a texttt{double}.

TODO: change return type to texttt{EmbReal}.

apifunc{emb_get_svg_token}

TODO: test this.

Argument 0: char * svg Argument 1: EmbString str

Parse a token (up to the next space or end of string) and pack it into an EmbString as the second argument.

Returns texttt{char *} to new position within the original svg string passed in.

apifunc{emb_get_svg_vector}

Argument 0: char * svg Argument 1: EmbVector *vector

Parse a vector in SVG path description passed as first.

Returns texttt{char *} to new position within the original svg string passed in.

newcommand{threadtable}[3]{
begin{center}
label{tab:#1}

csvreader[tabular=l l l,

table head=multicolumn{3}{c}{bfseries #2}\hline

bfseries Catalog Code & bfseries Name & bfseries Color\hline,

late after line=\hline]{#3}% {Catalog Code=catalogcode,Name=catalogname,Color=catalogcolor}{% texttt{catalogcode} & catalogname & catalogcolor

}

end{center}

}