public static unsafe byte[] Compress(int width, int height, List <List <Memory <byte> > > data, crn_format format, crn_mipmap_params mipmaps = null, int maxThreads = -1) { var comp_params = new crn_comp_params(); comp_params.width = (uint)width; comp_params.height = (uint)height; comp_params.format = format; return(Compress(data, comp_params, mipmaps)); }
public static extern IntPtr crn_compress_mip(crn_comp_params comp_params, crn_mipmap_params mip_params, out uint compressed_size, out uint actual_quality_level, out float actual_bitrate);
public static unsafe byte[] Compress(List <List <Memory <byte> > > data, crn_comp_params comp_params, crn_mipmap_params mipmaps = null, int maxThreads = -1) { if (data.Count != 1 && data.Count != 6) { throw new ArgumentOutOfRangeException("Invalid number of faces"); } var levels = data[0].Count; foreach (var face in data) { if (face.Count != levels) { throw new ArgumentOutOfRangeException("Inconsistent number of levels between faces"); } } if (comp_params.height <= 0 || comp_params.width <= 0) { throw new ArgumentOutOfRangeException("Texture size"); } comp_params.faces = (uint)data.Count; comp_params.levels = (uint)levels; int threads = Environment.ProcessorCount - 1; if (maxThreads >= 0) { threads = maxThreads; } comp_params.num_helper_threads = (uint)Math.Min(Constants.MAX_HELPER_THREADS, threads); List <MemoryHandle> handles = new List <MemoryHandle>(); try { for (int f = 0; f < data.Count; f++) { for (int m = 0; m < levels; m++) { var handle = data[f][m].Pin(); handles.Add(handle); comp_params.images[f, m] = new IntPtr(handle.Pointer); } } IntPtr compressedPtr; uint compressed_size; uint actual_quality_level; float actual_bitrate; if (mipmaps != null) { compressedPtr = NativeMethods.crn_compress_mip(comp_params, mipmaps, out compressed_size, out actual_quality_level, out actual_bitrate); } else { compressedPtr = NativeMethods.crn_compress(comp_params, out compressed_size, out actual_quality_level, out actual_bitrate); } byte[] compressedData = null; if (compressedPtr != IntPtr.Zero) { compressedData = new byte[compressed_size]; Marshal.Copy(compressedPtr, compressedData, 0, (int)compressed_size); NativeMethods.crn_free_block(compressedPtr); } return(compressedData); } finally { foreach (var handle in handles) { handle.Dispose(); } } }