int LoadBMPRLE4Data(FILE *Fin, ulong Width, slong Height, ushort Depth, ubyte *Data)
{
ulong PixelsRead = 0, TotalPixels = Width * Height;
ubyte Garbage[3], First, Second;
while(PixelsRead < TotalPixels)
{
if(fread(&First, sizeof(ubyte), 1, Fin) != 1)
{
perror("Failed to read in RLE encoded data");
return -1;
}
if(fread(&Second, sizeof(ubyte), 1, Fin) != 1)
{
perror("Failed to read in RLE encoded data");
return -1;
}
if(First == 0)
{
if(Second == 0)
{
if(PixelsRead % Width != 0)
PixelsRead += (PixelsRead % Width);
}
else if(Second == 1)
break;
else if(Second == 2)
{
sbyte HOffSet, VOffSet;
if(fread(&HOffSet, sizeof(sbyte), 1, Fin) != 1)
{
perror("Failed to read in RLE encoded data");
return -1;
}
if(fread(&VOffSet, sizeof(sbyte), 1, Fin) != 1)
{
perror("Failed to read in RLE encoded data");
return -1;
}
PixelsRead += (VOffSet * Width) + HOffSet;
}
else
{
ubyte Color;
for(int j = 0; j < Second; )
{
if(fread(&Color, sizeof(sbyte), 1, Fin) != 1)
{
perror("Failed to read in RLE encoded data");
return -1;
}
Data[PixelsRead++] = (Color & 0xF0) >> 4;
j++;
if(j < Second)
{
Data[PixelsRead++] = (Color & 0x0F);
j++;
}
}
if((Second % 8 != 0) && (((Second + 1) % 8) != 0))
{
int Remains = ((Second + 1)/2) % 4;
int Fat = 4 - Remains;
if(fread(Garbage, sizeof(ubyte) * Fat, 1, Fin) != 1)
{
perror("Failed to read in RLE encoded data");
return -1;
}
}
}
}
else
{
for(int j = 0; j < First; )
{
Data[PixelsRead++] = (Second & 0xF0) >> 4;
j++;
if(j < First)
{
Data[PixelsRead++] = (Second & 0x0F);
j++;
}
}
}
}
return 0;
}