/*! 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; } } }
/*! 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 readDxf(EmbPattern* pattern, const char* fileName) { FILE* file = 0; char* buff = ""; char* dxfVersion = ""; char* section = ""; char* tableName = ""; char* layerName = ""; char* entityType = ""; EmbHash* layerColorHash = 0; /* hash <layerName, EmbColor> */ int eof = 0; /* End Of File */ double bulge, firstX, firstY, x, y, prevX, prevY; char firstStitch = 1; char bulgeFlag = 0; int fileLength = 0; unsigned char colorNum = 0; if(!pattern) { embLog_error("format-dxf.c readDxf(), pattern argument is null\n"); return 0; } if(!fileName) { embLog_error("format-dxf.c readDxf(), fileName argument is null\n"); return 0; } layerColorHash = embHash_create(); if(!layerColorHash) { embLog_error("format-dxf.c readDxf(), unable to allocate memory for layerColorHash\n"); return 0; } file = fopen(fileName, "r"); if(!file) { embLog_error("format-dxf.c readDxf(), cannot open %s for reading\n", fileName); return 0; } fseek(file, 0L, SEEK_END); fileLength = ftell(file); fseek(file, 0L, SEEK_SET); while(ftell(file) < fileLength) { buff = readLine(file); /*printf("%s\n", buff);*/ if((!strcmp(buff, "HEADER")) || (!strcmp(buff, "CLASSES")) || (!strcmp(buff, "TABLES")) || (!strcmp(buff, "BLOCKS")) || (!strcmp(buff, "ENTITIES")) || (!strcmp(buff, "OBJECTS")) || (!strcmp(buff, "THUMBNAILIMAGE"))) { section = buff; printf("SECTION:%s\n", buff); } if(!strcmp(buff, "ENDSEC")) { section = ""; printf("ENDSEC:%s\n", buff); } if((!strcmp(buff, "LWPOLYLINE")) || (!strcmp(buff, "CIRCLE"))) { entityType = buff; } if(!strcmp(buff, "EOF")) { eof = 1; } if(!strcmp(section, "HEADER")) { if(!strcmp(buff, "$ACADVER")) { buff = readLine(file); dxfVersion = readLine(file); /* TODO: Allow these versions when POLYLINE is handled. */ if((!strcmp(dxfVersion, DXF_VERSION_R10)) || (!strcmp(dxfVersion, DXF_VERSION_R11)) || (!strcmp(dxfVersion, DXF_VERSION_R12)) || (!strcmp(dxfVersion, DXF_VERSION_R13)) || (!strcmp(dxfVersion, DXF_VERSION_R14))) return 0; } } else if(!strcmp(section,"TABLES")) { if(!strcmp(buff,"ENDTAB")) { tableName = NULL; } if(tableName == NULL) { if(!strcmp(buff,"2")) /* Table Name */ { tableName = readLine(file); } } else if(!strcmp(tableName, "LAYER")) { /* Common Group Codes for Tables */ if(!strcmp(buff,"5")) /* Handle */ { buff = readLine(file); continue; } else if(!strcmp(buff,"330")) /* Soft Pointer */ { buff = readLine(file); continue; } else if(!strcmp(buff,"100")) /* Subclass Marker */ { buff = readLine(file); continue; } else if(!strcmp(buff,"70")) /* Number of Entries in Table */ { buff = readLine(file); continue; } /* The meaty stuff */ else if(!strcmp(buff,"2")) /* Layer Name */ { layerName = readLine(file); } else if(!strcmp(buff,"62")) /* Color Number */ { buff = readLine(file); colorNum = atoi(buff); /* TODO: finish this unsigned char colorNum = atoi(buff); EmbColor* co = embColor_create(_dxfColorTable[colorNum][0], _dxfColorTable[colorNum][1], _dxfColorTable[colorNum][2]); if(!co) { / TODO: error allocating memory for EmbColor return 0; } printf("inserting:%s,%d,%d,%d\n", layerName, co->r, co->g, co->b); if(embHash_insert(layerColorHash, emb_strdup(layerName), co)) { TODO: log error: failed inserting into layerColorHash } */ layerName = NULL; } } } else if(!strcmp(section,"ENTITIES")) { /* Common Group Codes for Entities */ if(!strcmp(buff, "5")) /* Handle */ { buff = readLine(file); continue; } else if(!strcmp(buff, "330")) /* Soft Pointer */ { buff = readLine(file); continue; } else if(!strcmp(buff, "100")) /* Subclass Marker */ { buff = readLine(file); continue; } else if(!strcmp(buff, "8")) /* Layer Name */ { buff = readLine(file); /* embPattern_changeColor(pattern, colorIndexMap[buff]); TODO: port to C */ continue; } if(!strcmp(entityType,"LWPOLYLINE")) { double* arcMidX = 0; double* arcMidY = 0; /* The not so important group codes */ if(!strcmp(buff, "90")) /* Vertices */ { buff = readLine(file); continue; } else if(!strcmp(buff,"70")) /* Polyline Flag */ { buff = readLine(file); continue; } /* TODO: Try to use the widths at some point */ else if(!strcmp(buff,"40")) /* Starting Width */ { buff = readLine(file); continue; } else if(!strcmp(buff,"41")) /* Ending Width */ { buff = readLine(file); continue; } else if(!strcmp(buff,"43")) /* Constant Width */ { buff = readLine(file); continue; } /* The meaty stuff */ else if(!strcmp(buff,"42")) /* Bulge */ { buff = readLine(file); bulge = atof(buff); bulgeFlag = 1; } else if(!strcmp(buff,"10")) /* X */ { buff = readLine(file); x = atof(buff); } else if(!strcmp(buff,"20")) /* Y */ { buff = readLine(file); y = atof(buff); if(bulgeFlag) { bulgeFlag = 0; if(!getArcDataFromBulge(bulge, prevX, prevY, x, y, arcMidX, arcMidY, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)) { /*TODO: error */ return 0; } if(firstStitch) { /* embPattern_addStitchAbs(pattern, x, y, TRIM, 1); TODO: Add moveTo point to embPath pointList */ } /* embPattern_addStitchAbs(pattern, x, y, ARC, 1); TODO: Add arcTo point to embPath pointList */ } else { /*if(firstStitch) embPattern_addStitchAbs(pattern, x, y, TRIM, 1); TODO: Add moveTo point to embPath pointList */ /*else embPattern_addStitchAbs(pattern, x, y, NORMAL, 1); TODO: Add lineTo point to embPath pointList */ } prevX = x; prevY = y; if(firstStitch) { firstX = x; firstY = y; firstStitch = 0; } } else if(!strcmp(buff,"0")) { entityType = NULL; firstStitch = 1; if(bulgeFlag) { bulgeFlag = 0; if(!getArcDataFromBulge(bulge, prevX, prevY, firstX, firstY, arcMidX, arcMidY, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)) { /*TODO: error */ return 0; } /* embPattern_addStitchAbs(pattern, prevX, prevY, ARC, 1); TODO: Add arcTo point to embPath pointList */ } else { /* embPattern_addStitchAbs(pattern, firstX, firstY, NORMAL, 1); TODO: Add lineTo point to embPath pointList */ } } } /* end LWPOLYLINE */ } /* end ENTITIES section */ } /* end while loop */ fclose(file); /* EmbColor* testColor = 0; testColor = embHash_value(layerColorHash, "OMEGA"); if(!testColor) printf("NULL POINTER!!!!!!!!!!!!!!\n"); else printf("LAYERCOLOR: %d,%d,%d\n", testColor->r, testColor->g, testColor->b); */ if(!eof) { /* NOTE: The EOF item must be present at the end of file to be considered a valid DXF file. */ embLog_error("format-dxf.c readDxf(), missing EOF at end of DXF file\n"); } return eof; }
void embPattern_movePolylinesToStitchList(EmbPattern* p) { if(!p) { embLog_error("emb-pattern.c embPattern_movePolylinesToStitchList(), p argument is null\n"); return; } embPattern_copyPolylinesToStitchList(p); embPolylineObjectList_free(p->polylineObjList); }
/*! Writes the data from \a pattern to a file with the given \a fileName. * Returns \c true if successful, otherwise returns \c false. */ int writeNew(EmbPattern* pattern, const char* fileName) { if(!pattern) { embLog_error("format-new.c writeNew(), pattern argument is null\n"); return 0; } if(!fileName) { embLog_error("format-new.c writeNew(), fileName argument is null\n"); return 0; } return 0; /*TODO: finish writeNew */ }
void readPecStitches(EmbPattern* pattern, EmbFile* file) { int stitchNumber = 0; if(!pattern) { embLog_error("format-pec.c readPecStitches(), pattern argument is null\n"); return; } if(!file) { embLog_error("format-pec.c readPecStitches(), file argument is null\n"); return; } while(!embFile_eof(file)) { int val1 = (int)binaryReadUInt8(file); int val2 = (int)binaryReadUInt8(file); int stitchType = NORMAL; if(val1 == 0xFF && val2 == 0x00) { embPattern_addStitchRel(pattern, 0.0, 0.0, END, 1); break; } if(val1 == 0xFE && val2 == 0xB0) { (void)binaryReadByte(file); embPattern_addStitchRel(pattern, 0.0, 0.0, STOP, 1); stitchNumber++; continue; } /* High bit set means 12-bit offset, otherwise 7-bit signed delta */ if(val1 & 0x80) { if(val1 & 0x20) stitchType = TRIM; if(val1 & 0x10) stitchType = JUMP; val1 = ((val1 & 0x0F) << 8) + val2; /* Signed 12-bit arithmetic */ if(val1 & 0x800) { val1 -= 0x1000; } val2 = binaryReadUInt8(file); } else if(val1 >= 0x40) { val1 -= 0x80; } if(val2 & 0x80) { if(val2 & 0x20) stitchType = TRIM; if(val2 & 0x10) stitchType = JUMP; val2 = ((val2 & 0x0F) << 8) + binaryReadUInt8(file); /* Signed 12-bit arithmetic */ if(val2 & 0x800) { val2 -= 0x1000; } } else if(val2 >= 0x40) { val2 -= 0x80; } embPattern_addStitchRel(pattern, val1 / 10.0, val2 / 10.0, stitchType, 1); stitchNumber++; } }
/*! 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 readVp3(EmbPattern* pattern, const char* fileName) { unsigned char magicString[5]; unsigned char some; unsigned char* softwareVendorString = 0; unsigned char v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18; unsigned char* anotherSoftwareVendorString = 0; int numberOfColors; long colorSectionOffset; unsigned char magicCode[6]; short someShort; unsigned char someByte; int bytesRemainingInFile; unsigned char* fileCommentString = 0; /* some software writes used settings here */ int hoopConfigurationOffset; unsigned char* anotherCommentString = 0; int i; EmbFile* file = 0; if(!pattern) { embLog_error("format-vp3.c readVp3(), pattern argument is null\n"); return 0; } if(!fileName) { embLog_error("format-vp3.c readVp3(), fileName argument is null\n"); return 0; } file = embFile_open(fileName, "rb"); if(!file) { embLog_error("format-vp3.c readVp3(), cannot open %s for reading\n", fileName); return 0; } binaryReadBytes(file, magicString, 5); /* %vsm% */ /* TODO: check return value */ some = binaryReadByte(file); /* 0 */ softwareVendorString = vp3ReadString(file); someShort = binaryReadInt16(file); someByte = binaryReadByte(file); bytesRemainingInFile = binaryReadInt32(file); fileCommentString = vp3ReadString(file); hoopConfigurationOffset = (int)embFile_tell(file); vp3ReadHoopSection(file); anotherCommentString = vp3ReadString(file); /* TODO: review v1 thru v18 variables and use emb_unused() if needed */ v1 = binaryReadByte(file); v2 = binaryReadByte(file); v3 = binaryReadByte(file); v4 = binaryReadByte(file); v5 = binaryReadByte(file); v6 = binaryReadByte(file); v7 = binaryReadByte(file); v8 = binaryReadByte(file); v9 = binaryReadByte(file); v10 = binaryReadByte(file); v11 = binaryReadByte(file); v12 = binaryReadByte(file); v13 = binaryReadByte(file); v14 = binaryReadByte(file); v15 = binaryReadByte(file); v16 = binaryReadByte(file); v17 = binaryReadByte(file); v18 = binaryReadByte(file); binaryReadBytes(file, magicCode, 6); /* 0x78 0x78 0x55 0x55 0x01 0x00 */ /* TODO: check return value */ anotherSoftwareVendorString = vp3ReadString(file); numberOfColors = binaryReadInt16BE(file); embLog_error("format-vp3.c Number of Colors: %d\n", numberOfColors); colorSectionOffset = (int)embFile_tell(file); for(i = 0; i < numberOfColors; i++) { EmbThread t; char tableSize; int startX, startY, offsetToNextColorX, offsetToNextColorY; unsigned char* threadColorNumber, *colorName, *threadVendor; int unknownThreadString, numberOfBytesInColor; embFile_seek(file, colorSectionOffset, SEEK_SET); embLog_error("format-vp3.c Color Check Byte #1: 0 == %d\n", binaryReadByte(file)); embLog_error("format-vp3.c Color Check Byte #2: 5 == %d\n", binaryReadByte(file)); embLog_error("format-vp3.c Color Check Byte #3: 0 == %d\n", binaryReadByte(file)); colorSectionOffset = binaryReadInt32BE(file); colorSectionOffset += embFile_tell(file); startX = binaryReadInt32BE(file); startY = binaryReadInt32BE(file); embPattern_addStitchAbs(pattern, startX / 1000, -startY / 1000, JUMP, 0); tableSize = binaryReadByte(file); binaryReadByte(file); t.color.r = binaryReadByte(file); t.color.g = binaryReadByte(file); t.color.b = binaryReadByte(file); embPattern_addThread(pattern, t); embFile_seek(file, 6*tableSize - 1, SEEK_CUR); threadColorNumber = vp3ReadString(file); colorName = vp3ReadString(file); threadVendor = vp3ReadString(file); offsetToNextColorX = binaryReadInt32BE(file); offsetToNextColorY = binaryReadInt32BE(file); unknownThreadString = binaryReadInt16BE(file); embFile_seek(file, unknownThreadString, SEEK_CUR); numberOfBytesInColor = binaryReadInt32BE(file); embFile_seek(file, 0x3, SEEK_CUR); while(embFile_tell(file) < colorSectionOffset - 1) { int lastFilePosition = embFile_tell(file); int x = vp3Decode(binaryReadByte(file)); int y = vp3Decode(binaryReadByte(file)); if(x == 0x80) { switch (y) { case 0x00: case 0x03: break; case 0x01: x = vp3DecodeInt16(binaryReadInt16BE(file)); y = vp3DecodeInt16(binaryReadInt16BE(file)); binaryReadInt16BE(file); embPattern_addStitchRel(pattern, x/ 10.0, y / 10.0, TRIM, 1); break; default: break; } } else { embPattern_addStitchRel(pattern, x / 10.0, y / 10.0, NORMAL, 1); } if(embFile_tell(file) == lastFilePosition) { embLog_error("format-vp3.c could not read stitch block in entirety\n"); return 0; } } if(i + 1 < numberOfColors) embPattern_addStitchRel(pattern, 0, 0, STOP, 1); } embFile_close(file); /* 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); embPattern_flipVertical(pattern); 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; }
/*TODO: Description needed. */ void embPattern_loadExternalColorFile(EmbPattern* p, const char* fileName) { #ifdef ARDUINO return; /* TODO ARDUINO: This function leaks memory. While it isn't crucial to running the machine, it would be nice use this function, so fix it up. */ #endif /* ARDUINO */ char hasRead = 0; EmbReaderWriter* colorFile = 0; const char* dotPos = strrchr(fileName, '.'); char* extractName = 0; if(!p) { embLog_error("emb-pattern.c embPattern_loadExternalColorFile(), p argument is null\n"); return; } if(!fileName) { embLog_error("emb-pattern.c embPattern_loadExternalColorFile(), fileName argument is null\n"); return; } extractName = (char*)malloc(dotPos - fileName + 5); if(!extractName) { embLog_error("emb-pattern.c embPattern_loadExternalColorFile(), cannot allocate memory for extractName\n"); return; } extractName = (char*)memcpy(extractName, fileName, dotPos - fileName); extractName[dotPos - fileName] = '\0'; strcat(extractName,".edr"); colorFile = embReaderWriter_getByFileName(extractName); if(colorFile) { hasRead = (char)colorFile->reader(p, extractName); } if(!hasRead) { free(colorFile); colorFile = 0; extractName = (char*)memcpy(extractName, fileName, dotPos - fileName); extractName[dotPos - fileName] = '\0'; strcat(extractName,".rgb"); colorFile = embReaderWriter_getByFileName(extractName); if(colorFile) { hasRead = (char)colorFile->reader(p, extractName); } } if(!hasRead) { free(colorFile); colorFile = 0; extractName = (char*)memcpy(extractName, fileName, dotPos - fileName); extractName[dotPos - fileName] = '\0'; strcat(extractName,".col"); colorFile = embReaderWriter_getByFileName(extractName); if(colorFile) { hasRead = (char)colorFile->reader(p, extractName); } } if(!hasRead) { free(colorFile); colorFile = 0; extractName = (char*)memcpy(extractName, fileName, dotPos - fileName); extractName[dotPos - fileName] = '\0'; strcat(extractName,".inf"); colorFile = embReaderWriter_getByFileName(extractName); if(colorFile) { hasRead = (char)colorFile->reader(p, extractName); } } free(colorFile); colorFile = 0; free(extractName); extractName = 0; }
int main(int argc, const char* argv[]) { #ifdef SHORT_WAY EmbPattern* p = 0; int successful = 0, i = 0; if(argc < 3) { usage(); exit(0); } p = embPattern_create(); if(!p) { embLog_error("libembroidery-convert-main.c main(), cannot allocate memory for p\n"); exit(1); } successful = embPattern_read(p, argv[1]); if(!successful) { embLog_error("libembroidery-convert-main.c main(), reading file %s was unsuccessful\n", argv[1]); embPattern_free(p); exit(1); } i = 2; for(i = 2; i < argc; i++) { successful = embPattern_write(p, argv[i]); if(!successful) embLog_error("libembroidery-convert-main.c main(), writing file %s was unsuccessful\n", argv[i]); } embPattern_free(p); return 0; #else /* LONG_WAY */ EmbPattern* p = 0; EmbReaderWriter* reader = 0, *writer = 0; int successful = 0, i = 0; if(argc < 3) { usage(); exit(0); } p = embPattern_create(); if(!p) { embLog_error("libembroidery-convert-main.c main(), cannot allocate memory for p\n"); exit(1); } successful = 0; reader = embReaderWriter_getByFileName(argv[1]); if(!reader) { successful = 0; embLog_error("libembroidery-convert-main.c main(), unsupported read file type: %s\n", argv[1]); } else { successful = reader->reader(p, argv[1]); if(!successful) embLog_error("libembroidery-convert-main.c main(), reading file was unsuccessful: %s\n", argv[1]); } free(reader); if(!successful) { embPattern_free(p); exit(1); } i = 2; for(i = 2; i < argc; i++) { writer = embReaderWriter_getByFileName(argv[i]); if(!writer) { embLog_error("libembroidery-convert-main.c main(), unsupported write file type: %s\n", argv[i]); } else { successful = writer->writer(p, argv[i]); if(!successful) embLog_error("libembroidery-convert-main.c main(), writing file %s was unsuccessful\n", argv[i]); } free(writer); } embPattern_free(p); return 0; #endif /* SHORT_WAY */ }
/*! 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 embPattern_flip(EmbPattern* p, int horz, int vert) { EmbStitchList* stList = 0; EmbArcObjectList* aObjList = 0; EmbCircleObjectList* cObjList = 0; EmbEllipseObjectList* eObjList = 0; EmbLineObjectList* liObjList = 0; EmbPathObjectList* paObjList = 0; EmbPointList* paPointList = 0; EmbPointObjectList* pObjList = 0; EmbPolygonObjectList* pogObjList = 0; EmbPointList* pogPointList = 0; EmbPolylineObjectList* polObjList = 0; EmbPointList* polPointList = 0; EmbRectObjectList* rObjList = 0; EmbSplineObjectList* sObjList = 0; if(!p) { embLog_error("emb-pattern.c embPattern_flip(), p argument is null\n"); return; } stList = p->stitchList; while(stList) { if(horz) { stList->stitch.xx = -stList->stitch.xx; } if(vert) { stList->stitch.yy = -stList->stitch.yy; } stList = stList->next; } aObjList = p->arcObjList; while(aObjList) { /* TODO: embPattern_flip for arcs */ aObjList = aObjList->next; } cObjList = p->circleObjList; while(cObjList) { if(horz) { cObjList->circleObj.circle.centerX = -cObjList->circleObj.circle.centerX; } if(vert) { cObjList->circleObj.circle.centerY = -cObjList->circleObj.circle.centerY; } cObjList = cObjList->next; } eObjList = p->ellipseObjList; while(eObjList) { if(horz) { eObjList->ellipseObj.ellipse.centerX = -eObjList->ellipseObj.ellipse.centerX; } if(vert) { eObjList->ellipseObj.ellipse.centerY = -eObjList->ellipseObj.ellipse.centerY; } eObjList = eObjList->next; } liObjList = p->lineObjList; while(liObjList) { if(horz) { liObjList->lineObj.line.x1 = -liObjList->lineObj.line.x1; liObjList->lineObj.line.x2 = -liObjList->lineObj.line.x2; } if(vert) { liObjList->lineObj.line.y1 = -liObjList->lineObj.line.y1; liObjList->lineObj.line.y2 = -liObjList->lineObj.line.y2; } liObjList = liObjList->next; } paObjList = p->pathObjList; while(paObjList) { paPointList = paObjList->pathObj->pointList; while(paPointList) { if(horz) { paPointList->point.xx = -paPointList->point.xx; } if(vert) { paPointList->point.yy = -paPointList->point.yy; } paPointList = paPointList->next; } paObjList = paObjList->next; } pObjList = p->pointObjList; while(pObjList) { if(horz) { pObjList->pointObj.point.xx = -pObjList->pointObj.point.xx; } if(vert) { pObjList->pointObj.point.yy = -pObjList->pointObj.point.yy; } pObjList = pObjList->next; } pogObjList = p->polygonObjList; while(pogObjList) { pogPointList = pogObjList->polygonObj->pointList; while(pogPointList) { if(horz) { pogPointList->point.xx = -pogPointList->point.xx; } if(vert) { pogPointList->point.yy = -pogPointList->point.yy; } pogPointList = pogPointList->next; } pogObjList = pogObjList->next; } polObjList = p->polylineObjList; while(polObjList) { polPointList = polObjList->polylineObj->pointList; while(polPointList) { if(horz) { polPointList->point.xx = -polPointList->point.xx; } if(vert) { polPointList->point.yy = -polPointList->point.yy; } polPointList = polPointList->next; } polObjList = polObjList->next; } rObjList = p->rectObjList; while(rObjList) { if(horz) { rObjList->rectObj.rect.left = -rObjList->rectObj.rect.left; rObjList->rectObj.rect.right = -rObjList->rectObj.rect.right; } if(vert) { rObjList->rectObj.rect.top = -rObjList->rectObj.rect.top; rObjList->rectObj.rect.bottom = -rObjList->rectObj.rect.bottom; } rObjList = rObjList->next; } sObjList = p->splineObjList; while(sObjList) { /* TODO: embPattern_flip for splines */ sObjList = sObjList->next; } }
/*TODO: The params determine the max XY movement rather than the length. They need renamed or clarified further. */ void embPattern_correctForMaxStitchLength(EmbPattern* p, double maxStitchLength, double maxJumpLength) { int j = 0, splits; double maxXY, maxLen, addX, addY; if(!p) { embLog_error("emb-pattern.c embPattern_correctForMaxStitchLength(), p argument is null\n"); return; } if(embStitchList_count(p->stitchList) > 1) { EmbStitchList* pointer = 0; EmbStitchList* prev = 0; prev = p->stitchList; pointer = prev->next; while(pointer) { double xx = prev->stitch.xx; double yy = prev->stitch.yy; double dx = pointer->stitch.xx - xx; double dy = pointer->stitch.yy - yy; if((fabs(dx) > maxStitchLength) || (fabs(dy) > maxStitchLength)) { maxXY = max(fabs(dx), fabs(dy)); if(pointer->stitch.flags & (JUMP | TRIM)) maxLen = maxJumpLength; else maxLen = maxStitchLength; splits = (int)ceil((double)maxXY / maxLen); if(splits > 1) { int flagsToUse = pointer->stitch.flags; int colorToUse = pointer->stitch.color; addX = (double)dx / splits; addY = (double)dy / splits; for(j = 1; j < splits; j++) { EmbStitchList* item = 0; EmbStitch s; s.xx = xx + addX * j; s.yy = yy + addY * j; s.flags = flagsToUse; s.color = colorToUse; item = (EmbStitchList*)malloc(sizeof(EmbStitchList)); if(!item) { embLog_error("emb-pattern.c embPattern_correctForMaxStitchLength(), cannot allocate memory for item\n"); return; } item->stitch = s; item->next = pointer; prev->next = item; prev = item; } } } prev = pointer; if(pointer) { pointer = pointer->next; } } } if(p->lastStitch && p->lastStitch->stitch.flags != END) { embPattern_addStitchAbs(p, p->lastStitch->stitch.xx, p->lastStitch->stitch.yy, END, 1); } }
/*! Flips the entire pattern (\a p) vertically about the x-axis. */ void embPattern_flipVertical(EmbPattern* p) { if(!p) { embLog_error("emb-pattern.c embPattern_flipVertical(), p argument is null\n"); return; } embPattern_flip(p, 0, 1); }
/*! Flips the entire pattern (\a p) horizontally about the y-axis. */ void embPattern_flipHorizontal(EmbPattern* p) { if(!p) { embLog_error("emb-pattern.c embPattern_flipHorizontal(), p argument is null\n"); return; } embPattern_flip(p, 1, 0); }
/*! Returns an EmbRect that encapsulates all stitches and objects in the pattern (\a p). */ EmbRect embPattern_calcBoundingBox(EmbPattern* p) { EmbStitchList* pointer = 0; EmbRect boundingRect; EmbStitch pt; EmbArcObjectList* aObjList = 0; EmbArc arc; EmbCircleObjectList* cObjList = 0; EmbCircle circle; EmbEllipseObjectList* eObjList = 0; EmbEllipse ellipse; EmbLineObjectList* liObjList = 0; EmbLine line; EmbPointObjectList* pObjList = 0; EmbPoint point; EmbPolygonObjectList* pogObjList = 0; EmbPointList* pogPointList = 0; EmbPoint pogPoint; EmbPolylineObjectList* polObjList = 0; EmbPointList* polPointList = 0; EmbPoint polPoint; EmbRectObjectList* rObjList = 0; EmbRect rect; EmbSplineObjectList* sObjList = 0; EmbBezier bezier; if(!p) { embLog_error("emb-pattern.c embPattern_calcBoundingBox(), p argument is null\n"); return boundingRect; } /* Calculate the bounding rectangle. It's needed for smart repainting. */ /* TODO: Come back and optimize this mess so that after going thru all objects and stitches, if the rectangle isn't reasonable, then return a default rect */ if(embStitchList_empty(p->stitchList) && embArcObjectList_empty(p->arcObjList) && embCircleObjectList_empty(p->circleObjList) && embEllipseObjectList_empty(p->ellipseObjList) && embLineObjectList_empty(p->lineObjList) && embPointObjectList_empty(p->pointObjList) && embPolygonObjectList_empty(p->polygonObjList) && embPolylineObjectList_empty(p->polylineObjList) && embRectObjectList_empty(p->rectObjList) && embSplineObjectList_empty(p->splineObjList)) { boundingRect.top = 0.0; boundingRect.left = 0.0; boundingRect.bottom = 1.0; boundingRect.right = 1.0; return boundingRect; } boundingRect.left = 99999.0; boundingRect.top = 99999.0; boundingRect.right = -99999.0; boundingRect.bottom = -99999.0; pointer = p->stitchList; while(pointer) { /* If the point lies outside of the accumulated bounding * rectangle, then inflate the bounding rect to include it. */ pt = pointer->stitch; if(!(pt.flags & TRIM)) { boundingRect.left = (double)min(boundingRect.left, pt.xx); boundingRect.top = (double)min(boundingRect.top, pt.yy); boundingRect.right = (double)max(boundingRect.right, pt.xx); boundingRect.bottom = (double)max(boundingRect.bottom, pt.yy); } pointer = pointer->next; } aObjList = p->arcObjList; while(aObjList) { arc = aObjList->arcObj.arc; /* TODO: embPattern_calcBoundingBox for arcs */ aObjList = aObjList->next; } cObjList = p->circleObjList; while(cObjList) { circle = cObjList->circleObj.circle; boundingRect.left = (double)min(boundingRect.left, circle.centerX - circle.radius); boundingRect.top = (double)min(boundingRect.top, circle.centerY - circle.radius); boundingRect.right = (double)max(boundingRect.right, circle.centerX + circle.radius); boundingRect.bottom = (double)max(boundingRect.bottom, circle.centerY + circle.radius); cObjList = cObjList->next; } eObjList = p->ellipseObjList; while(eObjList) { ellipse = eObjList->ellipseObj.ellipse; /* TODO: embPattern_calcBoundingBox for ellipses */ eObjList = eObjList->next; } liObjList = p->lineObjList; while(liObjList) { line = liObjList->lineObj.line; /* TODO: embPattern_calcBoundingBox for lines */ liObjList = liObjList->next; } pObjList = p->pointObjList; while(pObjList) { point = pObjList->pointObj.point; /* TODO: embPattern_calcBoundingBox for points */ pObjList = pObjList->next; } pogObjList = p->polygonObjList; while(pogObjList) { pogPointList = pogObjList->polygonObj->pointList; while(pogPointList) { pogPoint = pogPointList->point; /* TODO: embPattern_calcBoundingBox for polygons */ pogPointList = pogPointList->next; } pogObjList = pogObjList->next; } polObjList = p->polylineObjList; while(polObjList) { polPointList = polObjList->polylineObj->pointList; while(polPointList) { polPoint = polPointList->point; /* TODO: embPattern_calcBoundingBox for polylines */ polPointList = polPointList->next; } polObjList = polObjList->next; } rObjList = p->rectObjList; while(rObjList) { rect = rObjList->rectObj.rect; /* TODO: embPattern_calcBoundingBox for rectangles */ rObjList = rObjList->next; } sObjList = p->splineObjList; while(sObjList) { bezier = sObjList->splineObj.bezier; /* TODO: embPattern_calcBoundingBox for splines */ sObjList = sObjList->next; } return boundingRect; }
/*! 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 readEys(EmbPattern* pattern, const char* fileName) { if(!pattern) { embLog_error("format-eys.c readEys(), pattern argument is null\n"); return 0; } if(!fileName) { embLog_error("format-eys.c readEys(), fileName argument is null\n"); return 0; } return 0; /*TODO: finish readEys */ }
/*! 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; }
/*! 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 readT01(EmbPattern* pattern, const char* fileName) { unsigned char b[3]; EmbFile* file = 0; if(!pattern) { embLog_error("format-t01.c readt01(), pattern argument is null\n"); return 0; } if(!fileName) { embLog_error("format-t01.c readt01(), fileName argument is null\n"); return 0; } file = embFile_open(fileName, "rb"); if(!file) { embLog_error("format-t01.c readt01(), cannot open %s for reading\n", fileName); return 0; } embPattern_loadExternalColorFile(pattern, fileName); while(embFile_read(b, 1, 3, file) == 3) { int flags; int x = 0; int y = 0; if(b[0] & 0x01) x += 1; if(b[0] & 0x02) x -= 1; if(b[0] & 0x04) x += 9; if(b[0] & 0x08) x -= 9; if(b[0] & 0x80) y += 1; if(b[0] & 0x40) y -= 1; if(b[0] & 0x20) y += 9; if(b[0] & 0x10) y -= 9; if(b[1] & 0x01) x += 3; if(b[1] & 0x02) x -= 3; if(b[1] & 0x04) x += 27; if(b[1] & 0x08) x -= 27; if(b[1] & 0x80) y += 3; if(b[1] & 0x40) y -= 3; if(b[1] & 0x20) y += 27; if(b[1] & 0x10) y -= 27; if(b[2] & 0x04) x += 81; if(b[2] & 0x08) x -= 81; if(b[2] & 0x20) y += 81; if(b[2] & 0x10) y -= 81; flags = decodeRecordFlags(b[2]); embPattern_addStitchRel(pattern, x / 10.0, y / 10.0, flags, 1); if(flags == END) break; } embFile_close(file); /* 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); 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 readPcs(EmbPattern* pattern, const char* fileName) { char allZeroColor = 1; int i = 0; unsigned char b[9]; double dx = 0, dy = 0; int flags = 0, st = 0; unsigned char version, hoopSize; unsigned short colorCount; EmbFile* file = 0; if(!pattern) { embLog_error("format-pcs.c readPcs(), pattern argument is null\n"); return 0; } if(!fileName) { embLog_error("format-pcs.c readPcs(), fileName argument is null\n"); return 0; } file = embFile_open(fileName, "rb"); if(!file) { embLog_error("format-pcs.c readPcs(), cannot open %s for reading\n", fileName); return 0; } version = binaryReadByte(file); hoopSize = binaryReadByte(file); /* 0 for PCD, 1 for PCQ (MAXI), 2 for PCS with small hoop(80x80), */ /* and 3 for PCS with large hoop (115x120) */ switch(hoopSize) { case 2: pattern->hoop.width = 80.0; pattern->hoop.height = 80.0; break; case 3: pattern->hoop.width = 115; pattern->hoop.height = 120.0; break; } colorCount = binaryReadUInt16(file); for(i = 0; i < colorCount; i++) { EmbThread t; t.color.r = binaryReadByte(file); t.color.g = binaryReadByte(file); t.color.b = binaryReadByte(file); t.catalogNumber = ""; t.description = ""; if(t.color.r || t.color.g || t.color.b) { allZeroColor = 0; } embPattern_addThread(pattern, t); binaryReadByte(file); } if(allZeroColor) embPattern_loadExternalColorFile(pattern, fileName); st = binaryReadUInt16(file); /* READ STITCH RECORDS */ for(i = 0; i < st; i++) { flags = NORMAL; if(embFile_read(b, 1, 9, file) != 9) break; if(b[8] & 0x01) { flags = STOP; } else if(b[8] & 0x04) { flags = TRIM; } else if(b[8] != 0) { /* TODO: ONLY INTERESTED IN THIS CASE TO LEARN MORE ABOUT THE FORMAT */ } dx = pcsDecode(b[1], b[2], b[3]); dy = pcsDecode(b[5], b[6], b[7]); embPattern_addStitchAbs(pattern, dx / 10.0, dy / 10.0, flags, 1); } embFile_close(file); /* 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); 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 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; }
static int stxReadThread(StxThread* thread, EmbFile* file) { /* TODO: pointer safety */ int j, colorNameLength, sectionNameLength; int somethingsomething, somethingsomething2, somethingelse, numberOfOtherDescriptors; char* codeNameBuff = 0; char* sectionNameBuff = 0; EmbColor col; unsigned char whatIsthis; int codeLength = binaryReadUInt8(file); char* codeBuff = (char*)malloc(codeLength); if(!codeBuff) { embLog_error("format-stx.c stxReadThread(), unable to allocate memory for codeBuff\n"); return 0; } binaryReadBytes(file, (unsigned char*)codeBuff, codeLength); thread->ColorCode = codeBuff; colorNameLength = binaryReadUInt8(file); codeNameBuff = (char*)malloc(colorNameLength); if(!codeNameBuff) { embLog_error("format-stx.c stxReadThread(), unable to allocate memory for codeNameBuff\n"); return 0; } binaryReadBytes(file, (unsigned char*)codeNameBuff, colorNameLength); thread->ColorName = codeNameBuff; col.r = binaryReadUInt8(file); col.b = binaryReadUInt8(file); col.g = binaryReadUInt8(file); whatIsthis = binaryReadUInt8(file); sectionNameLength = binaryReadUInt8(file); sectionNameBuff = (char*)malloc(sectionNameLength); if(!sectionNameBuff) { embLog_error("format-stx.c stxReadThread(), unable to allocate memory for sectionNameBuff\n"); return 0; } binaryReadBytes(file, (unsigned char*)sectionNameBuff, sectionNameLength); thread->SectionName = sectionNameBuff; somethingsomething = binaryReadInt32(file); somethingsomething2 = binaryReadInt32(file); somethingelse = binaryReadInt32(file); numberOfOtherDescriptors = binaryReadInt16(file); thread->SubDescriptors = (SubDescriptor*)malloc(sizeof(SubDescriptor) * numberOfOtherDescriptors); if(!thread->SubDescriptors) return 0; for(j = 0; j < numberOfOtherDescriptors; j++) { SubDescriptor sd; char* subCodeBuff, *subColorNameBuff; int subcodeLength, subcolorNameLength; sd.SomeNum = binaryReadInt16(file); /* Debug.Assert(sd.SomeNum == 1); */ sd.SomeInt = binaryReadInt32(file); subcodeLength = binaryReadUInt8(file); subCodeBuff = (char*)malloc(subcodeLength); if(!subCodeBuff) { embLog_error("format-stx.c stxReadThread(), unable to allocate memory for subCodeBuff\n"); return 0; } binaryReadBytes(file, (unsigned char*)subCodeBuff, subcodeLength); sd.ColorCode = subCodeBuff; subcolorNameLength = binaryReadUInt8(file); subColorNameBuff = (char*)malloc(subcolorNameLength); if(!subColorNameBuff) { embLog_error("format-stx.c stxReadThread(), unable to allocate memory for subColorNameBuff\n"); return 0; } binaryReadBytes(file, (unsigned char*)subColorNameBuff, subcolorNameLength); sd.ColorName = subColorNameBuff; sd.SomeOtherInt = binaryReadInt32(file); thread->SubDescriptors[j] = sd; } 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; }
/*! 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 readStx(EmbPattern* pattern, const char* fileName) { int i, threadCount; unsigned char* gif = 0; /* public Bitmap Image; */ StxThread* stxThreads = 0; unsigned char headerBytes[7]; char* header = 0; char filetype[4], version[5]; int paletteLength, imageLength, something1, stitchDataOffset, something3, threadDescriptionOffset, stitchCount, left, right, colors; int val1, val2, val3, val4, val5, val6; int vala1, vala2, vala3, vala4, vala5, vala6; int bottom,top; EmbFile* file = 0; if(!pattern) { embLog_error("format-stx.c readStx(), pattern argument is null\n"); return 0; } if(!fileName) { embLog_error("format-stx.c readStx(), fileName argument is null\n"); return 0; } file = embFile_open(fileName, "rb"); if(!file) { embLog_error("format-stx.c readStx(), cannot open %s for reading\n", fileName); return 0; } binaryReadBytes(file, headerBytes, 7); header = (char*)headerBytes; memcpy(filetype, &header[0], 3); memcpy(version, &header[3], 4); filetype[3] = '\0'; version[4] = '\0'; binaryReadByte(file); paletteLength = binaryReadInt32(file); imageLength = binaryReadInt32(file); something1 = binaryReadInt32(file); stitchDataOffset = binaryReadInt32(file); something3 = binaryReadInt32(file); threadDescriptionOffset = binaryReadInt32(file); stitchCount = binaryReadInt32(file); colors = binaryReadInt32(file); right = binaryReadInt16(file); left = binaryReadInt16(file); bottom = binaryReadInt16(file); top = binaryReadInt16(file); gif = (unsigned char*)malloc(imageLength); if(!gif) { embLog_error("format-stx.c readStx(), unable to allocate memory for gif\n"); return 0; } binaryReadBytes(file, gif, imageLength); /*Stream s2 = new MemoryStream(gif); */ /*Image = new Bitmap(s2); */ threadCount = binaryReadInt16(file); stxThreads = (StxThread*)malloc(sizeof(StxThread) * threadCount); if(!stxThreads) { embLog_error("format-stx.c readStx(), unable to allocate memory for stxThreads\n"); return 0; } for(i = 0; i < threadCount; i++) { EmbThread t; StxThread st; stxReadThread(&st, file); t.color.r = st.StxColor.r; t.color.g = st.StxColor.g; t.color.b = st.StxColor.b; t.description = st.ColorName; t.catalogNumber = st.ColorCode; embPattern_addThread(pattern, t); stxThreads[i] = st; } binaryReadInt32(file); binaryReadInt32(file); binaryReadInt32(file); binaryReadInt16(file); binaryReadUInt8(file); val1 = binaryReadInt16(file); val2 = binaryReadInt16(file); val3 = binaryReadInt16(file); val4 = binaryReadInt16(file); val5 = binaryReadInt16(file); /* 0 */ val6 = binaryReadInt16(file); /* 0 */ vala1 = binaryReadInt16(file); vala2 = binaryReadInt16(file); vala3 = binaryReadInt16(file); vala4 = binaryReadInt16(file); vala5 = binaryReadInt16(file); /* 0 */ vala6 = binaryReadInt16(file); /* 0 */ binaryReadInt32(file); /* 0 */ binaryReadInt32(file); /* 0 */ /* br.BaseStream.Position = stitchDataOffset; */ for(i = 1; i < stitchCount; ) { char b0 = binaryReadByte(file); char b1 = binaryReadByte(file); if(b0 == -128) { switch (b1) { case 1: b0 = binaryReadByte(file); b1 = binaryReadByte(file); /*embPattern_addStitchRel(b0, b1, STOP);*/ i++; break; case 2: b0 = binaryReadByte(file); b1 = binaryReadByte(file); embPattern_addStitchRel(pattern, b0 / 10.0, b1 / 10.0, JUMP, 1); i++; break; case -94: /* NOTE: Is this a syncronize */ break; default: /*Debugger.Break(); */ break; } } else { embPattern_addStitchRel(pattern, b0 / 10.0, b1 / 10.0, NORMAL, 1); i++; } } embFile_close(file); /* 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); embPattern_flipVertical(pattern); 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); if (flen > 16) { flen = 16; } for (i = 0; i < flen; i++) { binaryWriteByte(file, (unsigned char)*(start + i)); } 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); } }
/*! 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; }
/*! 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 readBro(EmbPattern* pattern, const char* fileName) { unsigned char x55; short unknown1, unknown2, unknown3, unknown4, moreBytesToEnd; char name[8]; int stitchType; FILE* file = 0; if(!pattern) { embLog_error("format-bro.c readBro(), pattern argument is null\n"); return 0; } if(!fileName) { embLog_error("format-bro.c readBro(), fileName argument is null\n"); return 0; } file = fopen(fileName,"rb"); if(!file) { embLog_error("format-bro.c readBro(), cannot open %s for reading\n", fileName); return 0; } embPattern_loadExternalColorFile(pattern, fileName); x55 = binaryReadByte(file); unknown1 = binaryReadInt16(file); fread(name, 1, 8, file); unknown2 = binaryReadInt16(file); unknown3 = binaryReadInt16(file); unknown4 = binaryReadInt16(file); moreBytesToEnd = binaryReadInt16(file); fseek(file, 0x100, SEEK_SET); while(1) { short b1, b2; stitchType = NORMAL; b1 = binaryReadByte(file); b2 = binaryReadByte(file); if(b1 == -128) { unsigned char bCode = binaryReadByte(file); b1 = binaryReadInt16(file); b2 = binaryReadInt16(file); if(bCode == 2) { stitchType = STOP; } else if(bCode == 3) { stitchType = TRIM; } else if(bCode == 0x7E) { embPattern_addStitchRel(pattern, 0, 0, END, 1); break; } } embPattern_addStitchRel(pattern, b1 / 10.0, b2 / 10.0, stitchType, 1); } fclose(file); /* 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); 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 readVip(EmbPattern* pattern, const char* fileName) { int fileLength; int i; unsigned char prevByte = 0; unsigned char *attributeData = 0, *decodedColors = 0, *attributeDataDecompressed = 0; unsigned char *xData = 0, *xDecompressed = 0, *yData = 0, *yDecompressed = 0; VipHeader header; EmbFile* file = 0; if(!pattern) { embLog_error("format-vip.c readVip(), pattern argument is null\n"); return 0; } if(!fileName) { embLog_error("format-vip.c readVip(), fileName argument is null\n"); return 0; } file = embFile_open(fileName, "rb"); if(!file) { embLog_error("format-vip.c readVip(), cannot open %s for reading\n", fileName); return 0; } embFile_seek(file, 0x0, SEEK_END); fileLength = embFile_tell(file); embFile_seek(file, 0x00, SEEK_SET); header.magicCode = binaryReadInt32(file); header.numberOfStitches = binaryReadInt32(file); header.numberOfColors = binaryReadInt32(file); header.postitiveXHoopSize = binaryReadInt16(file); header.postitiveYHoopSize = binaryReadInt16(file); header.negativeXHoopSize = binaryReadInt16(file); header.negativeYHoopSize = binaryReadInt16(file); header.attributeOffset = binaryReadInt32(file); header.xOffset = binaryReadInt32(file); header.yOffset = binaryReadInt32(file); /*stringVal = (unsigned char*)malloc(sizeof(unsigned char)*8); TODO: review this and uncomment or remove if(!stringVal) { embLog_error("format-vip.c readVip(), cannot allocate memory for stringVal\n"); return 0; } */ binaryReadBytes(file, header.stringVal, 8); /* TODO: check return value */ header.unknown = binaryReadInt16(file); header.colorLength = binaryReadInt32(file); decodedColors = (unsigned char*)malloc(header.numberOfColors*4); if(!decodedColors) { embLog_error("format-vip.c readVip(), cannot allocate memory for decodedColors\n"); return 0; } for(i = 0; i < header.numberOfColors*4; ++i) { unsigned char inputByte = binaryReadByte(file); unsigned char tmpByte = (unsigned char) (inputByte ^ vipDecodingTable[i]); decodedColors[i] = (unsigned char) (tmpByte ^ prevByte); prevByte = inputByte; } for(i = 0; i < header.numberOfColors; i++) { EmbThread thread; int startIndex = i << 2; thread.color.r = decodedColors[startIndex]; thread.color.g = decodedColors[startIndex + 1]; thread.color.b = decodedColors[startIndex + 2]; /* printf("%d\n", decodedColors[startIndex + 3]); */ embPattern_addThread(pattern, thread); } embFile_seek(file, header.attributeOffset, SEEK_SET); attributeData = (unsigned char*)malloc(header.xOffset - header.attributeOffset); if(!attributeData) { embLog_error("format-vip.c readVip(), cannot allocate memory for attributeData\n"); return 0; } binaryReadBytes(file, attributeData, header.xOffset - header.attributeOffset); /* TODO: check return value */ attributeDataDecompressed = vipDecompressData(attributeData, header.xOffset - header.attributeOffset, header.numberOfStitches); embFile_seek(file, header.xOffset, SEEK_SET); xData = (unsigned char*)malloc(header.yOffset - header.xOffset); if(!xData) { embLog_error("format-vip.c readVip(), cannot allocate memory for xData\n"); return 0; } binaryReadBytes(file, xData, header.yOffset - header.xOffset); /* TODO: check return value */ xDecompressed = vipDecompressData(xData, header.yOffset - header.xOffset, header.numberOfStitches); embFile_seek(file, header.yOffset, SEEK_SET); yData = (unsigned char*)malloc(fileLength - header.yOffset); if(!yData) { embLog_error("format-vip.c readVip(), cannot allocate memory for yData\n"); return 0; } binaryReadBytes(file, yData, fileLength - header.yOffset); /* TODO: check return value */ yDecompressed = vipDecompressData(yData, fileLength - header.yOffset, header.numberOfStitches); for(i = 0; i < header.numberOfStitches; i++) { embPattern_addStitchRel(pattern, vipDecodeByte(xDecompressed[i]) / 10.0, vipDecodeByte(yDecompressed[i]) / 10.0, vipDecodeStitchType(attributeDataDecompressed[i]), 1); } embPattern_addStitchRel(pattern, 0, 0, END, 1); embFile_close(file); free(attributeData); attributeData = 0; free(xData); xData = 0; free(yData); yData = 0; free(attributeDataDecompressed); attributeDataDecompressed = 0; free(xDecompressed); xDecompressed = 0; free(yDecompressed); yDecompressed = 0; return 1; }
void embPattern_moveStitchListToPolylines(EmbPattern* p) { if(!p) { embLog_error("emb-pattern.c embPattern_moveStitchListToPolylines(), p argument is null\n"); return; } embPattern_copyStitchListToPolylines(p); embStitchList_free(p->stitchList); }
/*! 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 readEmd(EmbPattern* pattern, const char* fileName) { unsigned char b0 = 0, b1 = 0; char dx = 0, dy = 0; int flags = NORMAL; char endOfStream = 0; unsigned char jemd0[6]; int width, height, colors; int i; FILE* file = 0; if(!pattern) { embLog_error("format-emd.c readEmd(), pattern argument is null\n"); return 0; } if(!fileName) { embLog_error("format-emd.c readEmd(), fileName argument is null\n"); return 0; } file = fopen(fileName, "rb"); if(!file) { embLog_error("format-emd.c readEmd(), cannot open %s for reading\n", fileName); return 0; } embPattern_loadExternalColorFile(pattern, fileName); binaryReadBytes(file, jemd0, 6); width = binaryReadInt16(file); height = binaryReadInt16(file); colors = binaryReadInt16(file); fseek(file, 0x30, SEEK_SET); for(i = 0; !endOfStream; i++) { flags = NORMAL; b0 = binaryReadUInt8(file); b1 = binaryReadUInt8(file); if(b0 == 0x80) { if(b1 == 0x2A) { embPattern_addStitchRel(pattern, 0, 0, STOP, 1); continue; } else if((b1 == 0x80)) { b0 = binaryReadUInt8(file); b1 = binaryReadUInt8(file); flags = TRIM; } else if(b1 == 0xFD) { embPattern_addStitchRel(pattern, 0, 0, END, 1); break; } else { continue; } } dx = emdDecode(b0); dy = emdDecode(b1); embPattern_addStitchRel(pattern, dx / 10.0, dy / 10.0, flags, 1); } fclose(file); /* 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); return 1; }
void embPattern_changeColor(EmbPattern* p, int index) { if(!p) { embLog_error("emb-pattern.c embPattern_changeColor(), p argument is null\n"); return; } p->currentColorIndex = index; }
/*! 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 readPhb(EmbPattern* pattern, const char* fileName) { unsigned int fileOffset; short colorCount; FILE* file = 0; int i; if(!pattern) { embLog_error("format-phb.c readPhb(), pattern argument is null\n"); return 0; } if(!fileName) { embLog_error("format-phb.c readPhb(), fileName argument is null\n"); return 0; } file = fopen(fileName, "rb"); if(!file) { embLog_error("format-phb.c readPhb(), cannot open %s for reading\n", fileName); return 0; } fseek(file, 0x71, SEEK_SET); colorCount = binaryReadInt16(file); for(i = 0; i < colorCount; i++) { EmbThread t = pecThreads[(int)binaryReadByte(file)]; embPattern_addThread(pattern, t); } /* TODO: check that file begins with #PHB */ fseek(file, 0x54, SEEK_SET); fileOffset = 0x52; fileOffset += binaryReadUInt32(file); fseek(file, fileOffset, SEEK_SET); fileOffset += binaryReadUInt32(file) + 2; fseek(file, fileOffset, SEEK_SET); fileOffset += binaryReadUInt32(file); fseek(file, fileOffset + 14, SEEK_SET); /* 28 */ colorCount = (short)binaryReadByte(file); for(i = 0; i< colorCount; i++) { binaryReadByte(file); } binaryReadInt32(file); /* bytes to end of file */ binaryReadInt32(file); binaryReadByte(file); binaryReadInt16(file); binaryReadInt16(file); binaryReadInt16(file); binaryReadInt16(file); binaryReadInt16(file); binaryReadInt16(file); readPecStitches(pattern, file); fclose(file); /* 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); embPattern_flipVertical(pattern); return 1; /*TODO: finish ReadPhb */ }