2 // System.Drawing.Imaging.EncoderParameter.cs
5 // Ravindra (rkumar@novell.com)
6 // Vladimir Vukicevic (vladimir@pobox.com)
8 // (C) 2004 Novell, Inc. http://www.novell.com
14 using System.Runtime.InteropServices;
16 namespace System.Drawing.Imaging {
18 public sealed class EncoderParameter : IDisposable {
20 private Encoder encoder;
21 private int valuesCount;
22 private EncoderParameterValueType type;
23 private IntPtr valuePtr;
25 internal EncoderParameter ()
29 public EncoderParameter (Encoder encoder, byte value)
31 this.encoder = encoder;
33 this.type = EncoderParameterValueType.ValueTypeByte;
34 this.valuePtr = Marshal.AllocHGlobal (1);
35 Marshal.WriteByte (this.valuePtr, value);
38 public EncoderParameter (Encoder encoder, byte[] value)
40 this.encoder = encoder;
41 this.valuesCount = value.Length;
42 this.type = EncoderParameterValueType.ValueTypeByte;
43 this.valuePtr = Marshal.AllocHGlobal (1 * valuesCount);
44 Marshal.Copy (value, 0, this.valuePtr, valuesCount);
47 public EncoderParameter (Encoder encoder, short value)
49 this.encoder = encoder;
51 this.type = EncoderParameterValueType.ValueTypeShort;
52 this.valuePtr = Marshal.AllocHGlobal (2);
53 Marshal.WriteInt16 (this.valuePtr, value);
56 public EncoderParameter (Encoder encoder, short[] value)
58 this.encoder = encoder;
59 this.valuesCount = value.Length;
60 this.type = EncoderParameterValueType.ValueTypeShort;
61 this.valuePtr = Marshal.AllocHGlobal (2 * valuesCount);
62 Marshal.Copy (value, 0, this.valuePtr, valuesCount);
66 public EncoderParameter (Encoder encoder, long value)
68 this.encoder = encoder;
70 this.type = EncoderParameterValueType.ValueTypeLong;
71 this.valuePtr = Marshal.AllocHGlobal (4);
72 Marshal.WriteInt32 (this.valuePtr, (int) value);
75 public EncoderParameter (Encoder encoder, long[] value)
77 this.encoder = encoder;
78 this.valuesCount = value.Length;
79 this.type = EncoderParameterValueType.ValueTypeLong;
80 this.valuePtr = Marshal.AllocHGlobal (4 * valuesCount);
81 int [] ivals = new int[value.Length];
82 for (int i = 0; i < value.Length; i++) ivals[i] = (int) value[i];
83 Marshal.Copy (ivals, 0, this.valuePtr, valuesCount);
86 public EncoderParameter (Encoder encoder, string value)
88 this.encoder = encoder;
90 ASCIIEncoding ascii = new ASCIIEncoding ();
91 int asciiByteCount = ascii.GetByteCount (value);
92 byte[] bytes = new byte [asciiByteCount];
93 ascii.GetBytes (value, 0, value.Length, bytes, 0);
95 this.valuesCount = bytes.Length;
96 this.type = EncoderParameterValueType.ValueTypeAscii;
97 this.valuePtr = Marshal.AllocHGlobal (valuesCount);
98 Marshal.Copy (bytes, 0, this.valuePtr, valuesCount);
101 public EncoderParameter (Encoder encoder, byte value, bool undefined)
103 this.encoder = encoder;
104 this.valuesCount = 1;
106 this.type = EncoderParameterValueType.ValueTypeUndefined;
108 this.type = EncoderParameterValueType.ValueTypeByte;
109 this.valuePtr = Marshal.AllocHGlobal (1);
110 Marshal.WriteByte (this.valuePtr, value);
113 public EncoderParameter (Encoder encoder, byte[] value, bool undefined)
115 this.encoder = encoder;
116 this.valuesCount = value.Length;
118 this.type = EncoderParameterValueType.ValueTypeUndefined;
120 this.type = EncoderParameterValueType.ValueTypeByte;
121 this.valuePtr = Marshal.AllocHGlobal (valuesCount);
122 Marshal.Copy (value, 0, this.valuePtr, valuesCount);
125 public EncoderParameter (Encoder encoder, int numerator, int denominator)
127 this.encoder = encoder;
128 this.valuesCount = 1;
129 this.type = EncoderParameterValueType.ValueTypeRational;
130 this.valuePtr = Marshal.AllocHGlobal (8);
131 int [] valuearray = { numerator, denominator };
132 Marshal.Copy (valuearray, 0, this.valuePtr, valuearray.Length);
135 public EncoderParameter (Encoder encoder, int[] numerator, int[] denominator)
137 if (numerator.Length != denominator.Length)
138 throw new ArgumentException ("Invalid parameter used.");
140 this.encoder = encoder;
141 this.valuesCount = numerator.Length;
142 this.type = EncoderParameterValueType.ValueTypeRational;
143 this.valuePtr = Marshal.AllocHGlobal (4 * valuesCount * 2);
144 IntPtr dest = this.valuePtr;
145 for (int i = 0; i < valuesCount; i++) {
146 Marshal.WriteInt32 (dest, (int) numerator[i]);
147 dest = (IntPtr) ((int) dest + 4);
148 Marshal.WriteInt32 (dest, (int) denominator[i]);
149 dest = (IntPtr) ((int) dest + 4);
153 public EncoderParameter (Encoder encoder, long rangebegin, long rangeend)
155 this.encoder = encoder;
156 this.valuesCount = 1;
157 this.type = EncoderParameterValueType.ValueTypeLongRange;
158 this.valuePtr = Marshal.AllocHGlobal (8);
159 int [] valuearray = { (int) rangebegin, (int) rangeend };
160 Marshal.Copy (valuearray, 0, this.valuePtr, valuearray.Length);
163 public EncoderParameter (Encoder encoder, long[] rangebegin, long[] rangeend)
165 if (rangebegin.Length != rangeend.Length)
166 throw new ArgumentException ("Invalid parameter used.");
168 this.encoder = encoder;
169 this.valuesCount = rangebegin.Length;
170 this.type = EncoderParameterValueType.ValueTypeLongRange;
172 this.valuePtr = Marshal.AllocHGlobal (4 * valuesCount * 2);
173 IntPtr dest = this.valuePtr;
174 for (int i = 0; i < valuesCount; i++) {
175 Marshal.WriteInt32 (dest, (int) rangebegin[i]);
176 dest = (IntPtr) ((int) dest + 4);
177 Marshal.WriteInt32 (dest, (int) rangeend[i]);
178 dest = (IntPtr) ((int) dest + 4);
182 public EncoderParameter (Encoder encoder, int numberOfValues, int type, int value)
184 this.encoder = encoder;
185 this.valuePtr = (IntPtr) value;
186 this.valuesCount = numberOfValues;
187 this.type = (EncoderParameterValueType) type;
190 public EncoderParameter (Encoder encoder, int numerator1, int denominator1, int numerator2, int denominator2)
192 this.encoder = encoder;
193 this.valuesCount = 1;
194 this.type = EncoderParameterValueType.ValueTypeRationalRange;
195 this.valuePtr = Marshal.AllocHGlobal (4 * 4);
196 int [] valuearray = { numerator1, denominator1, numerator2, denominator2 };
197 Marshal.Copy (valuearray, 0, this.valuePtr, 4);
200 public EncoderParameter (Encoder encoder, int[] numerator1, int[] denominator1, int[] numerator2, int[] denominator2)
202 if (numerator1.Length != denominator1.Length ||
203 numerator2.Length != denominator2.Length ||
204 numerator1.Length != numerator2.Length)
205 throw new ArgumentException ("Invalid parameter used.");
207 this.encoder = encoder;
208 this.valuesCount = numerator1.Length;
209 this.type = EncoderParameterValueType.ValueTypeRationalRange;
211 this.valuePtr = Marshal.AllocHGlobal (4 * valuesCount * 4);
212 IntPtr dest = this.valuePtr;
213 for (int i = 0; i < valuesCount; i++) {
214 Marshal.WriteInt32 (dest, numerator1[i]);
215 dest = (IntPtr) ((int) dest + 4);
216 Marshal.WriteInt32 (dest, denominator1[i]);
217 dest = (IntPtr) ((int) dest + 4);
218 Marshal.WriteInt32 (dest, numerator2[i]);
219 dest = (IntPtr) ((int) dest + 4);
220 Marshal.WriteInt32 (dest, denominator2[i]);
221 dest = (IntPtr) ((int) dest + 4);
225 public Encoder Encoder {
235 public int NumberOfValues {
241 public EncoderParameterValueType Type {
247 public EncoderParameterValueType ValueType {
253 void Dispose (bool disposing) {
254 if (valuePtr != IntPtr.Zero) {
255 Marshal.FreeHGlobal (valuePtr);
256 valuePtr = IntPtr.Zero;
260 public void Dispose () {
264 ~EncoderParameter () {
268 internal static int NativeSize () {
269 return Marshal.SizeOf (typeof(GdipEncoderParameter));
272 internal void ToNativePtr (IntPtr epPtr) {
273 GdipEncoderParameter ep = new GdipEncoderParameter ();
274 ep.guid = this.encoder.Guid;
275 ep.numberOfValues = (uint) this.valuesCount;
277 ep.value = this.valuePtr;
278 Marshal.StructureToPtr (ep, epPtr, false);
281 internal static EncoderParameter FromNativePtr (IntPtr epPtr) {
282 GdipEncoderParameter ep;
283 ep = (GdipEncoderParameter) Marshal.PtrToStructure (epPtr, typeof(GdipEncoderParameter));
289 case EncoderParameterValueType.ValueTypeAscii:
290 case EncoderParameterValueType.ValueTypeByte:
291 case EncoderParameterValueType.ValueTypeUndefined:
292 valType = typeof(byte);
293 valCount = ep.numberOfValues;
295 case EncoderParameterValueType.ValueTypeShort:
296 valType = typeof(short);
297 valCount = ep.numberOfValues;
299 case EncoderParameterValueType.ValueTypeLong:
300 valType = typeof(int);
301 valCount = ep.numberOfValues;
303 case EncoderParameterValueType.ValueTypeLongRange:
304 case EncoderParameterValueType.ValueTypeRational:
305 valType = typeof(int);
306 valCount = ep.numberOfValues * 2;
308 case EncoderParameterValueType.ValueTypeRationalRange:
309 valType = typeof(int);
310 valCount = ep.numberOfValues * 4;
316 EncoderParameter eparam = new EncoderParameter();
317 eparam.encoder = new Encoder(ep.guid);
318 eparam.valuesCount = (int) ep.numberOfValues;
319 eparam.type = ep.type;
320 eparam.valuePtr = Marshal.AllocHGlobal ((int)(valCount * Marshal.SizeOf(valType)));
322 /* There's nothing in Marshal to do a memcpy() between two IntPtrs. This sucks. */
324 byte *s = (byte *) ep.value;
325 byte *d = (byte *) eparam.valuePtr;
326 for (int i = 0; i < valCount * Marshal.SizeOf(valType); i++)