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); } }
internal static unsafe extern int Save( [In] ref DDSSaveInfo input, [In, MarshalAs(UnmanagedType.FunctionPtr)] DdsWriteImageCallback writeImageCallback, [In, MarshalAs(UnmanagedType.FunctionPtr)] DdsProgressCallback progressCallback);
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); }