|
|
|
@ -148,7 +148,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp |
|
|
|
+ $"bigger then the max allowed size '{int.MaxValue}x{int.MaxValue}'"); |
|
|
|
} |
|
|
|
|
|
|
|
Image<TPixel> image = new Image<TPixel>(this.configuration, this.infoHeader.Width, this.infoHeader.Height); |
|
|
|
var image = new Image<TPixel>(this.configuration, this.infoHeader.Width, this.infoHeader.Height); |
|
|
|
using (PixelAccessor<TPixel> pixels = image.Lock()) |
|
|
|
{ |
|
|
|
switch (this.infoHeader.Compression) |
|
|
|
@ -196,6 +196,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp |
|
|
|
/// <param name="height">The height of the bitmap.</param>
|
|
|
|
/// <param name="inverted">Whether the bitmap is inverted.</param>
|
|
|
|
/// <returns>The <see cref="int"/> representing the inverted value.</returns>
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|
|
|
private static int Invert(int y, int height, bool inverted) |
|
|
|
{ |
|
|
|
int row; |
|
|
|
@ -234,7 +235,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Looks up color values and builds the image from de-compressed RLE8 data.
|
|
|
|
/// Compresssed RLE8 stream is uncompressed by <see cref="UncompressRle8(int, Buffer{byte})"/>
|
|
|
|
/// Compresssed RLE8 stream is uncompressed by <see cref="UncompressRle8(int, Span{byte})"/>
|
|
|
|
/// </summary>
|
|
|
|
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
|
|
|
/// <param name="pixels">The <see cref="PixelAccessor{TPixel}"/> to assign the palette to.</param>
|
|
|
|
@ -246,19 +247,21 @@ namespace SixLabors.ImageSharp.Formats.Bmp |
|
|
|
where TPixel : struct, IPixel<TPixel> |
|
|
|
{ |
|
|
|
var color = default(TPixel); |
|
|
|
var rgba = default(Rgba32); |
|
|
|
var rgba = new Rgba32(0, 0, 0, 255); |
|
|
|
|
|
|
|
using (var buffer = Buffer<byte>.CreateClean(width * height)) |
|
|
|
using (var buffer = Buffer2D<byte>.CreateClean(width, height)) |
|
|
|
{ |
|
|
|
this.UncompressRle8(width, buffer); |
|
|
|
|
|
|
|
for (int y = 0; y < height; y++) |
|
|
|
{ |
|
|
|
int newY = Invert(y, height, inverted); |
|
|
|
Span<byte> bufferRow = buffer.GetRowSpan(y); |
|
|
|
Span<TPixel> pixelRow = pixels.GetRowSpan(newY); |
|
|
|
|
|
|
|
for (int x = 0; x < width; x++) |
|
|
|
{ |
|
|
|
rgba.Bgr = Unsafe.As<byte, Bgr24>(ref colors[buffer[(y * width) + x] * 4]); |
|
|
|
rgba.Bgr = Unsafe.As<byte, Bgr24>(ref colors[bufferRow[x] * 4]); |
|
|
|
color.PackFromRgba32(rgba); |
|
|
|
pixelRow[x] = color; |
|
|
|
} |
|
|
|
@ -276,7 +279,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp |
|
|
|
/// </remarks>
|
|
|
|
/// <param name="w">The width of the bitmap.</param>
|
|
|
|
/// <param name="buffer">Buffer for uncompressed data.</param>
|
|
|
|
private void UncompressRle8(int w, Buffer<byte> buffer) |
|
|
|
private void UncompressRle8(int w, Span<byte> buffer) |
|
|
|
{ |
|
|
|
byte[] cmd = new byte[2]; |
|
|
|
int count = 0; |
|
|
|
@ -368,35 +371,36 @@ namespace SixLabors.ImageSharp.Formats.Bmp |
|
|
|
padding = 4 - padding; |
|
|
|
} |
|
|
|
|
|
|
|
byte[] row = new byte[arrayWidth + padding]; |
|
|
|
TPixel color = default(TPixel); |
|
|
|
|
|
|
|
Rgba32 rgba = default(Rgba32); |
|
|
|
|
|
|
|
for (int y = 0; y < height; y++) |
|
|
|
using (var row = Buffer<byte>.CreateClean(arrayWidth + padding)) |
|
|
|
{ |
|
|
|
int newY = Invert(y, height, inverted); |
|
|
|
this.currentStream.Read(row, 0, row.Length); |
|
|
|
int offset = 0; |
|
|
|
Span<TPixel> pixelRow = pixels.GetRowSpan(y); |
|
|
|
var color = default(TPixel); |
|
|
|
var rgba = new Rgba32(0, 0, 0, 255); |
|
|
|
|
|
|
|
// TODO: Could use PixelOperations here!
|
|
|
|
for (int x = 0; x < arrayWidth; x++) |
|
|
|
for (int y = 0; y < height; y++) |
|
|
|
{ |
|
|
|
int colOffset = x * ppb; |
|
|
|
int newY = Invert(y, height, inverted); |
|
|
|
this.currentStream.Read(row.Array, 0, row.Length); |
|
|
|
int offset = 0; |
|
|
|
Span<TPixel> pixelRow = pixels.GetRowSpan(newY); |
|
|
|
|
|
|
|
for (int shift = 0; shift < ppb && (x + shift) < width; shift++) |
|
|
|
// TODO: Could use PixelOperations here!
|
|
|
|
for (int x = 0; x < arrayWidth; x++) |
|
|
|
{ |
|
|
|
int colorIndex = ((row[offset] >> (8 - bits - (shift * bits))) & mask) * 4; |
|
|
|
int newX = colOffset + shift; |
|
|
|
int colOffset = x * ppb; |
|
|
|
|
|
|
|
// Stored in b-> g-> r order.
|
|
|
|
rgba.Bgr = Unsafe.As<byte, Bgr24>(ref colors[colorIndex]); |
|
|
|
color.PackFromRgba32(rgba); |
|
|
|
pixelRow[newX] = color; |
|
|
|
} |
|
|
|
for (int shift = 0; shift < ppb && (x + shift) < width; shift++) |
|
|
|
{ |
|
|
|
int colorIndex = ((row[offset] >> (8 - bits - (shift * bits))) & mask) * 4; |
|
|
|
int newX = colOffset + shift; |
|
|
|
|
|
|
|
offset++; |
|
|
|
// Stored in b-> g-> r order.
|
|
|
|
rgba.Bgr = Unsafe.As<byte, Bgr24>(ref colors[colorIndex]); |
|
|
|
color.PackFromRgba32(rgba); |
|
|
|
pixelRow[newX] = color; |
|
|
|
} |
|
|
|
|
|
|
|
offset++; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
@ -417,10 +421,10 @@ namespace SixLabors.ImageSharp.Formats.Bmp |
|
|
|
const int ScaleG = 4; // 256/64
|
|
|
|
const int ComponentCount = 2; |
|
|
|
|
|
|
|
TPixel color = default(TPixel); |
|
|
|
Rgba32 rgba = new Rgba32(0, 0, 0, 255); |
|
|
|
var color = default(TPixel); |
|
|
|
var rgba = new Rgba32(0, 0, 0, 255); |
|
|
|
|
|
|
|
using (PixelArea<TPixel> row = new PixelArea<TPixel>(width, ComponentOrder.Xyz)) |
|
|
|
using (var row = new PixelArea<TPixel>(width, ComponentOrder.Xyz)) |
|
|
|
{ |
|
|
|
for (int y = 0; y < height; y++) |
|
|
|
{ |
|
|
|
@ -459,7 +463,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp |
|
|
|
where TPixel : struct, IPixel<TPixel> |
|
|
|
{ |
|
|
|
int padding = CalculatePadding(width, 3); |
|
|
|
using (PixelArea<TPixel> row = new PixelArea<TPixel>(width, ComponentOrder.Zyx, padding)) |
|
|
|
using (var row = new PixelArea<TPixel>(width, ComponentOrder.Zyx, padding)) |
|
|
|
{ |
|
|
|
for (int y = 0; y < height; y++) |
|
|
|
{ |
|
|
|
@ -483,7 +487,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp |
|
|
|
where TPixel : struct, IPixel<TPixel> |
|
|
|
{ |
|
|
|
int padding = CalculatePadding(width, 4); |
|
|
|
using (PixelArea<TPixel> row = new PixelArea<TPixel>(width, ComponentOrder.Zyxw, padding)) |
|
|
|
using (var row = new PixelArea<TPixel>(width, ComponentOrder.Zyxw, padding)) |
|
|
|
{ |
|
|
|
for (int y = 0; y < height; y++) |
|
|
|
{ |
|
|
|
|