**** Merged from MCS ****
[mono-project.git] / mcs / class / System.Drawing / System.Drawing.Imaging / EncoderParameter.cs
blobdaa79d97ca3bc8ec8acdc3bde48683f51f99c7cb
1 //
2 // System.Drawing.Imaging.EncoderParameter.cs
3 //
4 // Author:
5 // Ravindra (rkumar@novell.com)
6 // Vladimir Vukicevic (vladimir@pobox.com)
7 //
8 // (C) 2004 Novell, Inc. http://www.novell.com
9 //
12 // Copyright (C) 2004 Novell, Inc (http://www.novell.com)
14 // Permission is hereby granted, free of charge, to any person obtaining
15 // a copy of this software and associated documentation files (the
16 // "Software"), to deal in the Software without restriction, including
17 // without limitation the rights to use, copy, modify, merge, publish,
18 // distribute, sublicense, and/or sell copies of the Software, and to
19 // permit persons to whom the Software is furnished to do so, subject to
20 // the following conditions:
21 //
22 // The above copyright notice and this permission notice shall be
23 // included in all copies or substantial portions of the Software.
24 //
25 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
29 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
30 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
31 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
34 using System;
35 using System.Text;
37 using System.Runtime.InteropServices;
39 namespace System.Drawing.Imaging {
41 public sealed class EncoderParameter : IDisposable {
43 private Encoder encoder;
44 private int valuesCount;
45 private EncoderParameterValueType type;
46 private IntPtr valuePtr;
48 internal EncoderParameter ()
52 public EncoderParameter (Encoder encoder, byte value)
54 this.encoder = encoder;
55 this.valuesCount = 1;
56 this.type = EncoderParameterValueType.ValueTypeByte;
57 this.valuePtr = Marshal.AllocHGlobal (1);
58 Marshal.WriteByte (this.valuePtr, value);
61 public EncoderParameter (Encoder encoder, byte[] value)
63 this.encoder = encoder;
64 this.valuesCount = value.Length;
65 this.type = EncoderParameterValueType.ValueTypeByte;
66 this.valuePtr = Marshal.AllocHGlobal (1 * valuesCount);
67 Marshal.Copy (value, 0, this.valuePtr, valuesCount);
70 public EncoderParameter (Encoder encoder, short value)
72 this.encoder = encoder;
73 this.valuesCount = 1;
74 this.type = EncoderParameterValueType.ValueTypeShort;
75 this.valuePtr = Marshal.AllocHGlobal (2);
76 Marshal.WriteInt16 (this.valuePtr, value);
79 public EncoderParameter (Encoder encoder, short[] value)
81 this.encoder = encoder;
82 this.valuesCount = value.Length;
83 this.type = EncoderParameterValueType.ValueTypeShort;
84 this.valuePtr = Marshal.AllocHGlobal (2 * valuesCount);
85 Marshal.Copy (value, 0, this.valuePtr, valuesCount);
89 public EncoderParameter (Encoder encoder, long value)
91 this.encoder = encoder;
92 this.valuesCount = 1;
93 this.type = EncoderParameterValueType.ValueTypeLong;
94 this.valuePtr = Marshal.AllocHGlobal (4);
95 Marshal.WriteInt32 (this.valuePtr, (int) value);
98 public EncoderParameter (Encoder encoder, long[] value)
100 this.encoder = encoder;
101 this.valuesCount = value.Length;
102 this.type = EncoderParameterValueType.ValueTypeLong;
103 this.valuePtr = Marshal.AllocHGlobal (4 * valuesCount);
104 int [] ivals = new int[value.Length];
105 for (int i = 0; i < value.Length; i++) ivals[i] = (int) value[i];
106 Marshal.Copy (ivals, 0, this.valuePtr, valuesCount);
109 public EncoderParameter (Encoder encoder, string value)
111 this.encoder = encoder;
113 ASCIIEncoding ascii = new ASCIIEncoding ();
114 int asciiByteCount = ascii.GetByteCount (value);
115 byte[] bytes = new byte [asciiByteCount];
116 ascii.GetBytes (value, 0, value.Length, bytes, 0);
118 this.valuesCount = bytes.Length;
119 this.type = EncoderParameterValueType.ValueTypeAscii;
120 this.valuePtr = Marshal.AllocHGlobal (valuesCount);
121 Marshal.Copy (bytes, 0, this.valuePtr, valuesCount);
124 public EncoderParameter (Encoder encoder, byte value, bool undefined)
126 this.encoder = encoder;
127 this.valuesCount = 1;
128 if (undefined)
129 this.type = EncoderParameterValueType.ValueTypeUndefined;
130 else
131 this.type = EncoderParameterValueType.ValueTypeByte;
132 this.valuePtr = Marshal.AllocHGlobal (1);
133 Marshal.WriteByte (this.valuePtr, value);
136 public EncoderParameter (Encoder encoder, byte[] value, bool undefined)
138 this.encoder = encoder;
139 this.valuesCount = value.Length;
140 if (undefined)
141 this.type = EncoderParameterValueType.ValueTypeUndefined;
142 else
143 this.type = EncoderParameterValueType.ValueTypeByte;
144 this.valuePtr = Marshal.AllocHGlobal (valuesCount);
145 Marshal.Copy (value, 0, this.valuePtr, valuesCount);
148 public EncoderParameter (Encoder encoder, int numerator, int denominator)
150 this.encoder = encoder;
151 this.valuesCount = 1;
152 this.type = EncoderParameterValueType.ValueTypeRational;
153 this.valuePtr = Marshal.AllocHGlobal (8);
154 int [] valuearray = { numerator, denominator };
155 Marshal.Copy (valuearray, 0, this.valuePtr, valuearray.Length);
158 public EncoderParameter (Encoder encoder, int[] numerator, int[] denominator)
160 if (numerator.Length != denominator.Length)
161 throw new ArgumentException ("Invalid parameter used.");
163 this.encoder = encoder;
164 this.valuesCount = numerator.Length;
165 this.type = EncoderParameterValueType.ValueTypeRational;
166 this.valuePtr = Marshal.AllocHGlobal (4 * valuesCount * 2);
167 IntPtr dest = this.valuePtr;
168 for (int i = 0; i < valuesCount; i++) {
169 Marshal.WriteInt32 (dest, (int) numerator[i]);
170 dest = (IntPtr) ((int) dest + 4);
171 Marshal.WriteInt32 (dest, (int) denominator[i]);
172 dest = (IntPtr) ((int) dest + 4);
176 public EncoderParameter (Encoder encoder, long rangebegin, long rangeend)
178 this.encoder = encoder;
179 this.valuesCount = 1;
180 this.type = EncoderParameterValueType.ValueTypeLongRange;
181 this.valuePtr = Marshal.AllocHGlobal (8);
182 int [] valuearray = { (int) rangebegin, (int) rangeend };
183 Marshal.Copy (valuearray, 0, this.valuePtr, valuearray.Length);
186 public EncoderParameter (Encoder encoder, long[] rangebegin, long[] rangeend)
188 if (rangebegin.Length != rangeend.Length)
189 throw new ArgumentException ("Invalid parameter used.");
191 this.encoder = encoder;
192 this.valuesCount = rangebegin.Length;
193 this.type = EncoderParameterValueType.ValueTypeLongRange;
195 this.valuePtr = Marshal.AllocHGlobal (4 * valuesCount * 2);
196 IntPtr dest = this.valuePtr;
197 for (int i = 0; i < valuesCount; i++) {
198 Marshal.WriteInt32 (dest, (int) rangebegin[i]);
199 dest = (IntPtr) ((int) dest + 4);
200 Marshal.WriteInt32 (dest, (int) rangeend[i]);
201 dest = (IntPtr) ((int) dest + 4);
205 public EncoderParameter (Encoder encoder, int numberOfValues, int type, int value)
207 this.encoder = encoder;
208 this.valuePtr = (IntPtr) value;
209 this.valuesCount = numberOfValues;
210 this.type = (EncoderParameterValueType) type;
213 public EncoderParameter (Encoder encoder, int numerator1, int denominator1, int numerator2, int denominator2)
215 this.encoder = encoder;
216 this.valuesCount = 1;
217 this.type = EncoderParameterValueType.ValueTypeRationalRange;
218 this.valuePtr = Marshal.AllocHGlobal (4 * 4);
219 int [] valuearray = { numerator1, denominator1, numerator2, denominator2 };
220 Marshal.Copy (valuearray, 0, this.valuePtr, 4);
223 public EncoderParameter (Encoder encoder, int[] numerator1, int[] denominator1, int[] numerator2, int[] denominator2)
225 if (numerator1.Length != denominator1.Length ||
226 numerator2.Length != denominator2.Length ||
227 numerator1.Length != numerator2.Length)
228 throw new ArgumentException ("Invalid parameter used.");
230 this.encoder = encoder;
231 this.valuesCount = numerator1.Length;
232 this.type = EncoderParameterValueType.ValueTypeRationalRange;
234 this.valuePtr = Marshal.AllocHGlobal (4 * valuesCount * 4);
235 IntPtr dest = this.valuePtr;
236 for (int i = 0; i < valuesCount; i++) {
237 Marshal.WriteInt32 (dest, numerator1[i]);
238 dest = (IntPtr) ((int) dest + 4);
239 Marshal.WriteInt32 (dest, denominator1[i]);
240 dest = (IntPtr) ((int) dest + 4);
241 Marshal.WriteInt32 (dest, numerator2[i]);
242 dest = (IntPtr) ((int) dest + 4);
243 Marshal.WriteInt32 (dest, denominator2[i]);
244 dest = (IntPtr) ((int) dest + 4);
248 public Encoder Encoder {
249 get {
250 return encoder;
253 set {
254 encoder = value;
258 public int NumberOfValues {
259 get {
260 return valuesCount;
264 public EncoderParameterValueType Type {
265 get {
266 return type;
270 public EncoderParameterValueType ValueType {
271 get {
272 return type;
276 void Dispose (bool disposing) {
277 if (valuePtr != IntPtr.Zero) {
278 Marshal.FreeHGlobal (valuePtr);
279 valuePtr = IntPtr.Zero;
283 public void Dispose () {
284 Dispose (true);
287 ~EncoderParameter () {
288 Dispose (false);
291 internal static int NativeSize () {
292 return Marshal.SizeOf (typeof(GdipEncoderParameter));
295 internal void ToNativePtr (IntPtr epPtr) {
296 GdipEncoderParameter ep = new GdipEncoderParameter ();
297 ep.guid = this.encoder.Guid;
298 ep.numberOfValues = (uint) this.valuesCount;
299 ep.type = this.type;
300 ep.value = this.valuePtr;
301 Marshal.StructureToPtr (ep, epPtr, false);
304 internal static EncoderParameter FromNativePtr (IntPtr epPtr) {
305 GdipEncoderParameter ep;
306 ep = (GdipEncoderParameter) Marshal.PtrToStructure (epPtr, typeof(GdipEncoderParameter));
308 Type valType;
309 uint valCount;
311 switch (ep.type) {
312 case EncoderParameterValueType.ValueTypeAscii:
313 case EncoderParameterValueType.ValueTypeByte:
314 case EncoderParameterValueType.ValueTypeUndefined:
315 valType = typeof(byte);
316 valCount = ep.numberOfValues;
317 break;
318 case EncoderParameterValueType.ValueTypeShort:
319 valType = typeof(short);
320 valCount = ep.numberOfValues;
321 break;
322 case EncoderParameterValueType.ValueTypeLong:
323 valType = typeof(int);
324 valCount = ep.numberOfValues;
325 break;
326 case EncoderParameterValueType.ValueTypeLongRange:
327 case EncoderParameterValueType.ValueTypeRational:
328 valType = typeof(int);
329 valCount = ep.numberOfValues * 2;
330 break;
331 case EncoderParameterValueType.ValueTypeRationalRange:
332 valType = typeof(int);
333 valCount = ep.numberOfValues * 4;
334 break;
335 default:
336 return null;
339 EncoderParameter eparam = new EncoderParameter();
340 eparam.encoder = new Encoder(ep.guid);
341 eparam.valuesCount = (int) ep.numberOfValues;
342 eparam.type = ep.type;
343 eparam.valuePtr = Marshal.AllocHGlobal ((int)(valCount * Marshal.SizeOf(valType)));
345 /* There's nothing in Marshal to do a memcpy() between two IntPtrs. This sucks. */
346 unsafe {
347 byte *s = (byte *) ep.value;
348 byte *d = (byte *) eparam.valuePtr;
349 for (int i = 0; i < valCount * Marshal.SizeOf(valType); i++)
350 *d++ = *s++;
353 return eparam;