예제 #1
0
 protected override void Dispose(bool disposing)
 {
     if (disposing)
     {
         if (this.disposeDocument && (this.documentCanvas.Document != null))
         {
             PaintDotNet.Document document = this.documentCanvas.Document;
             this.documentCanvas.Document = null;
             document.Dispose();
         }
         this.CleanupTimer();
         if (this.handIcon != null)
         {
             this.handIcon.Dispose();
             this.handIcon = null;
         }
         if (this.handIconMouseDown != null)
         {
             this.handIconMouseDown.Dispose();
             this.handIconMouseDown = null;
         }
         if (this.components != null)
         {
             this.components.Dispose();
             this.components = null;
         }
     }
     base.Dispose(disposing);
 }
예제 #2
0
        private void DocumentSetImpl(PaintDotNet.Document value)
        {
            PointDouble documentScrollPosition = this.DocumentScrollPosition;

            this.OnDocumentChanging(value);
            this.SuspendRefresh();
            try
            {
                if (this.document != null)
                {
                    this.document.Metadata.Changed -= new EventHandler(this.DocumentMetadataChangedHandler);
                    this.document.Invalidated      -= new EventHandler <RectInt32InvalidatedEventArgs>(this.DocumentInvalidated);
                }
                this.document = value;
                this.documentCanvas.Document = value;
                if (this.document != null)
                {
                    this.document.Metadata.Changed += new EventHandler(this.DocumentMetadataChangedHandler);
                    this.document.Invalidated      += new EventHandler <RectInt32InvalidatedEventArgs>(this.DocumentInvalidated);
                }
                base.Invalidate(true);
                this.DocumentMetadataChangedHandler(this, EventArgs.Empty);
                this.OnResize(EventArgs.Empty);
                this.OnDocumentChanged();
            }
            finally
            {
                this.ResumeRefresh();
            }
            this.DocumentScrollPosition = documentScrollPosition;
            this.RaiseCanvasLayout();
        }
예제 #3
0
 private void UpdateFileSizeAndPreview(string tempFileName)
 {
     if (!base.IsDisposed)
     {
         if (tempFileName == null)
         {
             string str = PdnResources.GetString("SaveConfigDialog.FileSizeText.Text.Error");
             this.previewHeader.Text = string.Format(this.fileSizeTextFormat, str);
         }
         else
         {
             FileInfo info   = new FileInfo(tempFileName);
             long     length = info.Length;
             this.previewHeader.Text    = string.Format(this.fileSizeTextFormat, SizeStringFromBytes(length));
             this.canvasControl.Visible = true;
             using (PaintDotNet.Document document = null)
             {
                 if (this.disposeDocument && (this.documentCanvas.Document != null))
                 {
                     document = this.documentCanvas.Document;
                 }
                 if (this.fileType.IsReflexive(this.SaveConfigToken))
                 {
                     this.documentCanvas.Document = this.Document;
                     this.disposeDocument         = false;
                 }
                 else
                 {
                     PaintDotNet.Document document2;
                     FileStream           input = new FileStream(tempFileName, FileMode.Open, FileAccess.Read, FileShare.Read);
                     try
                     {
                         CleanupManager.RequestCleanup();
                         document2 = this.fileType.Load(input);
                     }
                     catch (Exception)
                     {
                         document2 = null;
                         string str2 = PdnResources.GetString("SaveConfigDialog.FileSizeText.Text.Error");
                         this.previewHeader.Text = string.Format(this.fileSizeTextFormat, str2);
                     }
                     input.Close();
                     if (document2 != null)
                     {
                         this.documentCanvas.Document = document2;
                         this.disposeDocument         = true;
                     }
                     CleanupManager.RequestCleanup();
                 }
                 try
                 {
                     info.Delete();
                 }
                 catch (Exception)
                 {
                 }
             }
         }
     }
 }
예제 #4
0
        public static void LoadProperties(Image dstImage, Document srcDoc)
        {
            Bitmap asBitmap = dstImage as Bitmap;

            if (asBitmap != null)
            {
                // Sometimes GDI+ does not honor the resolution tags that we
                // put in manually via the EXIF properties.
                float dpiX;
                float dpiY;

                switch (srcDoc.DpuUnit)
                {
                    case MeasurementUnit.Centimeter:
                        dpiX = (float)Document.DotsPerCmToDotsPerInch(srcDoc.DpuX);
                        dpiY = (float)Document.DotsPerCmToDotsPerInch(srcDoc.DpuY);
                        break;

                    case MeasurementUnit.Inch:
                        dpiX = (float)srcDoc.DpuX;
                        dpiY = (float)srcDoc.DpuY;
                        break;

                    default:
                    case MeasurementUnit.Pixel:
                        dpiX = 1.0f;
                        dpiY = 1.0f;
                        break;
                }

                try
                {
                    asBitmap.SetResolution(dpiX, dpiY);
                }

                catch (Exception)
                {
                    // Ignore error
                }
            }

            Metadata metaData = srcDoc.Metadata;

            foreach (string key in metaData.GetKeys(Metadata.ExifSectionName))
            {
                string blob = metaData.GetValue(Metadata.ExifSectionName, key);
                PropertyItem pi = PdnGraphics.DeserializePropertyItem(blob);

                try
                {
                    dstImage.SetPropertyItem(pi);
                }

                catch (ArgumentException)
                {
                    // Ignore error: the image does not support property items
                }
            }
        }
예제 #5
0
 public CompositionBenchmark(string name, Document composeMe, 
     Surface dstSurface, SetLayerInfoDelegate sliDelegate)
     : base(name)
 {
     this.composeMe = composeMe;
     this.dstSurface = dstSurface;
     this.sliDelegate = sliDelegate;
 }
예제 #6
0
 protected override void Dispose(bool disposing)
 {
     if (disposing && (this.document != null))
     {
         this.document.Dispose();
         this.document = null;
     }
     base.Dispose(disposing);
 }
