Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for encoding 16 bit per pixel bitmaps #899

Merged
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/ImageSharp/Formats/Bmp/BmpBitsPerPixel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ namespace SixLabors.ImageSharp.Formats.Bmp
/// </summary>
public enum BmpBitsPerPixel : short
{
/// <summary>
/// 16 bits per pixel. Each pixel consists of 2 bytes.
/// </summary>
Pixel16 = 16,

/// <summary>
/// 24 bits per pixel. Each pixel consists of 3 bytes.
/// </summary>
Expand Down
3 changes: 2 additions & 1 deletion src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1022,7 +1022,8 @@ private void ReadInfoHeader()
this.bmpMetadata.InfoHeaderType = infoHeaderType;

// We can only encode at these bit rates so far.
if (bitsPerPixel.Equals((short)BmpBitsPerPixel.Pixel24)
if (bitsPerPixel.Equals((short)BmpBitsPerPixel.Pixel16)
|| bitsPerPixel.Equals((short)BmpBitsPerPixel.Pixel24)
|| bitsPerPixel.Equals((short)BmpBitsPerPixel.Pixel32))
{
this.bmpMetadata.BitsPerPixel = (BmpBitsPerPixel)bitsPerPixel;
Expand Down
30 changes: 30 additions & 0 deletions src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,10 @@ private void WriteImage<TPixel>(Stream stream, ImageFrame<TPixel> image)
case BmpBitsPerPixel.Pixel24:
this.Write24Bit(stream, pixels);
break;

case BmpBitsPerPixel.Pixel16:
this.Write16Bit(stream, pixels);
break;
}
}

Expand Down Expand Up @@ -246,5 +250,31 @@ private void Write24Bit<TPixel>(Stream stream, Buffer2D<TPixel> pixels)
}
}
}

/// <summary>
/// Writes the 16bit color palette to the stream.
/// </summary>
/// <typeparam name="TPixel">The type of the pixel.</typeparam>
/// <param name="stream">The <see cref="Stream"/> to write to.</param>
/// <param name="pixels">The <see cref="Buffer2D{TPixel}"/> containing pixel data.</param>
private void Write16Bit<TPixel>(Stream stream, Buffer2D<TPixel> pixels)
where TPixel : struct, IPixel<TPixel>
{
using (IManagedByteBuffer row = this.AllocateRow(pixels.Width, 2))
{
for (int y = pixels.Height - 1; y >= 0; y--)
{
Span<TPixel> pixelSpan = pixels.GetRowSpan(y);

PixelOperations<TPixel>.Instance.ToBgra5551Bytes(
this.configuration,
pixelSpan,
row.GetSpan(),
pixelSpan.Length);

stream.Write(row.Array, 0, row.Length());
}
}
}
}
}
2 changes: 1 addition & 1 deletion src/ImageSharp/Formats/Bmp/IBmpEncoderOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp
/// <summary>
/// Configuration options for use during bmp encoding
/// </summary>
/// <remarks>The encoder can currently only write 24-bit and 32-bit rgb images to streams.</remarks>
/// <remarks>The encoder can currently only write 16-bit, 24-bit and 32-bit rgb images to streams.</remarks>
internal interface IBmpEncoderOptions
{
/// <summary>
Expand Down
6 changes: 6 additions & 0 deletions src/ImageSharp/PixelFormats/IPixel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,12 @@ public interface IPixel
/// <param name="source">The <see cref="Argb32"/> value.</param>
void FromArgb32(Argb32 source);

/// <summary>
/// Initializes the pixel instance from an <see cref="Bgra5551"/> value.
/// </summary>
/// <param name="source">The <see cref="Bgra5551"/> value.</param>
void FromBgra5551(Bgra5551 source);

/// <summary>
/// Initializes the pixel instance from an <see cref="Bgr24"/> value.
/// </summary>
Expand Down
4 changes: 4 additions & 0 deletions src/ImageSharp/PixelFormats/PixelImplementations/Alpha8.cs
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,10 @@ public struct Alpha8 : IPixel<Alpha8>, IPackedVector<byte>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra32(Bgra32 source) => this.PackedValue = source.A;

/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra5551(Bgra5551 source) => this.FromScaledVector4(source.ToScaledVector4());

/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromGray8(Gray8 source) => this.PackedValue = byte.MaxValue;
Expand Down
4 changes: 4 additions & 0 deletions src/ImageSharp/PixelFormats/PixelImplementations/Argb32.cs
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,10 @@ public uint PackedValue
[MethodImpl(InliningOptions.ShortMethod)]
public void FromArgb32(Argb32 source) => this.PackedValue = source.PackedValue;

/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra5551(Bgra5551 source) => this.FromScaledVector4(source.ToScaledVector4());

/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgr24(Bgr24 source)
Expand Down
4 changes: 4 additions & 0 deletions src/ImageSharp/PixelFormats/PixelImplementations/Bgr24.cs
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,10 @@ public void FromArgb32(Argb32 source)
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgr24(Bgr24 source) => this = source;

/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra5551(Bgra5551 source) => this.FromScaledVector4(source.ToScaledVector4());

/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra32(Bgra32 source)
Expand Down
4 changes: 4 additions & 0 deletions src/ImageSharp/PixelFormats/PixelImplementations/Bgr565.cs
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,10 @@ public void FromVector4(Vector4 vector)
[MethodImpl(InliningOptions.ShortMethod)]
public void FromArgb32(Argb32 source) => this.FromVector4(source.ToVector4());

/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra5551(Bgra5551 source) => this.FromVector4(source.ToVector4());

/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgr24(Bgr24 source) => this.FromScaledVector4(source.ToScaledVector4());
Expand Down
4 changes: 4 additions & 0 deletions src/ImageSharp/PixelFormats/PixelImplementations/Bgra32.cs
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,10 @@ public void FromBgr24(Bgr24 source)
this.A = byte.MaxValue;
}

