<commit_before>using System;
using System.IO;
using System.Linq;
using Eto.Drawing;
using SD = System.Drawing;
using MonoTouch.UIKit;
using MonoTouch.Foundation;
using MonoTouch.CoreGraphics;

namespace Eto.Platform.iOS.Drawing
{
	public class BitmapDataHandler : BitmapData
	{
		public BitmapDataHandler(Image image, IntPtr data, int scanWidth, int bitsPerPixel, object controlObject)
			: base(image, data, scanWidth, bitsPerPixel, controlObject)
		{
		}

		public override uint TranslateArgbToData(uint argb)
		{
			return argb; //(argb & 0xFF00FF00) | ((argb & 0xFF) << 16) | ((argb & 0xFF0000) >> 16);
		}

		public override uint TranslateDataToArgb(uint bitmapData)
		{
			return bitmapData; //(bitmapData & 0xFF00FF00) | ((bitmapData & 0xFF) << 16) | ((bitmapData & 0xFF0000) >> 16);
		}

		public override bool Flipped
		{
			get
			{
				return false;
			}
		}
	}

	public class BitmapHandler : ImageHandler<UIImage, Bitmap>, IBitmap
	{
		CGDataProvider provider;
		CGImage cgimage;

		public NSMutableData Data { get; private set; }

		public void Create(string fileName)
		{
			Control = new UIImage(fileName);
		}

		public void Create(Stream stream)
		{
			Control = new UIImage(NSData.FromStream(stream));
		}

		internal void Create(UIImage image)
		{
			Control = image;
		}

		public void Create(int width, int height, PixelFormat pixelFormat)
		{			
			switch (pixelFormat)
			{
				case PixelFormat.Format32bppRgba:
					{
						const int numComponents = 4;
						const int bitsPerComponent = 8;
						const int bitsPerPixel = numComponents * bitsPerComponent;
						const int bytesPerPixel = bitsPerPixel / 8;
						int bytesPerRow = bytesPerPixel * width;

						Data = NSMutableData.FromLength(bytesPerRow * height);

						provider = new CGDataProvider(Data.MutableBytes, (int)Data.Length, false);
						cgimage = new CGImage(width, height, bitsPerComponent, bitsPerPixel, bytesPerRow, CGColorSpace.CreateDeviceRGB(), CGBitmapFlags.ByteOrder32Little | CGBitmapFlags.PremultipliedFirst, provider, null, true, CGColorRenderingIntent.Default);
						Control = UIImage.FromImage(cgimage);
				
						break;
					}
				case PixelFormat.Format32bppRgb:
					{
						const int numComponents = 4;
						const int bitsPerComponent = 8;
						const int bitsPerPixel = numComponents * bitsPerComponent;
						const int bytesPerPixel = bitsPerPixel / 8;
						int bytesPerRow = bytesPerPixel * width;
						Data = NSMutableData.FromLength(bytesPerRow * height);
						//Data = new NSMutableData ((uint)(bytesPerRow * height));
				
						provider = new CGDataProvider(Data.MutableBytes, (int)Data.Length, false);
						cgimage = new CGImage(width, height, bitsPerComponent, bitsPerPixel, bytesPerRow, CGColorSpace.CreateDeviceRGB(), CGBitmapFlags.ByteOrder32Little | CGBitmapFlags.NoneSkipFirst, provider, null, true, CGColorRenderingIntent.Default);
						Control = UIImage.FromImage(cgimage);
				
						break;
					}
				case PixelFormat.Format24bppRgb:
					{
						const int numComponents = 3;
						const int bitsPerComponent = 8;
						const int bitsPerPixel = numComponents * bitsPerComponent;
						const int bytesPerPixel = bitsPerPixel / 8;
						int bytesPerRow = bytesPerPixel * width;
						Data = new NSMutableData((uint)(bytesPerRow * height));
				
						provider = new CGDataProvider(Data.MutableBytes, (int)Data.Length, false);
						cgimage = new CGImage(width, height, bitsPerComponent, bitsPerPixel, bytesPerRow, CGColorSpace.CreateDeviceRGB(), CGBitmapFlags.ByteOrder32Little | CGBitmapFlags.PremultipliedFirst, provider, null, true, CGColorRenderingIntent.Default);
						Control = UIImage.FromImage(cgimage);
						break;
					}
				default:
					throw new ArgumentOutOfRangeException("pixelFormat", pixelFormat, "Not supported");
			}
		}

		public void Create(Image image, int width, int height, ImageInterpolation interpolation)
		{
			var source = image.ToUI();
			// todo: use interpolation
			Control = source.Scale(new SD.SizeF(width, height));
		}

