/*! Writes the data from \a pattern to a file with the given \a fileName. * Returns \c true if successful, otherwise returns \c false. */ int writeCol(EmbPattern* pattern, const char* fileName) { FILE* file = 0; int i, colorCount; EmbThreadList *colors; if(!pattern) { embLog_error("format-col.c writeCol(), pattern argument is null\n"); return 0; } if(!fileName) { embLog_error("format-col.c writeCol(), fileName argument is null\n"); return 0; } file = fopen(fileName, "w"); if(!file) { embLog_error("format-col.c writeCol(), cannot open %s for writing\n", fileName); return 0; } colorCount = embThreadList_count(pattern->threadList); fprintf(file, "%d\n\r", colorCount); /* TODO: needs to be \r\n */ colors = pattern->threadList; i = 0; while(colors) { EmbColor c; c = colors->thread.color; fprintf(file, "%d,%d,%d,%d\n\r", i, (int)c.r, (int)c.g, (int)c.b); /* TODO: needs to be \r\n */ i++; colors = colors->next; } fclose(file); return 1; }
void embPattern_fixColorCount(EmbPattern* p) { /* fix color count to be max of color index. */ int maxColorIndex = 0; EmbStitchList* list = 0; if(!p) { embLog_error("emb-pattern.c embPattern_fixColorCount(), p argument is null\n"); return; } list = p->stitchList; while(list) { maxColorIndex = max(maxColorIndex, list->stitch.color); list = list->next; } #ifndef ARDUINO /* ARDUINO TODO: The while loop below never ends because memory cannot be allocated in the addThread * function and thus the thread count is never incremented. Arduino or not, it's wrong. */ while((int)embThreadList_count(p->threadList) <= maxColorIndex) { embPattern_addThread(p, embThread_getRandom()); } #endif /* while(embThreadList_count(p->threadList) > (maxColorIndex + 1)) { TODO: erase last color p->threadList.pop_back(); } */ }
/*! Writes the data from \a pattern to a file with the given \a fileName. * Returns \c true if successful, otherwise returns \c false. */ int writeT01(EmbPattern* pattern, const char* fileName) { EmbRect boundingRect; EmbFile* file = 0; int xx, yy, dx, dy, flags; int co = 1, st = 0; int ax, ay, mx, my; EmbStitchList* pointer = 0; if (!embStitchList_count(pattern->stitchList)) { embLog_error("format-t01.c writeDst(), pattern contains no stitches\n"); return 0; } /* Check for an END stitch and add one if it is not present */ if (pattern->lastStitch->stitch.flags != END) embPattern_addStitchRel(pattern, 0, 0, END, 1); file = embFile_open(fileName, "wb"); if (!file) { embLog_error("format-t01.c writet01(), cannot open %s for writing\n", fileName); return 0; } embPattern_correctForMaxStitchLength(pattern, 12.1, 12.1); xx = yy = 0; co = 1; co = embThreadList_count(pattern->threadList); st = 0; st = embStitchList_count(pattern->stitchList); flags = NORMAL; boundingRect = embPattern_calcBoundingBox(pattern); ax = ay = mx = my = 0; xx = yy = 0; pointer = pattern->stitchList; while (pointer) { /* convert from mm to 0.1mm for file format */ dx = roundDouble(pointer->stitch.xx * 10.0) - xx; dy = roundDouble(pointer->stitch.yy * 10.0) - yy; xx = roundDouble(pointer->stitch.xx * 10.0); yy = roundDouble(pointer->stitch.yy * 10.0); flags = pointer->stitch.flags; encode_record(file, dx, dy, flags); pointer = pointer->next; } embFile_close(file); return 1; }
/*! Writes the data from \a pattern to a file with the given \a fileName. * Returns \c true if successful, otherwise returns \c false. */ int writeInf(EmbPattern* pattern, const char* fileName) { EmbThreadList* pointer = 0; int i = 1, bytesRemaining; FILE* file = 0; if(!pattern) { embLog_error("format-inf.c writeInf(), pattern argument is null\n"); return 0; } if(!fileName) { embLog_error("format-inf.c writeInf(), fileName argument is null\n"); return 0; } file = fopen(fileName, "wb"); if(!file) { embLog_error("format-inf.c writeInf(), cannot open %s for writing\n", fileName); return 0; } binaryWriteUIntBE(file, 0x01); binaryWriteUIntBE(file, 0x08); /* write place holder offset */ binaryWriteUIntBE(file, 0x00); binaryWriteUIntBE(file, embThreadList_count(pattern->threadList)); pointer = pattern->threadList; while(pointer) { char buffer[50]; EmbColor c; c = pointer->thread.color; sprintf(buffer, "RGB(%d,%d,%d)", (int)c.r, (int)c.g, (int)c.b); binaryWriteUShortBE(file, (unsigned short)(14 + strlen(buffer))); /* record length */ binaryWriteUShortBE(file, (unsigned short)i); /* record number */ binaryWriteByte(file, c.r); binaryWriteByte(file, c.g); binaryWriteByte(file, c.b); binaryWriteUShortBE(file, (unsigned short)i); /* needle number */ binaryWriteBytes(file, "RGB\0", 4); fprintf(file, buffer); binaryWriteByte(file, 0); pointer = pointer->next; i++; } fseek(file, -8, SEEK_END); bytesRemaining = ftell(file); fseek(file, 8, SEEK_SET); binaryWriteUIntBE(file, bytesRemaining); fclose(file); return 1; }
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); } }
int writeXxx(EmbPattern* pattern, const char* fileName) { FILE* file = 0; int i; EmbRect rect; int endOfStitches; EmbThreadList* colors; int curColor = 0; if(!pattern) { embLog_error("format-xxx.c writeXxx(), pattern argument is null\n"); return 0; } if(!fileName) { embLog_error("format-xxx.c writeXxx(), fileName argument is null\n"); return 0; } embPattern_correctForMaxStitchLength(pattern, 124, 127); file = fopen(fileName, "wb"); if(!file) { embLog_error("format-xxx.c writeXxx(), cannot open %s for writing\n", fileName); return 0; } for(i = 0; i < 0x17; i++) { binaryWriteByte(file, 0x00); } binaryWriteUInt(file, (unsigned int) embStitchList_count(pattern->stitchList)); for(i = 0; i < 0x0C; i++) { binaryWriteByte(file, 0x00); } binaryWriteUShort(file, (unsigned short)embThreadList_count(pattern->threadList)); binaryWriteShort(file, 0x0000); rect = embPattern_calcBoundingBox(pattern); binaryWriteShort(file, (short)(embRect_width(rect) * 10.0)); binaryWriteShort(file, (short)(embRect_height(rect) * 10.0)); binaryWriteShort(file, (short)(embRect_width(rect) / 2.0 * 10)); /*TODO: xEnd from start point x=0 */ binaryWriteShort(file, (short)(embRect_height(rect) / 2.0 * 10)); /*TODO: yEnd from start point y=0 */ binaryWriteShort(file, (short)(embRect_width(rect)/2.0 * 10)); /*TODO: left from start x = 0 */ binaryWriteShort(file, (short)(embRect_height(rect)/2.0 * 10)); /*TODO: bottom from start y = 0 */ for(i = 0; i < 0xC5; i++) { binaryWriteByte(file, 0x00); } binaryWriteInt(file, 0x0000); /* place holder for end of stitches */ xxxEncodeDesign(file, pattern); endOfStitches = ftell(file); fseek(file, 0xFC, SEEK_SET); binaryWriteUInt(file, endOfStitches); fseek(file, 0, SEEK_END); binaryWriteByte(file, 0x7F); /* is this really correct? */ binaryWriteByte(file, 0x7F); binaryWriteByte(file, 0x03); binaryWriteByte(file, 0x14); binaryWriteByte(file, 0x00); binaryWriteByte(file, 0x00); colors = pattern->threadList; while(colors) { binaryWriteByte(file, 0x00); binaryWriteByte(file, colors->thread.color.r); binaryWriteByte(file, colors->thread.color.g); binaryWriteByte(file, colors->thread.color.b); curColor++; colors = colors->next; } for(i = 0; i < (22 - curColor); i++) { binaryWriteUInt(file, 0x01000000); } binaryWriteByte(file, 0x00); binaryWriteByte(file, 0x01); fclose(file); return 1; }
/*! Reads a file with the given \a fileName and loads the data into \a pattern. * Returns \c true if successful, otherwise returns \c false. */ int readCsv(EmbPattern* pattern, const char* fileName) { FILE* file = 0; int numColorChanges = 0; int size = 1024; int pos = 0; int c = 0; int cellNum = 0; int process = 0; int csvMode = CSV_MODE_NULL; int expect = CSV_EXPECT_QUOTE1; int flags = 0; double xx = 0.0; double yy = 0.0; unsigned char r = 0, g = 0, b = 0; char* buff = 0; if(!pattern) { embLog_error("format-csv.c readCsv(), pattern argument is null\n"); return 0; } if(!fileName) { embLog_error("format-csv.c readCsv(), fileName argument is null\n"); return 0; } buff = (char*)malloc(size); if(!buff) { embLog_error("format-csv.c readCsv(), unable to allocate memory for buff\n"); return 0; } file = fopen(fileName,"r"); if(!file) { embLog_error("format-csv.c readCsv(), cannot open %s for reading\n", fileName); return 0; } else { pos = 0; do { c = fgetc(file); switch(c) { case '"': if(expect == CSV_EXPECT_QUOTE1) { expect = CSV_EXPECT_QUOTE2; } else if(expect == CSV_EXPECT_QUOTE2) expect = CSV_EXPECT_COMMA; break; case ',': if(expect == CSV_EXPECT_COMMA) { process = 1; } break; case '\n': if(expect == CSV_EXPECT_COMMA) { process = 1; } else if(expect == CSV_EXPECT_QUOTE1) { /* Do Nothing. We encountered a blank line. */ } else { embLog_error("format-csv.c readCsv(), premature newline\n"); return 0; } break; } if(pos >= size - 1) { size *= 2; buff = (char*)realloc(buff,size); if(!buff) { embLog_error("format-csv.c readCsv(), cannot re-allocate memory for buff\n"); return 0; } } if(process) { buff[pos] = 0; pos = 0; process = 0; cellNum++; expect = CSV_EXPECT_QUOTE1; if(csvMode == CSV_MODE_NULL) { if (!strcmp(buff, "#")) { csvMode = CSV_MODE_COMMENT; } else if(!strcmp(buff, ">")) { csvMode = CSV_MODE_VARIABLE; } else if(!strcmp(buff, "$")) { csvMode = CSV_MODE_THREAD; } else if(!strcmp(buff, "*")) { csvMode = CSV_MODE_STITCH; } else { /* TODO: error */ return 0; } } else if(csvMode == CSV_MODE_COMMENT) { /* Do Nothing */ } else if(csvMode == CSV_MODE_VARIABLE) { /* Do Nothing */ } else if(csvMode == CSV_MODE_THREAD) { if(cellNum == 2) { /* Do Nothing. Ignore Thread Number */ } else if(cellNum == 3) r = (unsigned char)atoi(buff); else if(cellNum == 4) g = (unsigned char)atoi(buff); else if(cellNum == 5) b = (unsigned char)atoi(buff); else if(cellNum == 6) { /* TODO: Thread Description */ } else if(cellNum == 7) { /* TODO: Thread Catalog Number */ EmbThread t; t.color.r = r; t.color.g = g; t.color.b = b; t.description = "TODO:DESCRIPTION"; t.catalogNumber = "TODO:CATALOG_NUMBER"; embPattern_addThread(pattern, t); csvMode = CSV_MODE_NULL; cellNum = 0; } else { /* TODO: error */ return 0; } } else if(csvMode == CSV_MODE_STITCH) { if(cellNum == 2) { flags = csvStrToStitchFlag(buff); if(flags == STOP) numColorChanges++; } else if(cellNum == 3) xx = atof(buff); else if(cellNum == 4) { yy = atof(buff); embPattern_addStitchAbs(pattern, xx, yy, flags, 1); csvMode = CSV_MODE_NULL; cellNum = 0; } else { /* TODO: error */ return 0; } } if(c == '\n') { csvMode = CSV_MODE_NULL; cellNum = 0; } } else { if(expect == CSV_EXPECT_QUOTE2 && c != '"') buff[pos++] = (char)c; } } while(c != EOF); fclose(file); } /* if not enough colors defined, fill in random colors */ while(embThreadList_count(pattern->threadList) < numColorChanges) { embPattern_addThread(pattern, embThread_getRandom()); } free(buff); buff = 0; return 1; }
/*! Writes the data from \a pattern to a file with the given \a fileName. * Returns \c true if successful, otherwise returns \c false. */ int writeCsv(EmbPattern* pattern, const char* fileName) { FILE* file = 0; EmbStitchList* sList = 0; EmbThreadList* tList = 0; EmbRect boundingRect; int i = 0; int stitchCount = 0; int threadCount = 0; if(!pattern) { embLog_error("format-csv.c writeCsv(), pattern argument is null\n"); return 0; } if(!fileName) { embLog_error("format-csv.c writeCsv(), fileName argument is null\n"); return 0; } sList = pattern->stitchList; stitchCount = embStitchList_count(sList); tList = pattern->threadList; threadCount = embThreadList_count(tList); boundingRect = embPattern_calcBoundingBox(pattern); if(!stitchCount) { embLog_error("format-csv.c writeCsv(), pattern contains no stitches\n"); return 0; } /* Check for an END stitch and add one if it is not present */ if(pattern->lastStitch->stitch.flags != END) { embPattern_addStitchRel(pattern, 0, 0, END, 1); stitchCount++; } file = fopen(fileName, "w"); if(!file) { embLog_error("format-csv.c writeCsv(), cannot open %s for writing\n", fileName); return 0; } /* write header */ fprintf(file, "\"#\",\"Embroidermodder 2 CSV Embroidery File\"\n"); fprintf(file, "\"#\",\"http://embroidermodder.github.io\"\n"); fprintf(file, "\n"); fprintf(file, "\"#\",\"General Notes:\"\n"); fprintf(file, "\"#\",\"This file can be read by Excel or LibreOffice as CSV (Comma Separated Value) or with a text editor.\"\n"); fprintf(file, "\"#\",\"Lines beginning with # are comments.\"\n"); fprintf(file, "\"#\",\"Lines beginning with > are variables: [VAR_NAME], [VAR_VALUE]\"\n"); fprintf(file, "\"#\",\"Lines beginning with $ are threads: [THREAD_NUMBER], [RED], [GREEN], [BLUE], [DESCRIPTION], [CATALOG_NUMBER]\"\n"); fprintf(file, "\"#\",\"Lines beginning with * are stitch entries: [STITCH_TYPE], [X], [Y]\"\n"); fprintf(file, "\n"); fprintf(file, "\"#\",\"Stitch Entry Notes:\"\n"); fprintf(file, "\"#\",\"STITCH instructs the machine to move to the position [X][Y] and then make a stitch.\"\n"); fprintf(file, "\"#\",\"JUMP instructs the machine to move to the position [X][Y] without making a stitch.\"\n"); fprintf(file, "\"#\",\"TRIM instructs the machine to cut the thread before moving to the position [X][Y] without making a stitch.\"\n"); fprintf(file, "\"#\",\"COLOR instructs the machine to stop temporarily so that the user can change to a different color thread before resuming.\"\n"); fprintf(file, "\"#\",\"END instructs the machine that the design is completed and there are no further instructions.\"\n"); fprintf(file, "\"#\",\"UNKNOWN encompasses instructions that may not be supported currently.\"\n"); fprintf(file, "\"#\",\"[X] and [Y] are absolute coordinates in millimeters (mm).\"\n"); fprintf(file, "\n"); /* write variables */ fprintf(file,"\"#\",\"[VAR_NAME]\",\"[VAR_VALUE]\"\n"); fprintf(file, "\">\",\"STITCH_COUNT:\",\"%u\"\n", (unsigned int)stitchCount); fprintf(file, "\">\",\"THREAD_COUNT:\",\"%u\"\n", (unsigned int)threadCount); fprintf(file, "\">\",\"EXTENTS_LEFT:\",\"%f\"\n", boundingRect.left); fprintf(file, "\">\",\"EXTENTS_TOP:\",\"%f\"\n", boundingRect.top); fprintf(file, "\">\",\"EXTENTS_RIGHT:\",\"%f\"\n", boundingRect.right); fprintf(file, "\">\",\"EXTENTS_BOTTOM:\",\"%f\"\n", boundingRect.bottom); fprintf(file, "\">\",\"EXTENTS_WIDTH:\",\"%f\"\n", embRect_width(boundingRect)); fprintf(file, "\">\",\"EXTENTS_HEIGHT:\",\"%f\"\n", embRect_height(boundingRect)); fprintf(file,"\n"); /* write colors */ fprintf(file, "\"#\",\"[THREAD_NUMBER]\",\"[RED]\",\"[GREEN]\",\"[BLUE]\",\"[DESCRIPTION]\",\"[CATALOG_NUMBER]\"\n"); i = 1; while(tList) { fprintf(file, "\"$\",\"%d\",\"%d\",\"%d\",\"%d\",\"%s\",\"%s\"\n", i, /* TODO: fix segfault that backtraces here when libembroidery-convert from dst to csv. */ (int)tList->thread.color.r, (int)tList->thread.color.g, (int)tList->thread.color.b, tList->thread.description, tList->thread.catalogNumber); i++; tList = tList->next; } fprintf(file, "\n"); /* write stitches */ fprintf(file, "\"#\",\"[STITCH_TYPE]\",\"[X]\",\"[Y]\"\n"); while(sList) { EmbStitch s = sList->stitch; fprintf(file, "\"*\",\"%s\",\"%f\",\"%f\"\n", csvStitchFlagToStr(s.flags), s.xx, s.yy); sList = sList->next; } fclose(file); return 1; }
/*! Writes the data from \a pattern to a file with the given \a fileName. * Returns \c true if successful, otherwise returns \c false. */ int writeVip(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 = 0, *yValues = 0, *attributeValues = 0; EmbStitchList* pointer = 0; double xx = 0.0; double yy = 0.0; int flags = 0; int i = 0; unsigned char* attributeCompressed = 0, *xCompressed = 0, *yCompressed = 0, *decodedColors = 0, *encodedColors = 0; unsigned char prevByte = 0; EmbThreadList* colorPointer = 0; EmbFile* file = 0; if(!pattern) { embLog_error("format-vip.c writeVip(), pattern argument is null\n"); return 0; } if(!fileName) { embLog_error("format-vip.c writeVip(), fileName argument is null\n"); return 0; } stitchCount = embStitchList_count(pattern->stitchList); if(!stitchCount) { embLog_error("format-vip.c writeVip(), pattern contains no stitches\n"); return 0; } /* Check for an END stitch and add one if it is not present */ if(pattern->lastStitch && pattern->lastStitch->stitch.flags != END) { embPattern_addStitchRel(pattern, 0, 0, END, 1); stitchCount++; } file = embFile_open(fileName, "wb"); if(file == 0) { embLog_error("format-vip.c writeVip(), cannot open %s for writing\n", fileName); return 0; } minColors = embThreadList_count(pattern->threadList); decodedColors = (unsigned char*)malloc(minColors << 2); if(!decodedColors) return 0; encodedColors = (unsigned char*)malloc(minColors << 2); if(encodedColors) /* TODO: review this line. It looks clearly wrong. If not, note why. */ { free(decodedColors); decodedColors = 0; return 0; } /* embPattern_correctForMaxStitchLength(pattern, 0x7F, 0x7F); */ patternColor = minColors; if(minColors > 24) minColors = 24; binaryWriteUInt(file, 0x0190FC5D); 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, 0x38 + (minColors << 3)); xValues = (unsigned char*)malloc(sizeof(unsigned char)*(stitchCount)); yValues = (unsigned char*)malloc(sizeof(unsigned char)*(stitchCount)); attributeValues = (unsigned char*)malloc(sizeof(unsigned char)*(stitchCount)); if(xValues && yValues && attributeValues) { pointer = pattern->stitchList; while(pointer) { xx = pointer->stitch.xx; yy = pointer->stitch.yy; flags = pointer->stitch.flags; xValues[i] = vipEncodeByte((xx - previousX) * 10.0); previousX = xx; yValues[i] = vipEncodeByte((yy - previousY) * 10.0); previousY = yy; attributeValues[i] = vipEncodeStitchType(flags); pointer = pointer->next; i++; } attributeCompressed = vipCompressData(attributeValues, stitchCount, &attributeSize); xCompressed = vipCompressData(xValues, stitchCount, &xCompressedSize); yCompressed = vipCompressData(yValues, stitchCount, &yCompressedSize); binaryWriteUInt(file, (unsigned int) (0x38 + (minColors << 3) + attributeSize)); binaryWriteUInt(file, (unsigned int) (0x38 + (minColors << 3) + attributeSize + xCompressedSize)); binaryWriteUInt(file, 0x00000000); binaryWriteUInt(file, 0x00000000); binaryWriteUShort(file, 0x0000); binaryWriteInt(file, minColors << 2); colorPointer = pattern->threadList; for(i = 0; i < minColors; i++) { int byteChunk = i << 2; EmbColor currentColor = colorPointer->thread.color; decodedColors[byteChunk] = currentColor.r; decodedColors[byteChunk + 1] = currentColor.g; decodedColors[byteChunk + 2] = currentColor.b; decodedColors[byteChunk + 3] = 0x01; colorPointer = colorPointer->next; } for(i = 0; i < minColors << 2; ++i) { unsigned char tmpByte = (unsigned char) (decodedColors[i] ^ vipDecodingTable[i]); prevByte = (unsigned char) (tmpByte ^ prevByte); binaryWriteByte(file, prevByte); } for(i = 0; i <= minColors; i++) { binaryWriteInt(file, 1); } binaryWriteUInt(file, 0); /* string length */ binaryWriteShort(file, 0); binaryWriteBytes(file, (char*) attributeCompressed, attributeSize); binaryWriteBytes(file, (char*) xCompressed, xCompressedSize); binaryWriteBytes(file, (char*) yCompressed, yCompressedSize); } if(attributeCompressed) { free(attributeCompressed); attributeCompressed = 0; } if(xCompressed) { free(xCompressed); xCompressed = 0; } if(yCompressed) { free(yCompressed); yCompressed = 0; } if(attributeValues) { free(attributeValues); attributeValues = 0; } if(xValues) { free(xValues); xValues = 0; } if(yValues) { free(yValues); yValues = 0; } if(decodedColors) { free(decodedColors); decodedColors = 0; } if(encodedColors) { free(encodedColors); encodedColors = 0; } embFile_close(file); return 1; }
/*! Writes the data from \a pattern to a file with the given \a fileName. * Returns \c true if successful, otherwise returns \c false. */ int writePcs(EmbPattern* pattern, const char* fileName) { EmbStitchList* pointer = 0; EmbThreadList* threadPointer = 0; EmbFile* file = 0; int i = 0; unsigned char colorCount = 0; double xx = 0.0, yy = 0.0; if(!pattern) { embLog_error("format-pcs.c writePcs(), pattern argument is null\n"); return 0; } if(!fileName) { embLog_error("format-pcs.c writePcs(), fileName argument is null\n"); return 0; } if(!embStitchList_count(pattern->stitchList)) { embLog_error("format-pcs.c writePcs(), pattern contains no stitches\n"); return 0; } /* Check for an END stitch and add one if it is not present */ if(pattern->lastStitch->stitch.flags != END) embPattern_addStitchRel(pattern, 0, 0, END, 1); file = embFile_open(fileName, "wb"); if(!file) { embLog_error("format-pcs.c writePcs(), cannot open %s for writing\n", fileName); return 0; } binaryWriteByte(file, (unsigned char)'2'); binaryWriteByte(file, 3); /* TODO: select hoop size defaulting to Large PCS hoop */ colorCount = (unsigned char)embThreadList_count(pattern->threadList); binaryWriteUShort(file, (unsigned short)colorCount); threadPointer = pattern->threadList; i = 0; while(threadPointer) { EmbColor color = threadPointer->thread.color; binaryWriteByte(file, color.r); binaryWriteByte(file, color.g); binaryWriteByte(file, color.b); binaryWriteByte(file, 0); threadPointer = threadPointer->next; i++; } for(; i < 16; i++) { binaryWriteUInt(file, 0); /* write remaining colors to reach 16 */ } binaryWriteUShort(file, (unsigned short)embStitchList_count(pattern->stitchList)); /* write stitches */ xx = yy = 0; pointer = pattern->stitchList; while(pointer) { pcsEncode(file, roundDouble(pointer->stitch.xx * 10.0), roundDouble(pointer->stitch.yy * 10.0), pointer->stitch.flags); pointer = pointer->next; } embFile_close(file); return 1; }
/*! Writes the data from \a pattern to a file with the given \a fileName. * Returns \c true if successful, otherwise returns \c false. */ int writeJef(EmbPattern* pattern, const char* fileName) { int colorlistSize, minColors, designWidth, designHeight, i; EmbRect boundingRect; FILE* file = 0; EmbTime time; EmbThreadList* threadPointer = 0; EmbStitch c; EmbStitchList* pointer = 0; double prevX, prevY; if(!pattern) { embLog_error("format-jef.c writeJef(), pattern argument is null\n"); return 0; } if(!fileName) { embLog_error("format-jef.c writeJef(), fileName argument is null\n"); return 0; } if(!embStitchList_count(pattern->stitchList)) { embLog_error("format-jef.c writeJef(), pattern contains no stitches\n"); return 0; } /* Check for an END stitch and add one if it is not present */ if(pattern->lastStitch->stitch.flags != END) embPattern_addStitchRel(pattern, 0, 0, END, 1); file = fopen(fileName, "wb"); if(!file) { embLog_error("format-jef.c writeJef(), cannot open %s for writing\n", fileName); return 0; } embPattern_correctForMaxStitchLength(pattern, 127, 127); colorlistSize = embThreadList_count(pattern->threadList); minColors = max(colorlistSize, 6); binaryWriteInt(file, 0x74 + (minColors * 4)); binaryWriteInt(file, 0x0A); embTime_initNow(&time); fprintf(file, "%04d%02d%02d%02d%02d%02d", (int)(time.year + 1900), (int)(time.month + 1), (int)(time.day), (int)(time.hour), (int)(time.minute), (int)(time.second)); binaryWriteByte(file, 0x00); binaryWriteByte(file, 0x00); binaryWriteInt(file, embThreadList_count(pattern->threadList)); binaryWriteInt(file, embStitchList_count(pattern->stitchList) + max(0, (6 - colorlistSize) * 2) + 1); boundingRect = embPattern_calcBoundingBox(pattern); designWidth = (int)(embRect_width(boundingRect) * 10.0); designHeight = (int)(embRect_width(boundingRect) * 10.0); binaryWriteInt(file, jefGetHoopSize(designWidth, designHeight)); /* Distance from center of Hoop */ binaryWriteInt(file, (int) (designWidth / 2)); /* left */ binaryWriteInt(file, (int) (designHeight / 2)); /* top */ binaryWriteInt(file, (int) (designWidth / 2)); /* right */ binaryWriteInt(file, (int) (designHeight / 2)); /* bottom */ /* Distance from default 110 x 110 Hoop */ if(min(550 - designWidth / 2, 550 - designHeight / 2) >= 0) { binaryWriteInt(file, (int) max(-1, 550 - designWidth / 2)); /* left */ binaryWriteInt(file, (int) max(-1, 550 - designHeight / 2)); /* top */ binaryWriteInt(file, (int) max(-1, 550 - designWidth / 2)); /* right */ binaryWriteInt(file, (int) max(-1, 550 - designHeight / 2)); /* bottom */ } else { binaryWriteInt(file, -1); binaryWriteInt(file, -1); binaryWriteInt(file, -1); binaryWriteInt(file, -1); } /* Distance from default 50 x 50 Hoop */ if(min(250 - designWidth / 2, 250 - designHeight / 2) >= 0) { binaryWriteInt(file, (int) max(-1, 250 - designWidth / 2)); /* left */ binaryWriteInt(file, (int) max(-1, 250 - designHeight / 2)); /* top */ binaryWriteInt(file, (int) max(-1, 250 - designWidth / 2)); /* right */ binaryWriteInt(file, (int) max(-1, 250 - designHeight / 2)); /* bottom */ } else { binaryWriteInt(file, -1); binaryWriteInt(file, -1); binaryWriteInt(file, -1); binaryWriteInt(file, -1); } /* Distance from default 140 x 200 Hoop */ binaryWriteInt(file, (int) (700 - designWidth / 2)); /* left */ binaryWriteInt(file, (int) (1000 - designHeight / 2)); /* top */ binaryWriteInt(file, (int) (700 - designWidth / 2)); /* right */ binaryWriteInt(file, (int) (1000 - designHeight / 2)); /* bottom */ /* repeated Distance from default 140 x 200 Hoop */ /* TODO: Actually should be distance to custom hoop */ binaryWriteInt(file, (int) (630 - designWidth / 2)); /* left */ binaryWriteInt(file, (int) (550 - designHeight / 2)); /* top */ binaryWriteInt(file, (int) (630 - designWidth / 2)); /* right */ binaryWriteInt(file, (int) (550 - designHeight / 2)); /* bottom */ threadPointer = pattern->threadList; while(threadPointer) { binaryWriteInt(file, embThread_findNearestColorInArray(threadPointer->thread.color, (EmbThread*)jefThreads, 79)); threadPointer = threadPointer->next; } for(i = 0; i < (minColors - colorlistSize); i++) { binaryWriteInt(file, 0x0D); } pointer = pattern->stitchList; prevX = pointer->stitch.xx; prevY = pointer->stitch.yy; jefEncode(file, (unsigned char) prevX, (unsigned char) prevY, pointer->stitch.flags); pointer = pointer->next; while(pointer) { c = pointer->stitch; jefEncode(file, (unsigned char) (c.xx - prevX), (unsigned char) (c.yy - prevY), c.flags); prevX = c.xx; prevY = c.yy; pointer = pointer->next; } fclose(file); return 1; }
/*! Writes the data from \a pattern to a file with the given \a fileName. * Returns \c true if successful, otherwise returns \c false. */ int writeDst(EmbPattern* pattern, const char* fileName) { EmbRect boundingRect; FILE* file = 0; int xx, yy, dx, dy, flags; int i; int co = 1, st = 0; int ax, ay, mx, my; char* pd = 0; EmbStitchList* pointer = 0; if(!pattern) { embLog_error("format-dst.c writeDst(), pattern argument is null\n"); return 0; } if(!fileName) { embLog_error("format-dst.c writeDst(), fileName argument is null\n"); return 0; } file = fopen(fileName, "wb"); if(!file) { embLog_error("format-dst.c writeDst(), cannot open %s for writing\n", fileName); return 0; } embPattern_correctForMaxStitchLength(pattern, 12.1, 12.1); xx = yy = 0; co = 1; co = embThreadList_count(pattern->threadList); st = 0; st = embStitchList_count(pattern->stitchList); flags = NORMAL; boundingRect = embPattern_calcBoundingBox(pattern); /* TODO: review the code below if (pattern->get_variable("design_name") != NULL) { char *la = stralloccopy(pattern->get_variable("design_name")); if (strlen(la)>16) la[16]='\0'; fprintf(file,"LA:%-16s\x0d",la); free (la); } else { */ fprintf(file, "LA:%-16s\x0d", "Untitled"); /*} */ fprintf(file, "ST:%7d\x0d", st); fprintf(file, "CO:%3d\x0d", co - 1); /* number of color changes, not number of colors! */ fprintf(file, "+X:%5d\x0d", (int)(boundingRect.right * 10.0)); fprintf(file, "-X:%5d\x0d", (int)(fabs(boundingRect.left) * 10.0)); fprintf(file, "+Y:%5d\x0d", (int)(boundingRect.bottom * 10.0)); fprintf(file, "-Y:%5d\x0d", (int)(fabs(boundingRect.top) * 10.0)); ax = ay = mx = my = 0; /* TODO: review the code below */ /*ax=pattern->get_variable_int("ax"); */ /* will return 0 if not defined */ /*ay=pattern->get_variable_int("ay"); */ /*mx=pattern->get_variable_int("mx"); */ /*my=pattern->get_variable_int("my"); */ /*pd=pattern->get_variable("pd");*/ /* will return null pointer if not defined */ pd = 0; if(pd == 0 || strlen(pd) != 6) { /* pd is not valid, so fill in a default consisting of "******" */ pd = "******"; }; fprintf(file, "AX:+%5d\x0d", ax); fprintf(file, "AY:+%5d\x0d", ay); fprintf(file, "MX:+%5d\x0d", mx); fprintf(file, "MY:+%5d\x0d", my); fprintf(file, "PD:%6s\x0d", pd); binaryWriteByte(file, 0x1a); /* 0x1a is the code for end of section. */ /* pad out header to proper length */ for(i = 125; i < 512; i++) { fprintf(file, " "); } /* write stitches */ xx = yy = 0; pointer = pattern->stitchList; while(pointer) { /* convert from mm to 0.1mm for file format */ dx = roundDouble(pointer->stitch.xx * 10.0) - xx; dy = roundDouble(pointer->stitch.yy * 10.0) - yy; xx = roundDouble(pointer->stitch.xx * 10.0); yy = roundDouble(pointer->stitch.yy * 10.0); flags = pointer->stitch.flags; encode_record(file, dx, dy, flags); pointer = pointer->next; } binaryWriteByte(file, 0xA1); /* finish file with a terminator character */ binaryWriteShort(file, 0); fclose(file); return 1; }
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; }