/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra5551(Bgra5551 source) => this.FromScaledVector4(source.ToScaledVector4());

/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra32(Bgra32 source) => this = source;
Expand Down
4 changes: 4 additions & 0 deletions src/ImageSharp/PixelFormats/PixelImplementations/Bgra4444.cs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,10 @@ public Vector4 ToVector4()
[MethodImpl(InliningOptions.ShortMethod)]
public void FromArgb32(Argb32 source) => this.FromScaledVector4(source.ToScaledVector4());

/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra5551(Bgra5551 source) => this.FromScaledVector4(source.ToScaledVector4());

/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgr24(Bgr24 source) => this.FromScaledVector4(source.ToScaledVector4());
Expand Down
4 changes: 4 additions & 0 deletions src/ImageSharp/PixelFormats/PixelImplementations/Bgra5551.cs
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,10 @@ public Vector4 ToVector4()
(this.PackedValue >> 15) & 0x01);
}

/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra5551(Bgra5551 source) => this = source;

/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromArgb32(Argb32 source) => this.FromScaledVector4(source.ToScaledVector4());
Expand Down
4 changes: 4 additions & 0 deletions src/ImageSharp/PixelFormats/PixelImplementations/Byte4.cs
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,10 @@ public Vector4 ToVector4()
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgb24(Rgb24 source) => this.FromScaledVector4(source.ToScaledVector4());

/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra5551(Bgra5551 source) => this.FromScaledVector4(source.ToScaledVector4());

/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgba32(Rgba32 source) => this.FromScaledVector4(source.ToScaledVector4());
Expand Down
4 changes: 4 additions & 0 deletions src/ImageSharp/PixelFormats/PixelImplementations/Gray16.cs
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,10 @@ public void FromBgra32(Bgra32 source)
ImageMaths.UpscaleFrom8BitTo16Bit(source.B));
}

/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra5551(Bgra5551 source) => this.FromScaledVector4(source.ToScaledVector4());

/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromGray8(Gray8 source) => this.PackedValue = ImageMaths.UpscaleFrom8BitTo16Bit(source.PackedValue);
Expand Down
4 changes: 4 additions & 0 deletions src/ImageSharp/PixelFormats/PixelImplementations/Gray8.cs
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,10 @@ public Vector4 ToVector4()
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra32(Bgra32 source) => this.PackedValue = ImageMaths.Get8BitBT709Luminance(source.R, source.G, source.B);

/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra5551(Bgra5551 source) => this.FromScaledVector4(source.ToScaledVector4());

/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromGray8(Gray8 source) => this.PackedValue = source.PackedValue;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,10 @@ public Vector4 ToScaledVector4()
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra32(Bgra32 source) => this.FromScaledVector4(source.ToScaledVector4());

/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra5551(Bgra5551 source) => this.FromScaledVector4(source.ToScaledVector4());

/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromGray8(Gray8 source) => this.FromScaledVector4(source.ToScaledVector4());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,10 @@ public Vector4 ToVector4()
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra32(Bgra32 source) => this.FromScaledVector4(source.ToScaledVector4());

/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra5551(Bgra5551 source) => this.FromScaledVector4(source.ToScaledVector4());

/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromGray8(Gray8 source) => this.FromScaledVector4(source.ToScaledVector4());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,10 @@ public Vector4 ToVector4()
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra32(Bgra32 source) => this.FromScaledVector4(source.ToScaledVector4());

/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra5551(Bgra5551 source) => this.FromScaledVector4(source.ToScaledVector4());

