start populating the new System.Web.Configuration_2.0 dir
[mono.git] / mcs / class / System.Drawing / System.Drawing / Bitmap.jvm.cs
1 using System;
2 using System.IO;
3 using System.Drawing.Imaging;
4 using System.Runtime.Serialization;
5 using Mainsoft.Drawing.Imaging;
6
7 using io = java.io;
8 using imageio = javax.imageio;
9 using stream = javax.imageio.stream;
10 using spi = javax.imageio.spi;
11 using BufferedImage = java.awt.image.BufferedImage;
12 using JavaImage = java.awt.Image;
13 using awt = java.awt;
14 using image = java.awt.image;
15
16 namespace System.Drawing 
17 {
18         public sealed class Bitmap : Image {
19
20                 # region Static fields
21
22                 static readonly image.ColorModel _jpegColorModel = new image.DirectColorModel(24, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x0);
23
24                 #endregion
25
26                 #region constructors
27
28                 Bitmap (PlainImage orig) {
29                         base.Initialize( orig, false );
30                 }
31
32                 private Bitmap (SerializationInfo info, StreamingContext context) {
33                         throw new NotImplementedException ();
34                 }
35
36                 public Bitmap (int width, int height, Graphics g) 
37                         :this (width, height, PixelFormat.Format32bppArgb) {
38                         CurrentImage.HorizontalResolution = g.DpiX;
39                         CurrentImage.VerticalResolution = g.DpiY;
40                 }
41
42                 public Bitmap (Image original) 
43                         :this (original, original.Size) {}
44
45                 public Bitmap (Image orig, Size newSize)
46                         :this (orig, newSize.Width, newSize.Height) {}
47
48                 public Bitmap (Image orig, int width, int height)
49                         :base (CreateScaledImage (orig, width, height), ImageFormat.MemoryBmp) {}
50
51                 internal Bitmap (java.awt.Image nativeObject, ImageFormat format)
52                         :base (nativeObject, format) {}
53
54                 private Bitmap (java.awt.Image nativeObject, ImageFormat format, PixelFormat pixFormat)
55                         :this (nativeObject, format) {
56                         if (pixFormat != this.PixelFormat)
57                                 throw new NotImplementedException ("Converting PixelFormat is not implemented yet.");
58                 }
59
60                 public Bitmap (int width, int height) 
61                         :this (width, height, PixelFormat.Format32bppArgb) {}
62
63                 public Bitmap (int width, int height, PixelFormat format)
64                         :base (
65                         new java.awt.image.BufferedImage (width, height,
66                         ToBufferedImageFormat (format)),
67                         ImageFormat.Bmp) {
68                 }
69
70                 public Bitmap (Stream stream)
71                         :this (stream, false) {}
72
73                 public Bitmap (string filename) 
74                         :this (filename, false) {}
75
76                 public Bitmap (Stream stream, bool useIcm)
77                         :this (stream, useIcm, null) {}
78
79                 public Bitmap (string filename, bool useIcm)
80                         :this (filename, useIcm, null) {}
81
82                 internal Bitmap (Stream stream, bool useIcm, ImageFormat format) {
83                         // TBD: useIcm param
84                         io.InputStream jis = vmw.common.IOUtils.ToInputStream (stream);
85             Initialize (new stream.MemoryCacheImageInputStream (jis), format);
86                 }
87
88                 internal Bitmap (string filename, bool useIcm, ImageFormat format) {
89                         // TBD: useIcm param
90                         java.io.File file = vmw.common.IOUtils.getJavaFile (filename);
91                         if (!file.exists ())
92                                  throw new System.IO.FileNotFoundException (filename);
93                         Initialize (new stream.FileImageInputStream (file), format);
94                 }
95
96                 public Bitmap (Type type, string resource) {
97                         using (Stream s = type.Assembly.GetManifestResourceStream (resource)) {
98                                 if (s == null)
99                                         throw new ArgumentException("Resource '" + resource + "' could not be found in class '" + type.ToString() + "'");
100
101                                 io.InputStream jis = vmw.common.IOUtils.ToInputStream (s);
102                                 Initialize (new stream.MemoryCacheImageInputStream (jis), null);
103                         }
104                 }
105 #if INTPTR_SUPPORT
106                 public Bitmap (int width, int height, int stride, PixelFormat format, IntPtr scan0)
107                 {                                               
108                         throw new NotImplementedException();                    
109                 }
110 #endif
111                 #endregion
112
113                 #region Internal Initialization
114
115                 private void Initialize (stream.ImageInputStream input, ImageFormat format) {
116                         ImageCodec ic = null;
117
118                         if (format == null)
119                                 ic = ImageCodec.CreateReader(input);
120                         else
121                                 ic = ImageCodec.CreateReader(format);
122
123                         try {
124                                 ic.NativeStream = input;
125                                 PlainImage pi = ic.ReadPlainImage();
126                                 base.Initialize( pi, false );
127
128                                 pi = ic.ReadNextPlainImage();
129                                 while ( pi != null) {
130                                         base.Initialize( pi, true );
131                                         pi = ic.ReadNextPlainImage();
132                                 }
133
134                                 _flags |= (int)(ImageFlags.ImageFlagsReadOnly | ImageFlags.ImageFlagsHasRealPixelSize);
135                         }
136                         catch (IOException ex) {
137                                 throw ex;
138                         }
139                         catch (Exception) {
140                                 throw new OutOfMemoryException ("Out of memory");
141                         }
142                         finally {
143                                 ic.Dispose();
144                         }
145                 }
146
147                 #endregion
148
149                 #region InternalSave
150                 protected override void InternalSave (stream.ImageOutputStream output, Guid clsid) {
151
152                         ImageCodec ic = ImageCodec.CreateWriter( clsid );
153
154                         // .net saves in png if cannot find requested encoder. act id 316563
155                         if (ic == null)
156                                 ic = ImageCodec.CreateWriter( ImageFormat.Png );
157
158                         if (ic == null)
159                                 throw new NotSupportedException("The requested format encoder is not supported");
160
161                         using (ic) {
162
163                                 PlainImage plainImage = CurrentImage;
164                                 plainImage.NativeImage.flush();
165
166                                 if ( ImageCodec.ClsidToImageFormat( clsid ).Equals( ImageFormat.Jpeg ) ) {
167                                         image.ColorModel cm = ((image.BufferedImage)CurrentImage.NativeImage).getColorModel();
168                                         if (cm.hasAlpha()) {
169                                                 if (cm is image.DirectColorModel) {
170                                                         image.Raster raster = ((image.BufferedImage)CurrentImage.NativeImage).getRaster();
171                                                         image.DataBuffer db = raster.getDataBuffer();
172                                                         image.DirectColorModel dcm = (image.DirectColorModel)cm;
173                                                         image.SinglePixelPackedSampleModel jpegSampleModel = new image.SinglePixelPackedSampleModel( 
174                                                                 db.getDataType(), Width, Height, 
175                                                                 new int[] {dcm.getRedMask(), dcm.getGreenMask(), dcm.getBlueMask()}     );
176                 
177                                                         image.BufferedImage tb = new image.BufferedImage( 
178                                                                 _jpegColorModel, 
179                                                                 image.Raster.createWritableRaster( jpegSampleModel, db, null ),
180                                                                 false, null );
181
182                                                         plainImage = new PlainImage( tb, plainImage.Thumbnails, ImageFormat.Jpeg, plainImage.HorizontalResolution, plainImage.VerticalResolution, plainImage.Dimension );
183                                                         plainImage.NativeMetadata = plainImage.NativeMetadata;
184                                                 }
185                                         }
186                                 }
187
188                                 ic.NativeStream = output;
189                                 ic.WritePlainImage( plainImage );
190                         }
191                 }
192
193                 #endregion
194
195                 #region private statics: ToBufferedImageFormat, CreateScaledImage
196
197                 private static int ToBufferedImageFormat (PixelFormat format) {
198                         switch(format) {
199                                 case PixelFormat.Format16bppGrayScale:
200                                         return BufferedImage.TYPE_USHORT_GRAY;
201                                 case PixelFormat.Format1bppIndexed:
202                                         return BufferedImage.TYPE_BYTE_GRAY;
203                                 case PixelFormat.Format32bppArgb:
204                                         return BufferedImage.TYPE_INT_ARGB;
205                                 case PixelFormat.Format32bppRgb:
206                                         return BufferedImage.TYPE_INT_RGB;
207                                 case PixelFormat.Format32bppPArgb:
208                                         return BufferedImage.TYPE_INT_ARGB_PRE;
209                                 case PixelFormat.Format16bppRgb555:
210                                         return BufferedImage.TYPE_USHORT_555_RGB;
211                                 case PixelFormat.Format16bppRgb565:
212                                         return BufferedImage.TYPE_USHORT_565_RGB;
213                                 case PixelFormat.Indexed:
214                                         return BufferedImage.TYPE_BYTE_INDEXED;
215                                 default:
216                                         return BufferedImage.TYPE_INT_ARGB;
217                         }                       
218                 }
219
220                 private static java.awt.Image CreateScaledImage(Image original, int width, int height) {
221                         JavaImage oldscaled = original.CurrentImage.NativeImage.getScaledInstance(width, height,
222                                 JavaImage.SCALE_DEFAULT);
223                         BufferedImage newimage = new BufferedImage(oldscaled.getWidth(null), 
224                                 oldscaled.getHeight(null),
225                                 BufferedImage.TYPE_INT_ARGB);
226                         java.awt.Graphics2D graphics2d = newimage.createGraphics();
227                         graphics2d.drawImage(oldscaled, 0, 0, null);
228                         graphics2d.dispose();
229                         return newimage;                                
230                 }
231                 #endregion
232
233                 #region Get-SetPixel
234                 public Color GetPixel (int x, int y) 
235                 {
236
237                         int argb = NativeObject.getRGB(x,y);                            
238                         return Color.FromArgb(argb); 
239                 }
240
241                 public void SetPixel (int x, int y, Color color)
242                 {                               
243                         int rgb = color.ToArgb();
244                         NativeObject.setRGB(x,y,rgb);
245                 }
246                 #endregion
247
248                 #region Clone
249                 public override object Clone () {
250                         return new Bitmap ( (PlainImage)CurrentImage.Clone() );
251                 }
252
253                 public Bitmap Clone (Rectangle rect, PixelFormat pixFormat)
254                 {
255                         return Clone(new RectangleF( rect.X, rect.Y, rect.Width, rect.Height ), pixFormat);
256         }
257                 
258                 public Bitmap Clone (RectangleF rect, PixelFormat pixFormat)
259                 {
260                         PlainImage plainImage = CurrentImage.Clone(false);\r
261                         BufferedImage clone = new BufferedImage( (int)rect.Width, (int)rect.Height, ToBufferedImageFormat( pixFormat ) );\r
262                         awt.Graphics2D g = clone.createGraphics();\r
263                         try {\r
264                                 g.drawImage( NativeObject, -(int)rect.X, -(int)rect.Y, null );\r
265                         }\r
266                         finally {\r
267                                 g.dispose();\r
268                         }\r
269 \r
270                         plainImage.NativeImage = clone;\r
271                         return new Bitmap(plainImage);\r
272                 }
273                 #endregion
274
275                 #region LockBits
276                 // TBD: implement this
277                 public BitmapData LockBits (Rectangle rect, ImageLockMode flags, PixelFormat format) {
278                         throw new NotImplementedException();
279                 }
280                 #endregion
281
282                 #region MakeTransparent
283                 public void MakeTransparent ()
284                 {
285                         Color clr = GetPixel(0,0);                      
286                         MakeTransparent (clr);
287                 }
288
289                 public void MakeTransparent (Color transparentColor)
290                 {
291                         byte A = transparentColor.A;
292                         image.WritableRaster raster = NativeObject.getRaster();
293                         int numBands  = raster.getNumBands();
294                         int maxWidth  = raster.getWidth() + raster.getMinX();
295                         int maxHeight = raster.getHeight() + raster.getMinY();
296                         int[] srcPix  = new int[numBands];
297
298                         for (int y = raster.getMinY(); y < maxHeight; y++) {
299                                 for (int x = raster.getMinX(); x < maxWidth; x++) {
300                                         /*srcPix =*/ raster.getPixel(x, y, srcPix);
301                                         for (int z = 0; z < numBands; z++) {
302                                                 int argb = srcPix[z];
303                                                 if ((uint)argb >> 24 == A) {
304                                                         argb &= 0x00FFFFFF;
305                                                         srcPix[z] = argb;
306                                                 }
307                                         }
308                                 }
309                         }
310                 }
311                 #endregion
312
313                 #region SetResolution
314                 public void SetResolution (float xDpi, float yDpi)
315                 {
316                         CurrentImage.HorizontalResolution = xDpi;
317                         CurrentImage.VerticalResolution = yDpi;
318                 }
319                 #endregion 
320
321                 #region UnlockBits
322                 // TBD: implement this
323                 public void UnlockBits (BitmapData bitmap_data)
324                 {
325                         throw new NotImplementedException();
326                 }
327                 #endregion 
328
329                 #region NativeObject
330                 internal new BufferedImage NativeObject {
331                         get {
332                                 return (BufferedImage)base.NativeObject.CurrentImage.NativeImage;
333                         }
334                 }
335
336                 protected override java.awt.Image[] CloneNativeObjects(java.awt.Image[] src) {
337                         if (src == null)
338                                 return null;
339
340                         awt.Image[] dst = new awt.Image[src.Length];
341                         for (int i = 0; i < dst.Length; i++) {
342                                 BufferedImage image = src[i] as BufferedImage;
343                                 if (image == null)
344                                         throw new ArgumentException(String.Format("Unsupported image type '{0}'", src[i].ToString()), "src");
345
346                                 dst[i] = new BufferedImage(image.getColorModel(), image.copyData(null), image.isAlphaPremultiplied(), null);
347                         }
348
349                         return dst;
350                 }
351
352                 #endregion
353
354                 #region InternalPixelFormat
355                 protected override PixelFormat InternalPixelFormat {
356                         get {
357                                 int t = NativeObject.getType();
358                                 switch(t) {
359                                         case 11://JavaImage.TYPE_USHORT_GRAY:
360                                                 return PixelFormat.Format16bppGrayScale;
361                                         case 10://JavaImage.TYPE_BYTE_GRAY:
362                                                 return PixelFormat.Format1bppIndexed;                           
363                                         case 1: //JavaImage.TYPE_INT_RGB
364                                                 return PixelFormat.Format32bppRgb;
365                                         case 2: //JavaImage.TYPE_INT_ARGB:                      
366                                                 return PixelFormat.Format32bppArgb;
367                                         case 3://JavaImage.TYPE_INT_ARGB_PRE:
368                                                 return PixelFormat.Format32bppPArgb;
369                                         case 9://JavaImage.TYPE_USHORT_555_RGB:
370                                                 return PixelFormat.Format16bppRgb555;
371                                         case 8://JavaImage.TYPE_USHORT_565_RGB:
372                                                 return PixelFormat.Format16bppRgb565;
373                                         case 13://JavaImage.TYPE_BYTE_INDEXED:
374                                                 return PixelFormat.Indexed;
375                                                 //TBD: support this
376                                         case 12://JavaImage.TYPE_BYTE_BINARY:
377                                         case 0://JavaImage.TYPE_CUSTOM:
378                                         case 4://JavaImage.TYPE_INT_BGR:
379                                         case 5://JavaImage.TYPE_3BYTE_BGR:                                      
380                                         case 6://JavaImage.TYPE_4BYTE_ABGR:
381                                         case 7://JavaImage.TYPE_4BYTE_ABGR_PRE:
382                                         default:
383                                                 return PixelFormat.Undefined;
384                                 }                       
385                         }               
386                 }
387                 #endregion
388
389 #if INTPTR_SUPPORT
390                 public static Bitmap FromHicon (IntPtr hicon)
391                 {       
392                         throw new NotImplementedException();
393                 }
394
395                 public static Bitmap FromResource (IntPtr hinstance, string bitmapName) //TBD: Untested
396                 {
397                         throw new NotImplementedException();
398                 }
399
400                 public IntPtr GetHbitmap ()
401                 {
402                         throw new NotImplementedException();
403                 }
404
405                 public IntPtr GetHbitmap (Color background)
406                 {
407                         throw new NotImplementedException();
408                 }
409
410                 public IntPtr GetHicon ()
411                 {
412                         throw new NotImplementedException();
413                 }
414 #endif
415
416         }
417 }