		public void Create(int width, int height, Graphics graphics)
		{
			Create(width, height, PixelFormat.Format32bppRgba);
		}

		public BitmapData Lock()
		{
			cgimage = cgimage ?? Control.CGImage;
			return new BitmapDataHandler(Widget, Data.MutableBytes, cgimage.BytesPerRow, cgimage.BitsPerPixel, Control);
		}

		public void Unlock(BitmapData bitmapData)
		{
			// don't need to do anythin
		}

		public void Save(Stream stream, ImageFormat format)
		{
			NSData data;
			switch (format)
			{
				case ImageFormat.Jpeg:
					data = Control.AsJPEG();
					break;
				case ImageFormat.Png:
					data = Control.AsPNG();
					break;
				case ImageFormat.Bitmap:
				case ImageFormat.Gif:
				case ImageFormat.Tiff:
				default:
					throw new NotSupportedException();
			}
			data.AsStream().CopyTo(stream);
			data.Dispose();
		}

		public override Size Size
		{
			get { return Control.Size.ToEtoSize(); }
		}

		public override void DrawImage(GraphicsHandler graphics, float x, float y)
		{
			var nsimage = Control;
			var destRect = graphics.TranslateView(new SD.RectangleF(x, y, (int)nsimage.Size.Width, (int)nsimage.Size.Height), false);
			nsimage.Draw(destRect, CGBlendMode.Normal, 1);
		}