예제 #7
0
 public DocumentView()
 {
     this.InitializeComponent();
     this.documentCanvas.CompositionIdle += new EventHandler(this.OnDocumentCanvasCompositionIdle);
     this.scrollableCanvasControl.Canvas  = this.documentCanvas;
     this.scrollableCanvasControl.CanvasView.ViewportCanvasOffsetChanged += new ValueChangedEventHandler <PointDouble>(this.OnViewportCanvasOffsetChanged);
     this.scrollableCanvasControl.CanvasView.ScaleRatioChanged           += new ValueChangedEventHandler <double>(this.OnScaleRatioChanged);
     PixelGridCanvasLayer.AddIsPixelGridEnabledChangedHandler(this.scrollableCanvasControl.CanvasView, new ValueChangedEventHandler <bool>(this.OnCanvasViewIsPixelGridEnabledChanged));
     this.document = null;
 }
예제 #8
0
 protected override void OnSave(Document input, Stream output, SaveConfigToken token, Surface scratchSurface, ProgressEventHandler callback)
 {
     if (callback == null)
     {
         input.SaveToStream(output);
     }
     else
     {
         UpdateProgressTranslator upt = new UpdateProgressTranslator(ApproximateMaxOutputOffset(input), callback);
         input.SaveToStream(output, new IOEventHandler(upt.IOEventHandler));
     }
 }
예제 #9
0
        protected override void OnSave(Document input, Stream output, SaveConfigToken token, Surface scratchSurface, ProgressEventHandler progressCallback)
        {
            GifSaveConfigToken gsct = (GifSaveConfigToken)token;

            // Flatten and pre-process the image
            scratchSurface.Clear(ColorBgra.FromBgra(255, 255, 255, 0));

            using (RenderArgs ra = new RenderArgs(scratchSurface))
            {
                input.Render(ra, true);
            }

            for (int y = 0; y < scratchSurface.Height; ++y)
            {
                unsafe
                {
                    ColorBgra* ptr = scratchSurface.GetRowAddressUnchecked(y);

                    for (int x = 0; x < scratchSurface.Width; ++x)
                    {
                        if (ptr->A < gsct.Threshold)
                        {
                            ptr->Bgra = 0;
                        }
                        else
                        {
                            if (gsct.PreMultiplyAlpha)
                            {
                                int r = ((ptr->R * ptr->A) + (255 * (255 - ptr->A))) / 255;
                                int g = ((ptr->G * ptr->A) + (255 * (255 - ptr->A))) / 255;
                                int b = ((ptr->B * ptr->A) + (255 * (255 - ptr->A))) / 255;
                                int a = 255;

                                *ptr = ColorBgra.FromBgra((byte)b, (byte)g, (byte)r, (byte)a);
                            }
                            else
                            {
                                ptr->Bgra |= 0xff000000;
                            }
                        }

                        ++ptr;
                    }
                }
            }

            using (Bitmap quantized = Quantize(scratchSurface, gsct.DitherLevel, 255, progressCallback))
            {
                quantized.Save(output, ImageFormat.Gif);
            }
        }
예제 #10
0
        protected override unsafe void OnSave( Document input, Stream output, SaveConfigToken token, Surface scratchSurface, ProgressEventHandler callback )
		{
			DdsSaveConfigToken ddsToken = ( DdsSaveConfigToken )token;

			// We need to be able to feast on the goo inside..
			scratchSurface.Clear( ColorBgra.Transparent );

			using ( RenderArgs ra = new RenderArgs( scratchSurface ) )
			{
				input.Render( ra, true );
			}

			// Create the DDS file, and save it..
			DdsFile ddsFile = new DdsFile();
			ddsFile.Save( output, scratchSurface, ddsToken, callback );
		}
 public DocumentCanvasLayerView(DocumentCanvasLayer owner, PaintDotNet.Canvas.CanvasView canvasView, IList <DocumentCanvasTileCache> tileCaches)
 {
     Validate.Begin().IsNotNull <DocumentCanvasLayer>(owner, "owner").IsNotNull <PaintDotNet.Canvas.CanvasView>(canvasView, "canvasView").IsNotNull <IList <DocumentCanvasTileCache> >(tileCaches, "tileCaches").Check();
     this.owner      = owner;
     this.document   = this.owner.Document;
     this.canvasView = canvasView;
     this.canvasView.IsVisibleChanged += new ValueChangedEventHandler <bool>(this.OnCanvasViewIsVisibleChanged);
     this.tileCaches = tileCaches;
     this.mipLayers  = new DocumentCanvasLayerViewMipLayer[this.tileCaches.Count];
     for (int i = 0; i < this.mipLayers.Length; i++)
     {
         this.mipLayers[i] = new DocumentCanvasLayerViewMipLayer(this, this.tileCaches[i].TileMathHelper.TileEdgeLog2, i, this.tileCaches[i]);
     }
     this.deviceBitmapPool = new ObjectPool <SizeInt32, IDeviceBitmap>(new Func <SizeInt32, IDeviceBitmap>(this.CreateDeviceBitmap), new Action <SizeInt32, IDeviceBitmap>(this.DisposeDeviceBitmap));
     this.mipLayerZOrder   = new List <DocumentCanvasLayerViewMipLayer>();
 }
예제 #12
0
 protected override Document OnLoad(Stream input)
 {
     // This allows us to open images that were created in Explorer using New -> Bitmap Image
     // which actually just creates a 0-byte file
     if (input.Length == 0)
     {
         Document newDoc = new Document(800, 600);
         Layer layer = Layer.CreateBackgroundLayer(newDoc.Width, newDoc.Height);
         newDoc.Layers.Add(layer);
         return newDoc;
     }
     else
     {
         return base.OnLoad(input);
     }
 }
예제 #13
0
        public static void Save(Document input, Stream output, Surface scratchSurface, ImageFormat format, ProgressEventHandler callback)
        {
            // flatten the document
            scratchSurface.Clear(ColorBgra.FromBgra(0, 0, 0, 0));

            using (RenderArgs ra = new RenderArgs(scratchSurface))
            {
                input.Render(ra, true);
            }

            using (Bitmap bitmap = scratchSurface.CreateAliasedBitmap())
            {
                LoadProperties(bitmap, input);
                bitmap.Save(output, format);
            }
        }
