예제 #1
0
        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));
        }
예제 #2
0
 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);
예제 #3
0
        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();
                }
            }
        }