EncoderParameter
Used to pass a value, or an array of values, to an image encoder.
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using Windows.Win32.Graphics.GdiPlus;
namespace System.Drawing.Imaging
{
[StructLayout(LayoutKind.Sequential)]
[NullableContext(1)]
[Nullable(0)]
public sealed class EncoderParameter : IDisposable
{
private Guid _parameterGuid;
private readonly int _numberOfValues;
private readonly EncoderParameterValueType _parameterValueType;
private IntPtr _parameterValue;
public Encoder Encoder {
get {
return new Encoder(_parameterGuid);
}
set {
_parameterGuid = value.Guid;
}
}
public EncoderParameterValueType Type => _parameterValueType;
public EncoderParameterValueType ValueType => _parameterValueType;
public int NumberOfValues => _numberOfValues;
internal unsafe global::Windows.Win32.Graphics.GdiPlus.EncoderParameter ToNative()
{
global::Windows.Win32.Graphics.GdiPlus.EncoderParameter result = default(global::Windows.Win32.Graphics.GdiPlus.EncoderParameter);
result.Guid = _parameterGuid;
result.Type = (uint)_parameterValueType;
result.NumberOfValues = (uint)_numberOfValues;
result.Value = (void*)(long)_parameterValue;
return result;
}
public void Dispose()
{
if (_parameterValue != (IntPtr)0)
Marshal.FreeHGlobal(_parameterValue);
_parameterValue = (IntPtr)0;
GC.KeepAlive(this);
GC.SuppressFinalize(this);
}
~EncoderParameter()
{
Dispose();
}
public unsafe EncoderParameter(Encoder encoder, byte value)
{
_parameterGuid = encoder.Guid;
_parameterValueType = EncoderParameterValueType.ValueTypeByte;
_numberOfValues = 1;
_parameterValue = Marshal.AllocHGlobal(1);
*(sbyte*)(long)_parameterValue = (sbyte)value;
GC.KeepAlive(this);
}
public unsafe EncoderParameter(Encoder encoder, byte value, bool undefined)
{
_parameterGuid = encoder.Guid;
_parameterValueType = ((!undefined) ? EncoderParameterValueType.ValueTypeByte : EncoderParameterValueType.ValueTypeUndefined);
_numberOfValues = 1;
_parameterValue = Marshal.AllocHGlobal(1);
*(sbyte*)(long)_parameterValue = (sbyte)value;
GC.KeepAlive(this);
}
public unsafe EncoderParameter(Encoder encoder, short value)
{
_parameterGuid = encoder.Guid;
_parameterValueType = EncoderParameterValueType.ValueTypeShort;
_numberOfValues = 1;
_parameterValue = Marshal.AllocHGlobal(2);
*(short*)(long)_parameterValue = value;
GC.KeepAlive(this);
}
public unsafe EncoderParameter(Encoder encoder, long value)
{
_parameterGuid = encoder.Guid;
_parameterValueType = EncoderParameterValueType.ValueTypeLong;
_numberOfValues = 1;
_parameterValue = Marshal.AllocHGlobal(4);
*(int*)(long)_parameterValue = (int)value;
GC.KeepAlive(this);
}
public unsafe EncoderParameter(Encoder encoder, int numerator, int denominator)
{
_parameterGuid = encoder.Guid;
_parameterValueType = EncoderParameterValueType.ValueTypeRational;
_numberOfValues = 1;
_parameterValue = Marshal.AllocHGlobal(8);
*(int*)(long)_parameterValue = numerator;
*(int*)((long)_parameterValue + 4) = denominator;
GC.KeepAlive(this);
}
public unsafe EncoderParameter(Encoder encoder, long rangebegin, long rangeend)
{
_parameterGuid = encoder.Guid;
_parameterValueType = EncoderParameterValueType.ValueTypeLongRange;
_numberOfValues = 1;
_parameterValue = Marshal.AllocHGlobal(8);
*(int*)(long)_parameterValue = (int)rangebegin;
*(int*)((long)_parameterValue + 4) = (int)rangeend;
GC.KeepAlive(this);
}
public unsafe EncoderParameter(Encoder encoder, int numerator1, int demoninator1, int numerator2, int demoninator2)
{
_parameterGuid = encoder.Guid;
_parameterValueType = EncoderParameterValueType.ValueTypeRationalRange;
_numberOfValues = 1;
_parameterValue = Marshal.AllocHGlobal(16);
*(int*)(long)_parameterValue = numerator1;
*(int*)((long)_parameterValue + 4) = demoninator1;
*(int*)((long)_parameterValue + (long)(IntPtr)(void*)(2 * 4)) = numerator2;
*(int*)((long)_parameterValue + (long)(IntPtr)(void*)(3 * 4)) = demoninator2;
GC.KeepAlive(this);
}
public EncoderParameter(Encoder encoder, string value)
{
_parameterGuid = encoder.Guid;
_parameterValueType = EncoderParameterValueType.ValueTypeAscii;
_numberOfValues = value.Length;
_parameterValue = Marshal.StringToHGlobalAnsi(value);
GC.KeepAlive(this);
}
public EncoderParameter(Encoder encoder, byte[] value)
{
_parameterGuid = encoder.Guid;
_parameterValueType = EncoderParameterValueType.ValueTypeByte;
_numberOfValues = value.Length;
_parameterValue = Marshal.AllocHGlobal(_numberOfValues);
Marshal.Copy(value, 0, _parameterValue, _numberOfValues);
GC.KeepAlive(this);
}
public EncoderParameter(Encoder encoder, byte[] value, bool undefined)
{
_parameterGuid = encoder.Guid;
_parameterValueType = ((!undefined) ? EncoderParameterValueType.ValueTypeByte : EncoderParameterValueType.ValueTypeUndefined);
_numberOfValues = value.Length;
_parameterValue = Marshal.AllocHGlobal(_numberOfValues);
Marshal.Copy(value, 0, _parameterValue, _numberOfValues);
GC.KeepAlive(this);
}
public EncoderParameter(Encoder encoder, short[] value)
{
_parameterGuid = encoder.Guid;
_parameterValueType = EncoderParameterValueType.ValueTypeShort;
_numberOfValues = value.Length;
_parameterValue = Marshal.AllocHGlobal(checked(_numberOfValues * 2));
Marshal.Copy(value, 0, _parameterValue, _numberOfValues);
GC.KeepAlive(this);
}
public unsafe EncoderParameter(Encoder encoder, long[] value)
{
_parameterGuid = encoder.Guid;
_parameterValueType = EncoderParameterValueType.ValueTypeLong;
_numberOfValues = value.Length;
_parameterValue = Marshal.AllocHGlobal(checked(_numberOfValues * 4));
int* parameterValue = (int*)(long)_parameterValue;
for (int i = 0; i < value.Length; i++) {
parameterValue[i] = (int)value[i];
}
GC.KeepAlive(this);
}
public unsafe EncoderParameter(Encoder encoder, int[] numerator, int[] denominator)
{
_parameterGuid = encoder.Guid;
if (numerator.Length != denominator.Length)
throw Status.InvalidParameter.GetException();
_parameterValueType = EncoderParameterValueType.ValueTypeRational;
_numberOfValues = numerator.Length;
_parameterValue = Marshal.AllocHGlobal(checked(_numberOfValues * 2 * 4));
for (int i = 0; i < _numberOfValues; i++) {
*(int*)((long)_parameterValue + (long)(IntPtr)(void*)((long)(i * 2) * 4)) = numerator[i];
*(int*)((long)_parameterValue + (long)(IntPtr)(void*)((long)(i * 2 + 1) * 4)) = denominator[i];
}
GC.KeepAlive(this);
}
public unsafe EncoderParameter(Encoder encoder, long[] rangebegin, long[] rangeend)
{
_parameterGuid = encoder.Guid;
if (rangebegin.Length != rangeend.Length)
throw Status.InvalidParameter.GetException();
_parameterValueType = EncoderParameterValueType.ValueTypeLongRange;
_numberOfValues = rangebegin.Length;
_parameterValue = Marshal.AllocHGlobal(checked(_numberOfValues * 2 * 4));
for (int i = 0; i < _numberOfValues; i++) {
*(int*)((long)_parameterValue + (long)(IntPtr)(void*)((long)(i * 2) * 4)) = (int)rangebegin[i];
*(int*)((long)_parameterValue + (long)(IntPtr)(void*)((long)(i * 2 + 1) * 4)) = (int)rangeend[i];
}
GC.KeepAlive(this);
}
public unsafe EncoderParameter(Encoder encoder, int[] numerator1, int[] denominator1, int[] numerator2, int[] denominator2)
{
_parameterGuid = encoder.Guid;
if (numerator1.Length != denominator1.Length || numerator1.Length != denominator2.Length || denominator1.Length != denominator2.Length)
throw Status.InvalidParameter.GetException();
_parameterValueType = EncoderParameterValueType.ValueTypeRationalRange;
_numberOfValues = numerator1.Length;
_parameterValue = Marshal.AllocHGlobal(checked(_numberOfValues * 4 * 4));
for (int i = 0; i < _numberOfValues; i++) {
*(int*)((long)_parameterValue + (long)(IntPtr)(void*)((long)(i * 4) * 4)) = numerator1[i];
*(int*)((long)_parameterValue + (long)(IntPtr)(void*)((long)(i * 4 + 1) * 4)) = denominator1[i];
*(int*)((long)_parameterValue + (long)(IntPtr)(void*)((long)(i * 4 + 2) * 4)) = numerator2[i];
*(int*)((long)_parameterValue + (long)(IntPtr)(void*)((long)(i * 4 + 3) * 4)) = denominator2[i];
}
GC.KeepAlive(this);
}
[Obsolete("This constructor has been deprecated. Use EncoderParameter(Encoder encoder, int numberValues, EncoderParameterValueType type, IntPtr value) instead.")]
public unsafe EncoderParameter(Encoder encoder, int NumberOfValues, int Type, int Value)
{
int num;
switch (Type) {
case 1:
case 2:
num = 1;
break;
case 3:
num = 2;
break;
case 4:
num = 4;
break;
case 5:
case 6:
num = 8;
break;
case 7:
num = 1;
break;
case 8:
num = 16;
break;
default:
throw Status.WrongState.GetException();
}
int num2 = checked(num * NumberOfValues);
_parameterValue = Marshal.AllocHGlobal(num2);
new ReadOnlySpan<byte>((void*)Value, num2).CopyTo(new Span<byte>((void*)(long)_parameterValue, num2));
_parameterValueType = (EncoderParameterValueType)Type;
_numberOfValues = NumberOfValues;
_parameterGuid = encoder.Guid;
GC.KeepAlive(this);
}
public unsafe EncoderParameter(Encoder encoder, int numberValues, EncoderParameterValueType type, IntPtr value)
{
int num;
switch (type) {
case EncoderParameterValueType.ValueTypeByte:
case EncoderParameterValueType.ValueTypeAscii:
num = 1;
break;
case EncoderParameterValueType.ValueTypeShort:
num = 2;
break;
case EncoderParameterValueType.ValueTypeLong:
num = 4;
break;
case EncoderParameterValueType.ValueTypeRational:
case EncoderParameterValueType.ValueTypeLongRange:
num = 8;
break;
case EncoderParameterValueType.ValueTypeUndefined:
num = 1;
break;
case EncoderParameterValueType.ValueTypeRationalRange:
num = 16;
break;
case EncoderParameterValueType.ValueTypePointer:
num = IntPtr.Size;
break;
default:
throw Status.WrongState.GetException();
}
int num2 = checked(num * numberValues);
_parameterValue = Marshal.AllocHGlobal(num2);
new ReadOnlySpan<byte>((void*)(long)value, num2).CopyTo(new Span<byte>((void*)(long)_parameterValue, num2));
_parameterValueType = type;
_numberOfValues = numberValues;
_parameterGuid = encoder.Guid;
GC.KeepAlive(this);
}
}
}