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
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:
22 // The above copyright notice and this permission notice shall be
23 // included in all copies or substantial portions of the Software.
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.
37 using System.Runtime.InteropServices;
39 namespace System.Drawing.Imaging {
41 [StructLayout(LayoutKind.Sequential)]
42 public sealed class EncoderParameter : IDisposable {
44 private Encoder encoder;
45 private int valuesCount;
46 private EncoderParameterValueType type;
47 private IntPtr valuePtr;
49 internal EncoderParameter ()
53 public EncoderParameter (Encoder encoder, byte value)
55 this.encoder = encoder;
57 this.type = EncoderParameterValueType.ValueTypeByte;
58 this.valuePtr = Marshal.AllocHGlobal (1);
59 Marshal.WriteByte (this.valuePtr, value);
62 public EncoderParameter (Encoder encoder, byte[] value)
64 this.encoder = encoder;
65 this.valuesCount = value.Length;
66 this.type = EncoderParameterValueType.ValueTypeByte;
67 this.valuePtr = Marshal.AllocHGlobal (1 * valuesCount);
68 Marshal.Copy (value, 0, this.valuePtr, valuesCount);
71 public EncoderParameter (Encoder encoder, short value)
73 this.encoder = encoder;
75 this.type = EncoderParameterValueType.ValueTypeShort;
76 this.valuePtr = Marshal.AllocHGlobal (2);
77 Marshal.WriteInt16 (this.valuePtr, value);
80 public EncoderParameter (Encoder encoder, short[] value)
82 this.encoder = encoder;
83 this.valuesCount = value.Length;
84 this.type = EncoderParameterValueType.ValueTypeShort;
85 this.valuePtr = Marshal.AllocHGlobal (2 * valuesCount);
86 Marshal.Copy (value, 0, this.valuePtr, valuesCount);
90 public EncoderParameter (Encoder encoder, long value)
92 this.encoder = encoder;
94 this.type = EncoderParameterValueType.ValueTypeLong;
95 this.valuePtr = Marshal.AllocHGlobal (4);
96 Marshal.WriteInt32 (this.valuePtr, (int) value);
99 public EncoderParameter (Encoder encoder, long[] value)
101 this.encoder = encoder;
102 this.valuesCount = value.Length;
103 this.type = EncoderParameterValueType.ValueTypeLong;
104 this.valuePtr = Marshal.AllocHGlobal (4 * valuesCount);
105 int [] ivals = new int[value.Length];
106 for (int i = 0; i < value.Length; i++) ivals[i] = (int) value[i];
107 Marshal.Copy (ivals, 0, this.valuePtr, valuesCount);
110 public EncoderParameter (Encoder encoder, string value)
112 this.encoder = encoder;
114 ASCIIEncoding ascii = new ASCIIEncoding ();
115 int asciiByteCount = ascii.GetByteCount (value);
116 byte[] bytes = new byte [asciiByteCount];
117 ascii.GetBytes (value, 0, value.Length, bytes, 0);
119 this.valuesCount = bytes.Length;
120 this.type = EncoderParameterValueType.ValueTypeAscii;
121 this.valuePtr = Marshal.AllocHGlobal (valuesCount);
122 Marshal.Copy (bytes, 0, this.valuePtr, valuesCount);
125 public EncoderParameter (Encoder encoder, byte value, bool undefined)
127 this.encoder = encoder;
128 this.valuesCount = 1;
130 this.type = EncoderParameterValueType.ValueTypeUndefined;
132 this.type = EncoderParameterValueType.ValueTypeByte;
133 this.valuePtr = Marshal.AllocHGlobal (1);
134 Marshal.WriteByte (this.valuePtr, value);
137 public EncoderParameter (Encoder encoder, byte[] value, bool undefined)
139 this.encoder = encoder;
140 this.valuesCount = value.Length;
142 this.type = EncoderParameterValueType.ValueTypeUndefined;
144 this.type = EncoderParameterValueType.ValueTypeByte;
145 this.valuePtr = Marshal.AllocHGlobal (valuesCount);
146 Marshal.Copy (value, 0, this.valuePtr, valuesCount);
149 public EncoderParameter (Encoder encoder, int numerator, int denominator)
151 this.encoder = encoder;
152 this.valuesCount = 1;
153 this.type = EncoderParameterValueType.ValueTypeRational;
154 this.valuePtr = Marshal.AllocHGlobal (8);
155 int [] valuearray = { numerator, denominator };
156 Marshal.Copy (valuearray, 0, this.valuePtr, valuearray.Length);
159 public EncoderParameter (Encoder encoder, int[] numerator, int[] denominator)
161 if (numerator.Length != denominator.Length)
162 throw new ArgumentException ("Invalid parameter used.");
164 this.encoder = encoder;
165 this.valuesCount = numerator.Length;
166 this.type = EncoderParameterValueType.ValueTypeRational;
167 this.valuePtr = Marshal.AllocHGlobal (4 * valuesCount * 2);
168 for (int i = 0; i < valuesCount; i++) {
169 Marshal.WriteInt32 (valuePtr, i * 4, (int) numerator[i]);
170 Marshal.WriteInt32 (valuePtr, (i + 1) * 4, (int) denominator[i]);
174 public EncoderParameter (Encoder encoder, long rangebegin, long rangeend)
176 this.encoder = encoder;
177 this.valuesCount = 1;
178 this.type = EncoderParameterValueType.ValueTypeLongRange;
179 this.valuePtr = Marshal.AllocHGlobal (8);
180 int [] valuearray = { (int) rangebegin, (int) rangeend };
181 Marshal.Copy (valuearray, 0, this.valuePtr, valuearray.Length);
184 public EncoderParameter (Encoder encoder, long[] rangebegin, long[] rangeend)
186 if (rangebegin.Length != rangeend.Length)
187 throw new ArgumentException ("Invalid parameter used.");
189 this.encoder = encoder;
190 this.valuesCount = rangebegin.Length;
191 this.type = EncoderParameterValueType.ValueTypeLongRange;
193 this.valuePtr = Marshal.AllocHGlobal (4 * valuesCount * 2);
194 IntPtr dest = this.valuePtr;
195 for (int i = 0; i < valuesCount; i++) {
196 Marshal.WriteInt32 (dest, i * 4, (int) rangebegin[i]);
197 Marshal.WriteInt32 (dest, (i + 1) * 4, (int) rangeend[i]);
201 public EncoderParameter (Encoder encoder, int NumberOfValues, int Type, int Value)
203 this.encoder = encoder;
204 this.valuePtr = (IntPtr) Value;
205 this.valuesCount = NumberOfValues;
206 this.type = (EncoderParameterValueType) Type;
209 public EncoderParameter (Encoder encoder, int numerator1, int demoninator1, int numerator2, int demoninator2)
211 this.encoder = encoder;
212 this.valuesCount = 1;
213 this.type = EncoderParameterValueType.ValueTypeRationalRange;
214 this.valuePtr = Marshal.AllocHGlobal (4 * 4);
215 int [] valuearray = { numerator1, demoninator1, numerator2, demoninator2 };
216 Marshal.Copy (valuearray, 0, this.valuePtr, 4);
219 public EncoderParameter (Encoder encoder, int[] numerator1, int[] denominator1, int[] numerator2, int[] denominator2)
221 if (numerator1.Length != denominator1.Length ||
222 numerator2.Length != denominator2.Length ||
223 numerator1.Length != numerator2.Length)
224 throw new ArgumentException ("Invalid parameter used.");
226 this.encoder = encoder;
227 this.valuesCount = numerator1.Length;
228 this.type = EncoderParameterValueType.ValueTypeRationalRange;
230 this.valuePtr = Marshal.AllocHGlobal (4 * valuesCount * 4);
231 IntPtr dest = this.valuePtr;
232 for (int i = 0; i < valuesCount; i++) {
233 Marshal.WriteInt32 (dest, i * 4, numerator1[i]);
234 Marshal.WriteInt32 (dest, (i + 1) * 4, denominator1[i]);
235 Marshal.WriteInt32 (dest, (i + 2) * 4, numerator2[i]);
236 Marshal.WriteInt32 (dest, (i + 3) * 4, denominator2[i]);
240 public Encoder Encoder {
250 public int NumberOfValues {
256 public EncoderParameterValueType Type {
262 public EncoderParameterValueType ValueType {
268 void Dispose (bool disposing) {
269 if (valuePtr != IntPtr.Zero) {
270 Marshal.FreeHGlobal (valuePtr);
271 valuePtr = IntPtr.Zero;
275 public void Dispose () {
277 GC.SuppressFinalize(this);
280 ~EncoderParameter () {
284 internal static int NativeSize () {
285 return Marshal.SizeOf (typeof(GdipEncoderParameter));
288 internal void ToNativePtr (IntPtr epPtr) {
289 GdipEncoderParameter ep = new GdipEncoderParameter ();
290 ep.guid = this.encoder.Guid;
291 ep.numberOfValues = (uint) this.valuesCount;
293 ep.value = this.valuePtr;
294 Marshal.StructureToPtr (ep, epPtr, false);
297 internal static EncoderParameter FromNativePtr (IntPtr epPtr) {
298 GdipEncoderParameter ep;
299 ep = (GdipEncoderParameter) Marshal.PtrToStructure (epPtr, typeof(GdipEncoderParameter));
305 case EncoderParameterValueType.ValueTypeAscii:
306 case EncoderParameterValueType.ValueTypeByte:
307 case EncoderParameterValueType.ValueTypeUndefined:
308 valType = typeof(byte);
309 valCount = ep.numberOfValues;
311 case EncoderParameterValueType.ValueTypeShort:
312 valType = typeof(short);
313 valCount = ep.numberOfValues;
315 case EncoderParameterValueType.ValueTypeLong:
316 valType = typeof(int);
317 valCount = ep.numberOfValues;
319 case EncoderParameterValueType.ValueTypeLongRange:
320 case EncoderParameterValueType.ValueTypeRational:
321 valType = typeof(int);
322 valCount = ep.numberOfValues * 2;
324 case EncoderParameterValueType.ValueTypeRationalRange:
325 valType = typeof(int);
326 valCount = ep.numberOfValues * 4;
332 EncoderParameter eparam = new EncoderParameter();
333 eparam.encoder = new Encoder(ep.guid);
334 eparam.valuesCount = (int) ep.numberOfValues;
335 eparam.type = ep.type;
336 eparam.valuePtr = Marshal.AllocHGlobal ((int)(valCount * Marshal.SizeOf(valType)));
338 /* There's nothing in Marshal to do a memcpy() between two IntPtrs. This sucks. */
340 byte *s = (byte *) ep.value;
341 byte *d = (byte *) eparam.valuePtr;
342 for (int i = 0; i < valCount * Marshal.SizeOf(valType); i++)