Ejemplo n.º 1
0
void embPattern_copyStitchListToPolylines(EmbPattern* p)
{
    EmbStitchList* stitches = 0;
    EmbPolylineObjectList* currentList = 0;

    if(!p) { embLog_error("emb-pattern.c embPattern_copyStitchListToPolylines(), p argument is null\n"); return; }
    stitches = p->stitchList;
    while(stitches)
    {
        EmbPointList* currentPointList = 0;
        EmbPolylineObject* currentPolyline = (EmbPolylineObject*)malloc(sizeof(EmbPolylineObject));
        if(!currentPolyline) { embLog_error("emb-pattern.c embPattern_copyStitchListToPolylines(), cannot allocate memory for currentPolyline\n"); return; }
        currentPolyline->pointList = 0;
        currentPolyline->lineType = 1; /* TODO: Determine what the correct value should be */
        currentPolyline->color = embThreadList_getAt(p->threadList, stitches->stitch.color).color;

        while(stitches)
        {
            if(stitches->stitch.flags & (STOP | TRIM))
            {
                break;
            }
            if(!(stitches->stitch.flags & JUMP))
            {
                if(!currentPointList)
                {
                    currentPointList = embPointList_create(stitches->stitch.xx, stitches->stitch.yy);
                    currentPolyline->pointList = currentPointList;
                }
                else
                {
                    currentPointList = embPointList_add(currentPointList, embPoint_make(stitches->stitch.xx, stitches->stitch.yy));
                }
            }
            stitches = stitches->next;
        }
        currentPointList = 0;
        if(!currentList)
        {
            currentList = embPolylineObjectList_create(currentPolyline);
            p->polylineObjList = currentList;
        }
        else
        {
            currentList = embPolylineObjectList_add(currentList, currentPolyline);
        }
        if(stitches && stitches->next)
        {
            stitches = stitches->next;
        }
    }
}
Ejemplo n.º 2
0
/* TODO: It doesn't appear that this function actually clears the stitchList so it is more of a copy than a move. */
void moveStitchListToPolyline(EmbPattern* p)
{
    /* TODO: pointer safety */
    EmbStitchList* stitches = p->stitchList;
    EmbPolylineObjectList* currentList = 0;
    while(stitches)
    {
        EmbPointList* currentPointList = 0;
        EmbPolylineObject* currentPolyline = (EmbPolylineObject*)malloc(sizeof(EmbPolylineObject));
        /* TODO: malloc fail error */
        currentPolyline->pointList = 0;
        currentPolyline->lineType = 1; /* TODO: Determine what the correct value should be */
        currentPolyline->color = embThreadList_getAt(p->threadList, stitches->stitch.color).color;

        while(stitches)
        {
            if(stitches->stitch.flags & (STOP | TRIM))
            {
                break;
            }
            if(!(stitches->stitch.flags & JUMP))
            {
                if(!currentPointList)
                {
                    currentPointList = embPointList_create(stitches->stitch.xx, stitches->stitch.yy);
                    currentPolyline->pointList = currentPointList;
                }
                else
                {
                    currentPointList = embPointList_add(currentPointList, embPoint_make(stitches->stitch.xx, stitches->stitch.yy));
                }
            }
            stitches = stitches->next;
        }
        currentPointList = 0;
        if(!currentList)
        {
            currentList = embPolylineObjectList_create(currentPolyline);
            p->polylineObjList = currentList;
        }
        else
        {
            currentList = embPolylineObjectList_add(currentList, currentPolyline);
        }
        if(stitches && stitches->next)
        {
            stitches = stitches->next;
        }
    }
}
Ejemplo n.º 3
0
void writePecStitches(EmbPattern* pattern, EmbFile* file, const char* fileName)
{
    EmbStitchList* tempStitches = 0;
    EmbRect bounds;
    unsigned char image[38][48];
    int i, flen, currentThreadCount, graphicsOffsetLocation, graphicsOffsetValue, height, width;
    double xFactor, yFactor;
    const char* forwardSlashPos = strrchr(fileName, '/');
    const char* backSlashPos = strrchr(fileName, '\\');
    const char* dotPos = strrchr(fileName, '.');
    const char* start = 0;

    if(!pattern) { embLog_error("format-pec.c writePecStitches(), pattern argument is null\n"); return; }
    if(!file) { embLog_error("format-pec.c writePecStitches(), file argument is null\n"); return; }
    if(!fileName) { embLog_error("format-pec.c writePecStitches(), fileName argument is null\n"); return; }

    if(forwardSlashPos)
    {
        start = forwardSlashPos + 1;
    }
    if(backSlashPos && backSlashPos > start)
    {
        start = backSlashPos + 1;
    }
    if(!start)
    {
        start = fileName;
    }
    binaryWriteBytes(file, "LA:", 3);
    flen = (int)(dotPos - start);

    while(start < dotPos)
    {
        binaryWriteByte(file, (unsigned char)*start);
        start++;
    }
    for(i = 0; i < (int)(16-flen); i++)
    {
        binaryWriteByte(file, (unsigned char)0x20);
    }
    binaryWriteByte(file, 0x0D);
    for(i = 0; i < 12; i++)
    {
        binaryWriteByte(file, (unsigned char)0x20);
    }
    binaryWriteByte(file, (unsigned char)0xFF);
    binaryWriteByte(file, (unsigned char)0x00);
    binaryWriteByte(file, (unsigned char)0x06);
    binaryWriteByte(file, (unsigned char)0x26);

    for(i = 0; i < 12; i++)
    {
        binaryWriteByte(file, (unsigned char)0x20);
    }
    currentThreadCount = embThreadList_count(pattern->threadList);
    binaryWriteByte(file, (unsigned char)(currentThreadCount-1));

    for(i = 0; i < currentThreadCount; i++)
    {
        binaryWriteByte(file, (unsigned char)embThread_findNearestColorInArray(embThreadList_getAt(pattern->threadList, i).color, (EmbThread*)pecThreads, pecThreadCount));
    }
    for(i = 0; i < (int)(0x1CF - currentThreadCount); i++)
    {
        binaryWriteByte(file, (unsigned char)0x20);
    }
    binaryWriteShort(file, (short)0x0000);

    graphicsOffsetLocation = embFile_tell(file);
    /* placeholder bytes to be overwritten */
    binaryWriteByte(file, (unsigned char)0x00);
    binaryWriteByte(file, (unsigned char)0x00);
    binaryWriteByte(file, (unsigned char)0x00);

    binaryWriteByte(file, (unsigned char)0x31);
    binaryWriteByte(file, (unsigned char)0xFF);
    binaryWriteByte(file, (unsigned char)0xF0);

    bounds = embPattern_calcBoundingBox(pattern);

    height = roundDouble(embRect_height(bounds));
    width = roundDouble(embRect_width(bounds));
    /* write 2 byte x size */
    binaryWriteShort(file, (short)width);
    /* write 2 byte y size */
    binaryWriteShort(file, (short)height);

    /* Write 4 miscellaneous int16's */
    binaryWriteShort(file, (short)0x1E0);
    binaryWriteShort(file, (short)0x1B0);

    binaryWriteUShortBE(file, (unsigned short)(0x9000 | -roundDouble(bounds.left)));
    binaryWriteUShortBE(file, (unsigned short)(0x9000 | -roundDouble(bounds.top)));

    pecEncode(file, pattern);
    graphicsOffsetValue = embFile_tell(file) - graphicsOffsetLocation + 2;
    embFile_seek(file, graphicsOffsetLocation, SEEK_SET);

    binaryWriteByte(file, (unsigned char)(graphicsOffsetValue & 0xFF));
    binaryWriteByte(file, (unsigned char)((graphicsOffsetValue >> 8) & 0xFF));
    binaryWriteByte(file, (unsigned char)((graphicsOffsetValue >> 16) & 0xFF));

    embFile_seek(file, 0x00, SEEK_END);

    /* Writing all colors */
    clearImage(image);
    tempStitches = pattern->stitchList;

    yFactor = 32.0 / height;
    xFactor = 42.0 / width;
    while(tempStitches->next)
    {
        int x = roundDouble((tempStitches->stitch.xx - bounds.left) * xFactor) + 3;
        int y = roundDouble((tempStitches->stitch.yy - bounds.top) * yFactor) + 3;
        image[y][x] = 1;
        tempStitches = tempStitches->next;
    }
    writeImage(file, image);

    /* Writing each individual color */
    tempStitches = pattern->stitchList;
    for(i = 0; i < currentThreadCount; i++)
    {
        clearImage(image);
        while(tempStitches->next)
        {
            int x = roundDouble((tempStitches->stitch.xx - bounds.left) * xFactor) + 3;
            int y = roundDouble((tempStitches->stitch.yy - bounds.top) * yFactor) + 3;
            if(tempStitches->stitch.flags & STOP)
            {
                tempStitches = tempStitches->next;
                break;
            }
            image[y][x] = 1;
            tempStitches = tempStitches->next;
        }
        writeImage(file, image);
    }
}
Ejemplo n.º 4
0
/*! Writes the data from \a pattern to a file with the given \a fileName.
 *  Returns \c true if successful, otherwise returns \c false. */