/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromGray8(Gray8 source) => this.FromScaledVector4(source.ToScaledVector4());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
namespace SixLabors.ImageSharp.PixelFormats
{
/// <summary>
/// Packed packed pixel type containing two 8-bit signed normalized values, ranging from −1 to 1.
/// Packed pixel type containing two 8-bit signed normalized values, ranging from −1 to 1.
/// <para>
/// Ranges from [-1, -1, 0, 1] to [1, 1, 0, 1] in vector form.
/// </para>
Expand Down Expand Up @@ -107,10 +107,11 @@ public void FromVector4(Vector4 vector)

/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void ToRgba32(ref Rgba32 dest)
{
dest.FromScaledVector4(this.ToScaledVector4());
}
public void FromBgra5551(Bgra5551 source) => this.FromScaledVector4(source.ToScaledVector4());

/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void ToRgba32(ref Rgba32 dest) => dest.FromScaledVector4(this.ToScaledVector4());

/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,10 @@ public Vector4 ToVector4()
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra32(Bgra32 source) => this.FromScaledVector4(source.ToScaledVector4());

/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra5551(Bgra5551 source) => this.FromScaledVector4(source.ToScaledVector4());

/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromGray8(Gray8 source) => this.FromScaledVector4(source.ToScaledVector4());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,10 @@ public void FromVector4(Vector4 vector)
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra32(Bgra32 source) => this.FromScaledVector4(source.ToScaledVector4());

/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra5551(Bgra5551 source) => this.FromScaledVector4(source.ToScaledVector4());

/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromGray8(Gray8 source) => this.FromScaledVector4(source.ToScaledVector4());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,10 @@ public Vector4 ToVector4()
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra32(Bgra32 source) => this.FromScaledVector4(source.ToScaledVector4());

/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra5551(Bgra5551 source) => this.FromScaledVector4(source.ToScaledVector4());

/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromGray8(Gray8 source) => this.FromScaledVector4(source.ToScaledVector4());
Expand Down
4 changes: 4 additions & 0 deletions src/ImageSharp/PixelFormats/PixelImplementations/Rg32.cs
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,10 @@ public void FromVector4(Vector4 vector)
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra32(Bgra32 source) => this.FromScaledVector4(source.ToScaledVector4());

/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra5551(Bgra5551 source) => this.FromScaledVector4(source.ToScaledVector4());

/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromGray8(Gray8 source) => this.FromScaledVector4(source.ToScaledVector4());
Expand Down
4 changes: 4 additions & 0 deletions src/ImageSharp/PixelFormats/PixelImplementations/Rgb24.cs
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,10 @@ public void FromGray16(Gray16 source)
this.B = rgb;
}

/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra5551(Bgra5551 source) => this.FromVector4(source.ToVector4());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FromScaledVector4, FromScaledVector4.


/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgb24(Rgb24 source) => this = source;
Expand Down
4 changes: 4 additions & 0 deletions src/ImageSharp/PixelFormats/PixelImplementations/Rgb48.cs
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,10 @@ public void FromBgra32(Bgra32 source)
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgba64(Rgba64 source) => this = source.Rgb;

/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra5551(Bgra5551 source) => this.FromScaledVector4(source.ToScaledVector4());

/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromGray8(Gray8 source)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,10 @@ public Vector4 ToVector4()
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra32(Bgra32 source) => this.FromScaledVector4(source.ToScaledVector4());

/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra5551(Bgra5551 source) => this.FromScaledVector4(source.ToScaledVector4());

/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromGray8(Gray8 source) => this.FromScaledVector4(source.ToScaledVector4());
Expand Down
4 changes: 4 additions & 0 deletions src/ImageSharp/PixelFormats/PixelImplementations/Rgba32.cs
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,10 @@ public void FromBgra32(Bgra32 source)
this.A = source.A;
}

/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra5551(Bgra5551 source) => this.FromScaledVector4(source.ToScaledVector4());

/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromGray8(Gray8 source)
Expand Down
6 changes: 5 additions & 1 deletion src/ImageSharp/PixelFormats/PixelImplementations/Rgba64.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
namespace SixLabors.ImageSharp.PixelFormats
{
/// <summary>
/// Packed pixel type containing four 16-bit unsigned normalized values ranging from 0 to 635535.
/// Packed pixel type containing four 16-bit unsigned normalized values ranging from 0 to 65535.
/// <para>
/// Ranges from [0, 0, 0, 0] to [1, 1, 1, 1] in vector form.
/// </para>
Expand Down Expand Up @@ -154,6 +154,10 @@ public void FromBgra32(Bgra32 source)
this.A = ImageMaths.UpscaleFrom8BitTo16Bit(source.A);
}

/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra5551(Bgra5551 source) => this.FromScaledVector4(source.ToScaledVector4());

/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromGray8(Gray8 source)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,10 @@ public void FromVector4(Vector4 vector)
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra32(Bgra32 source) => this.FromScaledVector4(source.ToScaledVector4());

/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra5551(Bgra5551 source) => this.FromScaledVector4(source.ToScaledVector4());

/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromGray8(Gray8 source) => this.FromScaledVector4(source.ToScaledVector4());
Expand All @@ -152,10 +156,7 @@ public void FromVector4(Vector4 vector)

/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void ToRgba32(ref Rgba32 dest)
{
dest.FromScaledVector4(this.ToScaledVector4());
}
public void ToRgba32(ref Rgba32 dest) => dest.FromScaledVector4(this.ToScaledVector4());

/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
Expand Down
Loading