I already posted about this in the lounge, but it has become more technical now. I don''t understand the conversion code concerning the format, so I decided to convert the Pascal code to C, 1 on 1.
I still don''t understand how the format works, because I blindly copied the copy and changed it to C(My Pascal knowledge sucks, I forgot most of it).
Now I converted the code, I am getting access violations, mainly because the first byte of the first image is 0x00.
If anyone can see what I am doing wrong, any help is welcome. There article on reading a format80 decoded file can be found here
http://www.geocities.com/SiliconValley/8682/ccfiles4.txt(Skip down to the Format80 header). The SHP layout can be found here
http://dune2.de/download/source/duneii_shp_specs.txt
Here is the code for reading the file(It''s a SHP file, but I can read it properly, I tested the data read, the headers are correct and the last BYTE of the image part is 0x80. That''s correct)
struct SHP_IMAGEHEADER
{
BYTE cType;
BYTE cReserved0;
BYTE cHeight;
BYTE cWidth;
BYTE cReserved1;
BYTE cHeight0;
WORD wSize;
WORD wChecksum;
};
struct SHP_IMAGE
{
SHP_IMAGE() { Data = NULL; } // Constructor
SHP_IMAGEHEADER Header;
BYTE *Data;
};
void ReadImage(ifstream &File, DWORD Offset, SHP_IMAGE &Image)
{
File.seekg(Offset + 2);
File.read((char *)&Image.Header, sizeof(SHP_IMAGEHEADER));
// Allocate memory for the data
Image.Data = new BYTE[Image.Header.wSize - 10];
File.read((char *)Image.Data, sizeof(BYTE) * (Image.Header.wSize - 10));
}
And this is my decode function:
void DecodeFormat80(SHP_IMAGE &Image, BYTE *Destination)
{
BYTE *Source;
BYTE *Dest;
BYTE Com;
int SP = 0;
int DP = 0;
int Posit = 0;
int Count = 0;
Source = Image.Data;
Dest = Destination;
while (SP < Image.Header.cWidth * Image.Header.cHeight)
{
Com = Source[SP];
SP++;
switch (Com >> 7)
{
case 0:
Count = ((Com & 0x7F) >> 4) + 3;
Posit = ((Com & 0x0F) << 8) + Source[SP];
++SP;
Posit = DP - Posit;
for (int i = Posit; i < Posit+Count; ++i)
{
Dest[DP] = Dest[i];
++DP;
}break;
case 1:
switch ((Com & 0x40) >> 6)
{
case 0:
Count = Com & 0x3F;
if (Count == 0) break; // EOF Marker
for (int i = 0; i < Count; ++i)
{
Dest[DP] = Source[SP];
++DP; ++ SP;
}break;
case 1:
Count = Com & 0x3F;
if (Count < 0x3E)
{
Count += 3;
Posit = (WORD)Source[SP];
Source += 2;
for (int i = Posit; i < Posit+Count; ++i)
{
Dest[DP] = Dest[i];
DP++;
}
}
else if (Count == 0x3F)
{
Count = WORD(Source[SP]);
Posit = WORD(Source[SP+2]);
SP += 4;
for (int i = Posit; i < Posit + Count; ++i)
{
Dest[DP] = Dest[i];
DP++;
}
}
else
{
BYTE Color;
Count = (WORD)Source[SP];
SP += 2;
Color = Source[SP];
for (int i = 0; i < Count; ++i)
{
Dest[DP] = Color;
DP++;
}
}break; // case 1:
} // switch (b6)
break;
} // switch (Command)
}
}
Toolmaker
-Earth is 98% full. Please delete anybody you can.