Skip to content

Commit

Permalink
Add DIB header
Browse files Browse the repository at this point in the history
  • Loading branch information
KeterSCP committed Dec 16, 2023
1 parent e537104 commit 0226777
Show file tree
Hide file tree
Showing 12 changed files with 286 additions and 68 deletions.
9 changes: 8 additions & 1 deletion src/SharpEmf.Svg/EmfSvgWriter.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Text;
using SharpEmf.Records.Bitmap;
using SharpEmf.Records.Drawing;
using SharpEmf.Records.ObjectCreation;
using SharpEmf.Records.ObjectManipulation;
Expand Down Expand Up @@ -70,7 +71,13 @@ public static string ConvertToSvg(EnhancedMetafile emf)
EmfDrawingRecordsHandlers.HandlePolybezierTo16(sb, state, polyBezierTo16);
break;
case EmrCloseFigure:
EmfPathBracketRecordsHandlers.HandleCloseFigure(sb);
EmfPathBracketRecordsHandlers.HandleCloseFigure(sb, state);
break;
case EmrStretchDiBits stretchDiBits:
EmfBitmapRecordsHandlers.HandleStretchDIBits(sb, state, stretchDiBits);
break;
default:
Console.WriteLine($"Skipped record: {record.Type}");
break;
}
}
Expand Down
24 changes: 24 additions & 0 deletions src/SharpEmf.Svg/RecordsProcessing/EmfBitmapRecordsHandlers.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using System.Text;
using SharpEmf.Records.Bitmap;

namespace SharpEmf.Svg.RecordsProcessing;

