Example #1
0
        /// <summary>
        /// data must be RGBA8888 byte array
        /// </summary>
        /// <param name="data"></param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <param name="targetFormat"></param>
        /// <returns></returns>
        public static byte[] Compress(byte[] data, int width, int height, CompressionFormat targetFormat)
        {
            try {
                QFormat format = QFormat.Q_FORMAT_RGBA_8UI;
                switch (targetFormat)
                {
                case CompressionFormat.AtcRgb:
                    format = QFormat.Q_FORMAT_ATC_RGB;
                    break;

                case CompressionFormat.AtcRgbaExplicitAlpha:
                    format = QFormat.Q_FORMAT_ATC_RGBA_EXPLICIT_ALPHA;
                    break;

                case CompressionFormat.AtcRgbaInterpolatedAlpha:
                    format = QFormat.Q_FORMAT_ATC_RGBA_INTERPOLATED_ALPHA;
                    break;

                case CompressionFormat.Etc1:
                    format = QFormat.Q_FORMAT_ETC1_RGB8;
                    break;

                case CompressionFormat.Etc2Rgba:
                    format = QFormat.Q_FORMAT_ETC2_RGBA8;
                    break;

                case CompressionFormat.Astc8:
                    format = QFormat.Q_FORMAT_ASTC_8;
                    break;

                case CompressionFormat.Astc16:
                    format = QFormat.Q_FORMAT_ASTC_16;
                    break;

                case CompressionFormat.DXT1:
                    format = QFormat.Q_FORMAT_S3TC_DXT1_RGB;
                    break;

                case CompressionFormat.DXT3:
                    format = QFormat.Q_FORMAT_S3TC_DXT3_RGBA;
                    break;

                case CompressionFormat.DXT5:
                    format = QFormat.Q_FORMAT_S3TC_DXT5_RGBA;
                    break;
                }

                uint uwidth  = (uint)width;
                uint uheight = (uint)height;

                var src = NativeMethods.CreateEmptyQonvertImage();
                var dst = NativeMethods.CreateEmptyQonvertImage();

                var handle = GCHandle.Alloc(data, GCHandleType.Pinned);
                try {
                    src.nWidth  = uwidth;
                    src.nHeight = uheight;
                    src.nFormat = (uint)QFormat.Q_FORMAT_RGBA_8UI;
                    src.pData   = handle.AddrOfPinnedObject();


                    dst.nWidth  = uwidth;
                    dst.nHeight = uheight;
                    dst.nFormat = (uint)format;
                    dst.pData   = IntPtr.Zero;

                    if (NativeMethods.Qonvert(ref src, ref dst, IntPtr.Zero) != (uint)TReturnCode.Q_SUCCESS)
                    {
                        throw new Exception(string.Format("Error getting compressed data size for {0} Compression", format.ToString()));
                    }

                    byte[] compressed       = new byte[dst.nDataSize];
                    var    compressedHandle = GCHandle.Alloc(compressed, GCHandleType.Pinned);
                    try {
                        dst.pData = compressedHandle.AddrOfPinnedObject();

                        if (NativeMethods.Qonvert(ref src, ref dst, IntPtr.Zero) != (uint)TReturnCode.Q_SUCCESS)
                        {
                            throw new Exception(string.Format("Error getting compressed data size for {0} Compression", format.ToString()));
                        }
                        return(compressed);
                    }
                    finally {
                        compressedHandle.Free();
                    }
                }
                finally {
                    handle.Free();
                }
            }
            catch (DllNotFoundException ex) {
                throw new DllNotFoundException(string.Format("{0} See Documentation for more details.", ex.Message));
            }
        }
        public static byte[] Compress(byte[] data, int width, int height, CompressionFormat targetFormat)
        {
            try {
                QFormat format = QFormat.Q_FORMAT_RGBA_8UI;
                switch (targetFormat)
                {
                case CompressionFormat.AtcRgb:
                    format = QFormat.Q_FORMAT_ATC_RGB;
                    break;

                case CompressionFormat.AtcRgbaExplicitAlpha:
                    format = QFormat.Q_FORMAT_ATC_RGBA_EXPLICIT_ALPHA;
                    break;

                case CompressionFormat.AtcRgbaInterpolatedAlpha:
                    format = QFormat.Q_FORMAT_ATC_RGBA_INTERPOLATED_ALPHA;
                    break;

                case CompressionFormat.Etc1:
                    format = QFormat.Q_FORMAT_ETC1_RGB8;
                    break;

                case CompressionFormat.Etc2Rgba:
                    format = QFormat.Q_FORMAT_ETC2_RGBA8;
                    break;
                }

                uint uwidth  = (uint)width;
                uint uheight = (uint)height;

                var src = NativeMethods.CreateEmptyQonvertImage();
                var dst = NativeMethods.CreateEmptyQonvertImage();

                var handle = GCHandle.Alloc(data, GCHandleType.Pinned);
                try {
                    src.nWidth  = uwidth;
                    src.nHeight = uheight;
                    src.nFormat = (uint)QFormat.Q_FORMAT_RGBA_8UI;
                    src.pData   = handle.AddrOfPinnedObject();

                    dst.nWidth  = uwidth;
                    dst.nHeight = uheight;
                    dst.nFormat = (uint)format;
                    dst.pData   = IntPtr.Zero;

                    if (NativeMethods.Qonvert(ref src, ref dst, IntPtr.Zero) != (uint)TReturnCode.Q_SUCCESS)
                    {
                        throw new Exception("Error getting compressed data size for ATC Compression");
                    }

                    byte[] compressed       = new byte[dst.nDataSize];
                    var    compressedHandle = GCHandle.Alloc(compressed, GCHandleType.Pinned);
                    try {
                        dst.pData = compressedHandle.AddrOfPinnedObject();

                        if (NativeMethods.Qonvert(ref src, ref dst, IntPtr.Zero) != (uint)TReturnCode.Q_SUCCESS)
                        {
                            throw new Exception("Error getting compressed texture ATC Compression");
                        }
                        return(compressed);
                    } finally {
                        compressedHandle.Free();
                    }
                } finally {
                    handle.Free();
                }
            } catch (DllNotFoundException ex) {
                throw new DllNotFoundException(string.Format("{0}{1}See Documentation for more details {1}{2}", ex.Message,
                                                             Environment.NewLine,
                                                             "https://github.com/infinitespace-studios/ATI.TextureConverter/blob/master/README.md"));
            }
        }