public Bitmap AsGDI(Profile profile = null) { bool pop = false; try { if (gdiBitmap != null) { return(gdiBitmap); } if (profile != null) { profile.Push("SmartBitmap.AsGDI"); pop = true; } if (wpfBitmap != null) { Bitmap gdiBitmap = new Bitmap(wpfBitmap.PixelWidth, wpfBitmap.PixelHeight, System.Drawing.Imaging.PixelFormat.Format32bppRgb); ApplyProperties(); BitmapData d = gdiBitmap.LockBits(new Rectangle(0, 0, gdiBitmap.Width, gdiBitmap.Height), ImageLockMode.WriteOnly, ManagedBitmap32.Format); int * scan0 = (int *)d.Scan0.ToPointer(); int stride = d.Stride; Debug.Assert(stride > 0); wpfBitmap.CopyPixels(new System.Windows.Int32Rect(0, 0, gdiBitmap.Width, gdiBitmap.Height), new IntPtr(scan0), stride, 0 /*offset*/); gdiBitmap.UnlockBits(d); wpfBitmap = null; return(gdiBitmap); } if (managedBitmap != null) { gdiBitmap = managedBitmap.CloneToGDI(); managedBitmap.Dispose(); managedBitmap = null; return(gdiBitmap); } } finally { if ((profile != null) && pop) { profile.Pop(); } } Debug.Assert(false); throw new InvalidOperationException(); }
private const bool Logging = true; // TODO: turn off public static int RunServer(string pipeName) { TextWriter log; if (Logging) { int i = 0; while (true) { try { log = new StreamWriter(Path.Combine(Path.GetTempPath(), String.Concat("ImageServerLog-", i, ".log"))); } catch (Exception) { i++; continue; } break; } log = TextWriter.Synchronized(log); } ManagedBitmap currentBitmap = null; try { ThreadPriority savedThreadPriority = Thread.CurrentThread.Priority; if (log != null) { log.WriteLine("Connecting to pipe {0}", pipeName); log.Flush(); } using (NamedPipeClientStream channel = new NamedPipeClientStream(".", pipeName)) { channel.Connect(); Thread disconnectMonitorThread = new Thread(new ThreadStart( delegate() { TimeoutThread(channel); if (log != null) { log.WriteLine("TimeoutThread terminated - connection broken, exiting"); log.Flush(); } })); disconnectMonitorThread.Start(); while (true) { if (log != null) { log.WriteLine("Waiting"); log.Flush(); } ClientServerCommunication.Commands command; object[] args; ClientServerCommunication.ReceiveMessage(log, channel, out command, out args); object[] extraResults = null; if (log != null) { log.WriteLine("Processing command"); log.Flush(); } Profile profile; try { profile = new Profile("ImageServer process command"); if (log != null) { log.WriteLine("Command: {0}", command); log.Flush(); } switch (command) { default: Debug.Assert(false); throw new ArgumentException(command.ToString()); case ClientServerCommunication.Commands.Quit: if (args.Length != 0) { const string Message = "remote command: wrong number of arguments"; Debug.Assert(false, Message); throw new ArgumentException(Message); } if (log != null) { log.WriteLine("Main thread exiting"); log.Flush(); log.Close(); log = null; } return(0); case ClientServerCommunication.Commands.Clear: if (args.Length != 0) { const string Message = "remote command: wrong number of arguments"; Debug.Assert(false, Message); throw new ArgumentException(Message); } if (currentBitmap == null) { const string Message = "Current bitmap is null"; Debug.Assert(false, Message); throw new InvalidOperationException(Message); } currentBitmap.Dispose(); currentBitmap = null; break; case ClientServerCommunication.Commands.LoadAndOrientGDI: if (args.Length != 3) { const string Message = "remote command: wrong number of arguments"; Debug.Assert(false, Message); throw new ArgumentException(Message); } if (currentBitmap != null) { const string Message = "Current bitmap hasn't been cleared"; Debug.Assert(false, Message); throw new InvalidOperationException(Message); } Thread.CurrentThread.Priority = (ThreadPriority)args[0]; RotateFlipType exifOrientation; LoadAndOrientGDI( profile, (string)args[1], (int)args[2], out currentBitmap, out exifOrientation); extraResults = new object[] { (int)exifOrientation }; break; case ClientServerCommunication.Commands.ResizeGDI: if (args.Length != 6) { const string Message = "remote command: wrong number of arguments"; Debug.Assert(false, Message); throw new ArgumentException(Message); } if (currentBitmap != null) { const string Message = "Current bitmap hasn't been cleared"; Debug.Assert(false, Message); throw new InvalidOperationException(Message); } Thread.CurrentThread.Priority = (ThreadPriority)args[0]; ResizeGDI( profile, (string)args[1], (int)args[2], (int)args[3], (int)args[4], (int)args[5], out currentBitmap); break; case ClientServerCommunication.Commands.CreateTileGDI: if (args.Length != 10) { const string Message = "remote command: wrong number of arguments"; Debug.Assert(false, Message); throw new ArgumentException(Message); } if (currentBitmap != null) { const string Message = "Current bitmap hasn't been cleared"; Debug.Assert(false, Message); throw new InvalidOperationException(Message); } Thread.CurrentThread.Priority = (ThreadPriority)args[0]; CreateTileGDI( profile, (string)args[1], (int)args[2], (int)args[3], (int)args[4], (int)args[5], (int)args[6], (int)args[7], (int)args[8], (int)args[9], out currentBitmap); break; case ClientServerCommunication.Commands.ShrinkExpandGDI: if (args.Length != 6) { const string Message = "remote command: wrong number of arguments"; Debug.Assert(false, Message); throw new ArgumentException(Message); } Thread.CurrentThread.Priority = (ThreadPriority)args[0]; ShrinkExpandGDI( profile, (int)args[1], (int)args[2], (string)args[3], (string)args[4], (double)args[5]); break; case ClientServerCommunication.Commands.ShrinkExpandWPF: if (args.Length != 6) { const string Message = "remote command: wrong number of arguments"; Debug.Assert(false, Message); throw new ArgumentException(Message); } Thread.CurrentThread.Priority = (ThreadPriority)args[0]; ShrinkExpandWPF( profile, (int)args[1], (int)args[2], (string)args[3], (string)args[4], (double)args[5]); break; } profile.End(); } catch (Exception exception) { if (log != null) { log.WriteLine("Recoverable exception: {0}", exception); log.Flush(); } ClientServerCommunication.SendMessage( log, channel, ClientServerCommunication.Commands.Exception, new object[] { exception.ToString() }); if (log != null) { log.WriteLine("Exception response sent"); log.Flush(); } continue; } finally { Thread.CurrentThread.Priority = savedThreadPriority; } if (log != null) { log.WriteLine("Forming response"); log.Flush(); } using (MemoryStream serializedProfileStream = new MemoryStream()) { if (log != null) { log.WriteLine("Serializing profile"); log.Flush(); } new BinaryFormatter().Serialize(serializedProfileStream, profile); if (currentBitmap == null) { if (log != null) { log.WriteLine("Sending 'Done'"); log.Flush(); } ClientServerCommunication.SendMessage( log, channel, ClientServerCommunication.Commands.Done, new object[] { serializedProfileStream.ToArray() }); } else { if (log != null) { log.WriteLine("Sending 'Pending'"); log.Flush(); } ClientServerCommunication.SendMessage( log, channel, ClientServerCommunication.Commands.Pending, new object[] { (string)currentBitmap.BackingName, (int)currentBitmap.Width, (int)currentBitmap.Height, (byte[])serializedProfileStream.ToArray() }, extraResults); } } if (log != null) { log.WriteLine("Sent"); log.Flush(); } } } } catch (Exception exception) { if (log != null) { log.WriteLine("Unrecoverable exception: {0}", exception); log.Flush(); } if (currentBitmap != null) { currentBitmap.Dispose(); } if (!(exception is ClientServerCommunication.ChannelDisconnectedException)) { MessageBox.Show(exception.ToString()); } if (log != null) { log.WriteLine("Terminating abnormally"); log.Flush(); log.Close(); log = null; } return(1); } #pragma warning disable CS0162 // unreachable if (log != null) { log.WriteLine("Terminating normally"); log.Flush(); log.Close(); log = null; } #pragma warning restore CS0162 if (currentBitmap != null) { currentBitmap.Dispose(); } return(0); }