int readMax(EmbPattern* pattern, const char* fileName) { int i; unsigned char b[8]; double dx = 0, dy = 0; int flags = 0; int stitchCount; FILE* file; file = fopen(fileName, "rb"); if(file == 0) { return 0; } fseek(file, 0xD5, SEEK_SET); stitchCount = binaryReadUInt32(file); /* READ STITCH RECORDS */ for(i = 0; i < stitchCount; i++) { flags = NORMAL; if(fread(b, 1, 8, file) != 8) break; dx = maxDecode(b[0], b[1], b[2]); dy = maxDecode(b[4], b[5], b[6]); embPattern_addStitchAbs(pattern, dx / 10.0, dy / 10.0, flags, 1); } embPattern_addStitchRel(pattern, 0, 0, END, 1); embPattern_flipVertical(pattern); fclose(file); return 1; }
/* TODO: It doesn't appear that this function actually clears the polylineObjList so it is more of a copy than a move. */ void movePolylinesToStitchList(EmbPattern* p) { if(p) { EmbPolylineObjectList* polyList = p->polylineObjList; EmbStitchList* currentList = 0; int firstObject = 1; /*int currentColor = polyList->polylineObj->color TODO: polyline color */ while(polyList) { EmbPolylineObject* currentPoly = polyList->polylineObj; EmbPointList* currentPointList = currentPoly->pointList; EmbThread thread; thread.catalogNumber = 0; thread.color = currentPoly->color; thread.description = 0; embPattern_addThread(p, thread); if(!firstObject) { embPattern_addStitchRel(p, currentPointList->point.xx, currentPointList->point.yy, TRIM, 1); embPattern_addStitchRel(p, 0.0, 0.0, STOP, 1); firstObject = 0; } while(currentPointList) { embPattern_addStitchAbs(p, currentPointList->point.xx, currentPointList->point.yy, NORMAL, 1); currentPointList = currentPointList->next; } polyList = polyList->next; } embPattern_addStitchRel(p, 0.0, 0.0, END, 1); } }
void embPattern_copyPolylinesToStitchList(EmbPattern* p) { EmbPolylineObjectList* polyList = 0; EmbStitchList* currentList = 0; int firstObject = 1; /*int currentColor = polyList->polylineObj->color TODO: polyline color */ if(!p) { embLog_error("emb-pattern.c embPattern_copyPolylinesToStitchList(), p argument is null\n"); return; } polyList = p->polylineObjList; while(polyList) { EmbPolylineObject* currentPoly = polyList->polylineObj; EmbPointList* currentPointList = currentPoly->pointList; EmbThread thread; thread.catalogNumber = 0; thread.color = currentPoly->color; thread.description = 0; embPattern_addThread(p, thread); if(!firstObject) { embPattern_addStitchRel(p, currentPointList->point.xx, currentPointList->point.yy, TRIM, 1); embPattern_addStitchRel(p, 0.0, 0.0, STOP, 1); firstObject = 0; } while(currentPointList) { embPattern_addStitchAbs(p, currentPointList->point.xx, currentPointList->point.yy, NORMAL, 1); currentPointList = currentPointList->next; } polyList = polyList->next; } embPattern_addStitchRel(p, 0.0, 0.0, END, 1); }
int readPcm(EmbPattern* pattern, const char* fileName) { int i; unsigned char b[9]; double dx = 0, dy = 0; int flags = 0, st = 0; FILE* file = fopen(fileName, "rb"); if(file == 0) { return 0; } fseek(file, 4, SEEK_SET); for(i = 0; i < 16; i++) { char zero = fgetc(file); int colorNumber = fgetc(file); embPattern_addThread(pattern, pcmThreads[colorNumber]); } st = binaryReadUInt16BE(file); /* READ STITCH RECORDS */ for(i = 0; i < st; i++) { flags = NORMAL; if(fread(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 = pcmDecode(b[2], b[1], b[0]); dy = pcmDecode(b[6], b[5], b[4]); embPattern_addStitchAbs(pattern, dx / 10.0, dy / 10.0, flags, 1); } embPattern_addStitchRel(pattern, 0, 0, END, 1); fclose(file); return 1; }
static void ofmReadExpanded(EmbFile* file, EmbPattern* p) { int i, numberOfStitches = 0; if(!file) { embLog_error("format-ofm.c ofmReadExpanded(), file argument is null\n"); return; } if(!p) { embLog_error("format-ofm.c ofmReadExpanded(), p argument is null\n"); return; } ofmReadBlockHeader(file); numberOfStitches = binaryReadInt32(file); for(i = 0; i < numberOfStitches; i++) { unsigned char stitch[5]; binaryReadBytes(file, stitch, 5); /* TODO: check return value */ if(stitch[0] == 0) { embPattern_addStitchAbs(p, ofmDecode(stitch[1], stitch[2]) / 10.0, ofmDecode(stitch[3], stitch[4]) / 10.0, i == 0 ? JUMP : EM_NORMAL, 1); } else if(stitch[0] == 32) { embPattern_addStitchAbs(p, ofmDecode(stitch[1], stitch[2]) / 10.0, ofmDecode(stitch[3], stitch[4]) / 10.0, i == 0 ? TRIM : EM_NORMAL, 1); } } }
static void ofmReadExpanded(FILE* file, EmbPattern* p) { int i, numberOfStitches = 0; ofmReadBlockHeader(file); numberOfStitches = binaryReadInt32(file); for(i = 0; i < numberOfStitches; i++) { unsigned char stitch[5]; binaryReadBytes(file, stitch, 5); if(stitch[0] == 0) { embPattern_addStitchAbs(p, ofmDecode(stitch[1], stitch[2]) / 10.0, ofmDecode(stitch[3], stitch[4]) / 10.0, i == 0 ? JUMP : NORMAL, 1); } } }
/* Adds a stitch at the relative position (dx,dy) to the previous stitch. Positive y is up. Units are in millimeters. */ void embPattern_addStitchRel(EmbPattern* p, double dx, double dy, int flags, int isAutoColorIndex) { /* TODO: pointer safety */ double x,y; if(!embStitchList_empty(p->stitchList)) { x = p->lastX + dx; y = p->lastY + dy; } else { /* the list is empty so assume starting location is 0,0 */ x = dx; y = dy; } embPattern_addStitchAbs(p, x, y, flags, isAutoColorIndex); }
/* Adds a stitch at the relative position (dx,dy) to the previous stitch. Positive y is up. Units are in millimeters. */ void embPattern_addStitchRel(EmbPattern* p, double dx, double dy, int flags, int isAutoColorIndex) { double x,y; if(!p) { embLog_error("emb-pattern.c embPattern_addStitchRel(), p argument is null\n"); return; } if(!embStitchList_empty(p->stitchList)) { x = p->lastX + dx; y = p->lastY + dy; } else { /* the list is empty so assume starting location is 0,0 */ x = dx; y = dy; } embPattern_addStitchAbs(p, x, y, flags, isAutoColorIndex); }
/*! Adds a stitch to the pattern (\a p) at the relative position (\a dx,\a dy) to the previous stitch. Positive y is up. Units are in millimeters. */ void embPattern_addStitchRel(EmbPattern* p, double dx, double dy, int flags, int isAutoColorIndex) { double x,y; if(!p) { embLog_error("emb-pattern.c embPattern_addStitchRel(), p argument is null\n"); return; } if(!embStitchList_empty(p->stitchList)) { x = p->lastX + dx; y = p->lastY + dy; } else { /* NOTE: The stitchList is empty, so add it to the HOME position. The embStitchList_create function will ensure the first coordinate is at the HOME position. */ EmbPoint home = embSettings_home(&(p->settings)); x = home.xx + dx; y = home.yy + dy; } embPattern_addStitchAbs(p, x, y, flags, isAutoColorIndex); }
/*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; 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); } }
/*! 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 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; }
/*! 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; }