예제 #14
0
        protected override void OnSave(Document input, Stream output, SaveConfigToken token, Surface scratchSurface, ProgressEventHandler callback)
        {
            ImageCodecInfo icf = GdiPlusFileType.GetImageCodecInfo(ImageFormat.Bmp);
            EncoderParameters parms = new EncoderParameters(1);
            EncoderParameter parm = new EncoderParameter(System.Drawing.Imaging.Encoder.ColorDepth, 24); // BMP's should always save as 24-bit
            parms.Param[0] = parm;

            scratchSurface.Clear(ColorBgra.White);

            using (RenderArgs ra = new RenderArgs(scratchSurface))
            {
                input.Render(ra, true);
            }

            // In order to save memory, we 'squish' the 32-bit bitmap down to 24-bit in-place
            // instead of allocating a new bitmap and copying it over.
            SquishSurfaceTo24Bpp(scratchSurface);

            using (Bitmap bitmap = CreateAliased24BppBitmap(scratchSurface))
            {
                GdiPlusFileType.LoadProperties(bitmap, input);
                bitmap.Save(output, icf, parms);
            }
        }
예제 #15
0
        public void Save(
            Document input,
            Stream output,
            SaveConfigToken token,
            Surface scratchSurface,
            ProgressEventHandler callback,
            bool rememberToken)
        {
            if (!this.SupportsSaving)
            {
                throw new NotImplementedException("Saving is not supported by this FileType");
            }
            else
            {
                Surface disposeMe = null;

                if (scratchSurface == null)
                {
                    disposeMe = new Surface(input.Size);
                    scratchSurface = disposeMe;
                }
                else if (scratchSurface.Size != input.Size)
                {
                    throw new ArgumentException("scratchSurface.Size must equal input.Size");
                }

                if (rememberToken)
                {
                    Type ourType = this.GetType();
                    string savedTokenName = ourType.Namespace + "." + ourType.Name;
                    SoapFormatter soap = new SoapFormatter();
                    MemoryStream ms = new MemoryStream();
                    soap.Serialize(ms, token);
                    byte[] bytes = ms.GetBuffer();
                    string utf8 = Encoding.UTF8.GetString(bytes);
                    Settings.CurrentUser.SetString(savedTokenName, utf8);
                }

                if (!this.SavesWithProgress)
                {
                    try
                    {
                        OnSave(input, output, token, scratchSurface, null);
                    }

                    catch (OnSaveNotImplementedException)
                    {
                        OldOnSaveTrampoline(input, output, token, null);
                    }
                }
                else
                {
                    try
                    {
                        OnSave(input, output, token, scratchSurface, callback);
                    }

                    catch (OnSaveNotImplementedException)
                    {
                        OldOnSaveTrampoline(input, output, token, callback);
                    }
                }

                if (disposeMe != null)
                {
                    disposeMe.Dispose();
                    disposeMe = null;
                }
            }
        }
예제 #16
0
 protected virtual void OnSave(Document input, Stream output, SaveConfigToken token, ProgressEventHandler callback)
 {
 }
예제 #17
0
 private long ApproximateMaxOutputOffset(Document measureMe)
 {
     return (long)measureMe.Layers.Count * (long)measureMe.Width * (long)measureMe.Height * (long)ColorBgra.SizeOf;
 }
예제 #18
0
 public void Save(Document input, Stream output, SaveConfigToken token, ProgressEventHandler callback, bool rememberToken)
 {
     using (Surface scratch = new Surface(input.Width, input.Height))
     {
         Save(input, output, token, callback, rememberToken);
     }
 }
예제 #19
0
 protected virtual void OnDocumentChanging(PaintDotNet.Document newDocument)
 {
     this.DocumentChanging.Raise <PaintDotNet.Document>(this, newDocument);
 }
예제 #20
0
 protected override void OnSave(Document input, Stream output, SaveConfigToken token, Surface scratchSurface, ProgressEventHandler callback)
 {
     GdiPlusFileType.Save(input, output, scratchSurface, this.ImageFormat, callback);
 }
예제 #21
0
        internal override void FinalSave(
            Document input, 
            Stream output, 
            Surface scratchSurface, 
            int ditherLevel, 
            SavableBitDepths bitDepth,
            PropertyBasedSaveConfigToken token,
            ProgressEventHandler progressCallback)
        {
            // finally, do the save.
            if (bitDepth == SavableBitDepths.Rgb24)
            {
                // In order to save memory, we 'squish' the 32-bit bitmap down to 24-bit in-place
                // instead of allocating a new bitmap and copying it over.
                SquishSurfaceTo24Bpp(scratchSurface);

                ImageCodecInfo icf = GdiPlusFileType.GetImageCodecInfo(ImageFormat.Bmp);
                EncoderParameters parms = new EncoderParameters(1);
                EncoderParameter parm = new EncoderParameter(Encoder.ColorDepth, 24);
                parms.Param[0] = parm;

                using (Bitmap bitmap = CreateAliased24BppBitmap(scratchSurface))
                {
                    GdiPlusFileType.LoadProperties(bitmap, input);
                    bitmap.Save(output, icf, parms);
                }
            }
            else if (bitDepth == SavableBitDepths.Rgb8)
            {
                using (Bitmap quantized = Quantize(scratchSurface, ditherLevel, 256, false, progressCallback))
                {
                    ImageCodecInfo icf = GdiPlusFileType.GetImageCodecInfo(ImageFormat.Bmp);
                    EncoderParameters parms = new EncoderParameters(1);
                    EncoderParameter parm = new EncoderParameter(Encoder.ColorDepth, 8);
                    parms.Param[0] = parm;

                    GdiPlusFileType.LoadProperties(quantized, input);
                    quantized.Save(output, icf, parms);
                }
            }
            else
            {
                throw new InvalidEnumArgumentException("bitDepth", (int)bitDepth, typeof(SavableBitDepths));
            }
        }
예제 #22
0
 public LayerList(Document parent)
 {
     this.parent = parent;
 }
