Some speed improvements on decoding images

amazfit_cor
Valeriy Mironov 2018-01-14 12:31:53 +02:00
parent 07c2dd228d
commit 237308699a
1 changed files with 86 additions and 35 deletions

View File

@ -37,7 +37,8 @@ namespace Resources.Image
else if (_bitsPerPixel == 16 || _bitsPerPixel == 24 || _bitsPerPixel == 32)
Logger.Trace("The image doesn't use a palette.");
else
throw new ArgumentException("The image format is not supported. Please report the issue on https://bitbucket.org/valeronm/amazfitbiptools");
throw new ArgumentException(
"The image format is not supported. Please report the issue on https://bitbucket.org/valeronm/amazfitbiptools");
return ReadImage();
}
@ -78,6 +79,15 @@ namespace Resources.Image
}
private Bitmap ReadImage()
{
if (_paletteColors > 0) return ReadPaletteImage();
if (_bitsPerPixel == 16) return Read16BitImage();
if (_bitsPerPixel == 24) return Read24BitImage();
if (_bitsPerPixel == 32) return Read32BitImage();
throw new ArgumentException();
}
private Bitmap ReadPaletteImage()
{
var image = new Bitmap(_width, _height);
using (var context = image.CreateUnsafeContext())
@ -88,44 +98,85 @@ namespace Resources.Image
var bitReader = new BitReader(rowBytes);
for (var x = 0; x < _width; x++)
{
if (_paletteColors > 0)
{
var pixelColorIndex = bitReader.ReadBits(_bitsPerPixel);
var color = _palette[(int) pixelColorIndex];
context.SetPixel(x, y, color);
}
else if (_bitsPerPixel == 16)
{
var firstByte = bitReader.ReadByte();
var secondByte = bitReader.ReadByte();
var b = (secondByte >> 3 & 0x1f) << 3;
var g = (secondByte & 0x07 << 2 | firstByte & 0x40 >> 5) << 3;
var r = (firstByte & 0x1f) << 3;
var color = Color.FromArgb(0xff, r, g, b);
context.SetPixel(x, y, color);
}
else if (_bitsPerPixel == 24)
{
var alpha = (int)bitReader.ReadByte();
var b = (int)(bitReader.ReadBits(5) << 3);
var g = (int)(bitReader.ReadBits(6) << 2);
var r = (int)(bitReader.ReadBits(5) << 3);
var color = Color.FromArgb(0xff - alpha, r, g, b);
context.SetPixel(x, y, color);
}
else if (_bitsPerPixel == 32)
{
var alpha = (int)bitReader.ReadByte();
var b = (int)bitReader.ReadByte();
var g = (int)bitReader.ReadByte();
var r = (int)bitReader.ReadByte();
var color = Color.FromArgb(0xff - alpha, r, g, b);
context.SetPixel(x, y, color);
}
var pixelColorIndex = bitReader.ReadBits(_bitsPerPixel);
var color = _palette[(int) pixelColorIndex];
context.SetPixel(x, y, color);
}
}
}
return image;
}
private Bitmap Read16BitImage()
{
var image = new Bitmap(_width, _height);
using (var context = image.CreateUnsafeContext())
{
for (var y = 0; y < _height; y++)
{
var rowBytes = _reader.ReadBytes(_rowLengthInBytes);
var bitReader = new BitReader(rowBytes);
for (var x = 0; x < _width; x++)
{
var firstByte = bitReader.ReadByte();
var secondByte = bitReader.ReadByte();
var b = ((secondByte >> 3) & 0x1f) << 3;
var g = ((secondByte & (0x07 << 2)) | (firstByte & (0x40 >> 5))) << 3;
var r = (firstByte & 0x1f) << 3;
var color = Color.FromArgb(0xff, r, g, b);
context.SetPixel(x, y, color);
}
}
}
return image;
}
private Bitmap Read24BitImage()
{
var image = new Bitmap(_width, _height);
using (var context = image.CreateUnsafeContext())
{
for (var y = 0; y < _height; y++)
{
var rowBytes = _reader.ReadBytes(_rowLengthInBytes);
var bitReader = new BitReader(rowBytes);
for (var x = 0; x < _width; x++)
{
var alpha = (int) bitReader.ReadByte();
var b = (int) (bitReader.ReadBits(5) << 3);
var g = (int) (bitReader.ReadBits(6) << 2);
var r = (int) (bitReader.ReadBits(5) << 3);
var color = Color.FromArgb(0xff - alpha, r, g, b);
context.SetPixel(x, y, color);
}
}
}
return image;
}
private Bitmap Read32BitImage()
{
var image = new Bitmap(_width, _height);
using (var context = image.CreateUnsafeContext())
{
for (var y = 0; y < _height; y++)
{
var rowBytes = _reader.ReadBytes(_rowLengthInBytes);
for (var x = 0; x < _width; x++)
{
var alpha = rowBytes[x * 4];
var b = rowBytes[x * 4 + 1];
var g = rowBytes[x * 4 + 2];
var r = rowBytes[x * 4 + 3];
var color = Color.FromArgb(0xff - alpha, r, g, b);
context.SetPixel(x, y, color);
}
}
}
return image;
}
}
}