예제 #1
0
        public static void Save(
            Document input,
            Stream output,
            DdsFileFormat format,
            DdsErrorMetric errorMetric,
            BC7CompressionMode compressionMode,
            bool cubeMap,
            bool generateMipmaps,
            MipMapSampling sampling,
            Surface scratchSurface,
            ProgressEventHandler progressCallback)
        {
            using (RenderArgs args = new RenderArgs(scratchSurface))
            {
                input.Render(args, true);
            }

            DdsProgressCallback ddsProgress = null;

            if (progressCallback != null)
            {
                ddsProgress = (UIntPtr done, UIntPtr total) =>
                {
                    double progress = (double)done.ToUInt64() / (double)total.ToUInt64();
                    progressCallback(null, new ProgressEventArgs(progress * 100.0, true));
                };
            }

            SaveDdsFile(scratchSurface, format, errorMetric, compressionMode, cubeMap, generateMipmaps, sampling, output, ddsProgress);
        }
예제 #2
0
        public static unsafe void Save(
            DDSSaveInfo info,
            TextureCollection textures,
            Stream output,
            DdsProgressCallback progressCallback)
        {
            StreamIOCallbacks streamIO  = new StreamIOCallbacks(output);
            IOCallbacks       callbacks = new IOCallbacks
            {
                Read    = streamIO.Read,
                Write   = streamIO.Write,
                Seek    = streamIO.Seek,
                GetSize = streamIO.GetSize
            };

            DDSBitmapData[] bitmapData = CreateBitmapDataArray(textures, info.arraySize, info.mipLevels);

            int hr;

            unsafe
            {
                fixed(DDSBitmapData *pBitmapData = bitmapData)
                {
                    if (IntPtr.Size == 8)
                    {
                        hr = DdsIO_x64.Save(info, pBitmapData, (uint)bitmapData.Length, callbacks, progressCallback);
                    }
                    else
                    {
                        hr = DdsIO_x86.Save(info, pBitmapData, (uint)bitmapData.Length, callbacks, progressCallback);
                    }
                }
            }

            GC.KeepAlive(streamIO);
            GC.KeepAlive(callbacks);
            GC.KeepAlive(progressCallback);

            if (FAILED(hr))
            {
                if (streamIO.CallbackExceptionInfo != null)
                {
                    streamIO.CallbackExceptionInfo.Throw();
                }
                else
                {
                    switch (hr)
                    {
                    case HResult.CanceledError:
                        throw new OperationCanceledException();

                    default:
                        Marshal.ThrowExceptionForHR(hr);
                        break;
                    }
                }
            }
        }
예제 #3
0
        private static void SaveDdsFile(
            Surface surface,
            DdsFileFormat format,
            DdsErrorMetric errorMetric,
            BC7CompressionMode compressionMode,
            bool cubeMap,
            bool generateMipmaps,
            MipMapSampling mipMapSampling,
            Stream output,
            DdsProgressCallback progressCallback)
        {
            DDSSaveInfo info = new DDSSaveInfo
            {
                scan0           = surface.Scan0.Pointer,
                width           = surface.Width,
                height          = surface.Height,
                stride          = surface.Stride,
                format          = format,
                errorMetric     = errorMetric,
                compressionMode = compressionMode,
                cubeMap         = cubeMap && IsCrossedCubeMapSize(surface),
                generateMipmaps = generateMipmaps,
                mipmapSampling  = mipMapSampling
            };

            StreamIOCallbacks streamIO  = new StreamIOCallbacks(output);
            IOCallbacks       callbacks = new IOCallbacks
            {
                Read    = streamIO.Read,
                Write   = streamIO.Write,
                Seek    = streamIO.Seek,
                GetSize = streamIO.GetSize
            };

            int hr;

            if (IntPtr.Size == 8)
            {
                hr = DdsIO_x64.Save(ref info, callbacks, progressCallback);
            }
            else
            {
                hr = DdsIO_x86.Save(ref info, callbacks, progressCallback);
            }

            GC.KeepAlive(streamIO);
            GC.KeepAlive(callbacks);
            GC.KeepAlive(progressCallback);

            if (FAILED(hr))
            {
                Marshal.ThrowExceptionForHR(hr);
            }
        }
