a575963da9
Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
350 lines
11 KiB
C#
350 lines
11 KiB
C#
//
|
|
// System.Drawing.Imaging.EncoderParameter.cs
|
|
//
|
|
// Author:
|
|
// Ravindra (rkumar@novell.com)
|
|
// Vladimir Vukicevic (vladimir@pobox.com)
|
|
//
|
|
// (C) 2004 Novell, Inc. http://www.novell.com
|
|
//
|
|
|
|
//
|
|
// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
|
|
//
|
|
// Permission is hereby granted, free of charge, to any person obtaining
|
|
// a copy of this software and associated documentation files (the
|
|
// "Software"), to deal in the Software without restriction, including
|
|
// without limitation the rights to use, copy, modify, merge, publish,
|
|
// distribute, sublicense, and/or sell copies of the Software, and to
|
|
// permit persons to whom the Software is furnished to do so, subject to
|
|
// the following conditions:
|
|
//
|
|
// The above copyright notice and this permission notice shall be
|
|
// included in all copies or substantial portions of the Software.
|
|
//
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
//
|
|
|
|
using System;
|
|
using System.Text;
|
|
|
|
using System.Runtime.InteropServices;
|
|
|
|
namespace System.Drawing.Imaging {
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
public sealed class EncoderParameter : IDisposable {
|
|
|
|
private Encoder encoder;
|
|
private int valuesCount;
|
|
private EncoderParameterValueType type;
|
|
private IntPtr valuePtr;
|
|
|
|
internal EncoderParameter ()
|
|
{
|
|
}
|
|
|
|
public EncoderParameter (Encoder encoder, byte value)
|
|
{
|
|
this.encoder = encoder;
|
|
this.valuesCount = 1;
|
|
this.type = EncoderParameterValueType.ValueTypeByte;
|
|
this.valuePtr = Marshal.AllocHGlobal (1);
|
|
Marshal.WriteByte (this.valuePtr, value);
|
|
}
|
|
|
|
public EncoderParameter (Encoder encoder, byte[] value)
|
|
{
|
|
this.encoder = encoder;
|
|
this.valuesCount = value.Length;
|
|
this.type = EncoderParameterValueType.ValueTypeByte;
|
|
this.valuePtr = Marshal.AllocHGlobal (1 * valuesCount);
|
|
Marshal.Copy (value, 0, this.valuePtr, valuesCount);
|
|
}
|
|
|
|
public EncoderParameter (Encoder encoder, short value)
|
|
{
|
|
this.encoder = encoder;
|
|
this.valuesCount = 1;
|
|
this.type = EncoderParameterValueType.ValueTypeShort;
|
|
this.valuePtr = Marshal.AllocHGlobal (2);
|
|
Marshal.WriteInt16 (this.valuePtr, value);
|
|
}
|
|
|
|
public EncoderParameter (Encoder encoder, short[] value)
|
|
{
|
|
this.encoder = encoder;
|
|
this.valuesCount = value.Length;
|
|
this.type = EncoderParameterValueType.ValueTypeShort;
|
|
this.valuePtr = Marshal.AllocHGlobal (2 * valuesCount);
|
|
Marshal.Copy (value, 0, this.valuePtr, valuesCount);
|
|
}
|
|
|
|
|
|
public EncoderParameter (Encoder encoder, long value)
|
|
{
|
|
this.encoder = encoder;
|
|
this.valuesCount = 1;
|
|
this.type = EncoderParameterValueType.ValueTypeLong;
|
|
this.valuePtr = Marshal.AllocHGlobal (4);
|
|
Marshal.WriteInt32 (this.valuePtr, (int) value);
|
|
}
|
|
|
|
public EncoderParameter (Encoder encoder, long[] value)
|
|
{
|
|
this.encoder = encoder;
|
|
this.valuesCount = value.Length;
|
|
this.type = EncoderParameterValueType.ValueTypeLong;
|
|
this.valuePtr = Marshal.AllocHGlobal (4 * valuesCount);
|
|
int [] ivals = new int[value.Length];
|
|
for (int i = 0; i < value.Length; i++) ivals[i] = (int) value[i];
|
|
Marshal.Copy (ivals, 0, this.valuePtr, valuesCount);
|
|
}
|
|
|
|
public EncoderParameter (Encoder encoder, string value)
|
|
{
|
|
this.encoder = encoder;
|
|
|
|
ASCIIEncoding ascii = new ASCIIEncoding ();
|
|
int asciiByteCount = ascii.GetByteCount (value);
|
|
byte[] bytes = new byte [asciiByteCount];
|
|
ascii.GetBytes (value, 0, value.Length, bytes, 0);
|
|
|
|
this.valuesCount = bytes.Length;
|
|
this.type = EncoderParameterValueType.ValueTypeAscii;
|
|
this.valuePtr = Marshal.AllocHGlobal (valuesCount);
|
|
Marshal.Copy (bytes, 0, this.valuePtr, valuesCount);
|
|
}
|
|
|
|
public EncoderParameter (Encoder encoder, byte value, bool undefined)
|
|
{
|
|
this.encoder = encoder;
|
|
this.valuesCount = 1;
|
|
if (undefined)
|
|
this.type = EncoderParameterValueType.ValueTypeUndefined;
|
|
else
|
|
this.type = EncoderParameterValueType.ValueTypeByte;
|
|
this.valuePtr = Marshal.AllocHGlobal (1);
|
|
Marshal.WriteByte (this.valuePtr, value);
|
|
}
|
|
|
|
public EncoderParameter (Encoder encoder, byte[] value, bool undefined)
|
|
{
|
|
this.encoder = encoder;
|
|
this.valuesCount = value.Length;
|
|
if (undefined)
|
|
this.type = EncoderParameterValueType.ValueTypeUndefined;
|
|
else
|
|
this.type = EncoderParameterValueType.ValueTypeByte;
|
|
this.valuePtr = Marshal.AllocHGlobal (valuesCount);
|
|
Marshal.Copy (value, 0, this.valuePtr, valuesCount);
|
|
}
|
|
|
|
public EncoderParameter (Encoder encoder, int numerator, int denominator)
|
|
{
|
|
this.encoder = encoder;
|
|
this.valuesCount = 1;
|
|
this.type = EncoderParameterValueType.ValueTypeRational;
|
|
this.valuePtr = Marshal.AllocHGlobal (8);
|
|
int [] valuearray = { numerator, denominator };
|
|
Marshal.Copy (valuearray, 0, this.valuePtr, valuearray.Length);
|
|
}
|
|
|
|
public EncoderParameter (Encoder encoder, int[] numerator, int[] denominator)
|
|
{
|
|
if (numerator.Length != denominator.Length)
|
|
throw new ArgumentException ("Invalid parameter used.");
|
|
|
|
this.encoder = encoder;
|
|
this.valuesCount = numerator.Length;
|
|
this.type = EncoderParameterValueType.ValueTypeRational;
|
|
this.valuePtr = Marshal.AllocHGlobal (4 * valuesCount * 2);
|
|
for (int i = 0; i < valuesCount; i++) {
|
|
Marshal.WriteInt32 (valuePtr, i * 4, (int) numerator[i]);
|
|
Marshal.WriteInt32 (valuePtr, (i + 1) * 4, (int) denominator[i]);
|
|
}
|
|
}
|
|
|
|
public EncoderParameter (Encoder encoder, long rangebegin, long rangeend)
|
|
{
|
|
this.encoder = encoder;
|
|
this.valuesCount = 1;
|
|
this.type = EncoderParameterValueType.ValueTypeLongRange;
|
|
this.valuePtr = Marshal.AllocHGlobal (8);
|
|
int [] valuearray = { (int) rangebegin, (int) rangeend };
|
|
Marshal.Copy (valuearray, 0, this.valuePtr, valuearray.Length);
|
|
}
|
|
|
|
public EncoderParameter (Encoder encoder, long[] rangebegin, long[] rangeend)
|
|
{
|
|
if (rangebegin.Length != rangeend.Length)
|
|
throw new ArgumentException ("Invalid parameter used.");
|
|
|
|
this.encoder = encoder;
|
|
this.valuesCount = rangebegin.Length;
|
|
this.type = EncoderParameterValueType.ValueTypeLongRange;
|
|
|
|
this.valuePtr = Marshal.AllocHGlobal (4 * valuesCount * 2);
|
|
IntPtr dest = this.valuePtr;
|
|
for (int i = 0; i < valuesCount; i++) {
|
|
Marshal.WriteInt32 (dest, i * 4, (int) rangebegin[i]);
|
|
Marshal.WriteInt32 (dest, (i + 1) * 4, (int) rangeend[i]);
|
|
}
|
|
}
|
|
|
|
public EncoderParameter (Encoder encoder, int numberOfValues, int type, int value)
|
|
{
|
|
this.encoder = encoder;
|
|
this.valuePtr = (IntPtr) value;
|
|
this.valuesCount = numberOfValues;
|
|
this.type = (EncoderParameterValueType) type;
|
|
}
|
|
|
|
public EncoderParameter (Encoder encoder, int numerator1, int denominator1, int numerator2, int denominator2)
|
|
{
|
|
this.encoder = encoder;
|
|
this.valuesCount = 1;
|
|
this.type = EncoderParameterValueType.ValueTypeRationalRange;
|
|
this.valuePtr = Marshal.AllocHGlobal (4 * 4);
|
|
int [] valuearray = { numerator1, denominator1, numerator2, denominator2 };
|
|
Marshal.Copy (valuearray, 0, this.valuePtr, 4);
|
|
}
|
|
|
|
public EncoderParameter (Encoder encoder, int[] numerator1, int[] denominator1, int[] numerator2, int[] denominator2)
|
|
{
|
|
if (numerator1.Length != denominator1.Length ||
|
|
numerator2.Length != denominator2.Length ||
|
|
numerator1.Length != numerator2.Length)
|
|
throw new ArgumentException ("Invalid parameter used.");
|
|
|
|
this.encoder = encoder;
|
|
this.valuesCount = numerator1.Length;
|
|
this.type = EncoderParameterValueType.ValueTypeRationalRange;
|
|
|
|
this.valuePtr = Marshal.AllocHGlobal (4 * valuesCount * 4);
|
|
IntPtr dest = this.valuePtr;
|
|
for (int i = 0; i < valuesCount; i++) {
|
|
Marshal.WriteInt32 (dest, i * 4, numerator1[i]);
|
|
Marshal.WriteInt32 (dest, (i + 1) * 4, denominator1[i]);
|
|
Marshal.WriteInt32 (dest, (i + 2) * 4, numerator2[i]);
|
|
Marshal.WriteInt32 (dest, (i + 3) * 4, denominator2[i]);
|
|
}
|
|
}
|
|
|
|
public Encoder Encoder {
|
|
get {
|
|
return encoder;
|
|
}
|
|
|
|
set {
|
|
encoder = value;
|
|
}
|
|
}
|
|
|
|
public int NumberOfValues {
|
|
get {
|
|
return valuesCount;
|
|
}
|
|
}
|
|
|
|
public EncoderParameterValueType Type {
|
|
get {
|
|
return type;
|
|
}
|
|
}
|
|
|
|
public EncoderParameterValueType ValueType {
|
|
get {
|
|
return type;
|
|
}
|
|
}
|
|
|
|
void Dispose (bool disposing) {
|
|
if (valuePtr != IntPtr.Zero) {
|
|
Marshal.FreeHGlobal (valuePtr);
|
|
valuePtr = IntPtr.Zero;
|
|
}
|
|
}
|
|
|
|
public void Dispose () {
|
|
Dispose (true);
|
|
GC.SuppressFinalize(this);
|
|
}
|
|
|
|
~EncoderParameter () {
|
|
Dispose (false);
|
|
}
|
|
|
|
internal static int NativeSize () {
|
|
return Marshal.SizeOf (typeof(GdipEncoderParameter));
|
|
}
|
|
|
|
internal void ToNativePtr (IntPtr epPtr) {
|
|
GdipEncoderParameter ep = new GdipEncoderParameter ();
|
|
ep.guid = this.encoder.Guid;
|
|
ep.numberOfValues = (uint) this.valuesCount;
|
|
ep.type = this.type;
|
|
ep.value = this.valuePtr;
|
|
Marshal.StructureToPtr (ep, epPtr, false);
|
|
}
|
|
|
|
internal static EncoderParameter FromNativePtr (IntPtr epPtr) {
|
|
GdipEncoderParameter ep;
|
|
ep = (GdipEncoderParameter) Marshal.PtrToStructure (epPtr, typeof(GdipEncoderParameter));
|
|
|
|
Type valType;
|
|
uint valCount;
|
|
|
|
switch (ep.type) {
|
|
case EncoderParameterValueType.ValueTypeAscii:
|
|
case EncoderParameterValueType.ValueTypeByte:
|
|
case EncoderParameterValueType.ValueTypeUndefined:
|
|
valType = typeof(byte);
|
|
valCount = ep.numberOfValues;
|
|
break;
|
|
case EncoderParameterValueType.ValueTypeShort:
|
|
valType = typeof(short);
|
|
valCount = ep.numberOfValues;
|
|
break;
|
|
case EncoderParameterValueType.ValueTypeLong:
|
|
valType = typeof(int);
|
|
valCount = ep.numberOfValues;
|
|
break;
|
|
case EncoderParameterValueType.ValueTypeLongRange:
|
|
case EncoderParameterValueType.ValueTypeRational:
|
|
valType = typeof(int);
|
|
valCount = ep.numberOfValues * 2;
|
|
break;
|
|
case EncoderParameterValueType.ValueTypeRationalRange:
|
|
valType = typeof(int);
|
|
valCount = ep.numberOfValues * 4;
|
|
break;
|
|
default:
|
|
return null;
|
|
}
|
|
|
|
EncoderParameter eparam = new EncoderParameter();
|
|
eparam.encoder = new Encoder(ep.guid);
|
|
eparam.valuesCount = (int) ep.numberOfValues;
|
|
eparam.type = ep.type;
|
|
eparam.valuePtr = Marshal.AllocHGlobal ((int)(valCount * Marshal.SizeOf(valType)));
|
|
|
|
/* There's nothing in Marshal to do a memcpy() between two IntPtrs. This sucks. */
|
|
unsafe {
|
|
byte *s = (byte *) ep.value;
|
|
byte *d = (byte *) eparam.valuePtr;
|
|
for (int i = 0; i < valCount * Marshal.SizeOf(valType); i++)
|
|
*d++ = *s++;
|
|
}
|
|
|
|
return eparam;
|
|
}
|
|
}
|
|
}
|