예제 #23
0
        protected override Document OnLoad(System.IO.Stream input)
        {
            TgaHeader header = new TgaHeader(input);
            bool compressed;

            switch (header.imageType)
            {
                case TgaType.Map:
                case TgaType.Rgb:
                case TgaType.Mono:
                    compressed = false;
                    break;
                    
                case TgaType.RleMap:
                case TgaType.RleRgb:
                case TgaType.RleMono:
                    compressed = true;
                    break;

                default:
                    throw new FormatException("unknown TGA image type");
            }

            if (header.imageWidth == 0 || 
                header.imageHeight == 0 || 
                header.pixelDepth == 0 || 
                header.cmapLength > 256)
            {
                throw new FormatException("bad TGA header");
            }

            if (header.pixelDepth != 8 && 
                header.pixelDepth != 15 && 
                header.pixelDepth != 16 && 
                header.pixelDepth != 24 && 
                header.pixelDepth != 32)
            {
                throw new FormatException("bad TGA header: pixelDepth not one of {8, 15, 16, 24, 32}");
            }

            if (header.idLength > 0)
            {
                input.Position += header.idLength; // skip descriptor
            }

            BitmapLayer layer = Layer.CreateBackgroundLayer(header.imageWidth, header.imageHeight);

            try
            {
                Surface surface = layer.Surface;
                surface.Clear((ColorBgra)0xffffffff);

                ColorBgra[] palette = null;
                if (header.cmapType != 0)
                {
                    palette = LoadPalette(input, header.cmapLength);
                }

                if (header.imageType == TgaType.Mono ||
                    header.imageType == TgaType.RleMono)
                {
                    palette = CreateGrayPalette();
                }

                // Bits 0 - 3 of the image descriptor byte describe number of bits used for alpha channel
                // For loading, we won't worry about this. Not all TGA implementations are correct (such
                // as older Paint.NET TGA implementations!) and we don't want to lose all their alpha bits.
                //int alphaBits = header.imageDesc & 0xf;

                // Bits 4 & 5 of the image descriptor byte control the ordering of the pixels
                bool xReversed = ((header.imageDesc & 16) == 16);
                bool yReversed = ((header.imageDesc & 32) == 32);            

                byte rleLeftOver = 255; // for images with illegal packet boundary

                for (int y = 0; y < header.imageHeight; ++y)
                {
                    MemoryBlock dstRow;

                    if (yReversed)
                    {
                        dstRow = surface.GetRow(y);
                    }
                    else
                    {
                        dstRow = surface.GetRow(header.imageHeight - y - 1);
                    }

                    if (compressed)
                    {
                        rleLeftOver = ExpandCompressedLine(dstRow, 0, ref header, input, header.imageWidth, y, rleLeftOver, palette);
                    }
                    else
                    {
                        ExpandUncompressedLine(dstRow, 0, ref header, input, header.imageWidth, y, 0, palette);
                    }
                }

                if (xReversed)
                {
                    MirrorX(surface);
                }

                Document document = new Document(surface.Width, surface.Height);
                document.Layers.Add(layer);
                return document;
            }

            catch
            {
                if (layer != null)
                {
                    layer.Dispose();
                    layer = null;
                }

                throw;
            }
        }
예제 #24
0
 internal override void FinalSave(
     Document input, 
     Stream output, 
     Surface scratchSurface, 
     int ditherLevel, 
     SavableBitDepths bitDepth, 
     PropertyBasedSaveConfigToken token, 
     ProgressEventHandler progressCallback)
 {
     bool rleCompress = token.GetProperty<BooleanProperty>(PropertyNames.RleCompress).Value;
     SaveTga(scratchSurface, output, bitDepth, rleCompress, progressCallback);
 }
예제 #25
0
        private void OnSaveImpl(
            Document input, 
            Stream output, 
            SaveConfigToken token, 
            Surface scratchSurface, 
            ProgressEventHandler callback)
        {
            HDPhotoSaveConfigToken hdToken = token as HDPhotoSaveConfigToken;
            WmpBitmapEncoder wbe = new WmpBitmapEncoder();

            using (RenderArgs ra = new RenderArgs(scratchSurface))
            {
                input.Render(ra, true);
            }

            MemoryBlock block = scratchSurface.Scan0;
            IntPtr scan0 = block.Pointer;

            double dpiX;
            double dpiY;

            switch (input.DpuUnit)
            {
                case MeasurementUnit.Centimeter:
                    dpiX = Document.DotsPerCmToDotsPerInch(input.DpuX);
                    dpiY = Document.DotsPerCmToDotsPerInch(input.DpuY);
                    break;

                case MeasurementUnit.Inch:
                    dpiX = input.DpuX;
                    dpiY = input.DpuY;
                    break;

                case MeasurementUnit.Pixel:
                    dpiX = Document.GetDefaultDpu(MeasurementUnit.Inch);
                    dpiY = Document.GetDefaultDpu(MeasurementUnit.Inch);
                    break;

                default:
                    throw new InvalidEnumArgumentException();
            }

            BitmapSource bitmapSource = BitmapFrame.Create(
                scratchSurface.Width,
                scratchSurface.Height,
                dpiX,
                dpiY,
                System.Windows.Media.PixelFormats.Bgra32,
                null,
                scan0,
                (int)block.Length, // TODO: does not support >2GB images
                scratchSurface.Stride);

            FormatConvertedBitmap fcBitmap = new FormatConvertedBitmap(
                bitmapSource,
                hdToken.BitDepth == 24 ? PixelFormats.Bgr24 : PixelFormats.Bgra32,
                null,
                0);

            BitmapFrame outputFrame0 = BitmapFrame.Create(fcBitmap);

            wbe.Frames.Add(outputFrame0);
            wbe.ImageQualityLevel = (float)hdToken.Quality / 100.0f;

            string tempFileName = FileSystem.GetTempFileName();

            FileStream tempFileOut = new FileStream(tempFileName, FileMode.Create, FileAccess.Write, FileShare.Read);
            wbe.Save(tempFileOut);
            tempFileOut.Close();
            tempFileOut = null;

            FileStream tempFileIn = new FileStream(tempFileName, FileMode.Open, FileAccess.ReadWrite, FileShare.Read);
            WmpBitmapDecoder wbd = new WmpBitmapDecoder(tempFileIn, BitmapCreateOptions.None, BitmapCacheOption.None);
            BitmapFrame ioFrame0 = wbd.Frames[0];
            InPlaceBitmapMetadataWriter metadata2 = ioFrame0.CreateInPlaceBitmapMetadataWriter();
            CopyMetadataTo(metadata2, input.Metadata);
            tempFileIn.Close();
            tempFileIn = null;

            FileStream tempFileIn2 = new FileStream(tempFileName, FileMode.Open, FileAccess.ReadWrite, FileShare.Read);
            Utility.CopyStream(tempFileIn2, output);
            tempFileIn2.Close();
            tempFileIn2 = null;

            try
            {
                File.Delete(tempFileName);
            }

            catch (Exception)
            {
            }

            // WPF doesn't give us an IDisposable implementation on its types
            Utility.GCFullCollect();
        }