예제 #4
0
        private static unsafe void SaveDdsFile(
            Surface surface,
            DdsFileFormat format,
            DdsErrorMetric errorMetric,
            BC7CompressionMode compressionMode,
            bool generateMipmaps,
            MipMapSampling mipMapSampling,
            DdsWriteImageCallback writeImageCallback,
            DdsProgressCallback progressCallback)
        {
            DDSSaveInfo info = new DDSSaveInfo
            {
                width           = surface.Width,
                height          = surface.Height,
                stride          = surface.Stride,
                format          = format,
                errorMetric     = errorMetric,
                compressionMode = compressionMode,
                generateMipmaps = generateMipmaps,
                mipmapSampling  = mipMapSampling,
                scan0           = surface.Scan0.Pointer
            };

            int hr;

            if (IntPtr.Size == 8)
            {
                hr = DdsIO_x64.Save(ref info, writeImageCallback, progressCallback);
            }
            else
            {
                hr = DdsIO_x86.Save(ref info, writeImageCallback, progressCallback);
            }

            if (FAILED(hr))
            {
                Marshal.ThrowExceptionForHR(hr);
            }
        }
예제 #5
0
        public static unsafe void Save(
            DDSSaveInfo info,
            TextureCollection textures,
            Stream output,
            DdsProgressCallback progressCallback)
        {
            StreamIOCallbacks streamIO  = new StreamIOCallbacks(output);
            IOCallbacks       callbacks = new IOCallbacks
            {
                Read    = streamIO.Read,
                Write   = streamIO.Write,
                Seek    = streamIO.Seek,
                GetSize = streamIO.GetSize
            };

            DDSBitmapData[] bitmapData = CreateBitmapDataArray(textures, info.arraySize, info.mipLevels);

            int hr;

            unsafe
            {
                fixed(DDSBitmapData *pBitmapData = bitmapData)
                {
#if NET47
                    if (IntPtr.Size == 8)
#else
                    if (RuntimeInformation.ProcessArchitecture == Architecture.X64)
#endif
                    {
                        hr = DdsIO_x64.Save(info, pBitmapData, (uint)bitmapData.Length, callbacks, progressCallback);
                    }
#if NET47
                    else if (IntPtr.Size == 4)
#else
                    else if (RuntimeInformation.ProcessArchitecture == Architecture.X86)
#endif
                    {
                        hr = DdsIO_x86.Save(info, pBitmapData, (uint)bitmapData.Length, callbacks, progressCallback);
                    }
                    else
                    {
                        throw new PlatformNotSupportedException();
                    }
                }
            }

            GC.KeepAlive(streamIO);
            GC.KeepAlive(callbacks);
            GC.KeepAlive(progressCallback);

            if (FAILED(hr))
            {
                if (streamIO.CallbackExceptionInfo != null)
                {
                    streamIO.CallbackExceptionInfo.Throw();
                }
                else
                {
                    switch (hr)
                    {
                    case HResult.CanceledError:
                        throw new OperationCanceledException();

                    case HResult.UnknownDdsSaveFormat:
                        throw new InvalidOperationException("The DDSFileFormat value does not map to a DXGI format.");

                    default:
                        Marshal.ThrowExceptionForHR(hr);
                        break;
                    }
                }
            }
        }
예제 #6
0
 internal static extern unsafe int Save(
     [In] DDSSaveInfo input,
     [In] DDSBitmapData *bitmapData,
     [In] uint bitmapDataLength,
     [In] IOCallbacks callbacks,
     [In, MarshalAs(UnmanagedType.FunctionPtr)] DdsProgressCallback progressCallback);