		public override void DrawImage(GraphicsHandler graphics, RectangleF source, RectangleF destination)
		{
			var sourceRect = source.ToSD();
			var imgsize = Control.Size;
			SD.RectangleF destRect = graphics.TranslateView(destination.ToSD(), false);
			if (source.TopLeft != Point.Empty || sourceRect.Size != imgsize)
			{
				graphics.Control.TranslateCTM(destRect.X - sourceRect.X, imgsize.Height - (destRect.Y - sourceRect.Y));
				graphics.Control.ScaleCTM(imgsize.Width / sourceRect.Width, -(imgsize.Height / sourceRect.Height));
				graphics.Control.DrawImage(new SD.RectangleF(SD.PointF.Empty, destRect.Size), Control.CGImage);
			}
			else<commit_msg>iOS: Fix cloning or drawing a portion of an image. Fixes #179<commit_after>using System;
using System.IO;
using System.Linq;
using Eto.Drawing;
using SD = System.Drawing;
using MonoTouch.UIKit;
using MonoTouch.Foundation;
using MonoTouch.CoreGraphics;

namespace Eto.Platform.iOS.Drawing
{
	public class BitmapDataHandler : BitmapData
	{
		public BitmapDataHandler(Image image, IntPtr data, int scanWidth, int bitsPerPixel, object controlObject)
			: base(image, data, scanWidth, bitsPerPixel, controlObject)
		{
		}

		public override uint TranslateArgbToData(uint argb)
		{
			return argb; //(argb & 0xFF00FF00) | ((argb & 0xFF) << 16) | ((argb & 0xFF0000) >> 16);
		}

		public override uint TranslateDataToArgb(uint bitmapData)
		{
			return bitmapData; //(bitmapData & 0xFF00FF00) | ((bitmapData & 0xFF) << 16) | ((bitmapData & 0xFF0000) >> 16);
		}

		public override bool Flipped
		{
			get
			{
				return false;
			}
		}
	}

	public class BitmapHandler : ImageHandler<UIImage, Bitmap>, IBitmap
	{
		CGDataProvider provider;
		CGImage cgimage;

		public NSMutableData Data { get; private set; }

		public void Create(string fileName)
		{
			Control = new UIImage(fileName);
		}

		public void Create(Stream stream)
		{
			Control = new UIImage(NSData.FromStream(stream));
		}

		internal void Create(UIImage image)
		{
			Control = image;
		}

		public void Create(int width, int height, PixelFormat pixelFormat)
		{			
			switch (pixelFormat)
			{
				case PixelFormat.Format32bppRgba:
					{
						const int numComponents = 4;
						const int bitsPerComponent = 8;
						const int bitsPerPixel = numComponents * bitsPerComponent;
						const int bytesPerPixel = bitsPerPixel / 8;
						int bytesPerRow = bytesPerPixel * width;

						Data = NSMutableData.FromLength(bytesPerRow * height);

						provider = new CGDataProvider(Data.MutableBytes, (int)Data.Length, false);
						cgimage = new CGImage(width, height, bitsPerComponent, bitsPerPixel, bytesPerRow, CGColorSpace.CreateDeviceRGB(), CGBitmapFlags.ByteOrder32Little | CGBitmapFlags.PremultipliedFirst, provider, null, true, CGColorRenderingIntent.Default);
						Control = UIImage.FromImage(cgimage);
				
						break;
					}
				case PixelFormat.Format32bppRgb:
					{
						const int numComponents = 4;
						const int bitsPerComponent = 8;
						const int bitsPerPixel = numComponents * bitsPerComponent;
						const int bytesPerPixel = bitsPerPixel / 8;
						int bytesPerRow = bytesPerPixel * width;
						Data = NSMutableData.FromLength(bytesPerRow * height);
						//Data = new NSMutableData ((uint)(bytesPerRow * height));
				
						provider = new CGDataProvider(Data.MutableBytes, (int)Data.Length, false);
						cgimage = new CGImage(width, height, bitsPerComponent, bitsPerPixel, bytesPerRow, CGColorSpace.CreateDeviceRGB(), CGBitmapFlags.ByteOrder32Little | CGBitmapFlags.NoneSkipFirst, provider, null, true, CGColorRenderingIntent.Default);
						Control = UIImage.FromImage(cgimage);
				
						break;
					}
				case PixelFormat.Format24bppRgb:
					{
						const int numComponents = 3;
						const int bitsPerComponent = 8;
						const int bitsPerPixel = numComponents * bitsPerComponent;
						const int bytesPerPixel = bitsPerPixel / 8;
						int bytesPerRow = bytesPerPixel * width;
						Data = new NSMutableData((uint)(bytesPerRow * height));
				
						provider = new CGDataProvider(Data.MutableBytes, (int)Data.Length, false);
						cgimage = new CGImage(width, height, bitsPerComponent, bitsPerPixel, bytesPerRow, CGColorSpace.CreateDeviceRGB(), CGBitmapFlags.ByteOrder32Little | CGBitmapFlags.PremultipliedFirst, provider, null, true, CGColorRenderingIntent.Default);
						Control = UIImage.FromImage(cgimage);
						break;
					}
				default:
					throw new ArgumentOutOfRangeException("pixelFormat", pixelFormat, "Not supported");
			}
		}

		public void Create(Image image, int width, int height, ImageInterpolation interpolation)
		{
			var source = image.ToUI();
			// todo: use interpolation
			Control = source.Scale(new SD.SizeF(width, height));
		}

		public void Create(int width, int height, Graphics graphics)
		{
			Create(width, height, PixelFormat.Format32bppRgba);
		}

		public BitmapData Lock()
		{
			cgimage = cgimage ?? Control.CGImage;
			return new BitmapDataHandler(Widget, Data.MutableBytes, cgimage.BytesPerRow, cgimage.BitsPerPixel, Control);
		}

		public void Unlock(BitmapData bitmapData)
		{
			// don't need to do anythin
		}

		public void Save(Stream stream, ImageFormat format)
		{
			NSData data;
			switch (format)
			{
				case ImageFormat.Jpeg:
					data = Control.AsJPEG();
					break;
				case ImageFormat.Png:
					data = Control.AsPNG();
					break;
				case ImageFormat.Bitmap:
				case ImageFormat.Gif:
				case ImageFormat.Tiff:
				default:
					throw new NotSupportedException();
			}
			data.AsStream().CopyTo(stream);
			data.Dispose();
		}

		public override Size Size
		{
			get { return Control.Size.ToEtoSize(); }
		}

		public override void DrawImage(GraphicsHandler graphics, float x, float y)
		{
			var nsimage = Control;
			var destRect = graphics.TranslateView(new SD.RectangleF(x, y, (int)nsimage.Size.Width, (int)nsimage.Size.Height), false);
			nsimage.Draw(destRect, CGBlendMode.Normal, 1);
		}

		public override void DrawImage(GraphicsHandler graphics, RectangleF source, RectangleF destination)
		{
			var sourceRect = source.ToSD();
			var imgsize = Control.Size;
			SD.RectangleF destRect = graphics.TranslateView(destination.ToSD(), false);
			if (source.TopLeft != Point.Empty || sourceRect.Size != imgsize)
			{
				graphics.Control.TranslateCTM(destRect.X - sourceRect.X, imgsize.Height + (destRect.Y - sourceRect.Y));
				graphics.Control.ScaleCTM(imgsize.Width / sourceRect.Width, -(imgsize.Height / sourceRect.Height));
				graphics.Control.DrawImage(new SD.RectangleF(SD.PointF.Empty, destRect.Size), Control.CGImage);
			}
			else
{'fraction_non_alphanumeric': 0.09977883633889077, 'fraction_numerical': 0.009441987070432119, 'mean_word_length': 3.7065652522017616, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4222247', 'n_tokens_mistral': 4556, 'n_tokens_neox': 3587, 'n_words': 880}