Created
September 26, 2018 09:51
-
-
Save JimBobSquarePants/4caeca96639dd94f2ce55bab7ea5219d to your computer and use it in GitHub Desktop.
Packing to and from 8bit array
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
void Main() | |
{ | |
const int bytesPer8bitScanline = 300; | |
const int bytesPerScanline = 38; | |
const int bits = 1; | |
Random r = new Random(); | |
byte[] source = new byte[bytesPer8bitScanline]; | |
for (int i = 0; i < source.Length; i++) | |
{ | |
source[i] = (byte)r.Next(0, 2); | |
} | |
TryScaleDownFrom8BitArray(source, bytesPerScanline, bits, out byte[] temp); | |
TryScaleUpTo8BitArray(temp, bytesPerScanline, bits, out byte[] destination); | |
// We're getting difference here. What is wrong? | |
for (int i = 0; i < source.Length; i++) | |
{ | |
if (source[i] != destination[i]) | |
{ | |
$"{source[i]} != {destination[i]} at {i}".Dump(); | |
} | |
} | |
source.Dump(); | |
destination.Dump(); | |
} | |
// This should be correct. We're using it to correctly decode pngs | |
private bool TryScaleUpTo8BitArray(byte[] source, int bytesPerScanline, int bits, out byte[] buffer) | |
{ | |
if (bits >= 8) | |
{ | |
buffer = null; | |
return false; | |
} | |
buffer = new byte[bytesPerScanline * 8 / bits]; | |
byte[] result = buffer; | |
int mask = 0xFF >> (8 - bits); | |
int resultOffset = 0; | |
for (int i = 0; i < bytesPerScanline; i++) | |
{ | |
byte b = source[i]; | |
for (int shift = 0; shift < 8; shift += bits) | |
{ | |
int index = (b >> (8 - bits - shift)) & mask; | |
result[resultOffset] = (byte)index; | |
resultOffset++; | |
} | |
} | |
return true; | |
} | |
// This appears to be incorrect. | |
private bool TryScaleDownFrom8BitArray(byte[] source, int bytesPerScanline, int bits, out byte[] result) | |
{ | |
if (bits >= 8) | |
{ | |
result = null; | |
return false; | |
} | |
result = new byte[bytesPerScanline]; | |
byte mask = (byte)(0xFF >> (8 - bits)); | |
byte shift0 = (byte)(8 - bits); | |
int shift = 8 - bits; | |
int v = 0; | |
int resultOffset = 0; | |
for (int i = 0; i < source.Length; i++) | |
{ | |
int value = source[i] & mask; | |
v |= (value << shift); | |
if (shift == 0) | |
{ | |
shift = shift0; | |
result[resultOffset] = (byte)v; | |
resultOffset++; | |
v = 0; | |
} | |
else | |
{ | |
shift -= bits; | |
} | |
} | |
if (shift != shift0) | |
{ | |
result[0] = (byte)v; | |
} | |
return true; | |
} | |
Should result[0] = (byte)v;
not be result[resultOffset] = (byte)v
?
Relevant ImageSharp PR https://github.com/SixLabors/ImageSharp/pull/712/files#r220508943
Ah @dlemstra You're the man!! Can't believe I missed this.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
When I run the above sample in LinqPad i'm getting differences in the
source
anddestination
arrays. They should match. I've no idea why.