예제 #7
0
 internal static extern int Save(
     [In] ref DDSSaveInfo input,
     [In] IOCallbacks callbacks,
     [In, MarshalAs(UnmanagedType.FunctionPtr)] DdsProgressCallback progressCallback);
예제 #8
0
 internal static unsafe extern int Save(
     [In] ref DDSSaveInfo input,
     [In, MarshalAs(UnmanagedType.FunctionPtr)] DdsWriteImageCallback writeImageCallback,
     [In, MarshalAs(UnmanagedType.FunctionPtr)] DdsProgressCallback progressCallback);
예제 #9
0
        public static unsafe void Save(
            Document input,
            Stream output,
            DdsFileFormat format,
            DdsErrorMetric errorMetric,
            BC7CompressionMode compressionMode,
            bool generateMipmaps,
            MipMapSampling sampling,
            Surface scratchSurface,
            ProgressEventHandler progressCallback)
        {
            using (RenderArgs args = new RenderArgs(scratchSurface))
            {
                input.Render(args, true);
            }

            DdsWriteImageCallback ddsWriteImage = delegate(IntPtr image, UIntPtr imageSize)
            {
                ulong size = imageSize.ToUInt64();

                if (image != IntPtr.Zero && size > 0)
                {
                    const int MaxBufferSize = 65536;

                    ulong  streamBufferSize = Math.Min(MaxBufferSize, size);
                    byte[] streamBuffer     = new byte[streamBufferSize];

                    output.SetLength(checked ((long)size));

                    ulong offset    = 0;
                    ulong remaining = size;

                    fixed(byte *destPtr = streamBuffer)
                    {
                        byte *srcPtr = (byte *)image.ToPointer();

                        while (remaining > 0)
                        {
                            ulong copySize = Math.Min(MaxBufferSize, remaining);

                            Buffer.MemoryCopy(srcPtr + offset, destPtr, streamBufferSize, copySize);

                            output.Write(streamBuffer, 0, (int)copySize);

                            offset    += copySize;
                            remaining -= copySize;
                        }
                    }
                }
            };

            DdsProgressCallback ddsProgress = delegate(UIntPtr done, UIntPtr total)
            {
                double progress = (double)done.ToUInt64() / (double)total.ToUInt64();
                progressCallback(null, new ProgressEventArgs(progress * 100.0, true));
            };

            SaveDdsFile(scratchSurface, format, errorMetric, compressionMode, generateMipmaps, sampling, ddsWriteImage, ddsProgress);

            GC.KeepAlive(ddsWriteImage);
        }
예제 #10
0
        public static void Save(
            IServiceProvider services,
            Document input,
            Stream output,
            DdsFileFormat format,
            DdsErrorMetric errorMetric,
            BC7CompressionSpeed compressionSpeed,
            bool cubeMap,
            bool generateMipmaps,
            ResamplingAlgorithm sampling,
            Surface scratchSurface,
            ProgressEventHandler progressCallback)
        {
            using (RenderArgs args = new RenderArgs(scratchSurface))
            {
                input.Render(args, true);
            }

            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;

            using (TextureCollection textures = GetTextures(scratchSurface, cubeMapFaceSize, mipLevels, sampling))
            {
                if (format == DdsFileFormat.R8G8B8X8 || format == DdsFileFormat.B8G8R8)
                {
                    new DX9DdsWriter(width, height, arraySize, mipLevels, format).Save(textures, output, progressCallback);
                }
                else
                {
                    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);
                            }
                        };
                    }

                    DDSSaveInfo info = new DDSSaveInfo
                    {
                        width                      = width,
                        height                     = height,
                        arraySize                  = arraySize,
                        mipLevels                  = mipLevels,
                        format                     = format,
                        errorMetric                = errorMetric,
                        compressionSpeed           = compressionSpeed,
                        cubeMap                    = cubeMapFaceSize.HasValue,
                        enableHardwareAcceleration = enableHardwareAcceleration
                    };

                    DdsNative.Save(info, textures, output, ddsProgress);
                }
            }
        }