예제 #26
0
        public void Save(
            Document input, 
            Stream output, 
            SaveConfigToken token, 
            Surface scratchSurface, 
            ProgressEventHandler callback, 
            bool rememberToken)
        {
            Tracing.LogFeature("Save(" + GetType().FullName + ")");

            if (!this.SupportsSaving)
            {
                throw new NotImplementedException("Saving is not supported by this FileType");
            }
            else
            {
                Surface disposeMe = null;

                if (scratchSurface == null)
                {
                    disposeMe = new Surface(input.Size);
                    scratchSurface = disposeMe;
                }
                else if (scratchSurface.Size != input.Size)
                {
                    throw new ArgumentException("scratchSurface.Size must equal input.Size");
                }

                if (rememberToken)
                {
                    Type ourType = this.GetType();
                    string savedTokenName = "SaveConfigToken." + ourType.Namespace + "." + ourType.Name + ".BinaryFormatter";

                    MemoryStream ms = new MemoryStream();

                    BinaryFormatter formatter = new BinaryFormatter();
                    DeferredFormatter deferredFormatter = new DeferredFormatter(false, null);
                    StreamingContext streamingContext = new StreamingContext(formatter.Context.State, deferredFormatter);
                    formatter.Context = streamingContext;

                    object tokenSubset = GetSerializablePortionOfSaveConfigToken(token);

                    formatter.Serialize(ms, tokenSubset);
                    deferredFormatter.FinishSerialization(ms);

                    byte[] bytes = ms.GetBuffer();
                    string base64Bytes = Convert.ToBase64String(bytes);

                    Settings.CurrentUser.SetString(savedTokenName, base64Bytes);
                }

                try
                {
                    OnSave(input, output, token, scratchSurface, callback);
                }

                catch (OnSaveNotImplementedException)
                {
                    OldOnSaveTrampoline(input, output, token, callback);
                }

                if (disposeMe != null)
                {
                    disposeMe.Dispose();
                    disposeMe = null;
                }
            }
        }
예제 #27
0
		protected override Document OnLoad( Stream input )
		{
			DdsFile	ddsFile	= new DdsFile();
			ddsFile.Load( input );

			BitmapLayer layer			= Layer.CreateBackgroundLayer( ddsFile.GetWidth(), ddsFile.GetHeight() );
			Surface		surface			= layer.Surface;
			ColorBgra	writeColour		= new ColorBgra();

			byte[]		readPixelData	= ddsFile.GetPixelData();

			for ( int y = 0; y < ddsFile.GetHeight(); y++ )
			{
				for ( int x = 0; x < ddsFile.GetWidth(); x++ )
				{
					int			readPixelOffset = ( y * ddsFile.GetWidth() * 4 ) + ( x * 4 );
					
					writeColour.R = readPixelData[ readPixelOffset + 0 ];
					writeColour.G = readPixelData[ readPixelOffset + 1 ];
					writeColour.B = readPixelData[ readPixelOffset + 2 ];
					writeColour.A = readPixelData[ readPixelOffset + 3 ];

					surface[ x, y ] = writeColour;
				}
			}

			// Create a document, add the surface layer to it, and return to caller.
			Document	document	= new Document( surface.Width, surface.Height );
			document.Layers.Add( layer );
			return document;
		}
예제 #28
0
 protected virtual void OnSave(Document input, Stream output, SaveConfigToken token, Surface scratchSurface, ProgressEventHandler callback)
 {
     throw new OnSaveNotImplementedException("Derived classes must implement this method. It is virtual instead of abstract in order to maintain compatibility with legacy plugins.");
 }
예제 #29
0
        protected override void OnSave(
            Document input, 
            Stream output, 
            SaveConfigToken token, 
            Surface scratchSurface, 
            ProgressEventHandler callback)
        {
            switch (Thread.CurrentThread.GetApartmentState())
            {
                // WIC does not support MTA, so we must marshal this stuff to another thread that is guaranteed to be STA.
                case ApartmentState.Unknown:
                case ApartmentState.MTA:
                    ParameterizedThreadStart pts = new ParameterizedThreadStart(OnSaveThreadProc);

                    OnSaveArgs osa = new OnSaveArgs();
                    osa.input = input;
                    osa.output = output;
                    osa.token = token;
                    osa.scratchSurface = scratchSurface;
                    osa.callback = callback;

                    Thread staThread = new Thread(pts);
                    staThread.SetApartmentState(ApartmentState.STA);
                    staThread.Start(osa);
                    staThread.Join();

                    if (osa.exception != null)
                    {
                        throw new ApplicationException("OnSaveImpl() threw an exception", osa.exception);
                    }
                    break;

                case ApartmentState.STA:
                    OnSaveImpl(input, output, token, scratchSurface, callback);
                    break;

                default:
                    throw new InvalidOperationException();
            }
        }
예제 #30
0
        /// <summary>
        /// Because the old OnSave() method is obsolete, we must use reflection to call it.
        /// This is important for legacy FileType plugins. It allows us to ensure that no
        /// new plugins can be compiled using the old OnSave() overload.
        /// </summary>
        private void OldOnSaveTrampoline(Document input, Stream output, SaveConfigToken token, ProgressEventHandler callback)
        {
            MethodInfo onSave = GetType().GetMethod(
                "OnSave",
                BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy,
                Type.DefaultBinder,
                new Type[]
                {
                    typeof(Document),
                    typeof(Stream),
                    typeof(SaveConfigToken),
                    typeof(ProgressEventHandler)
                },
                null);

            onSave.Invoke(
                this,
                new object[]
                {
                    input,
                    output,
                    token,
                    callback
                });
        }
