Author: pbartok
Date: 2005-03-17 06:08:27 -0500 (Thu, 17 Mar 2005)
New Revision: 41936

Modified:
   trunk/mcs/class/System.Drawing/System.Drawing/ChangeLog
   trunk/mcs/class/System.Drawing/System.Drawing/Image.cs
   trunk/mcs/class/System.Drawing/System.Drawing/gdipFunctions.cs
Log:
2005-03-17  Peter Bartok  <[EMAIL PROTECTED]>

        * gdipFunctions.cs: 
          - Changed P/Invoke signature for GdipLoadImageFromDelegate_linux()
            method, now includes a get header delegate
          - Added StreamGetHeaderImpl method, to allow libgdiplus to determine 
            the image type even on non-seekable streams
          - Fixed StreamGetBytesImpl to consider the bytes already retrieved
            via StreamGetHeaderImpl
        * Image.cs: Fixed call to GdipLoadImageFromDelegate_linux() to include
          the new StreamGetHeader delegate



Modified: trunk/mcs/class/System.Drawing/System.Drawing/ChangeLog
===================================================================
--- trunk/mcs/class/System.Drawing/System.Drawing/ChangeLog     2005-03-17 
11:08:15 UTC (rev 41935)
+++ trunk/mcs/class/System.Drawing/System.Drawing/ChangeLog     2005-03-17 
11:08:27 UTC (rev 41936)
@@ -1,3 +1,15 @@
+2005-03-17  Peter Bartok  <[EMAIL PROTECTED]>
+
+       * gdipFunctions.cs: 
+         - Changed P/Invoke signature for GdipLoadImageFromDelegate_linux()
+           method, now includes a get header delegate
+         - Added StreamGetHeaderImpl method, to allow libgdiplus to determine 
+           the image type even on non-seekable streams
+         - Fixed StreamGetBytesImpl to consider the bytes already retrieved
+           via StreamGetHeaderImpl
+       * Image.cs: Fixed call to GdipLoadImageFromDelegate_linux() to include
+         the new StreamGetHeader delegate
+
 2005-03-15 Jordi Mas i Hernandez <[EMAIL PROTECTED]>
 
        * Pen.cs: Fixes dispose method to allow to be called multiple times

Modified: trunk/mcs/class/System.Drawing/System.Drawing/Image.cs
===================================================================
--- trunk/mcs/class/System.Drawing/System.Drawing/Image.cs      2005-03-17 
11:08:15 UTC (rev 41935)
+++ trunk/mcs/class/System.Drawing/System.Drawing/Image.cs      2005-03-17 
11:08:27 UTC (rev 41936)
@@ -201,7 +201,7 @@
                        GDIPlus.GdiPlusStreamHelper sh = new 
GDIPlus.GdiPlusStreamHelper (stream);
                        IntPtr imagePtr;
 
