* EncoderParameterValueType.cs: fix Windows build (CSC),
[mono.git] / mcs / class / System.Drawing / System.Drawing.Imaging / EncoderParameter.cs
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 //
10
11 using System;
12 using System.Text;
13
14 using System.Runtime.InteropServices;
15
16 namespace System.Drawing.Imaging {
17
18         public sealed class EncoderParameter : IDisposable {
19
20                 private Encoder encoder;
21                 private int valuesCount;
22                 private EncoderParameterValueType type;
23                 private IntPtr valuePtr;
24
25                 internal EncoderParameter ()
26                 {
27                 }
28
29                 public EncoderParameter (Encoder encoder, byte value)
30                 {
31                         this.encoder = encoder;
32                         this.valuesCount = 1;
33                         this.type = EncoderParameterValueType.ValueTypeByte;
34                         this.valuePtr = Marshal.AllocHGlobal (1);
35                         Marshal.WriteByte (this.valuePtr, value);
36                 }
37
38                 public EncoderParameter (Encoder encoder, byte[] value)
39                 {
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);
45                 }
46
47                 public EncoderParameter (Encoder encoder, short value)
48                 {
49                         this.encoder = encoder;
50                         this.valuesCount = 1;
51                         this.type = EncoderParameterValueType.ValueTypeShort;
52                         this.valuePtr = Marshal.AllocHGlobal (2);
53                         Marshal.WriteInt16 (this.valuePtr, value);
54                 }
55
56                 public EncoderParameter (Encoder encoder, short[] value)
57                 {
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);
63                 }
64
65
66                 public EncoderParameter (Encoder encoder, long value)
67                 {
68                         this.encoder = encoder;
69                         this.valuesCount = 1;
70                         this.type = EncoderParameterValueType.ValueTypeLong;
71                         this.valuePtr = Marshal.AllocHGlobal (4);
72                         Marshal.WriteInt32 (this.valuePtr, (int) value);
73                 }
74
75                 public EncoderParameter (Encoder encoder, long[] value)
76                 {
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);
84                 }
85
86                 public EncoderParameter (Encoder encoder, string value)
87                 {
88                         this.encoder = encoder;
89
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);
94
95                         this.valuesCount = bytes.Length;
96                         this.type = EncoderParameterValueType.ValueTypeAscii;
97                         this.valuePtr = Marshal.AllocHGlobal (valuesCount);
98                         Marshal.Copy (bytes, 0, this.valuePtr, valuesCount);
99                 }
100
101                 public EncoderParameter (Encoder encoder, byte value, bool undefined)
102                 {
103                         this.encoder = encoder;
104                         this.valuesCount = 1;
105                         if (undefined)
106                                 this.type = EncoderParameterValueType.ValueTypeUndefined;
107                         else
108                                 this.type = EncoderParameterValueType.ValueTypeByte;
109                         this.valuePtr = Marshal.AllocHGlobal (1);
110                         Marshal.WriteByte (this.valuePtr, value);
111                 }
112
113                 public EncoderParameter (Encoder encoder, byte[] value, bool undefined)
114                 {
115                         this.encoder = encoder;
116                         this.valuesCount = value.Length;
117                         if (undefined)
118                                 this.type = EncoderParameterValueType.ValueTypeUndefined;
119                         else
120                                 this.type = EncoderParameterValueType.ValueTypeByte;
121                         this.valuePtr = Marshal.AllocHGlobal (valuesCount);
122                         Marshal.Copy (value, 0, this.valuePtr, valuesCount);
123                 }
124
125                 public EncoderParameter (Encoder encoder, int numerator, int denominator)
126                 {
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);
133                 }
134
135                 public EncoderParameter (Encoder encoder, int[] numerator, int[] denominator)
136                 {
137                         if (numerator.Length != denominator.Length)
138                                 throw new ArgumentException ("Invalid parameter used.");
139
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);
150                         }
151                 }
152
153                 public EncoderParameter (Encoder encoder, long rangebegin, long rangeend)
154                 {
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);
161                 }
162
163                 public EncoderParameter (Encoder encoder, long[] rangebegin, long[] rangeend)
164                 {
165                         if (rangebegin.Length != rangeend.Length)
166                                 throw new ArgumentException ("Invalid parameter used.");
167
168                         this.encoder = encoder;
169                         this.valuesCount = rangebegin.Length;
170                         this.type = EncoderParameterValueType.ValueTypeLongRange;
171
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);
179                         }
180                 }
181
182                 public EncoderParameter (Encoder encoder, int numberOfValues, int type, int value)
183                 {
184                         this.encoder = encoder;
185                         this.valuePtr = (IntPtr) value;
186                         this.valuesCount = numberOfValues;
187                         this.type = (EncoderParameterValueType) type;
188                 }
189
190                 public EncoderParameter (Encoder encoder, int numerator1, int denominator1, int numerator2, int denominator2)
191                 {
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);
198                 }
199
200                 public EncoderParameter (Encoder encoder, int[] numerator1, int[] denominator1, int[] numerator2, int[] denominator2)
201                 {
202                         if (numerator1.Length != denominator1.Length ||
203                             numerator2.Length != denominator2.Length ||
204                             numerator1.Length != numerator2.Length)
205                                 throw new ArgumentException ("Invalid parameter used.");
206
207                         this.encoder = encoder;
208                         this.valuesCount = numerator1.Length;
209                         this.type = EncoderParameterValueType.ValueTypeRationalRange;
210
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);
222                         }
223                 }
224
225                 public Encoder Encoder {
226                         get {
227                                 return encoder;
228                         }
229
230                         set {
231                                 encoder = value;
232                         }
233                 }
234
235                 public int NumberOfValues {
236                         get {
237                                 return valuesCount;
238                         }
239                 }
240
241                 public EncoderParameterValueType Type {
242                         get {
243                                 return type;
244                         }
245                 }
246
247                 public EncoderParameterValueType ValueType {
248                         get {
249                                 return type;
250                         }
251                 }
252
253                 void Dispose (bool disposing) {
254                         if (valuePtr != IntPtr.Zero) {
255                                 Marshal.FreeHGlobal (valuePtr);
256                                 valuePtr = IntPtr.Zero;
257                         }
258                 }
259
260                 public void Dispose () {
261                         Dispose (true);         
262                 }
263
264                 ~EncoderParameter () {
265                         Dispose (false);
266                 }
267
268                 internal static int NativeSize () {
269                         return Marshal.SizeOf (typeof(GdipEncoderParameter));
270                 }
271
272                 internal void ToNativePtr (IntPtr epPtr) {
273                         GdipEncoderParameter ep = new GdipEncoderParameter ();
274                         ep.guid = this.encoder.Guid;
275                         ep.numberOfValues = (uint) this.valuesCount;
276                         ep.type = this.type;
277                         ep.value = this.valuePtr;
278                         Marshal.StructureToPtr (ep, epPtr, false);
279                 }
280
281                 internal static EncoderParameter FromNativePtr (IntPtr epPtr) {
282                         GdipEncoderParameter ep;
283                         ep = (GdipEncoderParameter) Marshal.PtrToStructure (epPtr, typeof(GdipEncoderParameter));
284
285                         Type valType;
286                         uint valCount;
287
288                         switch (ep.type) {
289                         case EncoderParameterValueType.ValueTypeAscii:
290                         case EncoderParameterValueType.ValueTypeByte:
291                         case EncoderParameterValueType.ValueTypeUndefined:
292                                 valType = typeof(byte);
293                                 valCount = ep.numberOfValues;
294                                 break;
295                         case EncoderParameterValueType.ValueTypeShort:
296                                 valType = typeof(short);
297                                 valCount = ep.numberOfValues;
298                                 break;
299                         case EncoderParameterValueType.ValueTypeLong:
300                                 valType = typeof(int);
301                                 valCount = ep.numberOfValues;
302                                 break;
303                         case EncoderParameterValueType.ValueTypeLongRange:
304                         case EncoderParameterValueType.ValueTypeRational:
305                                 valType = typeof(int);
306                                 valCount = ep.numberOfValues * 2;
307                                 break;
308                         case EncoderParameterValueType.ValueTypeRationalRange:
309                                 valType = typeof(int);
310                                 valCount = ep.numberOfValues * 4;
311                                 break;
312                         default:
313                                 return null;
314                         }
315
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)));
321
322                         /* There's nothing in Marshal to do a memcpy() between two IntPtrs.  This sucks. */
323                         unsafe {
324                                 byte *s = (byte *) ep.value;
325                                 byte *d = (byte *) eparam.valuePtr;
326                                 for (int i = 0; i < valCount * Marshal.SizeOf(valType); i++)
327                                         *d++ = *s++;
328                         }
329
330                         return eparam;
331                 }
332         }
333 }