예제 #31
0
        private Document OnLoadImpl(Stream input)
        {
            WmpBitmapDecoder wbd = new WmpBitmapDecoder(input, BitmapCreateOptions.None, BitmapCacheOption.None);
            BitmapFrame frame0 = wbd.Frames[0];

            Document output = new Document(frame0.PixelWidth, frame0.PixelHeight);
            output.DpuUnit = MeasurementUnit.Inch;
            output.DpuX = frame0.DpiX;
            output.DpuY = frame0.DpiY;

            BitmapLayer layer = Layer.CreateBackgroundLayer(output.Width, output.Height);
            MemoryBlock memoryBlock = layer.Surface.Scan0;
            IntPtr scan0 = memoryBlock.Pointer;

            FormatConvertedBitmap fcb = new FormatConvertedBitmap(frame0, System.Windows.Media.PixelFormats.Bgra32, null, 0);

            fcb.CopyPixels(Int32Rect.Empty, scan0, (int)memoryBlock.Length, layer.Surface.Stride);
            output.Layers.Add(layer);

            BitmapMetadata hdMetadata = (BitmapMetadata)frame0.Metadata;
            CopyMetadataTo(output.Metadata, hdMetadata);

            // WPF doesn't give us an IDisposable implementation on its types
            Utility.GCFullCollect();

            return output;
        }