-                       Status st = GDIPlus.GdipLoadImageFromDelegate_linux 
(sh.GetBytesDelegate, sh.PutBytesDelegate,
+                       Status st = GDIPlus.GdipLoadImageFromDelegate_linux 
(sh.GetHeaderDelegate, sh.GetBytesDelegate, sh.PutBytesDelegate,
                                                                        
sh.SeekDelegate, sh.CloseDelegate, sh.SizeDelegate,
                                                                                
     out imagePtr);
                        GDIPlus.CheckStatus (st);

Modified: trunk/mcs/class/System.Drawing/System.Drawing/gdipFunctions.cs
===================================================================
--- trunk/mcs/class/System.Drawing/System.Drawing/gdipFunctions.cs      
2005-03-17 11:08:15 UTC (rev 41935)
+++ trunk/mcs/class/System.Drawing/System.Drawing/gdipFunctions.cs      
2005-03-17 11:08:27 UTC (rev 41936)
@@ -1484,6 +1484,7 @@
                //
                // These are stuff that is unix-only
                //
+               public delegate int StreamGetHeaderDelegate(IntPtr buf, int 
bufsz);
                public delegate int StreamGetBytesDelegate (IntPtr buf, int 
bufsz, bool peek);
                public delegate long StreamSeekDelegate (int offset, int 
whence);
                public delegate int StreamPutBytesDelegate (IntPtr buf, int 
bufsz);
@@ -1494,50 +1495,114 @@
                {
                        public Stream stream;
                        
+                       private StreamGetHeaderDelegate sghd = null;
                        private StreamGetBytesDelegate sgbd = null;
                        private StreamSeekDelegate skd = null;
                        private StreamPutBytesDelegate spbd = null;
                        private StreamCloseDelegate scd = null;
                        private StreamSizeDelegate ssd = null;
+                       private byte[]  start_buf;
+                       private int     start_buf_pos;
+                       private int     start_buf_len;
                        
                        public GdiPlusStreamHelper (Stream s) 
                        { 
                                stream = s;
-                               if (stream != null && stream.CanSeek) 
+                               if (stream != null && stream.CanSeek) {
                                        stream.Seek (0, SeekOrigin.Begin);
+                               }
                        }
 
+                       public int StreamGetHeaderImpl (IntPtr buf, int bufsz)  
{
+                               int     bytesRead;
+
+                               start_buf = new byte[bufsz];
+
+                               try {
+                                       bytesRead = stream.Read (start_buf, 0, 
bufsz);
+                               } catch (IOException) {
+                                       return -1;
+                               }
+
+                               if (bytesRead > 0 && buf != IntPtr.Zero) {
+                                       Marshal.Copy (start_buf, 0, (IntPtr) 
(buf.ToInt64()), bytesRead);
+                               }
+
+                               start_buf_pos = 0;
+                               start_buf_len = bytesRead;
+
+                               return bytesRead;
+                       }
+
+                       public StreamGetHeaderDelegate GetHeaderDelegate {
+                               get {
+                                       if (stream != null && stream.CanRead) {
+                                               if (sghd == null) {
+                                                       sghd = new 
StreamGetHeaderDelegate (StreamGetHeaderImpl);
+                                               }
+                                               return sghd;
+                                       }
+                                       return null;
+                               }
+                       }
+
                        public int StreamGetBytesImpl (IntPtr buf, int bufsz, 
bool peek) 
                        {
-                               if (buf == IntPtr.Zero && peek)
+                               if (buf == IntPtr.Zero && peek) {
                                        return -1;
+                               }
 
                                byte[] managedBuf = new byte[bufsz];
-                               int bytesReturn = 0;
                                int bytesRead = 0;
                                long streamPosition = 0;
-                               
+
                                if (bufsz > 0) {
-                                       streamPosition = stream.Position;
-                                       try {
-                                               bytesRead = stream.Read 
(managedBuf, 0, bufsz);
-                                       } catch (IOException) {
-                                               return -1;
+                                       if (stream.CanSeek) {
+                                               streamPosition = 
stream.Position;
                                        }
+                                       if (start_buf_len > 0) {
+                                               if (start_buf_len > bufsz) {
+                                                       Array.Copy(start_buf, 
start_buf_pos, managedBuf, 0, bufsz);
+                                                       start_buf_pos += bufsz;
+                                                       start_buf_len -= bufsz;
+                                                       bytesRead = bufsz;
+                                                       bufsz = 0;
+                                               } else {
+                                                       // this is easy
+                                                       Array.Copy(start_buf, 
start_buf_pos, managedBuf, 0, start_buf_len);
+                                                       bufsz -= start_buf_len;
+                                                       bytesRead = 
start_buf_len;
+                                                       start_buf_len = 0;
+                                               }
+                                       }
+
+                                       if (bufsz > 0) {
+                                               try {
+                                                       bytesRead += 
stream.Read (managedBuf, bytesRead, bufsz);
+                                               } catch (IOException) {
+                                                       return -1;
+                                               }
+                                       }
                        
                                        if (bytesRead > 0 && buf != 
IntPtr.Zero) {
-                                               Marshal.Copy (managedBuf, 0, 
(IntPtr) (buf.ToInt64() + bytesReturn), bytesRead);
+                                               Marshal.Copy (managedBuf, 0, 
(IntPtr) (buf.ToInt64()), bytesRead);
                                        }
 
+                                       if (!stream.CanSeek && (bufsz == 10) && 
peek) {
+                                               // Special 'hack' to support 
peeking of the type for gdi+ on non-seekable streams
+                                       }
+                               
                                        if (peek) {
-                                               // If we are peeking bytes, 
then go back to original position before peeking
-                                               stream.Seek (streamPosition, 
SeekOrigin.Begin);
+                                               if (stream.CanSeek) {
+                                                       // If we are peeking 
bytes, then go back to original position before peeking
+                                                       stream.Seek 
(streamPosition, SeekOrigin.Begin);
+                                               } else {
+                                                       throw new 
NotSupportedException();
+                                               }
                                        }
-                             
-                                       bytesReturn += bytesRead;
                                }
                                
-                               return bytesReturn;
+                               return bytesRead;
                        }
 
                        public StreamGetBytesDelegate GetBytesDelegate {
@@ -1648,7 +1713,7 @@
                internal static extern Status GdipCreateFromXDrawable_linux 
(IntPtr drawable, IntPtr display, out IntPtr graphics);
                
                [DllImport("gdiplus.dll")]
-               static internal extern Status GdipLoadImageFromDelegate_linux ( 
StreamGetBytesDelegate getBytes, StreamPutBytesDelegate putBytes, 
+               static internal extern Status GdipLoadImageFromDelegate_linux ( 
StreamGetHeaderDelegate getHeader, StreamGetBytesDelegate getBytes, 
StreamPutBytesDelegate putBytes, 
                                                        StreamSeekDelegate 
doSeek, StreamCloseDelegate close, StreamSizeDelegate size, out IntPtr image);
                [DllImport("gdiplus.dll")]
                static internal extern Status GdipSaveImageToDelegate_linux ( 
IntPtr image, StreamGetBytesDelegate getBytes, StreamPutBytesDelegate putBytes, 

_______________________________________________
Mono-patches maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches

Reply via email to