internal static class EmfBitmapRecordsHandlers
{
public static void HandleStretchDIBits(StringBuilder svgSb, EmfState state, EmrStretchDiBits stretchDiBits)
{
// TODO: fix this
var bitmapBase64 = Convert.ToBase64String(stretchDiBits.BitsSrc);

var scalingForMapMode = state.GetScalingForCurrentMapMode();
var scaleMatrix = $"matrix({scalingForMapMode.X},0,0,{scalingForMapMode.Y},0,0)";

var x = stretchDiBits.XDest;
var y = stretchDiBits.YDest;
var width = stretchDiBits.CXDest;
var height = stretchDiBits.CYDest;


svgSb.AppendLine($"<image transform=\"{scaleMatrix}\" x=\"{x}\" y=\"{y}\" width=\"{width}\" height=\"{height}\" xlink:href=\"data:image/bmp;base64,{bitmapBase64}\" />");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public static void HandleEndPath(StringBuilder svgSb, EmfState state)
svgSb.AppendLine(" />");
}

public static void HandleCloseFigure(StringBuilder svgSb)
public static void HandleCloseFigure(StringBuilder svgSb, EmfState state)
{
svgSb.Append("Z ");
}
Expand Down
2 changes: 1 addition & 1 deletion src/SharpEmf/Objects/EmrText.cs
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ private EmrText(
DxBuffer = dxBuffer;
}

public static EmrText Parse(Stream stream, EmfRecordType parentRecordType, int parentSizeWithoutTextBuffer)
public static EmrText Parse(Stream stream, EmfRecordType parentRecordType, long parentSizeWithoutTextBuffer)
{
var reference = PointL.Parse(stream);
var chars = stream.ReadUInt32();
Expand Down
42 changes: 15 additions & 27 deletions src/SharpEmf/Records/Bitmap/EmrStretchDiBits.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using SharpEmf.Enums;
using SharpEmf.Extensions;
using SharpEmf.WmfTypes;
using SharpEmf.WmfTypes.Bitmap;

namespace SharpEmf.Records.Bitmap;

Expand Down Expand Up @@ -96,12 +97,12 @@ public record EmrStretchDiBits : EnhancedMetafileRecord
/// <summary>
/// The source bitmap header
/// </summary>
public IReadOnlyList<byte> BmiSrc { get; }
public BitmapInfoHeader BmiHeader { get; }

/// <summary>
/// The source bitmap bits
/// </summary>
public IReadOnlyList<byte> BitsSrc { get; }
public byte[] BitsSrc { get; }

private EmrStretchDiBits(
EmfRecordType recordType,
Expand All @@ -121,8 +122,8 @@ private EmrStretchDiBits(
TernaryRasterOperation bitBltRasterOperation,
int cxDest,
int cyDest,
IReadOnlyList<byte> bmiSrc,
IReadOnlyList<byte> bitsSrc) : base(recordType, size)
BitmapInfoHeader bmiHeader,
byte[] bitsSrc) : base(recordType, size)
{
Bounds = bounds;
XDest = xDest;
Expand All @@ -139,12 +140,17 @@ private EmrStretchDiBits(
BitBltRasterOperation = bitBltRasterOperation;
CXDest = cxDest;
CYDest = cyDest;
BmiSrc = bmiSrc;
BmiHeader = bmiHeader;
BitsSrc = bitsSrc;
}

public static EmrStretchDiBits Parse(Stream stream, EmfRecordType recordType, uint size)
{
var positionBeforeParsing =
stream.Position -
// Base record fields
(Unsafe.SizeOf<EmfRecordType>() + Unsafe.SizeOf<uint>());

var bounds = RectL.Parse(stream);
var xDest = stream.ReadInt32();
var yDest = stream.ReadInt32();
Expand All @@ -161,26 +167,8 @@ public static EmrStretchDiBits Parse(Stream stream, EmfRecordType recordType, ui
var cxDest = stream.ReadInt32();
var cyDest = stream.ReadInt32();

var selfSizeWithoutBuffers =
// Base record fields
Unsafe.SizeOf<EmfRecordType>() +
Unsafe.SizeOf<uint>() +
// Self fields
Unsafe.SizeOf<RectL>() +
Unsafe.SizeOf<int>() +
Unsafe.SizeOf<int>() +
Unsafe.SizeOf<int>() +
Unsafe.SizeOf<int>() +
Unsafe.SizeOf<int>() +
Unsafe.SizeOf<int>() +
Unsafe.SizeOf<uint>() +
Unsafe.SizeOf<uint>() +
Unsafe.SizeOf<uint>() +
Unsafe.SizeOf<uint>() +
Unsafe.SizeOf<DIBColors>() +
Unsafe.SizeOf<TernaryRasterOperation>() +
Unsafe.SizeOf<int>() +
Unsafe.SizeOf<int>();
var positionAfterParsing = stream.Position;
var selfSizeWithoutBuffers = positionAfterParsing - positionBeforeParsing;

long seekOffset = 0;
if (offBmiSrc != 0)
Expand All @@ -189,11 +177,11 @@ public static EmrStretchDiBits Parse(Stream stream, EmfRecordType recordType, ui
stream.Seek(seekOffset, SeekOrigin.Current);
}

var bmiSrc = stream.ReadByteArray((int)cbBmiSrc);
var bmiSrc = BitmapInfoHeader.Parse(stream);

if (offBitsSrc != 0)
{
seekOffset = offBitsSrc - (seekOffset + bmiSrc.Length + selfSizeWithoutBuffers);
seekOffset = offBitsSrc - (seekOffset + bmiSrc.Size + selfSizeWithoutBuffers);
stream.Seek(seekOffset, SeekOrigin.Current);
}

Expand Down
16 changes: 7 additions & 9 deletions src/SharpEmf/Records/Drawing/EmrExtTextOutA.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,20 +61,18 @@ private EmrExtTextOutA(

public static EmrExtTextOutA Parse(Stream stream, EmfRecordType recordType, uint size)
{
var positionBeforeParsing =
stream.Position -
// Base record fields
(Unsafe.SizeOf<EmfRecordType>() + Unsafe.SizeOf<uint>());

var bounds = RectL.Parse(stream);
var iGraphicsMode = stream.ReadEnum<GraphicsMode>();
var exScale = stream.ReadFloat32();
var eyScale = stream.ReadFloat32();

var selfSizeWithoutTextBuffer =
// Base record fields
Unsafe.SizeOf<EmfRecordType>() +
Unsafe.SizeOf<uint>() +
// This record fields
Unsafe.SizeOf<RectL>() +
Unsafe.SizeOf<GraphicsMode>() +
Unsafe.SizeOf<float>() +
Unsafe.SizeOf<float>();
var positionAfterParsing = stream.Position;
var selfSizeWithoutTextBuffer = positionAfterParsing - positionBeforeParsing;

var aEmrText = EmrText.Parse(stream, recordType, selfSizeWithoutTextBuffer);

Expand Down
16 changes: 7 additions & 9 deletions src/SharpEmf/Records/Drawing/EmrExtTextOutW.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,20 +61,18 @@ private EmrExtTextOutW(

public static EmrExtTextOutW Parse(Stream stream, EmfRecordType recordType, uint size)
{
var positionBeforeParsing =
stream.Position -
// Base record fields
(Unsafe.SizeOf<EmfRecordType>() + Unsafe.SizeOf<uint>());

var bounds = RectL.Parse(stream);
var iGraphicsMode = stream.ReadEnum<GraphicsMode>();
var exScale = stream.ReadFloat32();
var eyScale = stream.ReadFloat32();

var selfSizeWithoutTextBuffer =
// Base record fields
Unsafe.SizeOf<EmfRecordType>() +
Unsafe.SizeOf<uint>() +
// This record fields
Unsafe.SizeOf<RectL>() +
Unsafe.SizeOf<GraphicsMode>() +
Unsafe.SizeOf<float>() +
Unsafe.SizeOf<float>();
var positionAfterParsing = stream.Position;
var selfSizeWithoutTextBuffer = positionAfterParsing - positionBeforeParsing;

var wEmrText = EmrText.Parse(stream, recordType, selfSizeWithoutTextBuffer);

Expand Down
17 changes: 7 additions & 10 deletions src/SharpEmf/Records/Drawing/EmrPolyTextOutA.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,22 +71,19 @@ private EmrPolyTextOutA(

public static EmrPolyTextOutA Parse(Stream stream, EmfRecordType recordType, uint size)
{
var positionBeforeParsing =
stream.Position -
// Base record fields
(Unsafe.SizeOf<EmfRecordType>() + Unsafe.SizeOf<uint>());

var bounds = RectL.Parse(stream);
var iGraphicsMode = stream.ReadEnum<GraphicsMode>();
var exScale = stream.ReadFloat32();
var eyScale = stream.ReadFloat32();
var cStrings = stream.ReadUInt32();

var selfSizeWithoutTextBuffers =
// Base record fields
Unsafe.SizeOf<EmfRecordType>() +
Unsafe.SizeOf<uint>() +
// This record fields
Unsafe.SizeOf<RectL>() +
Unsafe.SizeOf<GraphicsMode>() +
Unsafe.SizeOf<float>() +
Unsafe.SizeOf<float>() +
Unsafe.SizeOf<uint>();
var positionAfterParsing = stream.Position;
var selfSizeWithoutTextBuffers = positionAfterParsing - positionBeforeParsing;

var aEmrTexts = new List<EmrText>((int)cStrings);

Expand Down
17 changes: 7 additions & 10 deletions src/SharpEmf/Records/Drawing/EmrPolyTextOutW.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,22 +71,19 @@ private EmrPolyTextOutW(

public static EmrPolyTextOutW Parse(Stream stream, EmfRecordType recordType, uint size)
{
var positionBeforeParsing =
stream.Position -
// Base record fields
(Unsafe.SizeOf<EmfRecordType>() + Unsafe.SizeOf<uint>());

var bounds = RectL.Parse(stream);
var iGraphicsMode = stream.ReadEnum<GraphicsMode>();
var exScale = stream.ReadFloat32();
var eyScale = stream.ReadFloat32();
var cStrings = stream.ReadUInt32();

var selfSizeWithoutTextBuffers =
// Base record fields
Unsafe.SizeOf<EmfRecordType>() +
Unsafe.SizeOf<uint>() +
// This record fields
Unsafe.SizeOf<RectL>() +
Unsafe.SizeOf<GraphicsMode>() +
Unsafe.SizeOf<float>() +
Unsafe.SizeOf<float>() +
Unsafe.SizeOf<uint>();
var positionAfterParsing = stream.Position;
var selfSizeWithoutTextBuffers = positionAfterParsing - positionBeforeParsing;

var wEmrTexts = new List<EmrText>((int)cStrings);

Expand Down
42 changes: 42 additions & 0 deletions src/SharpEmf/WmfTypes/Bitmap/BitCount.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
namespace SharpEmf.WmfTypes.Bitmap;

/// <summary>
/// Specifies the number of bits that define each pixel and the maximum number of colors in a device-independent bitmap (DIB)
/// </summary>
public enum BitCount : ushort
{
/// <summary>
/// The number of bits per pixel is undefined
/// </summary>
BI_BITCOUNT_0 = 0x0000,

/// <summary>
/// The image is specified with two colors
/// </summary>
BI_BITCOUNT_1 = 0x0001,

/// <summary>
/// The image is specified with a maximum of 16 colors.
/// </summary>
BI_BITCOUNT_2 = 0x0004,

/// <summary>
/// The image is specified with a maximum of 256 colors
/// </summary>
BI_BITCOUNT_3 = 0x0008,

/// <summary>
/// The image is specified with a maximum of 2^16 colors
/// </summary>
BI_BITCOUNT_4 = 0x0010,

/// <summary>
/// The bitmap in the BitmapBuffer field of the DIB Object has a maximum of 2^24 colors
/// </summary>
BI_BITCOUNT_5 = 0x0018,

/// <summary>
/// The bitmap in the BitmapBuffer field of the DIB Object has a maximum of 2^24 colors
/// </summary>
BI_BITCOUNT_6 = 0x0020
}
Loading

0 comments on commit 0226777

Please sign in to comment.