|
//------------------------------------------------------------------------------
// <copyright file="EncoderParameter.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
//------------------------------------------------------------------------------
namespace System.Drawing.Imaging {
using System;
using System.Text;
using System.Diagnostics;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Drawing.Internal;
/// <include file='doc\EncoderParameter.uex' path='docs/doc[@for="EncoderParameter"]/*' />
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
[StructLayout(LayoutKind.Sequential)]
public sealed class EncoderParameter : IDisposable {
[MarshalAs(UnmanagedType.Struct)]
Guid parameterGuid; // GUID of the parameter
int numberOfValues; // Number of the parameter values
EncoderParameterValueType parameterValueType; // Value type, like ValueTypeLONG etc.
IntPtr parameterValue; // A pointer to the parameter values
/// <include file='doc\EncoderParameter.uex' path='docs/doc[@for="EncoderParameter.Finalize"]/*' />
~EncoderParameter() {
Dispose(false);
}
/// <include file='doc\EncoderParameter.uex' path='docs/doc[@for="EncoderParameter.Encoder"]/*' />
/// <devdoc>
/// Gets/Sets the Encoder for the EncoderPameter.
/// </devdoc>
public Encoder Encoder {
get {
return new Encoder(parameterGuid);
}
set {
parameterGuid = value.Guid;
}
}
/// <include file='doc\EncoderParameter.uex' path='docs/doc[@for="EncoderParameter.Type"]/*' />
/// <devdoc>
/// Gets the EncoderParameterValueType object from the EncoderParameter.
/// </devdoc>
public EncoderParameterValueType Type {
get {
return parameterValueType;
}
}
/// <include file='doc\EncoderParameter.uex' path='docs/doc[@for="EncoderParameter.ValueType"]/*' />
/// <devdoc>
/// Gets the EncoderParameterValueType object from the EncoderParameter.
/// </devdoc>
public EncoderParameterValueType ValueType {
get {
return parameterValueType;
}
}
/// <include file='doc\EncoderParameter.uex' path='docs/doc[@for="EncoderParameter.NumberOfValues"]/*' />
/// <devdoc>
/// Gets the NumberOfValues from the EncoderParameter.
/// </devdoc>
public int NumberOfValues {
get {
return numberOfValues;
}
}
/// <include file='doc\EncoderParameter.uex' path='docs/doc[@for="EncoderParameter.Dispose"]/*' />
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
public void Dispose() {
Dispose(true);
GC.KeepAlive(this);
GC.SuppressFinalize(this);
}
void Dispose(bool disposing) {
if (parameterValue != IntPtr.Zero)
Marshal.FreeHGlobal(parameterValue);
parameterValue = IntPtr.Zero;
}
/// <include file='doc\EncoderParameter.uex' path='docs/doc[@for="EncoderParameter.EncoderParameter"]/*' />
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
public EncoderParameter(Encoder encoder, byte value)
{
parameterGuid = encoder.Guid;
parameterValueType = EncoderParameterValueType.ValueTypeByte;
numberOfValues = 1;
parameterValue = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(Byte)));
if (parameterValue == IntPtr.Zero)
throw SafeNativeMethods.Gdip.StatusException(SafeNativeMethods.Gdip.OutOfMemory);
Marshal.WriteByte(parameterValue, value);
GC.KeepAlive(this);
}
/// <include file='doc\EncoderParameter.uex' path='docs/doc[@for="EncoderParameter.EncoderParameter1"]/*' />
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
public EncoderParameter(Encoder encoder, byte value, bool undefined)
{
parameterGuid = encoder.Guid;
if (undefined == true)
parameterValueType = EncoderParameterValueType.ValueTypeUndefined;
else
parameterValueType = EncoderParameterValueType.ValueTypeByte;
numberOfValues = 1;
parameterValue = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(Byte)));
if (parameterValue == IntPtr.Zero)
throw SafeNativeMethods.Gdip.StatusException(SafeNativeMethods.Gdip.OutOfMemory);
Marshal.WriteByte(parameterValue, value);
GC.KeepAlive(this);
}
/// <include file='doc\EncoderParameter.uex' path='docs/doc[@for="EncoderParameter.EncoderParameter2"]/*' />
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
public EncoderParameter(Encoder encoder, short value)
{
parameterGuid = encoder.Guid;
parameterValueType = EncoderParameterValueType.ValueTypeShort;
numberOfValues = 1;
parameterValue = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(Int16)));
if (parameterValue == IntPtr.Zero)
throw SafeNativeMethods.Gdip.StatusException(SafeNativeMethods.Gdip.OutOfMemory);
Marshal.WriteInt16(parameterValue, value);
GC.KeepAlive(this);
}
/// <include file='doc\EncoderParameter.uex' path='docs/doc[@for="EncoderParameter.EncoderParameter3"]/*' />
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
public EncoderParameter(Encoder encoder, long value)
{
parameterGuid = encoder.Guid;
parameterValueType = EncoderParameterValueType.ValueTypeLong;
numberOfValues = 1;
parameterValue = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(Int32)));
if (parameterValue == IntPtr.Zero)
throw SafeNativeMethods.Gdip.StatusException(SafeNativeMethods.Gdip.OutOfMemory);
Marshal.WriteInt32(parameterValue, unchecked((int)value));
GC.KeepAlive(this);
}
// Consider supporting a 'float' and converting to numerator/denominator
/// <include file='doc\EncoderParameter.uex' path='docs/doc[@for="EncoderParameter.EncoderParameter4"]/*' />
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
public EncoderParameter(Encoder encoder, int numerator, int denominator)
{
parameterGuid = encoder.Guid;
parameterValueType = EncoderParameterValueType.ValueTypeRational;
numberOfValues = 1;
int size = Marshal.SizeOf(typeof(Int32));
parameterValue = Marshal.AllocHGlobal(2*size);
if (parameterValue == IntPtr.Zero)
throw SafeNativeMethods.Gdip.StatusException(SafeNativeMethods.Gdip.OutOfMemory);
Marshal.WriteInt32(parameterValue, numerator);
Marshal.WriteInt32(Add(parameterValue, size), denominator);
GC.KeepAlive(this);
}
// Consider supporting a 'float' and converting to numerator/denominator
/// <include file='doc\EncoderParameter.uex' path='docs/doc[@for="EncoderParameter.EncoderParameter5"]/*' />
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
public EncoderParameter(Encoder encoder, long rangebegin, long rangeend)
{
parameterGuid = encoder.Guid;
parameterValueType = EncoderParameterValueType.ValueTypeLongRange;
numberOfValues = 1;
int size = Marshal.SizeOf(typeof(Int32));
parameterValue = Marshal.AllocHGlobal(2*size);
if (parameterValue == IntPtr.Zero)
throw SafeNativeMethods.Gdip.StatusException(SafeNativeMethods.Gdip.OutOfMemory);
Marshal.WriteInt32(parameterValue, unchecked((int)rangebegin));
Marshal.WriteInt32(Add(parameterValue, size), unchecked((int)rangeend));
GC.KeepAlive(this);
}
// Consider supporting a 'float' and converting to numerator/denominator
/// <include file='doc\EncoderParameter.uex' path='docs/doc[@for="EncoderParameter.EncoderParameter6"]/*' />
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
public EncoderParameter(Encoder encoder,
int numerator1, int demoninator1,
int numerator2, int demoninator2)
{
parameterGuid = encoder.Guid;
parameterValueType = EncoderParameterValueType.ValueTypeRationalRange;
numberOfValues = 1;
int size = Marshal.SizeOf(typeof(Int32));
parameterValue = Marshal.AllocHGlobal(4*size);
if (parameterValue == IntPtr.Zero)
throw SafeNativeMethods.Gdip.StatusException(SafeNativeMethods.Gdip.OutOfMemory);
Marshal.WriteInt32(parameterValue, numerator1);
Marshal.WriteInt32(Add(parameterValue, size), demoninator1);
Marshal.WriteInt32(Add(parameterValue, 2*size), numerator2);
Marshal.WriteInt32(Add(parameterValue, 3*size), demoninator2);
GC.KeepAlive(this);
}
/// <include file='doc\EncoderParameter.uex' path='docs/doc[@for="EncoderParameter.EncoderParameter7"]/*' />
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
public EncoderParameter(Encoder encoder, string value)
{
parameterGuid = encoder.Guid;
parameterValueType = EncoderParameterValueType.ValueTypeAscii;
numberOfValues = value.Length;
parameterValue = Marshal.StringToHGlobalAnsi(value);
GC.KeepAlive(this);
if (parameterValue == IntPtr.Zero)
throw SafeNativeMethods.Gdip.StatusException(SafeNativeMethods.Gdip.OutOfMemory);
}
/// <include file='doc\EncoderParameter.uex' path='docs/doc[@for="EncoderParameter.EncoderParameter8"]/*' />
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
public EncoderParameter(Encoder encoder, byte[] value)
{
parameterGuid = encoder.Guid;
parameterValueType = EncoderParameterValueType.ValueTypeByte;
numberOfValues = value.Length;
parameterValue = Marshal.AllocHGlobal(numberOfValues);
if (parameterValue == IntPtr.Zero)
throw SafeNativeMethods.Gdip.StatusException(SafeNativeMethods.Gdip.OutOfMemory);
Marshal.Copy(value, 0, parameterValue, numberOfValues);
GC.KeepAlive(this);
}
/// <include file='doc\EncoderParameter.uex' path='docs/doc[@for="EncoderParameter.EncoderParameter9"]/*' />
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
public EncoderParameter(Encoder encoder, byte[] value, bool undefined)
{
parameterGuid = encoder.Guid;
if (undefined == true)
parameterValueType = EncoderParameterValueType.ValueTypeUndefined;
else
parameterValueType = EncoderParameterValueType.ValueTypeByte;
numberOfValues = value.Length;
parameterValue = Marshal.AllocHGlobal(numberOfValues);
if (parameterValue == IntPtr.Zero)
throw SafeNativeMethods.Gdip.StatusException(SafeNativeMethods.Gdip.OutOfMemory);
Marshal.Copy(value, 0, parameterValue, numberOfValues);
GC.KeepAlive(this);
}
/// <include file='doc\EncoderParameter.uex' path='docs/doc[@for="EncoderParameter.EncoderParameter10"]/*' />
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
public EncoderParameter(Encoder encoder, short[] value)
{
parameterGuid = encoder.Guid;
parameterValueType = EncoderParameterValueType.ValueTypeShort;
numberOfValues = value.Length;
int size = Marshal.SizeOf(typeof(short));
parameterValue = Marshal.AllocHGlobal(checked(numberOfValues*size));
if (parameterValue == IntPtr.Zero)
throw SafeNativeMethods.Gdip.StatusException(SafeNativeMethods.Gdip.OutOfMemory);
Marshal.Copy(value, 0, parameterValue, numberOfValues);
GC.KeepAlive(this);
}
/// <include file='doc\EncoderParameter.uex' path='docs/doc[@for="EncoderParameter.EncoderParameter11"]/*' />
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
public unsafe EncoderParameter(Encoder encoder, long[] value)
{
parameterGuid = encoder.Guid;
parameterValueType = EncoderParameterValueType.ValueTypeLong;
numberOfValues = value.Length;
int size = Marshal.SizeOf(typeof(Int32));
parameterValue = Marshal.AllocHGlobal(checked(numberOfValues*size));
if (parameterValue == IntPtr.Zero)
throw SafeNativeMethods.Gdip.StatusException(SafeNativeMethods.Gdip.OutOfMemory);
int* dest = (int*)parameterValue;
fixed (long* source = value) {
for (int i=0; i<value.Length; i++) {
dest[i] = unchecked((int)source[i]);
}
}
GC.KeepAlive(this);
}
// Consider supporting a 'float' and converting to numerator/denominator
/// <include file='doc\EncoderParameter.uex' path='docs/doc[@for="EncoderParameter.EncoderParameter12"]/*' />
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
public EncoderParameter(Encoder encoder, int[] numerator, int[] denominator)
{
parameterGuid = encoder.Guid;
if (numerator.Length != denominator.Length)
throw SafeNativeMethods.Gdip.StatusException(SafeNativeMethods.Gdip.InvalidParameter);
parameterValueType = EncoderParameterValueType.ValueTypeRational;
numberOfValues = numerator.Length;
int size = Marshal.SizeOf(typeof(Int32));
parameterValue = Marshal.AllocHGlobal(checked(numberOfValues*2*size));
if (parameterValue == IntPtr.Zero)
throw SafeNativeMethods.Gdip.StatusException(SafeNativeMethods.Gdip.OutOfMemory);
for (int i=0; i<numberOfValues; i++)
{
Marshal.WriteInt32(Add(i*2*size, parameterValue), (int)numerator[i]);
Marshal.WriteInt32(Add((i*2+1)*size, parameterValue), (int)denominator[i]);
}
GC.KeepAlive(this);
}
// Consider supporting a 'float' and converting to numerator/denominator
/// <include file='doc\EncoderParameter.uex' path='docs/doc[@for="EncoderParameter.EncoderParameter13"]/*' />
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
public EncoderParameter(Encoder encoder, long[] rangebegin, long[] rangeend)
{
parameterGuid = encoder.Guid;
if (rangebegin.Length != rangeend.Length)
throw SafeNativeMethods.Gdip.StatusException(SafeNativeMethods.Gdip.InvalidParameter);
parameterValueType = EncoderParameterValueType.ValueTypeLongRange;
numberOfValues = rangebegin.Length;
int size = Marshal.SizeOf(typeof(Int32));
parameterValue = Marshal.AllocHGlobal(checked(numberOfValues*2*size));
if (parameterValue == IntPtr.Zero)
throw SafeNativeMethods.Gdip.StatusException(SafeNativeMethods.Gdip.OutOfMemory);
for (int i=0; i<numberOfValues; i++)
{
Marshal.WriteInt32(Add(i*2*size, parameterValue), unchecked((int)rangebegin[i]));
Marshal.WriteInt32(Add((i*2+1)*size, parameterValue), unchecked((int)rangeend[i]));
}
GC.KeepAlive(this);
}
// Consider supporting a 'float' and converting to numerator/denominator
/// <include file='doc\EncoderParameter.uex' path='docs/doc[@for="EncoderParameter.EncoderParameter14"]/*' />
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
public 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 SafeNativeMethods.Gdip.StatusException(SafeNativeMethods.Gdip.InvalidParameter);
parameterValueType = EncoderParameterValueType.ValueTypeRationalRange;
numberOfValues = numerator1.Length;
int size = Marshal.SizeOf(typeof(Int32));
parameterValue = Marshal.AllocHGlobal(checked(numberOfValues*4*size));
if (parameterValue == IntPtr.Zero)
throw SafeNativeMethods.Gdip.StatusException(SafeNativeMethods.Gdip.OutOfMemory);
for (int i=0; i<numberOfValues; i++)
{
Marshal.WriteInt32(Add(parameterValue, 4*i*size), numerator1[i]);
Marshal.WriteInt32(Add(parameterValue, (4*i+1)*size), denominator1[i]);
Marshal.WriteInt32(Add(parameterValue, (4*i+2)*size), numerator2[i]);
Marshal.WriteInt32(Add(parameterValue, (4*i+3)*size), denominator2[i]);
}
GC.KeepAlive(this);
}
// Consider supporting a 'float' and converting to numerator/denominator
/// <include file='doc\EncoderParameter.uex' path='docs/doc[@for="EncoderParameter.EncoderParameter15"]/*' />
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
[Obsolete("This constructor has been deprecated. Use EncoderParameter(Encoder encoder, int numberValues, EncoderParameterValueType type, IntPtr value) instead. http://go.microsoft.com/fwlink/?linkid=14202")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly")]
public EncoderParameter(Encoder encoder, int NumberOfValues, int Type, int Value)
{
int size;
IntSecurity.UnmanagedCode.Demand();
switch((EncoderParameterValueType)Type)
{
case EncoderParameterValueType.ValueTypeByte:
case EncoderParameterValueType.ValueTypeAscii: size = 1; break;
case EncoderParameterValueType.ValueTypeShort: size = 2; break;
case EncoderParameterValueType.ValueTypeLong: size = 4; break;
case EncoderParameterValueType.ValueTypeRational:
case EncoderParameterValueType.ValueTypeLongRange: size = 2*4; break;
case EncoderParameterValueType.ValueTypeUndefined: size = 1; break;
case EncoderParameterValueType.ValueTypeRationalRange: size = 2*2*4; break;
default:
throw SafeNativeMethods.Gdip.StatusException(SafeNativeMethods.Gdip.WrongState);
//
}
int bytes = checked(size*NumberOfValues);
parameterValue = Marshal.AllocHGlobal(bytes);
if (parameterValue == IntPtr.Zero)
throw SafeNativeMethods.Gdip.StatusException(SafeNativeMethods.Gdip.OutOfMemory);
for (int i=0; i<bytes; i++)
{
Marshal.WriteByte(Add(parameterValue, i), Marshal.ReadByte((IntPtr)(Value + i)));
}
parameterValueType = (EncoderParameterValueType)Type;
numberOfValues = NumberOfValues;
parameterGuid = encoder.Guid;
GC.KeepAlive(this);
}
/// <include file='doc\EncoderParameter.uex' path='docs/doc[@for="EncoderParameter.EncoderParameter16"]/*' />
/// <devdoc>
/// <para>[To be supplied.]</para>
/// </devdoc>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2004:RemoveCallsToGCKeepAlive")]
public EncoderParameter(Encoder encoder, int numberValues, EncoderParameterValueType type, IntPtr value)
{
int size;
IntSecurity.UnmanagedCode.Demand();
switch (type)
{
case EncoderParameterValueType.ValueTypeByte:
case EncoderParameterValueType.ValueTypeAscii: size = 1; break;
case EncoderParameterValueType.ValueTypeShort: size = 2; break;
case EncoderParameterValueType.ValueTypeLong: size = 4; break;
case EncoderParameterValueType.ValueTypeRational:
case EncoderParameterValueType.ValueTypeLongRange: size = 2 * 4; break;
case EncoderParameterValueType.ValueTypeUndefined: size = 1; break;
case EncoderParameterValueType.ValueTypeRationalRange: size = 2 * 2 * 4; break;
default:
throw SafeNativeMethods.Gdip.StatusException(SafeNativeMethods.Gdip.WrongState);
//
}
int bytes = checked(size * numberValues);
parameterValue = Marshal.AllocHGlobal(bytes);
if (parameterValue == IntPtr.Zero)
throw SafeNativeMethods.Gdip.StatusException(SafeNativeMethods.Gdip.OutOfMemory);
for (int i = 0; i < bytes; i++)
{
Marshal.WriteByte(Add(parameterValue, i), Marshal.ReadByte((IntPtr)(value + i)));
}
parameterValueType = type;
numberOfValues = numberValues;
parameterGuid = encoder.Guid;
GC.KeepAlive(this);
}
private static IntPtr Add(IntPtr a, int b) {
return (IntPtr) ((long)a + (long)b);
}
private static IntPtr Add(int a, IntPtr b) {
return (IntPtr) ((long)a + (long)b);
}
}
}
|