private byte[] DecodeRLE(bool is8, byte[] values)
{
byte[] val = new byte[width * height];
try {
int ptr = 0;
int x = 0;
int q = 0;
for (int y = 0; y < height && ptr < values.Length;) {
int count = values[ptr++] & 0xff;
if (count != 0) {
// encoded mode
int bt = values[ptr++] & 0xff;
if (is8) {
for (int i = count; i != 0; --i) {
val[q++] = (byte)bt;
}
}
else {
for (int i = 0; i < count; ++i) {
val[q++] = (byte)((i & 1) == 1 ? (bt & 0x0f) : ((bt >> 4) & 0x0f));
}
}
x += count;
}
else {
// escape mode
count = values[ptr++] & 0xff;
if (count == 1)
break;
switch (count) {
case 0:
x = 0;
++y;
q = y * width;
break;
case 2:
// delta mode
x += values[ptr++] & 0xff;
y += values[ptr++] & 0xff;
q = y * width + x;
break;
default:
// absolute mode
if (is8) {
for (int i = count; i != 0; --i)
val[q++] = (byte)(values[ptr++] & 0xff);
}
else {
int bt = 0;
for (int i = 0; i < count; ++i) {
if ((i & 1) == 0)
bt = values[ptr++] & 0xff;
val[q++] = (byte)((i & 1) == 1 ? (bt & 0x0f) : ((bt >> 4) & 0x0f));
}
}
x += count;
// read pad byte
if (is8) {
if ((count & 1) == 1)
++ptr;
}
else {
if ((count & 3) == 1 || (count & 3) == 2)
++ptr;
}
break;
}
}
}
}
catch {
//empty on purpose
}
return val;
}