Improved robustness of PesFile.OpenFile()

Branch_2.1.x
Nathan Crawford 2016-02-23 23:41:24 -05:00
rodzic 5cf44ec832
commit d0c2eb485a
1 zmienionych plików z 167 dodań i 177 usunięć

Wyświetl plik

@ -111,201 +111,191 @@ namespace PesFile
private void OpenFile(string filename)
{
#if !DEBUG
try
_filename = filename;
fileIn = new System.IO.BinaryReader(System.IO.File.Open(filename, System.IO.FileMode.Open, System.IO.FileAccess.Read));
string startFileSig = "";
for (int i = 0; i < 4; i++) // 4 bytes
{
#endif
_filename = filename;
fileIn = new System.IO.BinaryReader(System.IO.File.Open(filename, System.IO.FileMode.Open, System.IO.FileAccess.Read));
string startFileSig = "";
for (int i = 0; i < 4; i++) // 4 bytes
{
startFileSig += fileIn.ReadChar();
}
if (startFileSig != "#PES")
{
// This is not a file that we can read
readyStatus = statusEnum.ParseError;
lastError = "Missing #PES at beginning of file";
fileIn.Close();
return;
}
startFileSig += fileIn.ReadChar();
}
if (startFileSig != "#PES")
{
// This is not a file that we can read
readyStatus = statusEnum.ParseError;
lastError = "Missing #PES at beginning of file";
fileIn.Close();
return;
}
// PES version
string versionString = "";
for (int i = 0; i < 4; i++) // 4 bytes
{
versionString += fileIn.ReadChar();
}
pesVersion = Convert.ToUInt16(versionString);
// PES version
string versionString = "";
for (int i = 0; i < 4; i++) // 4 bytes
{
versionString += fileIn.ReadChar();
}
if(!UInt16.TryParse(versionString, out pesVersion))
{
// This is not a file that we can read
readyStatus = statusEnum.ParseError;
lastError = "PES version is not the correct format";
fileIn.Close();
return;
}
int pecstart = fileIn.ReadInt32();
int pecstart = fileIn.ReadInt32();
// Sanity check on PEC start position
if(fileIn.BaseStream.Length < (pecstart + 532))
{
// This file is probably truncated
readyStatus = statusEnum.ParseError;
lastError = "File appears to be truncated (PEC section is beyond end of file)";
fileIn.Close();
return;
}
// Read number of colors in this design
fileIn.BaseStream.Position = pecstart + 48;
int numColors = fileIn.ReadByte() +1;
List<byte> colorList = new List<byte>();
for (int x = 0; x < numColors; x++)
// Read number of colors in this design
fileIn.BaseStream.Position = pecstart + 48;
int numColors = fileIn.ReadByte() +1;
List<byte> colorList = new List<byte>();
for (int x = 0; x < numColors; x++)
{
colorList.Add(fileIn.ReadByte());
}
// Read stitch data
fileIn.BaseStream.Position = pecstart + 532;
bool thisPartIsDone = false;
StitchBlock curBlock;
int prevX = 0;
int prevY = 0;
int maxX = 0;
int minX = 0;
int maxY = 0;
int minY = 0;
int colorNum = -1;
int colorIndex = 0;
List<Stitch> tempStitches = new List<Stitch>();
while (!thisPartIsDone)
{
byte val1;
byte val2;
val1 = fileIn.ReadByte();
val2 = fileIn.ReadByte();
if (val1 == 0xff && val2 == 0x00)
{
colorList.Add(fileIn.ReadByte());
//end of stitches
thisPartIsDone = true;
//add the last block
curBlock = new StitchBlock();
curBlock.stitches = new Stitch[tempStitches.Count];
tempStitches.CopyTo(curBlock.stitches);
curBlock.stitchesTotal = tempStitches.Count;
colorNum++;
colorIndex = colorList[colorNum];
curBlock.colorIndex = colorIndex;
curBlock.color = getColorFromIndex(colorIndex);
blocks.Add(curBlock);
}
// Read stitch data
fileIn.BaseStream.Position = pecstart + 532;
bool thisPartIsDone = false;
StitchBlock curBlock;
int prevX = 0;
int prevY = 0;
int maxX = 0;
int minX = 0;
int maxY = 0;
int minY = 0;
int colorNum = -1;
int colorIndex = 0;
List<Stitch> tempStitches = new List<Stitch>();
while (!thisPartIsDone)
else if (val1 == 0xfe && val2 == 0xb0)
{
byte val1;
byte val2;
val1 = fileIn.ReadByte();
val2 = fileIn.ReadByte();
if (val1 == 0xff && val2 == 0x00)
//color switch, start a new block
curBlock = new StitchBlock();
curBlock.stitches = new Stitch[tempStitches.Count];
tempStitches.CopyTo(curBlock.stitches);
curBlock.stitchesTotal = tempStitches.Count;
colorNum++;
colorIndex = colorList[colorNum];
curBlock.colorIndex = colorIndex;
curBlock.color = getColorFromIndex(colorIndex);
//read useless(?) byte
// The value of this 'useless' byte seems to alternate
// between 2 and 1 for every other block. The only
// exception I've noted is the last block which appears
// to always be 0.
curBlock.unknownStartByte = fileIn.ReadByte();
blocks.Add(curBlock);
tempStitches = new List<Stitch>();
}
else
{
int deltaX = 0;
int deltaY = 0;
if ((val1 & 0x80) == 0x80)
{
//end of stitches
thisPartIsDone = true;
// This is a 12-bit int. Allows for needle movement
// of up to +2047 or -2048.
deltaX = get12Bit2sComplement(val1, val2);
//add the last block
curBlock = new StitchBlock();
curBlock.stitches = new Stitch[tempStitches.Count];
tempStitches.CopyTo(curBlock.stitches);
curBlock.stitchesTotal = tempStitches.Count;
colorNum++;
colorIndex = colorList[colorNum];
curBlock.colorIndex = colorIndex;
curBlock.color = getColorFromIndex(colorIndex);
blocks.Add(curBlock);
}
else if (val1 == 0xfe && val2 == 0xb0)
{
//color switch, start a new block
curBlock = new StitchBlock();
curBlock.stitches = new Stitch[tempStitches.Count];
tempStitches.CopyTo(curBlock.stitches);
curBlock.stitchesTotal = tempStitches.Count;
colorNum++;
colorIndex = colorList[colorNum];
curBlock.colorIndex = colorIndex;
curBlock.color = getColorFromIndex(colorIndex);
//read useless(?) byte
// The value of this 'useless' byte seems to alternate
// between 2 and 1 for every other block. The only
// exception I've noted is the last block which appears
// to always be 0.
curBlock.unknownStartByte = fileIn.ReadByte();
blocks.Add(curBlock);
tempStitches = new List<Stitch>();
// The X value used both bytes, so read next byte
// for Y value.
val1 = fileIn.ReadByte();
}
else
{
int deltaX = 0;
int deltaY = 0;
if ((val1 & 0x80) == 0x80)
{
// This is a 12-bit int. Allows for needle movement
// of up to +2047 or -2048.
deltaX = get12Bit2sComplement(val1, val2);
// This is a 7-bit int. Allows for needle movement
// of up to +63 or -64.
deltaX = get7Bit2sComplement(val1);
// The X value used both bytes, so read next byte
// for Y value.
val1 = fileIn.ReadByte();
}
else
{
// This is a 7-bit int. Allows for needle movement
// of up to +63 or -64.
deltaX = get7Bit2sComplement(val1);
// The X value only used 1 byte, so copy the second
// to to the first for Y value.
val1 = val2;
}
// The X value only used 1 byte, so copy the second
// to to the first for Y value.
val1 = val2;
}
if ((val1 & 0x80) == 0x80)
{
// This is a 12-bit int. Allows for needle movement
// of up to +2047 or -2048.
// Read in the next byte to get the full value
val2 = fileIn.ReadByte();
deltaY = get12Bit2sComplement(val1, val2);
}
else
{
// This is a 7-bit int. Allows for needle movement
// of up to +63 or -64.
deltaY = get7Bit2sComplement(val1);
// Finished reading data for this stitch, no more
// bytes needed.
}
tempStitches.Add(
new Stitch(
new Point(prevX, prevY),
new Point(prevX + deltaX, prevY + deltaY)
)
);
prevX = prevX + deltaX;
prevY = prevY + deltaY;
if (prevX > maxX)
{
maxX = prevX;
}
else if (prevX < minX)
{
minX = prevX;
}
if ((val1 & 0x80) == 0x80)
{
// This is a 12-bit int. Allows for needle movement
// of up to +2047 or -2048.
// Read in the next byte to get the full value
val2 = fileIn.ReadByte();
deltaY = get12Bit2sComplement(val1, val2);
}
else
{
// This is a 7-bit int. Allows for needle movement
// of up to +63 or -64.
deltaY = get7Bit2sComplement(val1);
// Finished reading data for this stitch, no more
// bytes needed.
}
tempStitches.Add(
new Stitch(
new Point(prevX, prevY),
new Point(prevX + deltaX, prevY + deltaY)
)
);
prevX = prevX + deltaX;
prevY = prevY + deltaY;
if (prevX > maxX)
{
maxX = prevX;
}
else if (prevX < minX)
{
minX = prevX;
}
if (prevY > maxY)
{
maxY = prevY;
}
else if (prevY < minY)
{
minY = prevY;
}
if (prevY > maxY)
{
maxY = prevY;
}
else if (prevY < minY)
{
minY = prevY;
}
}
imageWidth = maxX - minX;
imageHeight = maxY - minY;
translateStart.X = -minX;
translateStart.Y = -minY;
readyStatus = statusEnum.Ready;
}
imageWidth = maxX - minX;
imageHeight = maxY - minY;
translateStart.X = -minX;
translateStart.Y = -minY;
readyStatus = statusEnum.Ready;
// Close the file
fileIn.Close();
#if !DEBUG
}
catch (System.IO.IOException ioex)
{
readyStatus = statusEnum.IOError;
lastError = ioex.Message;
if (fileIn != null)
{
fileIn.Close();
}
}
catch (Exception ex)
{
readyStatus = statusEnum.ParseError;
lastError = ex.Message;
if (fileIn != null)
{
fileIn.Close();
}
}
#endif
// Close the file
fileIn.Close();
}
public int GetWidth()