#include "format-thr.h"
#include "helpers-binary.h"
#include "emb-file.h"
#include "emb-logging.h"
#include <string.h>
#define NOTFRM 0x00080000
typedef struct ThredHeader_
{
unsigned int sigVersion;
unsigned int length;
unsigned short numStiches;
unsigned short hoopSize;
unsigned short reserved[7];
} ThredHeader;
typedef struct ThredExtension_
{
float hoopX;
float hoopY;
float stitchGranularity;
char creatorName[50];
char modifierName[50];
char auxFormat;
char reserved[31];
} ThredExtension;
int readThr(EmbPattern* pattern, const char* fileName)
{
ThredHeader header;
unsigned char r, g, b;
int currentColor;
int i;
EmbFile* file = 0;
if(!pattern) { embLog_error("format-thr.c readThr(), pattern argument is null\n"); return 0; }
if(!fileName) { embLog_error("format-thr.c readThr(), fileName argument is null\n"); return 0; }
file = embFile_open(fileName, "rb");
if(!file)
{
embLog_error("format-thr.c readThr(), cannot open %s for reading\n", fileName);
return 0;
}
header.sigVersion = binaryReadUInt32(file);
header.length = binaryReadUInt32(file);
header.numStiches = binaryReadUInt16(file);
header.hoopSize = binaryReadUInt16(file);
header.reserved[0] = binaryReadUInt16(file);
header.reserved[1] = binaryReadUInt16(file);
header.reserved[2] = binaryReadUInt16(file);
header.reserved[3] = binaryReadUInt16(file);
header.reserved[4] = binaryReadUInt16(file);
header.reserved[5] = binaryReadUInt16(file);
header.reserved[6] = binaryReadUInt16(file);
if((header.sigVersion & 0xffffff) == 0x746872)
{
unsigned int verVar = (header.sigVersion & 0xff000000) >> 24;
switch(verVar)
{
case 0:
break;
case 1:
case 2:
embFile_seek(file, 144, SEEK_CUR);
break;
default:
return 0;
}
}
currentColor = -1;
for(i = 0; i < header.numStiches; i++)
{
int type = NORMAL;
float x = binaryReadFloat(file) / 10.0f;
float y = binaryReadFloat(file) / 10.0f;
unsigned int color = binaryReadUInt32(file);
if((int)(color & 0xF) != currentColor)
{
currentColor = (int)color & 0xF;
embPattern_changeColor(pattern, currentColor);
type = STOP | TRIM;
}
embPattern_addStitchAbs(pattern, x, y, type, 0);
}
embFile_seek(file, 16, SEEK_CUR);
r = binaryReadByte(file);
g = binaryReadByte(file);
b = binaryReadByte(file);
binaryReadByte(file);
for(i = 0; i < 16; i++)
{
EmbThread thread;
thread.description = NULL;
thread.catalogNumber = NULL;
thread.color.r = binaryReadByte(file);
thread.color.g = binaryReadByte(file);
thread.color.b = binaryReadByte(file);
binaryReadByte(file);
embPattern_addThread(pattern, thread);
}
embFile_close(file);
if(pattern->lastStitch->stitch.flags != END)
embPattern_addStitchRel(pattern, 0, 0, END, 1);
return 1;
}
int writeThr(EmbPattern* pattern, const char* fileName)
{
int i, stitchCount;
unsigned char version = 0;
ThredHeader header;
ThredExtension extension;
char bitmapName[16];
EmbStitchList* pointer = 0;
EmbThreadList* colorpointer = 0;
EmbFile* file = 0;
if(!pattern) { embLog_error("format-thr.c writeThr(), pattern argument is null\n"); return 0; }
if(!fileName) { embLog_error("format-thr.c writeThr(), fileName argument is null\n"); return 0; }
stitchCount = embStitchList_count(pattern->stitchList);
if(!stitchCount)
{
embLog_error("format-thr.c writeThr(), pattern contains no stitches\n");
return 0;
}
if(pattern->lastStitch->stitch.flags != END)
{
embPattern_addStitchRel(pattern, 0, 0, END, 1);
stitchCount++;
}
file = embFile_open(fileName, "wb");
if(!file)
{
embLog_error("format-thr.c writeThr(), cannot open %s for writing\n", fileName);
return 0;
}
memset(&header, 0, sizeof(ThredHeader));
header.sigVersion = 0x746872 | (version << 24);
header.length = stitchCount * 12 + 16;
if(version == 1 || version == 2)
{
header.length = header.length + sizeof(ThredHeader);
}
header.numStiches = (unsigned short)stitchCount;
header.hoopSize = 5;
binaryWriteUInt(file, header.sigVersion);
binaryWriteUInt(file, header.length);
binaryWriteUShort(file, header.numStiches);
binaryWriteUShort(file, header.hoopSize);
binaryWriteUShort(file, header.reserved[0]);
binaryWriteUShort(file, header.reserved[1]);
binaryWriteUShort(file, header.reserved[2]);
binaryWriteUShort(file, header.reserved[3]);
binaryWriteUShort(file, header.reserved[4]);
binaryWriteUShort(file, header.reserved[5]);
binaryWriteUShort(file, header.reserved[6]);
if(version == 1 || version == 2)
{
memset(&extension, 0, sizeof(ThredExtension));
extension.auxFormat = 1;
extension.hoopX = 640;
extension.hoopY = 640;
binaryWriteFloat(file, extension.hoopX);
binaryWriteFloat(file, extension.hoopY);
binaryWriteFloat(file, extension.stitchGranularity);
binaryWriteBytes(file, extension.creatorName, 50);
binaryWriteBytes(file, extension.modifierName, 50);
binaryWriteByte(file, extension.auxFormat);
binaryWriteBytes(file, extension.reserved, 31);
}
i = 0;
pointer = pattern->stitchList;
while(pointer)
{
binaryWriteFloat(file, (float)(pointer->stitch.xx * 10.0));
binaryWriteFloat(file, (float)(pointer->stitch.yy * 10.0));
binaryWriteUInt(file, NOTFRM | (pointer->stitch.color & 0x0F));
pointer = pointer->next;
i++;
if(i >= stitchCount) break;
}
binaryWriteBytes(file, bitmapName, 16);
binaryWriteByte(file, 0xFF);
binaryWriteByte(file, 0xFF);
binaryWriteByte(file, 0xFF);
binaryWriteByte(file, 0x00);
i = 0;
colorpointer = pattern->threadList;
while(colorpointer)
{
binaryWriteByte(file, colorpointer->thread.color.r);
binaryWriteByte(file, colorpointer->thread.color.g);
binaryWriteByte(file, colorpointer->thread.color.b);
binaryWriteByte(file, 0);
colorpointer = colorpointer->next;
i++;
if(i >= 16) break;
}
for(; i < 16; i++)
{
binaryWriteUInt(file, 0);
}
i = 0;
colorpointer = pattern->threadList;
while(colorpointer)
{
binaryWriteByte(file, colorpointer->thread.color.r);
binaryWriteByte(file, colorpointer->thread.color.g);
binaryWriteByte(file, colorpointer->thread.color.b);
binaryWriteByte(file, 0);
colorpointer = colorpointer->next;
i++;
if(i >= 16) break;
}
for(; i < 16; i++)
{
binaryWriteUInt(file, 0);
}
for(i = 0; i < 16; i++)
{
binaryWriteByte(file, '4');
}
embFile_close(file);
return 1;
}