예제 #32
0
        static void Main(string[] args)
        {
            for (int i = 0; i < args.Length; i++)
            {
                switch (args[i])
                {
                    case "/proc":
                        if (i + 1 == args.Length)
                        {
                            Console.WriteLine("Use /proc <N> to specify number of processors");
                            return;
                        }

                        int numProcs;

                        if (Int32.TryParse(args[i + 1], out numProcs))
                        {
                            // only increment i if successful b/c we're going to continue the run
                            // with the default # of processors and don't want to automatically 
                            // eat the next parameter.
                            ++i;
                            Processor.LogicalCpuCount = numProcs;
                        }
                        else
                        {
                            Console.WriteLine("You must specify a integer for /proc <N>, continuing with default");
                        }
                        break;

                    case "/image":
                        if (i + 1 == args.Length)
                        {
                            Console.WriteLine("Use /image <filename> to specify a file to perform benchmark with");
                            return;
                        }

                        ++i;
                        benchmarkImageName = args[i];

                        if (!System.IO.File.Exists(benchmarkImageName))
                        {
                            Console.WriteLine("Specified image doesn't exist");
                            return;
                        }
                        break;

                    case "/tsv":
                        useTsvOutput = true;
                        break;

                    case "/?":
                        PrintHelp();
                        return;

                    default:
                        break;
                }
            }

            //Processor.LogicalCpuCount = 1;
            Console.WriteLine("PdnBench v" + PdnInfo.GetVersion());
            Console.WriteLine("Running in " + (8 * Marshal.SizeOf(typeof(IntPtr))) + "-bit mode on Windows " +
                Environment.OSVersion.Version.ToString() + " " +
                OS.Revision + (OS.Revision.Length > 0 ? " " : string.Empty) +
                OS.Type + " " +
                Processor.NativeArchitecture.ToString().ToLower());

            Console.WriteLine("Processor: " + Processor.LogicalCpuCount + "x \"" + Processor.CpuName + "\" @ ~" + GetCpuSpeed() + " MHz");
            Console.WriteLine("Memory: " + ((Memory.TotalPhysicalBytes / 1024) / 1024) + " MB");
            Console.WriteLine();

            Console.WriteLine("Using " + Processor.LogicalCpuCount + " threads.");

            ArrayList benchmarks = new ArrayList();

            Document document;

            Console.Write("Loading image ... ");

            Stream imageStream = null;
            try
            {
                imageStream = (defaultImageName == benchmarkImageName) ?
                    Assembly.GetExecutingAssembly().GetManifestResourceStream(benchmarkImageName) :
                    new FileStream(benchmarkImageName, FileMode.Open);

                JpegFileType jft = new JpegFileType();
                document = jft.Load(imageStream);
            }

            finally
            {
                if (imageStream != null)
                {
                    imageStream.Dispose();
                }
            }

            Console.WriteLine("(" + document.Width + " x " + document.Height + ") done");

            Surface surface = ((BitmapLayer)document.Layers[0]).Surface;

#if EFFECTS
            for (double i = 0; i < (2 * Math.PI); i += 70.0 * ((2 * Math.PI) / 360.0))
            {
                benchmarks.Add(
                    new EffectBenchmark("Rotate/Zoom at " + ((i * 180.0) / Math.PI).ToString("F2") + " degrees",
                    3,
                    new PaintDotNet.Effects.RotateZoomEffect(),
                    new PaintDotNet.Effects.RotateZoomEffectConfigToken(
                        true,
                        (float)(Math.PI * 0.3f),
                        (float)((Math.PI * -0.4) + i),
                        50,
                        0.5f,
                        new PointF(-0.2f, 0.3f),
                        false,
                        true),
                        surface));
            }

            for (int i = 1; i <= 4; i += 3)
            {
                for (int j = 10; j < 100; j += 75)
                {
                    benchmarks.Add(
                        new EffectBenchmark(
                            "Oil Painting, brush size = " + i + ", coarseness = " + j,
                            1,
                            new OilPaintingEffect(),
                            new TwoAmountsConfigToken(i, j),
                            surface));
                }
            }

            for (int i = 2; i <= 50; i += i)
            {
                benchmarks.Add(
                    new EffectBenchmark(
                        "Blur with radius of " + i,
                        1,
                        new BlurEffect(),
                        new AmountEffectConfigToken(i),
                        surface));
            }

            for (int i = 1; i <= 4; i += 3)
            {
                benchmarks.Add(
                    new EffectBenchmark(
                        "Sharpen with value of " + i,
                        1,
                        new SharpenEffect(),
                        new AmountEffectConfigToken(i),
                        surface));
            }

            benchmarks.Add(
                new EffectBenchmark(
                    "Auto-Levels",
                    50,
                    new AutoLevelEffect(),
                    null,
                    surface));

            for (int i = 81; i >= 5; i /= 3)
            {
                benchmarks.Add(
                    new EffectBenchmark(
                        "Clouds, roughness = " + i,
                        2,
                        new CloudsEffect(),
                        new CloudsEffectConfigToken(50, i, 12345, new UserBlendOps.NormalBlendOp()),
                        surface));
            }

            for (int i = 4; i <= 64; i *= 4)
            {
                benchmarks.Add(
                    new EffectBenchmark(
                        "Median, radius " + i,
                        1,
                        new MedianEffect(),
                        new TwoAmountsConfigToken(/*radius*/i, /*roughness*/50),
                        surface));
            }

            for (int i = 4; i <= 64; i *= 4)
            {
                benchmarks.Add(
                   new EffectBenchmark(
                       "Unfocus, radius " + i,
                       1,
                       new UnfocusEffect(),
                       new AmountEffectConfigToken(i),
                        surface));
            }

            benchmarks.Add(
                new EffectBenchmark(
                    "Motion Blur, Horizontal",
                    1,
                    new MotionBlurEffect(),
                    new MotionBlurEffectConfigToken(0, 100, true),
                        surface));

            benchmarks.Add(
                new EffectBenchmark(
                    "Motion Blur, Vertical",
                    1,
                    new MotionBlurEffect(),
                    new MotionBlurEffectConfigToken(90, 100, true),
                        surface));

#endif

            Surface dst = new Surface(surface.Width * 4, surface.Height * 4);

#if RESIZE
            // Resize benchmarks
            for (int i = 1; i < 8; i += 2)
            {
                int newWidth = i * (dst.Width / 8);
                int newHeight = i * (dst.Height / 8);

                Surface dstWindow = dst.CreateWindow(new Rectangle(0, 0, newWidth, newHeight));
                benchmarks.Add(new ResizeBenchmark("Resize from " + surface.Width + "x" + surface.Height + " to " + newWidth + "x" + newHeight, surface, dstWindow));
                benchmarks.Add(new ResizeBenchmark("Resize from " + newWidth + "x" + newHeight + " to " + surface.Width + "x" + surface.Height, dstWindow, surface));
            }
#endif

#if GRADIENT
            // Gradient benchmarks
            benchmarks.Add(new GradientBenchmark(
                "Linear reflected gradient @ " + dst.Width + "x" + dst.Height + " (5x)",
                dst,
                new GradientRenderers.LinearReflected(false, new UserBlendOps.NormalBlendOp()),
                2));

            benchmarks.Add(new GradientBenchmark(
                "Conical gradient @ " + dst.Width + "x" + dst.Height + " (5x)",
                dst,
                new GradientRenderers.Conical(false, new UserBlendOps.NormalBlendOp()),
                2));

            benchmarks.Add(new GradientBenchmark(
                "Radial gradient @ " + dst.Width + "x" + dst.Height + " (5x)",
                dst,
                new GradientRenderers.Radial(false, new UserBlendOps.NormalBlendOp()),
                2));
#endif

#if COMPOSITION
            // Composition benchmarks
            Document doc1 = new Document(surface.Size);
            BitmapLayer layer1 = Layer.CreateBackgroundLayer(doc1.Width, doc1.Height);
            layer1.Surface.CopySurface(surface);
            doc1.Layers.Add(layer1);
            doc1.Layers.Add(layer1.Clone());
            doc1.Layers.Add(layer1.Clone());
            doc1.Layers.Add(layer1.Clone());

            benchmarks.Add(new CompositionBenchmark("Compositing one layer, Normal blend mode, 255 opacity (" + CompositionBenchmark.Iterations + "x)",
                doc1,
                surface,
                delegate(int layerIndex, Layer layer)
                {
                    if (layerIndex == 0)
                    {
                        layer.Visible = true;
                        layer.Opacity = 255;
                        ((BitmapLayer)layer).SetBlendOp(new UserBlendOps.NormalBlendOp());
                    }
                    else
                    {
                        layer.Visible = false;
                    }
                }));

            benchmarks.Add(new CompositionBenchmark("Compositing one layer, Normal blend mode, 128 opacity (" + CompositionBenchmark.Iterations + "x)",
                doc1,
                surface,
                delegate(int layerIndex, Layer layer)
                {
                    if (layerIndex == 0)
                    {
                        layer.Visible = true;
                        layer.Opacity = 128;
                        ((BitmapLayer)layer).SetBlendOp(new UserBlendOps.NormalBlendOp());
                    }
                    else
                    {
                        layer.Visible = false;
                    }
                }));

            benchmarks.Add(new CompositionBenchmark("Compositing four layers, Normal blend mode, 255 opacity (" + CompositionBenchmark.Iterations + "x)",
                doc1,
                surface,
                delegate(int layerIndex, Layer layer)
                {
                    layer.Visible = true;
                    layer.Opacity = 255;
                    ((BitmapLayer)layer).SetBlendOp(new UserBlendOps.NormalBlendOp());
                }));

            benchmarks.Add(new CompositionBenchmark("Compositing four layers, Normal blend mode, 255 (layer 0) and 128 (layer 1-3) opacity (" + CompositionBenchmark.Iterations + "x)", doc1, surface,
                delegate(int layerIndex, Layer layer)
                {
                    layer.Visible = true;
                    layer.Opacity = 128;
                    ((BitmapLayer)layer).SetBlendOp(new UserBlendOps.NormalBlendOp());
                }));

            benchmarks.Add(new CompositionBenchmark("Compositing four layers, Normal blend mode, 128 opacity (" + CompositionBenchmark.Iterations + "x)", doc1, surface,
                delegate(int layerIndex, Layer layer)
                {
                    layer.Visible = true;
                    layer.Opacity = 128;
                    ((BitmapLayer)layer).SetBlendOp(new UserBlendOps.NormalBlendOp());
                }));

            benchmarks.Add(new CompositionBenchmark("Compositing three layers, Normal+Multiply+Overlay blending, 150+255+170 opacity (" + CompositionBenchmark.Iterations + "x)", doc1, surface,
                delegate(int layerIndex, Layer layer)
                {
                    if (layerIndex == 0)
                    {
                        layer.Visible = true;
                        layer.Opacity = 150;
                        ((BitmapLayer)layer).SetBlendOp(new UserBlendOps.NormalBlendOp());
                    }
                    else if (layerIndex == 1)
                    {
                        layer.Visible = true;
                        layer.Opacity = 255;
                        ((BitmapLayer)layer).SetBlendOp(new UserBlendOps.MultiplyBlendOp());
                    }
                    else if (layerIndex == 2)
                    {
                        layer.Visible = true;
                        layer.Opacity = 170;
                        ((BitmapLayer)layer).SetBlendOp(new UserBlendOps.OverlayBlendOp());
                    }
                    else
                    {
                        layer.Visible = false;
                    }
                }));
#endif

#if TRANSFORM
            // Transform benchmarks
            Matrix m = new Matrix();
            m.Reset();

            MaskedSurface msSimple = new MaskedSurface(surface, new PdnRegion(surface.Bounds)); // simple masked surface

            PdnRegion complexRegion = new PdnRegion(surface.Bounds);

            // cut 4 holes in region 1 to form a complex clipping surface
            for (int x = -1; x < 3; ++x)
            {
                for (int y = -1; y < 3; ++y)
                {
                    int left = (1 + (x * 3)) * (surface.Width / 6);
                    int top = (1 + (x * 3)) * (surface.Height / 6);
                    int right = (2 + (x * 3)) * (surface.Width / 6);
                    int bottom = (2 + (x * 3)) * (surface.Height / 6);

                    Rectangle rect = Rectangle.FromLTRB(left, top, right, bottom);
                    PdnGraphicsPath path = new PdnGraphicsPath();
                    path.AddEllipse(rect);
                    complexRegion.Exclude(path);
                }
            }

            MaskedSurface msComplex = new MaskedSurface(surface, complexRegion);

            benchmarks.Add(new TransformBenchmark("Transform simple surface, no transform, nearest neighbor resampling (" + TransformBenchmark.Iterations + "x)",
                surface,
                msSimple,
                m,
                false));

            benchmarks.Add(new TransformBenchmark("Transform complex surface, no transform, nearest neighbor resampling (" + TransformBenchmark.Iterations + "x)",
                surface,
                msSimple,
                m,
                false));

            benchmarks.Add(new TransformBenchmark("Transform simple surface, no transform, bilinear resampling (" + TransformBenchmark.Iterations + "x)",
                surface,
                msSimple,
                m,
                true));

            benchmarks.Add(new TransformBenchmark("Transform complex surface, no transform, bilinear resampling (" + TransformBenchmark.Iterations + "x)",
                surface,
                msSimple,
                m,
                true));

            Matrix m2 = m.Clone();
            m2.RotateAt(45.0f, new PointF(surface.Width / 2, surface.Height / 2));

            benchmarks.Add(new TransformBenchmark("Transform simple surface, 45 deg. rotation about center, bilinear resampling (" + TransformBenchmark.Iterations + "x)",
                surface,
                msSimple,
                m2,
                true));

            benchmarks.Add(new TransformBenchmark("Transform complex surface, 45 deg. rotation about center, bilinear resampling (" + TransformBenchmark.Iterations + "x)",
                surface,
                msSimple,
                m2,
                true));

            Matrix m3 = m.Clone();
            m3.Scale(0.5f, 0.75f);

            benchmarks.Add(new TransformBenchmark("Transform simple surface, 50% x-scaling 75% y-scaling, bilinear resampling (" + TransformBenchmark.Iterations + "x)",
                surface,
                msSimple,
                m3,
                true));

            benchmarks.Add(new TransformBenchmark("Transform complex surface, 50% x-scaling 75% y-scaling, bilinear resampling (" + TransformBenchmark.Iterations + "x)",
                surface,
                msSimple,
                m3,
                true));
#endif

#if BLIT
            // Blit benchmarks
            benchmarks.Add(new ZoomOutBlitBenchmark("Zoom out, rotated grid multisampling, 66% (" + ZoomOutBlitBenchmark.IterationCount + "x)",
                surface,
                dst,
                new Size((surface.Width * 2) / 3, (surface.Height * 2) / 3)));

            benchmarks.Add(new ZoomOutBlitBenchmark("Zoom out, rotated grid multisampling, 28% (" + ZoomOutBlitBenchmark.IterationCount + "x)",
                surface,
                dst,
                new Size((surface.Width * 28) / 100, (surface.Height * 28) / 100)));

            benchmarks.Add(new ZoomOneToOneBlitBenchmark("Zoom 1:1, straight blit (" + ZoomOneToOneBlitBenchmark.IterationCount + "x)",
                surface,
                dst.CreateWindow(new Rectangle(0, 0, surface.Width, surface.Height))));
#endif

            // Run benchmarks!
            Timing timing = new Timing();
            ulong start = timing.GetTickCount();

            foreach (Benchmark benchmark in benchmarks)
            {
                Console.Write(benchmark.Name + (useTsvOutput ? "\t" : " ... "));
                TimeSpan timeSpan = benchmark.Execute();
                Console.WriteLine(" " + timeSpan.TotalMilliseconds.ToString() + (useTsvOutput ? "\t" : "") + " milliseconds");

                GC.Collect();
                GC.WaitForPendingFinalizers();
                GC.Collect();
                GC.WaitForPendingFinalizers();
            }

            ulong end = timing.GetTickCount();

            Console.WriteLine();
            Console.WriteLine("Total time: " + (useTsvOutput ? "\t" : "") + (end - start).ToString() + (useTsvOutput ? "\t" : "") + " milliseconds");
            Console.WriteLine();
        }