int writeVp3(EmbPattern* pattern, const char* fileName)
{
    EmbFile *file = 0;
    EmbRect bounds;
    int remainingBytesPos, remainingBytesPos2;
    int colorSectionStitchBytes;
    int first = 1;
    int numberOfColors = 0;
    EmbColor color;
    EmbStitchList *mainPointer = 0, *pointer = 0;

    if(!pattern) { embLog_error("format-vp3.c writeVp3(), pattern argument is null\n"); return 0; }
    if(!fileName) { embLog_error("format-vp3.c writeVp3(), fileName argument is null\n"); return 0; }

    if(!embStitchList_count(pattern->stitchList))
    {
        embLog_error("format-vp3.c writeVp3(), pattern contains no stitches\n");
        return 0;
    }

    bounds = embPattern_calcBoundingBox(pattern);

    file = embFile_open(fileName, "wb");
    if(!file)
    {
        embLog_error("format-vp3.c writeVp3(), cannot open %s for writing\n", fileName);
        return 0;
    }

    embPattern_correctForMaxStitchLength(pattern, 3200.0, 3200.0); /* VP3 can encode signed 16bit deltas */

    embPattern_flipVertical(pattern);

    binaryWriteBytes(file, "%vsm%", 5);
    binaryWriteByte(file, 0);
    vp3WriteString(file, "Embroidermodder");
    binaryWriteByte(file, 0);
    binaryWriteByte(file, 2);
    binaryWriteByte(file, 0);

    remainingBytesPos = embFile_tell(file);
    binaryWriteInt(file, 0); /* placeholder */
    vp3WriteString(file, "");
    binaryWriteIntBE(file, bounds.right * 1000);
    binaryWriteIntBE(file, bounds.bottom * 1000);
    binaryWriteIntBE(file, bounds.left * 1000);
    binaryWriteIntBE(file, bounds.top * 1000);
    binaryWriteInt(file, 0); /* this would be some (unknown) function of thread length */
    binaryWriteByte(file, 0);

    numberOfColors = 0;

    mainPointer = pattern->stitchList;
    while(mainPointer)
    {
        int flag;
        EmbColor newColor;

        pointer = mainPointer;
        flag = pointer->stitch.flags;
        newColor = embThreadList_getAt(pattern->threadList, pointer->stitch.color).color;
        if(newColor.r != color.r || newColor.g != color.g || newColor.b != color.b)
        {
            numberOfColors++;
            color.r = newColor.r;
            color.g = newColor.g;
            color.b = newColor.b;
        }
        else if(flag & END || flag & STOP)
        {
            numberOfColors++;
        }

        while(pointer && (flag == pointer->stitch.flags))
        {
            pointer = pointer->next;
        }
        mainPointer = pointer;
    }

    binaryWriteByte(file, numberOfColors);
    binaryWriteByte(file, 12);
    binaryWriteByte(file, 0);
    binaryWriteByte(file, 1);
    binaryWriteByte(file, 0);
    binaryWriteByte(file, 3);
    binaryWriteByte(file, 0);

    remainingBytesPos2 = embFile_tell(file);
    binaryWriteInt(file, 0); /* placeholder */

    binaryWriteIntBE(file, 0); /* origin X */
    binaryWriteIntBE(file, 0); /* origin Y */
    binaryWriteByte(file, 0);
    binaryWriteByte(file, 0);
    binaryWriteByte(file, 0);

    binaryWriteIntBE(file, bounds.right * 1000);
    binaryWriteIntBE(file, bounds.bottom * 1000);
    binaryWriteIntBE(file, bounds.left * 1000);
    binaryWriteIntBE(file, bounds.top * 1000);

    binaryWriteIntBE(file, (bounds.right - bounds.left) * 1000);
    binaryWriteIntBE(file, (bounds.bottom - bounds.top) * 1000);

    vp3WriteString(file, "");
    binaryWriteShortBE(file, 25700);
    binaryWriteIntBE(file, 4096);
    binaryWriteIntBE(file, 0);
    binaryWriteIntBE(file, 0);
    binaryWriteIntBE(file, 4096);

    binaryWriteBytes(file, "xxPP\x01\0", 6);
    vp3WriteString(file, "");
    binaryWriteShortBE(file, numberOfColors);

    mainPointer = pattern->stitchList;
    while(mainPointer)
    {
        char colorName[8] = { 0 };
        double lastX, lastY;
        int colorSectionLengthPos;
        EmbStitch s;
        int lastColor;

        if(!first)
            binaryWriteByte(file, 0);
        binaryWriteByte(file, 0);
        binaryWriteByte(file, 5);
        binaryWriteByte(file, 0);

        colorSectionLengthPos = embFile_tell(file);
        binaryWriteInt(file, 0); /* placeholder */

        pointer = mainPointer;
        color = embThreadList_getAt(pattern->threadList, pointer->stitch.color).color;

        if(first && pointer->stitch.flags & JUMP && pointer->next->stitch.flags & JUMP)
            pointer = pointer->next;

        s = pointer->stitch;
        embLog_print("format-vp3.c DEBUG %d, %lf, %lf\n", s.flags, s.xx, s.yy);
        binaryWriteIntBE(file, s.xx * 1000);
        binaryWriteIntBE(file, -s.yy * 1000);
        pointer = pointer->next;

        first = 0;

        lastX = s.xx;
        lastY = s.yy;
        lastColor = s.color;

        binaryWriteByte(file, 1);
        binaryWriteByte(file, 0);

        embLog_print("format-vp3.c writeVp3(), switching to color (%d, %d, %d)\n", color.r, color.g, color.b);
        binaryWriteByte(file, color.r);
        binaryWriteByte(file, color.g);
        binaryWriteByte(file, color.b);

        binaryWriteByte(file, 0);
        binaryWriteByte(file, 0);
        binaryWriteByte(file, 0);
        binaryWriteByte(file, 5);
        binaryWriteByte(file, 40);

        vp3WriteString(file, "");

        sprintf(colorName, "#%02x%02x%02x", color.b, color.g, color.r);

        vp3WriteString(file, colorName);
        vp3WriteString(file, "");

        binaryWriteIntBE(file, 0);
        binaryWriteIntBE(file, 0);

        vp3WriteStringLen(file, "\0", 1);

        colorSectionStitchBytes = embFile_tell(file);
        binaryWriteInt(file, 0); /* placeholder */

        binaryWriteByte(file, 10);
        binaryWriteByte(file, 246);
        binaryWriteByte(file, 0);

        while(pointer)
        {
            int dx, dy;

            EmbStitch s = pointer->stitch;
            if(s.color != lastColor)
                break;
            if(s.flags & END || s.flags & STOP)
                break;

            dx = (s.xx - lastX) * 10;
            dy = (s.yy - lastY) * 10;
            lastX = lastX + dx / 10.0; /* output is in ints, ensure rounding errors do not sum up */
            lastY = lastY + dy / 10.0;

            if(dx < -127 || dx > 127 || dy < -127 || dy > 127)
            {
                binaryWriteByte(file, 128);
                binaryWriteByte(file, 1);
                binaryWriteShortBE(file, dx);
                binaryWriteShortBE(file, dy);
                binaryWriteByte(file, 128);
                binaryWriteByte(file, 2);
            }
            else
            {
                binaryWriteByte(file, dx);
                binaryWriteByte(file, dy);
            }

            pointer = pointer->next;
        }

        vp3PatchByteCount(file, colorSectionStitchBytes, -4);
        vp3PatchByteCount(file, colorSectionLengthPos, -3);

        mainPointer = pointer;
    }

    vp3PatchByteCount(file, remainingBytesPos2, -4);
    vp3PatchByteCount(file, remainingBytesPos, -4);

    embFile_close(file);

    embPattern_flipVertical(pattern);

    return 1;
}
Ejemplo n.º 5
0
/*! Copies all of the EmbStitchList data to EmbPolylineObjectList data for pattern (\a p). */
void embPattern_copyStitchListToPolylines(EmbPattern* p)
{
    EmbStitchList* stList = 0;
    int breakAtFlags;

    if(!p) { embLog_error("emb-pattern.c embPattern_copyStitchListToPolylines(), p argument is null\n"); return; }

#ifdef EMB_DEBUG_JUMP
    breakAtFlags = (STOP | TRIM);
#else /* EMB_DEBUG_JUMP */
    breakAtFlags = (STOP | JUMP | TRIM);
#endif /* EMB_DEBUG_JUMP */

    stList = p->stitchList;
    while(stList)
    {
        EmbPointList* pointList = 0;
        EmbPointList* lastPoint = 0;
        EmbColor color;
        while(stList)
        {
            if(stList->stitch.flags & breakAtFlags)
            {
                break;
            }
            if(!(stList->stitch.flags & JUMP))
            {
                if(!pointList)
                {
                    pointList = lastPoint = embPointList_create(stList->stitch.xx, stList->stitch.yy);
                    color = embThreadList_getAt(p->threadList, stList->stitch.color).color;
                }
                else
                {
                    lastPoint = embPointList_add(lastPoint, embPoint_make(stList->stitch.xx, stList->stitch.yy));
                }
            }
            stList = stList->next;
        }

        /* NOTE: Ensure empty polylines are not created. This is critical. */
        if(pointList)
        {
            EmbPolylineObject* currentPolyline = (EmbPolylineObject*)malloc(sizeof(EmbPolylineObject));
            if(!currentPolyline) { embLog_error("emb-pattern.c embPattern_copyStitchListToPolylines(), cannot allocate memory for currentPolyline\n"); return; }
            currentPolyline->pointList = pointList;
            currentPolyline->color = color;
            currentPolyline->lineType = 1; /* TODO: Determine what the correct value should be */

            if(embPolylineObjectList_empty(p->polylineObjList))
            {
                p->polylineObjList = p->lastPolylineObj = embPolylineObjectList_create(currentPolyline);
            }
            else
            {
                p->lastPolylineObj = embPolylineObjectList_add(p->lastPolylineObj, currentPolyline);
            }
        }
        if(stList)
        {
            stList = stList->next;
        }
    }
}
Ejemplo n.º 6
0
static void pesWriteSewSegSection(EmbPattern* pattern, FILE* file)
{
    /* TODO: pointer safety */
    EmbStitchList* pointer = 0;
    EmbStitchList* mainPointer = 0;
    short* colorInfo = 0;
    int flag = 0;
    int count = 0;
    int colorCode = -1;
    int stitchType = 0;
    int blockCount = 0;
    int colorCount = 0;
    int newColorCode = 0;
    int colorInfoIndex = 0;
    int i;
    EmbRect bounds = embPattern_calcBoundingBox(pattern);
    EmbColor color;

    mainPointer = pattern->stitchList;
    while(mainPointer)
    {
        pointer = mainPointer;
        flag = pointer->stitch.flags;
        color = embThreadList_getAt(pattern->threadList, pointer->stitch.color).color;
        newColorCode = embThread_findNearestColorInArray(color, (EmbThread*)pecThreads, pecThreadCount);
        if(newColorCode != colorCode)
        {
            colorCount++;
            colorCode = newColorCode;
        }
        while(pointer && (flag == pointer->stitch.flags))
        {
            count++;
            pointer = pointer->next;
        }
        blockCount++;
        mainPointer = pointer;
    }

    binaryWriteShort(file, blockCount); /* block count */
    binaryWriteUShort(file, 0xFFFF);
    binaryWriteShort(file, 0x00);

    binaryWriteShort(file, 0x07); /* string length */
    binaryWriteBytes(file, "CSewSeg", 7);

    colorInfo = (short *) calloc(colorCount * 2, sizeof(short));
    mainPointer = pattern->stitchList;
    colorCode = -1;
    blockCount = 0;
    while(mainPointer)
    {
        pointer = mainPointer;
        flag = pointer->stitch.flags;
        color = embThreadList_getAt(pattern->threadList, pointer->stitch.color).color;
        newColorCode = embThread_findNearestColorInArray(color, (EmbThread*)pecThreads, pecThreadCount);
        if(newColorCode != colorCode)
        {
            colorInfo[colorInfoIndex++] = blockCount;
            colorInfo[colorInfoIndex++] = newColorCode;
            colorCode = newColorCode;
        }
        count = 0;
        while(pointer && (flag == pointer->stitch.flags))
        {
            count++;
            pointer = pointer->next;
        }
        if(flag & JUMP)
        {
            stitchType = 1;
        }
        else
        {
            stitchType = 0;
        }

        binaryWriteShort(file, stitchType); /* 1 for jump, 0 for normal */
        binaryWriteShort(file, (short)colorCode); /* color code */
        binaryWriteShort(file, count); /* stitches in block */
        pointer = mainPointer;
        while(pointer && (flag == pointer->stitch.flags))
        {
            EmbStitch s = pointer->stitch;
            binaryWriteShort(file, (short)(s.xx - bounds.left));
            binaryWriteShort(file, (short)(s.yy + bounds.top));
            pointer = pointer->next;
        }
        if(pointer)
        {
            binaryWriteShort(file, 0x8003);
        }
        blockCount++;
        mainPointer = pointer;
    }
    binaryWriteShort(file, colorCount);
    for(i = 0; i < colorCount; i++)
    {
        binaryWriteShort(file, colorInfo[i * 2]);
        binaryWriteShort(file, colorInfo[i * 2 + 1]);
    }
    binaryWriteInt(file, 0);
    if(colorInfo)
    {
        free(colorInfo);
        colorInfo = 0;
    }
}
Ejemplo n.º 7
0
int writeHus(EmbPattern* pattern, const char* fileName)
{
    EmbRect boundingRect;
    int stitchCount, minColors, patternColor;
    int attributeSize = 0;
    int xCompressedSize = 0;
    int yCompressedSize = 0;
    double previousX = 0;
    double previousY = 0;
    unsigned char* xValues, *yValues, *attributeValues;
    EmbStitchList* pointer = 0;
    double xx = 0.0;
    double yy = 0.0;
    int flags = 0;
    int i = 0;
    unsigned char* attributeCompressed, *xCompressed, *yCompressed;
    FILE* file = 0;

    file = fopen(fileName, "wb");
    if(!file)
    {
        /*TODO: set status here "Error opening HUS file for write:" */
        return 0;
    }

    stitchCount = embStitchList_count(pattern->stitchList);
    /* embPattern_correctForMaxStitchLength(pattern, 0x7F, 0x7F); */
    minColors = embThreadList_count(pattern->threadList);
    patternColor = minColors;
    if(minColors > 24) minColors = 24;
    binaryWriteUInt(file, 0x00C8AF5B);
    binaryWriteUInt(file, stitchCount);
    binaryWriteUInt(file, minColors);

    boundingRect = embPattern_calcBoundingBox(pattern);
    binaryWriteShort(file, (short) roundDouble(boundingRect.right * 10.0));
    binaryWriteShort(file, (short) -roundDouble(boundingRect.top * 10.0 - 1.0));
    binaryWriteShort(file, (short) roundDouble(boundingRect.left * 10.0));
    binaryWriteShort(file, (short) -roundDouble(boundingRect.bottom * 10.0 - 1.0));

    binaryWriteUInt(file, 0x2A + 2 * minColors);

    xValues = (unsigned char*)malloc(sizeof(unsigned char)*(stitchCount));
    /* TODO: malloc fail error */
    yValues = (unsigned char*)malloc(sizeof(unsigned char)*(stitchCount));
    /* TODO: malloc fail error */
    attributeValues = (unsigned char*)malloc(sizeof(unsigned char)*(stitchCount));
    /* TODO: malloc fail error */

    pointer = pattern->stitchList;
    while(pointer)
    {
        xx = pointer->stitch.xx;
        yy = pointer->stitch.yy;
        flags = pointer->stitch.flags;
        xValues[i] = husEncodeByte((xx - previousX) * 10.0);
        previousX = xx;
        yValues[i] = husEncodeByte((yy - previousY) * 10.0);
        previousY = yy;
        attributeValues[i] = husEncodeStitchType(flags);
        pointer = pointer->next;
        i++;
    }
    attributeCompressed = husCompressData(attributeValues, stitchCount, &attributeSize);
    xCompressed = husCompressData(xValues, stitchCount, &xCompressedSize);
    yCompressed = husCompressData(yValues, stitchCount, &yCompressedSize);
    /* TODO: error if husCompressData returns zero? */

    binaryWriteUInt(file, (unsigned int) (0x2A + 2 * patternColor + attributeSize));
    binaryWriteUInt(file, (unsigned int) (0x2A + 2 * patternColor + attributeSize + xCompressedSize));
    binaryWriteUInt(file, 0x00000000);
    binaryWriteUInt(file, 0x00000000);
    binaryWriteUShort(file, 0x0000);

    for(i = 0; i < patternColor; i++)
    {
        binaryWriteShort(file, (short)embThread_findNearestColorInArray(embThreadList_getAt(pattern->threadList, i).color, (EmbThread*)husThreads, husThreadCount));
    }

    binaryWriteBytes(file, (char*) attributeCompressed, attributeSize);
    binaryWriteBytes(file, (char*) xCompressed, xCompressedSize);
    binaryWriteBytes(file, (char*) yCompressed, yCompressedSize);

	free(xValues);
    free(xCompressed);
	free(yValues);
	free(yCompressed);
	free(attributeValues);
	free(attributeCompressed);

    fclose(file);
    return 1;
}