public void SetToDefaults() { this.antiAliasing = true; this.fontSmoothing = FontSmoothing.Smooth; this.primaryColor = ColorBgra.FromBgra(0, 0, 0, 255); this.secondaryColor = ColorBgra.FromBgra(255, 255, 255, 255); this.gradientInfo = new GradientInfo(GradientType.LinearClamped, false); this.penInfo = new PenInfo(PenInfo.DefaultDashStyle, 2.0f, PenInfo.DefaultLineCap, PenInfo.DefaultLineCap, PenInfo.DefaultCapScale); this.brushInfo = new BrushInfo(BrushType.Solid, HatchStyle.BackwardDiagonal); try { this.fontInfo = new FontInfo(new FontFamily("Arial"), 12, FontStyle.Regular); } catch (Exception) { this.fontInfo = new FontInfo(new FontFamily(GenericFontFamilies.SansSerif), 12, FontStyle.Regular); } this.textAlignment = TextAlignment.Left; this.shapeDrawType = ShapeDrawType.Outline; this.alphaBlending = true; this.tolerance = 0.5f; this.colorPickerClickBehavior = ColorPickerClickBehavior.NoToolSwitch; this.resamplingAlgorithm = ResamplingAlgorithm.Bilinear; this.selectionCombineMode = CombineMode.Replace; this.floodMode = FloodMode.Local; this.selectionDrawModeInfo = SelectionDrawModeInfo.CreateDefault(); }
public FitSurfaceContext(Surface dstSurface, Surface srcSurface, Rectangle[] dstRois, ResamplingAlgorithm algorithm) { DstSurface = dstSurface; SrcSurface = srcSurface; DstRois = dstRois; Algorithm = algorithm; }
public FitSurfaceContext(Surface dstSurface, Surface srcSurface, Rectangle[] dstRois, ResamplingAlgorithm algorithm) { this.dstSurface = dstSurface; this.srcSurface = srcSurface; this.dstRois = dstRois; this.algorithm = algorithm; }
public ResizeProgressDialog(Control owner, Document dst, Document src, Size newSize, ResamplingAlgorithm algorithm) : base(owner, PdnInfo.GetBareProductName(), PdnResources.GetString("ResizeAction.ProgressDialog.Description")) { this.dst = dst; this.src = src; this.newSize = newSize; this.algorithm = algorithm; this.tilesPerLayer = 50 * Processor.LogicalCpuCount; this.maxTiles = tilesPerLayer * src.Layers.Count; this.Icon = Utility.ImageToIcon(StaticImage.Reference); }
protected override void OnSaveT(Document input, Stream output, PropertyBasedSaveConfigToken token, Surface scratchSurface, ProgressEventHandler progressCallback) { DdsFileFormat fileFormat = (DdsFileFormat)token.GetProperty(PropertyNames.FileFormat).Value; BC7CompressionMode compressionMode = (BC7CompressionMode)token.GetProperty(PropertyNames.BC7CompressionMode).Value; DdsErrorMetric errorMetric = (DdsErrorMetric)token.GetProperty(PropertyNames.ErrorMetric).Value; bool cubeMap = token.GetProperty <BooleanProperty>(PropertyNames.CubeMap).Value; bool generateMipmaps = token.GetProperty <BooleanProperty>(PropertyNames.GenerateMipMaps).Value; ResamplingAlgorithm mipSampling = (ResamplingAlgorithm)token.GetProperty(PropertyNames.MipMapResamplingAlgorithm).Value; DdsFile.Save(this.services, input, output, fileFormat, errorMetric, compressionMode, cubeMap, generateMipmaps, mipSampling, scratchSurface, progressCallback); }
protected override void OnSaveT(Document input, Stream output, PropertyBasedSaveConfigToken token, Surface scratchSurface, ProgressEventHandler callback) { scratchSurface.Clear(ColorBgra.Zero); using (RenderArgs args = new RenderArgs(scratchSurface)) { input.Render(args, true); } DdsFileFormat fileFormat = (DdsFileFormat)token.GetProperty <StaticListChoiceProperty>(PropertyNames.FileFormat).Value; DdsCompressorType compressorType = (DdsCompressorType)token.GetProperty <StaticListChoiceProperty>(PropertyNames.CompressorType).Value; DdsErrorMetric errorMetric = (DdsErrorMetric)token.GetProperty <StaticListChoiceProperty>(PropertyNames.ErrorMetric).Value; bool weightColorByAlpha = token.GetProperty <BooleanProperty>(PropertyNames.WeightColorByAlpha).Value; bool generateMipMaps = token.GetProperty <BooleanProperty>(PropertyNames.GenerateMipMaps).Value; ResamplingAlgorithm mipMapResamplingAlgorithm = (ResamplingAlgorithm)token.GetProperty <StaticListChoiceProperty>(PropertyNames.MipMapResamplingAlgorithm).Value; new DdsFile().Save(output, scratchSurface, fileFormat, compressorType, errorMetric, generateMipMaps, mipMapResamplingAlgorithm, weightColorByAlpha, callback); }
protected override void OnLoad(EventArgs e) { srcBounds = this.EnvironmentParameters.SourceSurface.Bounds; float ratio = (float)srcBounds.Height / srcBounds.Width; if (ratio > 1) { int tx = (int)MathF.Round(PreViewBMP.ClientRectangle.Width / ratio); int pos = (int)MathF.Round((PreViewBMP.ClientRectangle.Width - tx) / 2f); PreViewBMP.Bounds = new Rectangle(pos, PreViewBMP.Top, tx, PreViewBMP.Height); } else if (ratio < 1) { int ty = (int)MathF.Round(PreViewBMP.ClientRectangle.Height * ratio); int pos = (int)MathF.Round((PreViewBMP.ClientRectangle.Height - ty) / 2f); PreViewBMP.Bounds = new Rectangle(PreViewBMP.Left, pos, PreViewBMP.ClientRectangle.Width, ty); } //=====make checkerboard Size previewBounds = PreViewBMP.ClientRectangle.Size; PreViewBMP.BackgroundImage = new Bitmap(previewBounds.Width, previewBounds.Height); PreViewBMP.Image = new Bitmap(previewBounds.Width, previewBounds.Height); using (Surface tmp = new Surface(previewBounds)) { ResamplingAlgorithm algorithm = (srcBounds.Width > tmp.Width || srcBounds.Height > tmp.Height) ? ResamplingAlgorithm.Fant : ResamplingAlgorithm.Bicubic; tmp.FitSurface(algorithm, this.EnvironmentParameters.SourceSurface); using (Graphics g = Graphics.FromImage(PreViewBMP.Image)) g.DrawImage(tmp.CreateAliasedBitmap(), 0, 0); tmp.ClearWithCheckerboardPattern(); using (Graphics g = Graphics.FromImage(PreViewBMP.BackgroundImage)) g.DrawImage(tmp.CreateAliasedBitmap(), 0, 0); } ConvertXY.X = (float)(srcBounds.Width - 1) / (previewBounds.Width - 1); ConvertXY.Y = (float)(srcBounds.Height - 1) / (previewBounds.Height - 1); Version version = Assembly.GetExecutingAssembly().GetName().Version; this.Text = EffectPlugin.StaticName + " ver. " + version.Major + "." + version.Minor + "." + version.Build; Reset(initialize); base.OnLoad(e); }
public void LoadFrom(AppEnvironment appEnvironment) { this.textAlignment = appEnvironment.textAlignment; this.gradientInfo = appEnvironment.gradientInfo.Clone(); this.fontSmoothing = appEnvironment.fontSmoothing; this.fontInfo = appEnvironment.fontInfo.Clone(); this.penInfo = appEnvironment.penInfo.Clone(); this.brushInfo = appEnvironment.brushInfo.Clone(); this.primaryColor = appEnvironment.primaryColor; this.secondaryColor = appEnvironment.secondaryColor; this.alphaBlending = appEnvironment.alphaBlending; this.shapeDrawType = appEnvironment.shapeDrawType; this.antiAliasing = appEnvironment.antiAliasing; this.colorPickerClickBehavior = appEnvironment.colorPickerClickBehavior; this.resamplingAlgorithm = appEnvironment.resamplingAlgorithm; this.tolerance = appEnvironment.tolerance; PerformAllChanged(); }
public void LoadFrom(ToolEnvironment toolEnvironment) { this.textAlignment = toolEnvironment.textAlignment; this.gradientInfo = toolEnvironment.gradientInfo.Clone(); this.fontSmoothing = toolEnvironment.fontSmoothing; this.fontInfo = toolEnvironment.fontInfo.Clone(); this.penInfo = toolEnvironment.penInfo.Clone(); this.brushInfo = toolEnvironment.brushInfo.Clone(); this.primaryColor = toolEnvironment.primaryColor; this.secondaryColor = toolEnvironment.secondaryColor; this.alphaBlending = toolEnvironment.alphaBlending; this.shapeDrawType = toolEnvironment.shapeDrawType; this.antiAliasing = toolEnvironment.antiAliasing; this.colorPickerClickBehavior = toolEnvironment.colorPickerClickBehavior; this.resamplingAlgorithm = toolEnvironment.resamplingAlgorithm; this.tolerance = toolEnvironment.tolerance; this.selectionCombineMode = toolEnvironment.selectionCombineMode; this.floodMode = toolEnvironment.floodMode; this.selectionDrawModeInfo = toolEnvironment.selectionDrawModeInfo.Clone(); PerformAllChanged(); }
public unsafe void Draw(Surface dst, Matrix transform, ResamplingAlgorithm sampling) { if (this.disposed) { throw new ObjectDisposedException("MaskedSurface"); } if (this.surface == null || !transform.IsInvertible) { return; } PdnRegion theRegion; Rectangle regionBounds; if (this.path == null) { theRegion = this.region.Clone(); regionBounds = this.region.GetBoundsInt(); theRegion.Transform(transform); } else { using (PdnGraphicsPath mPath = this.shadowPath.Clone()) { regionBounds = Rectangle.Truncate(mPath.GetBounds()); mPath.Transform(transform); theRegion = new PdnRegion(mPath); } } DrawContext dc = new DrawContext(); dc.boundsX = regionBounds.X; dc.boundsY = regionBounds.Y; Matrix inverse = transform.Clone(); inverse.Invert(); dc.inverses = new Matrix[Processor.LogicalCpuCount]; for (int i = 0; i < dc.inverses.Length; ++i) { dc.inverses[i] = inverse.Clone(); } // change in source-[X|Y] w.r.t. destination-[X|Y] PointF[] pts = new PointF[] { new PointF(1, 0), new PointF(0, 1) }; inverse.TransformVectors(pts); inverse.Dispose(); inverse = null; dc.dsxddx = pts[0].X; if (Math.Abs(dc.dsxddx) > fp_MaxValue) { dc.dsxddx = 0.0f; } dc.dsyddx = pts[0].Y; if (Math.Abs(dc.dsyddx) > fp_MaxValue) { dc.dsyddx = 0.0f; } dc.dsxddy = pts[1].X; if (Math.Abs(dc.dsxddy) > fp_MaxValue) { dc.dsxddy = 0.0f; } dc.dsyddy = pts[1].Y; if (Math.Abs(dc.dsyddy) > fp_MaxValue) { dc.dsyddy = 0.0f; } dc.fp_dsxddx = (int)(dc.dsxddx * fp_MultFactor); dc.fp_dsyddx = (int)(dc.dsyddx * fp_MultFactor); dc.fp_dsxddy = (int)(dc.dsxddy * fp_MultFactor); dc.fp_dsyddy = (int)(dc.dsyddy * fp_MultFactor); dc.dst = dst; dc.src = this.surface; Rectangle[] scans = theRegion.GetRegionScansReadOnlyInt(); if (scans.Length == 1) { dc.dstScans = new Rectangle[Processor.LogicalCpuCount]; Utility.SplitRectangle(scans[0], dc.dstScans); } else { dc.dstScans = scans; } WaitCallback wc; switch (sampling) { case ResamplingAlgorithm.NearestNeighbor: wc = new WaitCallback(dc.DrawScansNearestNeighbor); break; case ResamplingAlgorithm.Bilinear: wc = new WaitCallback(dc.DrawScansBilinear); break; default: throw new System.ComponentModel.InvalidEnumArgumentException(); } for (int i = 0; i < Processor.LogicalCpuCount; ++i) { if (i == Processor.LogicalCpuCount - 1) { // Don't queue the last work item into a separate thread wc(BoxedConstants.GetInt32(i)); } else { threadPool.QueueUserWorkItem(wc, BoxedConstants.GetInt32(i)); } } threadPool.Drain(); for (int i = 0; i < Processor.LogicalCpuCount; ++i) { dc.inverses[i].Dispose(); dc.inverses[i] = null; } dc.src = null; theRegion.Dispose(); theRegion = null; }
/// <summary> /// Fits the source surface to this surface using the given algorithm. /// </summary> /// <param name="algorithm">The surface to copy pixels from.</param> /// <param name="source">The algorithm to use.</param> public void FitSurface(ResamplingAlgorithm algorithm, Surface source) { FitSurface(algorithm, source, this.Bounds); }
private static BitmapLayer ResizeLayer(BitmapLayer layer, int width, int height, ResamplingAlgorithm algorithm, int tileCount, Procedure progressCallback, ref bool pleaseStopMonitor) { Surface surface = new Surface(width, height); surface.Clear(ColorBgra.FromBgra(255, 255, 255, 0)); PaintDotNet.Threading.ThreadPool threadPool = new PaintDotNet.Threading.ThreadPool(); int rectCount; if (tileCount == 0) { rectCount = Processor.LogicalCpuCount; } else { rectCount = tileCount; } Rectangle[] rects = new Rectangle[rectCount]; Utility.SplitRectangle(surface.Bounds, rects); FitSurfaceContext fsc = new FitSurfaceContext(surface, layer.Surface, rects, algorithm); if (progressCallback != null) { fsc.RenderedRect += progressCallback; } WaitCallback callback = new WaitCallback(fsc.FitSurface); for (int i = 0; i < rects.Length; ++i) { if (pleaseStopMonitor) { break; } else { threadPool.QueueUserWorkItem(callback, BoxedConstants.GetInt32(i)); } } threadPool.Drain(); threadPool.DrainExceptions(); if (pleaseStopMonitor) { surface.Dispose(); surface = null; } BitmapLayer newLayer; if (surface == null) { newLayer = null; } else { newLayer = new BitmapLayer(surface, true); newLayer.LoadProperties(layer.SaveProperties()); } if (progressCallback != null) { fsc.RenderedRect -= progressCallback; } return(newLayer); }
public static BitmapLayer ResizeLayer(BitmapLayer layer, int width, int height, ResamplingAlgorithm algorithm) { bool pleaseStop = false; return(ResizeLayer(layer, width, height, algorithm, 0, null, ref pleaseStop)); }
public override HistoryMemento PerformAction(DocumentWorkspace docWorkspace) { int newWidth; int newHeight; MeasurementUnit newDpuUnit; double newDpu; ResamplingAlgorithm algorithm = AppSettings.Instance.Workspace.LastResamplingMethod.Value; if (algorithm == ResamplingAlgorithm.SuperSampling) { algorithm = ResamplingAlgorithm.Fant; } bool flag = AppSettings.Instance.Workspace.LastMaintainAspectRatio.Value; using (ResizeDialog dialog = new ResizeDialog()) { dialog.OriginalSize = docWorkspace.Document.Size; dialog.OriginalDpuUnit = docWorkspace.Document.DpuUnit; dialog.OriginalDpu = docWorkspace.Document.DpuX; dialog.ImageHeight = docWorkspace.Document.Height; dialog.ImageWidth = docWorkspace.Document.Width; dialog.ResamplingAlgorithm = algorithm; dialog.LayerCount = docWorkspace.Document.Layers.Count; dialog.Units = dialog.OriginalDpuUnit; dialog.Resolution = docWorkspace.Document.DpuX; dialog.Units = AppSettings.Instance.Workspace.LastNonPixelUnits.Value; dialog.ConstrainToAspect = flag; if (dialog.ShowDialog(docWorkspace) == DialogResult.Cancel) { return(null); } AppSettings.Instance.Workspace.LastResamplingMethod.Value = dialog.ResamplingAlgorithm; AppSettings.Instance.Workspace.LastMaintainAspectRatio.Value = dialog.ConstrainToAspect; newDpuUnit = dialog.Units; newWidth = dialog.ImageWidth; newHeight = dialog.ImageHeight; newDpu = dialog.Resolution; algorithm = dialog.ResamplingAlgorithm; if (newDpuUnit != MeasurementUnit.Pixel) { AppSettings.Instance.Workspace.LastNonPixelUnits.Value = newDpuUnit; if (docWorkspace.AppWorkspace.Units != MeasurementUnit.Pixel) { docWorkspace.AppWorkspace.Units = newDpuUnit; } } if (((docWorkspace.Document.Size == new Size(dialog.ImageWidth, dialog.ImageHeight)) && (docWorkspace.Document.DpuX == newDpu)) && (docWorkspace.Document.DpuUnit == newDpuUnit)) { return(null); } } if ((newWidth == docWorkspace.Document.Width) && (newHeight == docWorkspace.Document.Height)) { MetadataHistoryMemento memento2 = new MetadataHistoryMemento(StaticName, PdnResources.GetImageResource(StaticImageName), docWorkspace); docWorkspace.Document.DpuUnit = newDpuUnit; docWorkspace.Document.DpuX = newDpu; docWorkspace.Document.DpuY = newDpu; return(memento2); } docWorkspace.FlushTool(); using (TaskProgressDialog progressDialog = new TaskProgressDialog()) {
public static BitmapLayer ResizeLayer(BitmapLayer layer, int width, int height, ResamplingAlgorithm algorithm) { bool pleaseStop = false; return ResizeLayer(layer, width, height, algorithm, 0, null, ref pleaseStop); }
public void LoadFrom(AppEnvironment appEnvironment) { this.textAlignment = appEnvironment.textAlignment; this.gradientInfo = appEnvironment.gradientInfo.Clone(); this.fontSmoothing = appEnvironment.fontSmoothing; this.fontInfo = appEnvironment.fontInfo.Clone(); this.penInfo = appEnvironment.penInfo.Clone(); this.brushInfo = appEnvironment.brushInfo.Clone(); this.primaryColor = appEnvironment.primaryColor; this.secondaryColor = appEnvironment.secondaryColor; this.alphaBlending = appEnvironment.alphaBlending; this.shapeDrawType = appEnvironment.shapeDrawType; this.antiAliasing = appEnvironment.antiAliasing; this.colorPickerClickBehavior = appEnvironment.colorPickerClickBehavior; this.resamplingAlgorithm = appEnvironment.resamplingAlgorithm; this.tolerance = appEnvironment.tolerance; this.selectionCombineMode = appEnvironment.selectionCombineMode; this.floodMode = appEnvironment.floodMode; this.selectionDrawModeInfo = appEnvironment.selectionDrawModeInfo.Clone(); PerformAllChanged(); }
public ResampleMethod(ResamplingAlgorithm method) { this.method = method; }
private static unsafe Texture CreateMipTexture(Surface fullSize, int mipWidth, int mipHeight, ResamplingAlgorithm algorithm) { Texture mipTexture = null; Surface mipSurface = null; try { mipSurface = new Surface(mipWidth, mipHeight); mipSurface.FitSurface(algorithm, fullSize); if (HasTransparency(fullSize)) { // Downscaling images with transparency is done in a way that allows the completely transparent areas // to retain their RGB color values, this behavior is required by some programs that use DDS files. using (Surface color = new Surface(mipWidth, mipHeight)) { using (Surface opaqueClone = fullSize.Clone()) { // Set the alpha channel to fully opaque to prevent Windows Imaging Component // from discarding the color information of completely transparent pixels. new UnaryPixelOps.SetAlphaChannelTo255().Apply(opaqueClone, opaqueClone.Bounds); color.FitSurface(algorithm, opaqueClone); } for (int y = 0; y < mipHeight; ++y) { ColorBgra *colorPtr = color.GetRowAddressUnchecked(y); ColorBgra *destPtr = mipSurface.GetRowAddressUnchecked(y); for (int x = 0; x < mipWidth; ++x) { // Copy the color data from the opaque image to create a merged // image with the transparent pixels retaining their original values. destPtr->B = colorPtr->B; destPtr->G = colorPtr->G; destPtr->R = colorPtr->R; ++colorPtr; ++destPtr; } } } } mipTexture = new Texture(mipSurface, true); mipSurface = null; } finally { if (mipSurface != null) { mipSurface.Dispose(); } } return(mipTexture); }
private static IRenderer <ColorBgra> CreatePdnResampler(IRenderer <ColorBgra> source, int newWidth, int newHeight, ResamplingAlgorithm algorithm) { switch (algorithm) { case ResamplingAlgorithm.NearestNeighbor: return(new ResizeNearestNeighborRendererBgra(source, newWidth, newHeight)); case ResamplingAlgorithm.Bilinear: return(new ResizeBilinearRendererBgra(source, newWidth, newHeight)); case ResamplingAlgorithm.Bicubic: return(new ResizeBicubicRendererBgra(source, newWidth, newHeight)); case ResamplingAlgorithm.SuperSampling: case ResamplingAlgorithm.Fant: if ((newWidth >= source.Width) || (newHeight >= source.Height)) { return(new ResizeBicubicRendererBgra(source, newWidth, newHeight)); } return(new ResizeSuperSamplingRendererBgra(source, newWidth, newHeight)); } throw ExceptionUtil.InvalidEnumArgumentException <ResamplingAlgorithm>(algorithm, "algorithm"); }
private static IRenderer <ColorBgra> CreateWicResampler(IRenderer <ColorBgra> source, int newWidth, int newHeight, ResamplingAlgorithm algorithm) { BitmapInterpolationMode nearestNeighbor; switch (algorithm) { case ResamplingAlgorithm.NearestNeighbor: nearestNeighbor = BitmapInterpolationMode.NearestNeighbor; break; case ResamplingAlgorithm.Bilinear: nearestNeighbor = BitmapInterpolationMode.Linear; break; case ResamplingAlgorithm.Bicubic: nearestNeighbor = BitmapInterpolationMode.Cubic; break; case ResamplingAlgorithm.SuperSampling: case ResamplingAlgorithm.Fant: if ((newWidth >= source.Width) || (newHeight >= source.Height)) { nearestNeighbor = BitmapInterpolationMode.Cubic; break; } nearestNeighbor = BitmapInterpolationMode.Fant; break; default: throw ExceptionUtil.InvalidEnumArgumentException <ResamplingAlgorithm>(algorithm, "algorithm"); } return(new ResizeWicRendererBgra(source, newWidth, newHeight, nearestNeighbor)); }
private static IRenderer <ColorBgra> CreateResampler(IRenderer <ColorBgra> source, int newWidth, int newHeight, ResamplingAlgorithm algorithm) { IRenderer <ColorBgra> renderer2; IRenderer <ColorBgra> renderer = CreateWicResampler(source, newWidth, newHeight, algorithm); ISurface <ColorBgra> dst = new Surface(1, 1); try { renderer.Render(dst, PointInt32.Zero); renderer2 = renderer; } catch (OverflowException) { renderer2 = CreatePdnResampler(source, newWidth, newHeight, algorithm); } finally { if (dst != null) { dst.Dispose(); } } return(renderer2); }
/// <summary> /// Fits the source surface to this surface using the given algorithm. /// </summary> /// <param name="algorithm">The surface to copy pixels from.</param> /// <param name="dstRoi">The rectangle to clip rendering to.</param> /// <param name="source">The algorithm to use.</param> public void FitSurface(ResamplingAlgorithm algorithm, Surface source, Rectangle dstRoi) { switch (algorithm) { case ResamplingAlgorithm.Bicubic: BicubicFitSurface(source, dstRoi); break; case ResamplingAlgorithm.Bilinear: BilinearFitSurface(source, dstRoi); break; case ResamplingAlgorithm.NearestNeighbor: NearestNeighborFitSurface(source, dstRoi); break; case ResamplingAlgorithm.SuperSampling: SuperSamplingFitSurface(source, dstRoi); break; default: throw new InvalidEnumArgumentException("algorithm"); } }
private static TextureCollection GetTextures(Surface scratchSurface, Size?cubeMapFaceSize, int mipLevels, ResamplingAlgorithm algorithm) { TextureCollection textures = null; TextureCollection tempTextures = null; try { tempTextures = new TextureCollection(mipLevels); if (cubeMapFaceSize.HasValue) { // DirectX 10+ requires DDS cube maps to have all 6 faces. tempTextures.Capacity *= 6; Size faceSize = cubeMapFaceSize.Value; Point[] cubeMapOffsets = new Point[6]; // Split the crossed image into the individual cube map faces. // // The crossed image uses the same layout as the Intel® Texture Works DDS plug-in for Adobe Photoshop® // (https://github.com/GameTechDev/Intel-Texture-Works-Plugin) // // The DirectXTex texassemble utility and Unity® both use different layouts, so there does not appear // to be any common standard for a crossed image. // // The cube map faces in a DDS file are always ordered: +X, -X, +Y, -Y, +Z, -Z. if (scratchSurface.Width > scratchSurface.Height) { // A horizontal crossed image uses the following layout: // // [ +Y ] // [ -X ][ +Z ][ +X ][ -Z ] // [ -Y ] // cubeMapOffsets[0] = new Point(faceSize.Width * 2, faceSize.Height); // +X cubeMapOffsets[1] = new Point(0, faceSize.Height); // -X cubeMapOffsets[2] = new Point(faceSize.Width, 0); // +Y cubeMapOffsets[3] = new Point(faceSize.Width, faceSize.Height * 2); // -Y cubeMapOffsets[4] = new Point(faceSize.Width, faceSize.Height); // +Z cubeMapOffsets[5] = new Point(faceSize.Width * 3, faceSize.Height); // -Z } else { // A vertical crossed image uses the following layout: // // [ +Y ] // [ -X ][ +Z ][ +X ] // [ -Y ] // [ -Z ] // cubeMapOffsets[0] = new Point(faceSize.Width * 2, faceSize.Height); // +X cubeMapOffsets[1] = new Point(0, faceSize.Height); // -X cubeMapOffsets[2] = new Point(faceSize.Width, 0); // +Y cubeMapOffsets[3] = new Point(faceSize.Width, faceSize.Height * 2); // -Y cubeMapOffsets[4] = new Point(faceSize.Width, faceSize.Height); // +Z cubeMapOffsets[5] = new Point(faceSize.Width, faceSize.Height * 3); // -Z } for (int i = 0; i < 6; ++i) { Point srcStartOffset = cubeMapOffsets[i]; tempTextures.Add(new Texture(scratchSurface.CreateWindow(srcStartOffset.X, srcStartOffset.Y, faceSize.Width, faceSize.Height), true)); if (mipLevels > 1) { Surface cubeMapSurface = tempTextures[tempTextures.Count - 1].Surface; for (int j = 1; j < mipLevels; ++j) { int mipWidth = Math.Max(1, cubeMapSurface.Width >> j); int mipHeight = Math.Max(1, cubeMapSurface.Height >> j); tempTextures.Add(CreateMipTexture(cubeMapSurface, mipWidth, mipHeight, algorithm)); } } } } else { tempTextures.Add(new Texture(scratchSurface, false)); if (mipLevels > 1) { for (int j = 1; j < mipLevels; ++j) { int mipWidth = Math.Max(1, scratchSurface.Width >> j); int mipHeight = Math.Max(1, scratchSurface.Height >> j); tempTextures.Add(CreateMipTexture(scratchSurface, mipWidth, mipHeight, algorithm)); } } } textures = tempTextures; tempTextures = null; } finally { if (tempTextures != null) { tempTextures.Dispose(); } } return(textures); }
private static BitmapLayer ResizeLayer(BitmapLayer layer, int width, int height, ResamplingAlgorithm algorithm, int tileCount, Procedure progressCallback, ref bool pleaseStopMonitor) { Surface surface = new Surface(width, height); surface.Clear(ColorBgra.FromBgra(255, 255, 255, 0)); PaintDotNet.Threading.ThreadPool threadPool = new PaintDotNet.Threading.ThreadPool(); int rectCount; if (tileCount == 0) { rectCount = Processor.LogicalCpuCount; } else { rectCount = tileCount; } Rectangle[] rects = new Rectangle[rectCount]; Utility.SplitRectangle(surface.Bounds, rects); FitSurfaceContext fsc = new FitSurfaceContext(surface, layer.Surface, rects, algorithm); if (progressCallback != null) { fsc.RenderedRect += progressCallback; } WaitCallback callback = new WaitCallback(fsc.FitSurface); for (int i = 0; i < rects.Length; ++i) { if (pleaseStopMonitor) { break; } else { threadPool.QueueUserWorkItem(callback, BoxedConstants.GetInt32(i)); } } threadPool.Drain(); threadPool.DrainExceptions(); if (pleaseStopMonitor) { surface.Dispose(); surface = null; } BitmapLayer newLayer; if (surface == null) { newLayer = null; } else { newLayer = new BitmapLayer(surface, true); newLayer.LoadProperties(layer.SaveProperties()); } if (progressCallback != null) { fsc.RenderedRect -= progressCallback; } return newLayer; }
public static void Save( IServiceProvider services, Document input, Stream output, DdsFileFormat format, DdsErrorMetric errorMetric, BC7CompressionMode compressionMode, bool cubeMap, bool generateMipmaps, ResamplingAlgorithm sampling, Surface scratchSurface, ProgressEventHandler progressCallback) { using (RenderArgs args = new RenderArgs(scratchSurface)) { input.Render(args, true); } DdsNative.DdsProgressCallback ddsProgress = null; if (progressCallback != null) { ddsProgress = (UIntPtr done, UIntPtr total) => { double progress = (double)done.ToUInt64() / (double)total.ToUInt64(); try { progressCallback(null, new ProgressEventArgs(progress * 100.0, true)); return(true); } catch (OperationCanceledException) { return(false); } }; } int width = scratchSurface.Width; int height = scratchSurface.Height; int arraySize = 1; Size?cubeMapFaceSize = null; if (cubeMap && IsCrossedCubeMapSize(scratchSurface)) { if (width > height) { width /= 4; height /= 3; } else { width /= 3; height /= 4; } arraySize = 6; cubeMapFaceSize = new Size(width, height); } int mipLevels = generateMipmaps ? GetMipCount(width, height) : 1; bool enableHardwareAcceleration = (bool)services.GetService <ISettingsService>().GetSetting(AppSettingPaths.UI.EnableHardwareAcceleration).Value; DdsNative.DDSSaveInfo info = new DdsNative.DDSSaveInfo { width = width, height = height, arraySize = arraySize, mipLevels = mipLevels, format = format, errorMetric = errorMetric, compressionMode = compressionMode, cubeMap = cubeMapFaceSize.HasValue, enableHardwareAcceleration = enableHardwareAcceleration }; using (TextureCollection textures = GetTextures(scratchSurface, cubeMapFaceSize, mipLevels, sampling)) { DdsNative.Save(info, textures, output, ddsProgress); } }
public void Save(Stream output, Surface surface, DdsFileFormat fileFormat, DdsCompressorType compressorType, DdsErrorMetric errorMetric, bool generateMipMaps, ResamplingAlgorithm mipMapResamplingAlgorithm, bool weightColorByAlpha, ProgressEventHandler progressCallback) { int num21; int num = 0; bool flag = ((fileFormat == DdsFileFormat.DDS_FORMAT_DXT1) || (fileFormat == DdsFileFormat.DDS_FORMAT_DXT3)) || (fileFormat == DdsFileFormat.DDS_FORMAT_DXT5); int num2 = 1; int mipWidth = surface.Width; int height = surface.Height; if (generateMipMaps) { while ((mipWidth > 1) || (height > 1)) { num2++; mipWidth /= 2; height /= 2; } } this.m_header.m_size = this.m_header.Size(); this.m_header.m_headerFlags = 0x1007; if (flag) { this.m_header.m_headerFlags |= 0x80000; } else { this.m_header.m_headerFlags |= 8; } if (num2 > 1) { this.m_header.m_headerFlags |= 0x20000; } this.m_header.m_height = (uint)surface.Height; this.m_header.m_width = (uint)surface.Width; if (flag) { int num5 = ((surface.Width + 3) / 4) * ((surface.Height + 3) / 4); int num6 = (fileFormat == DdsFileFormat.DDS_FORMAT_DXT1) ? 8 : 0x10; this.m_header.m_pitchOrLinearSize = (uint)(num5 * num6); } else { switch (fileFormat) { case DdsFileFormat.DDS_FORMAT_A8R8G8B8: case DdsFileFormat.DDS_FORMAT_X8R8G8B8: case DdsFileFormat.DDS_FORMAT_A8B8G8R8: case DdsFileFormat.DDS_FORMAT_X8B8G8R8: num = 4; break; case DdsFileFormat.DDS_FORMAT_A1R5G5B5: case DdsFileFormat.DDS_FORMAT_A4R4G4B4: case DdsFileFormat.DDS_FORMAT_R5G6B5: num = 2; break; case DdsFileFormat.DDS_FORMAT_R8G8B8: num = 3; break; } this.m_header.m_pitchOrLinearSize = (uint)(this.m_header.m_width * num); } this.m_header.m_depth = 0; this.m_header.m_mipMapCount = (num2 == 1) ? 0 : ((uint)num2); this.m_header.m_reserved1_0 = 0; this.m_header.m_reserved1_1 = 0; this.m_header.m_reserved1_2 = 0; this.m_header.m_reserved1_3 = 0; this.m_header.m_reserved1_4 = 0; this.m_header.m_reserved1_5 = 0; this.m_header.m_reserved1_6 = 0; this.m_header.m_reserved1_7 = 0; this.m_header.m_reserved1_8 = 0; this.m_header.m_reserved1_9 = 0; this.m_header.m_reserved1_10 = 0; this.m_header.m_pixelFormat.Initialise(fileFormat); this.m_header.m_surfaceFlags = 0x1000; if (num2 > 1) { this.m_header.m_surfaceFlags |= 0x400008; } this.m_header.m_cubemapFlags = 0; this.m_header.m_reserved2_0 = 0; this.m_header.m_reserved2_1 = 0; this.m_header.m_reserved2_2 = 0; output.WriteUInt32(0x20534444); this.m_header.Write(output); int squishFlags = this.GetSquishFlags(fileFormat, compressorType, errorMetric, weightColorByAlpha); mipWidth = surface.Width; height = surface.Height; SizeInt32[] numArray = new SizeInt32[num2]; int[] numArray2 = new int[num2]; int[] pixelsCompleted = new int[num2]; long totalPixels = 0L; for (int i = 0; i < num2; i++) { SizeInt32 num8 = new SizeInt32((mipWidth > 0) ? mipWidth : 1, (height > 0) ? height : 1); numArray[i] = num8; int num9 = num8.Width * num8.Height; numArray2[i] = num9; if (i == 0) { pixelsCompleted[i] = 0; } else { pixelsCompleted[i] = pixelsCompleted[i - 1] + numArray2[i - 1]; } totalPixels += num9; mipWidth /= 2; height /= 2; } mipWidth = surface.Width; height = surface.Height; for (int mipLoop = 0; mipLoop < num2; mipLoop = num21 + 1) { byte[] buffer; SizeInt32 size = numArray[mipLoop]; Surface surface2 = new Surface(size); if (mipLoop == 0) { surface2 = surface; } else { IRenderer <ColorBgra> renderer; SizeInt32 newSize = surface2.Size <ColorBgra>(); switch (mipMapResamplingAlgorithm) { case ResamplingAlgorithm.NearestNeighbor: renderer = surface.ResizeNearestNeighbor(newSize); break; case ResamplingAlgorithm.Bilinear: renderer = surface.ResizeBilinear(newSize); break; case ResamplingAlgorithm.Bicubic: renderer = surface.ResizeBicubic(newSize); break; case ResamplingAlgorithm.SuperSampling: renderer = surface.ResizeSuperSampling(newSize); break; case ResamplingAlgorithm.Fant: renderer = surface.ResizeFant(newSize); break; default: throw ExceptionUtil.InvalidEnumArgumentException <ResamplingAlgorithm>(mipMapResamplingAlgorithm, "mipMapResamplingAlgorithm"); } renderer.Render <ColorBgra>(surface2); } DdsSquish.ProgressFn fn = delegate(int workDone, int workTotal) { long num = workDone * mipWidth; long num2 = pixelsCompleted[mipLoop]; double num3 = (num + num2) / ((double)totalPixels); progressCallback(this, new ProgressEventArgs(DoubleUtil.Clamp(100.0 * num3, 0.0, 100.0))); }; if ((fileFormat >= DdsFileFormat.DDS_FORMAT_DXT1) && (fileFormat <= DdsFileFormat.DDS_FORMAT_DXT5)) { buffer = DdsSquish.CompressImage(surface2, squishFlags, (progressCallback == null) ? null : fn); } else { int num12 = num * surface2.Width; buffer = new byte[num12 * surface2.Height]; buffer.Initialize(); for (int j = 0; j < surface2.Height; j++) { for (int k = 0; k < surface2.Width; k++) { ColorBgra point = surface2.GetPoint(k, j); uint num15 = 0; switch (fileFormat) { case DdsFileFormat.DDS_FORMAT_A8R8G8B8: num15 = (uint)((((point.A << 0x18) | (point.R << 0x10)) | (point.G << 8)) | point.B); break; case DdsFileFormat.DDS_FORMAT_X8R8G8B8: num15 = (uint)(((point.R << 0x10) | (point.G << 8)) | point.B); break; case DdsFileFormat.DDS_FORMAT_A8B8G8R8: num15 = (uint)((((point.A << 0x18) | (point.B << 0x10)) | (point.G << 8)) | point.R); break; case DdsFileFormat.DDS_FORMAT_X8B8G8R8: num15 = (uint)(((point.B << 0x10) | (point.G << 8)) | point.R); break; case DdsFileFormat.DDS_FORMAT_A1R5G5B5: num15 = (uint)((((((point.A != null) ? 1 : 0) << 15) | ((point.R >> 3) << 10)) | ((point.G >> 3) << 5)) | (point.B >> 3)); break; case DdsFileFormat.DDS_FORMAT_A4R4G4B4: num15 = (uint)(((((point.A >> 4) << 12) | ((point.R >> 4) << 8)) | ((point.G >> 4) << 4)) | (point.B >> 4)); break; case DdsFileFormat.DDS_FORMAT_R8G8B8: num15 = (uint)(((point.R << 0x10) | (point.G << 8)) | point.B); break; case DdsFileFormat.DDS_FORMAT_R5G6B5: num15 = (uint)((((point.R >> 3) << 11) | ((point.G >> 2) << 5)) | (point.B >> 3)); break; } int num16 = (j * num12) + (k * num); for (int m = 0; m < num; m++) { buffer[num16 + m] = (byte)((num15 >> (8 * m)) & 0xff); } } if (progressCallback != null) { long num18 = (j + 1) * mipWidth; long num19 = pixelsCompleted[mipLoop]; double num20 = (num18 + num19) / ((double)totalPixels); progressCallback(this, new ProgressEventArgs(100.0 * num20)); } } } output.Write(buffer, 0, buffer.GetLength(0)); mipWidth /= 2; height /= 2; num21 = mipLoop; } }