예제 #33
0
        internal override void FinalSave(
            Document input, 
            Stream output, 
            Surface scratchSurface, 
            int ditherLevel, 
            SavableBitDepths bitDepth,
            PropertyBasedSaveConfigToken token,
            ProgressEventHandler progressCallback)
        {
            bool enableAlpha;

            switch (bitDepth)
            {
                case SavableBitDepths.Rgb8:
                    enableAlpha = false;
                    break;

                case SavableBitDepths.Rgba8:
                    enableAlpha = true;
                    break;

                default:
                    throw new InvalidEnumArgumentException("bitDepth", (int)bitDepth, typeof(SavableBitDepths));
            }

            using (Bitmap quantized = Quantize(scratchSurface, ditherLevel, 256, enableAlpha, progressCallback))
            {
                quantized.Save(output, ImageFormat.Gif);
            }
        }
예제 #34
0
 public MetadataHistoryMementoData(PaintDotNet.Document document)
 {
     this.document = document;
 }
예제 #35
0
        protected override void OnSave(Document input, Stream output, SaveConfigToken token, Surface scratchSurface, ProgressEventHandler callback)
        {
            scratchSurface.Clear(ColorBgra.FromBgra(255, 255, 255, 0));

            using (RenderArgs ra = new RenderArgs(scratchSurface))
            {
                input.Render(ra, true);
            }

            SaveTga(scratchSurface, output, token, callback);
        }