示例#1
0
        public static unsafe byte[] Convert(Byte[] data, int width, int height, DXGI_FORMAT inputFormat, DXGI_FORMAT outputFormat)
        {
            long inputRowPitch;
            long inputSlicePitch;

            TexHelper.Instance.ComputePitch(inputFormat, width, height, out inputRowPitch, out inputSlicePitch, CP_FLAGS.NONE);

            if (data.Length == inputSlicePitch)
            {
                byte *buf;
                buf = (byte *)Marshal.AllocHGlobal((int)inputSlicePitch);
                Marshal.Copy(data, 0, (IntPtr)buf, (int)inputSlicePitch);

                DirectXTexNet.Image inputImage = new DirectXTexNet.Image(
                    width, height, inputFormat, inputRowPitch,
                    inputSlicePitch, (IntPtr)buf, null);

                TexMetadata texMetadata = new TexMetadata(width, height, 1, 1, 1, 0, 0,
                                                          inputFormat, TEX_DIMENSION.TEXTURE2D);

                ScratchImage scratchImage = TexHelper.Instance.InitializeTemporary(
                    new DirectXTexNet.Image[] { inputImage }, texMetadata, null);

                var convFlags = TEX_FILTER_FLAGS.DEFAULT;

                if (inputFormat == DXGI_FORMAT.B8G8R8A8_UNORM_SRGB ||
                    inputFormat == DXGI_FORMAT.B8G8R8X8_UNORM_SRGB ||
                    inputFormat == DXGI_FORMAT.R8G8B8A8_UNORM_SRGB)
                {
                    convFlags |= TEX_FILTER_FLAGS.SRGB;
                }

                using (var decomp = scratchImage.Convert(0, outputFormat, convFlags, 0.5f))
                {
                    long outRowPitch;
                    long outSlicePitch;
                    TexHelper.Instance.ComputePitch(outputFormat, width, height, out outRowPitch, out outSlicePitch, CP_FLAGS.NONE);

                    byte[] result = new byte[outSlicePitch];
                    Marshal.Copy(decomp.GetImage(0).Pixels, result, 0, result.Length);

                    inputImage = null;
                    scratchImage.Dispose();


                    return(result);
                }
            }
            return(null);
        }
示例#2
0
        private void Decompress(ref ScratchImage scratch)
        {
            var          meta = scratch.GetMetadata();
            ScratchImage decompressed;

            switch (meta.Format)
            {
            case DXGI_FORMAT.BC1_TYPELESS:
            case DXGI_FORMAT.BC1_UNORM:
            case DXGI_FORMAT.BC1_UNORM_SRGB:
            case DXGI_FORMAT.BC2_TYPELESS:
            case DXGI_FORMAT.BC2_UNORM:
            case DXGI_FORMAT.BC2_UNORM_SRGB:
            case DXGI_FORMAT.BC3_TYPELESS:
            case DXGI_FORMAT.BC3_UNORM:
            case DXGI_FORMAT.BC3_UNORM_SRGB:
            case DXGI_FORMAT.BC4_TYPELESS:
            case DXGI_FORMAT.BC4_UNORM:
            case DXGI_FORMAT.BC4_SNORM:
            case DXGI_FORMAT.BC5_TYPELESS:
            case DXGI_FORMAT.BC5_UNORM:
            case DXGI_FORMAT.BC5_SNORM:
            case DXGI_FORMAT.BC6H_TYPELESS:
            case DXGI_FORMAT.BC6H_UF16:
            case DXGI_FORMAT.BC6H_SF16:
            case DXGI_FORMAT.BC7_TYPELESS:
            case DXGI_FORMAT.BC7_UNORM:
            case DXGI_FORMAT.BC7_UNORM_SRGB:
                decompressed = scratch.Decompress(DXGI_FORMAT.B8G8R8A8_UNORM);
                break;

            default:
                decompressed = scratch.Convert(DXGI_FORMAT.B8G8R8A8_UNORM, TEX_FILTER_FLAGS.FANT, 0.5f);
                break;
            }

            scratch.Dispose();
            scratch = decompressed;
        }
示例#3
0
        /// <summary>
        /// Matches a given DDS file on the disk to a D3DTX object.
        /// </summary>
        /// <param name="ddsPath"></param>
        /// <param name="d3dtx"></param>
        /// <param name="options"></param>
        public void Match_DDS_With_D3DTX(string ddsPath, D3DTX_Master d3dtx, DDS_Matching_Options options)
        {
            //load in the DDS image using DirectXTexNet
            ScratchImage scratchImage = TexHelper.Instance.LoadFromDDSFile(ddsPath, DDS_FLAGS.NONE);

            //create our main variables that will be used when doing conversion operations
            int             d3dtx_width     = 0;
            int             d3dtx_height    = 0;
            int             d3dtx_mipAmount = 0;
            T3SurfaceFormat d3dtx_format    = T3SurfaceFormat.eSurface_DXT1;
            T3SurfaceGamma  d3dtx_gamma     = T3SurfaceGamma.eSurfaceGamma_sRGB;

            //assign the values depending on which version is active
            if (d3dtx.d3dtx9 != null)
            {
                d3dtx_width     = (int)d3dtx.d3dtx9.mWidth;
                d3dtx_height    = (int)d3dtx.d3dtx9.mHeight;
                d3dtx_mipAmount = (int)d3dtx.d3dtx9.mNumMipLevels;
                d3dtx_format    = d3dtx.d3dtx9.mSurfaceFormat;
                d3dtx_gamma     = d3dtx.d3dtx9.mSurfaceGamma;
            }
            else if (d3dtx.d3dtx8 != null)
            {
                d3dtx_width     = (int)d3dtx.d3dtx8.mWidth;
                d3dtx_height    = (int)d3dtx.d3dtx8.mHeight;
                d3dtx_mipAmount = (int)d3dtx.d3dtx8.mNumMipLevels;
                d3dtx_format    = d3dtx.d3dtx8.mSurfaceFormat;
                d3dtx_gamma     = d3dtx.d3dtx8.mSurfaceGamma;
            }
            else if (d3dtx.d3dtx7 != null)
            {
                d3dtx_width     = (int)d3dtx.d3dtx7.mWidth;
                d3dtx_height    = (int)d3dtx.d3dtx7.mHeight;
                d3dtx_mipAmount = (int)d3dtx.d3dtx7.mNumMipLevels;
                d3dtx_format    = d3dtx.d3dtx7.mSurfaceFormat;
                d3dtx_gamma     = d3dtx.d3dtx7.mSurfaceGamma;
            }
            else if (d3dtx.d3dtx6 != null)
            {
                d3dtx_width     = (int)d3dtx.d3dtx6.mWidth;
                d3dtx_height    = (int)d3dtx.d3dtx6.mHeight;
                d3dtx_mipAmount = (int)d3dtx.d3dtx6.mNumMipLevels;
                d3dtx_format    = d3dtx.d3dtx6.mSurfaceFormat;
                d3dtx_gamma     = T3SurfaceGamma.eSurfaceGamma_sRGB; //this version doesn't have a surface gamma field, so give it an SRGB by default
            }
            else if (d3dtx.d3dtx5 != null)
            {
                d3dtx_width     = (int)d3dtx.d3dtx5.mWidth;
                d3dtx_height    = (int)d3dtx.d3dtx5.mHeight;
                d3dtx_mipAmount = (int)d3dtx.d3dtx5.mNumMipLevels;
                d3dtx_format    = d3dtx.d3dtx5.mSurfaceFormat;
                d3dtx_gamma     = T3SurfaceGamma.eSurfaceGamma_sRGB; //this version doesn't have a surface gamma field, so give it an SRGB by default
            }
            else if (d3dtx.d3dtx4 != null)
            {
                d3dtx_width     = (int)d3dtx.d3dtx4.mWidth;
                d3dtx_height    = (int)d3dtx.d3dtx4.mHeight;
                d3dtx_mipAmount = (int)d3dtx.d3dtx4.mNumMipLevels;
                d3dtx_format    = d3dtx.d3dtx4.mSurfaceFormat;
                d3dtx_gamma     = T3SurfaceGamma.eSurfaceGamma_sRGB; //this version doesn't have a surface gamma field, so give it an SRGB by default
            }

            //-------------------------------------- CONVERSION START --------------------------------------
            //change the compression if needed
            if (options.MatchCompression)
            {
                DXGI_FORMAT dxgi_format = DDS_Functions.GetSurfaceFormatAsDXGI(d3dtx_format, d3dtx_gamma);
                scratchImage.Convert(dxgi_format, TEX_FILTER_FLAGS.DITHER, 0.0f);
            }

            //rescale the image to match if needed
            if (options.MatchResolution)
            {
                scratchImage.Resize(d3dtx_width, d3dtx_height, TEX_FILTER_FLAGS.CUBIC);
            }

            //generate mip maps if needed
            if (options.GenerateMipMaps)
            {
                if (options.MatchMipMapCount)
                {
                    scratchImage.GenerateMipMaps(0, TEX_FILTER_FLAGS.CUBIC, d3dtx_mipAmount, false);
                }
                else
                {
                    scratchImage.GenerateMipMaps(0, TEX_FILTER_FLAGS.CUBIC, 0, false);
                }
            }

            //resave the newly modified DDS
            scratchImage.SaveToDDSFile(DDS_FLAGS.NONE, ddsPath);
        }
示例#4
0
        public static unsafe byte[] ConvertDDS(Stream ddsSteam, DXGI_FORMAT targetFormat, WICCodecs codec, int frame)
        {
            try {
                CoInitializeEx(IntPtr.Zero, CoInit.MultiThreaded | CoInit.SpeedOverMemory);

                byte[] data = new byte[ddsSteam.Length];
                ddsSteam.Read(data, 0, data.Length);
                ScratchImage scratch = null;
                try
                {
                    fixed(byte *dataPin = data)
                    {
                        scratch = TexHelper.Instance.LoadFromDDSMemory((IntPtr)dataPin, data.Length, DDS_FLAGS.NONE);
                        TexMetadata info = scratch.GetMetadata();

                        if (TexHelper.Instance.IsCompressed(info.Format))
                        {
                            ScratchImage temp = scratch.Decompress(DXGI_FORMAT.UNKNOWN);
                            scratch.Dispose();
                            scratch = temp;

                            info = scratch.GetMetadata();
                        }

                        if (info.Format != targetFormat)
                        {
                            ScratchImage temp = scratch.Convert(targetFormat, TEX_FILTER_FLAGS.DEFAULT, 0.5f);
                            scratch.Dispose();
                            scratch = temp;
                        }

                        UnmanagedMemoryStream stream = null;
                        var isMultiFrame             = codec == WICCodecs.GIF || codec == WICCodecs.TIFF;

                        if (info.ArraySize == 1 || !isMultiFrame)
                        {
                            stream = scratch.SaveToWICMemory(frame, WIC_FLAGS.NONE, TexHelper.Instance.GetWICCodec(codec));
                        }
                        else
                        {
                            stream = scratch.SaveToWICMemory(0, info.ArraySize, WIC_FLAGS.ALL_FRAMES, TexHelper.Instance.GetWICCodec(codec));
                        }

                        if (stream == null)
                        {
                            return(null);
                        }

                        byte[] tex = new byte[stream.Length];
                        stream.Read(tex, 0, tex.Length);
                        scratch.Dispose();
                        return(tex);
                    }
                } catch {
                    if (scratch != null && scratch.IsDisposed == false)
                    {
                        scratch.Dispose();
                    }
                }
            } catch {
                // ignored
            }

            return(null);
        }
示例#5
0
        public static byte[] ConvertDDS(GUIDEntry value, DXGI_FORMAT targetFormat, ImageFormat imageFormat, int frame)
        {
            try
            {
                if (GetDataType(value) != DataType.Image)
                {
                    return(null);
                }
                teTexture texture = new teTexture(IOHelper.OpenFile(value));
                if (texture.PayloadRequired)
                {
                    ulong payload = texture.GetPayloadGUID(value.GUID);
                    if (value.APM.FirstOccurence.ContainsKey(payload))
                    {
                        texture.LoadPayload(IOHelper.OpenFile(value.APM.FirstOccurence[payload]));
                    }
                    else
                    {
                        return(null);
                    }
                }

                Stream ms = texture.SaveToDDS();

                CoInitializeEx(IntPtr.Zero, CoInit.MultiThreaded | CoInit.SpeedOverMemory);

                byte[] data = new byte[ms.Length];
                ms.Read(data, 0, data.Length);
                ScratchImage scratch = null;
                try
                {
                    unsafe
                    {
                        fixed(byte *dataPin = data)
                        {
                            scratch = TexHelper.Instance.LoadFromDDSMemory((IntPtr)dataPin, data.Length, DDS_FLAGS.NONE);
                            TexMetadata info = scratch.GetMetadata();

                            if (TexHelper.Instance.IsCompressed(info.Format))
                            {
                                ScratchImage temp = scratch.Decompress(frame, DXGI_FORMAT.UNKNOWN);
                                scratch.Dispose();
                                scratch = temp;
                            }
                            info = scratch.GetMetadata();

                            if (info.Format != targetFormat)
                            {
                                ScratchImage temp = scratch.Convert(targetFormat, TEX_FILTER_FLAGS.DEFAULT, 0.5f);
                                scratch.Dispose();
                                scratch = temp;
                            }

                            UnmanagedMemoryStream stream = null;

                            if (imageFormat == ImageFormat.TGA)
                            {
                                stream = scratch.SaveToTGAMemory(frame < 0 ? 0 : frame);
                            }
                            else
                            {
                                WICCodecs codec        = WICCodecs.PNG;
                                bool      isMultiframe = false;
                                switch (imageFormat)
                                {
                                case ImageFormat.BMP:
                                    codec = WICCodecs.BMP;
                                    break;

                                case ImageFormat.GIF:
                                    codec        = WICCodecs.GIF;
                                    isMultiframe = true;
                                    break;

                                case ImageFormat.JPEG:
                                    codec = WICCodecs.JPEG;
                                    break;

                                case ImageFormat.PNG:
                                    codec = WICCodecs.PNG;
                                    break;

                                case ImageFormat.TIF:
                                    codec        = WICCodecs.TIFF;
                                    isMultiframe = true;
                                    break;
                                }

                                if (frame < 0)
                                {
                                    if (!isMultiframe)
                                    {
                                        frame = 0;
                                    }
                                    else
                                    {
                                        stream = scratch.SaveToWICMemory(0, info.ArraySize, WIC_FLAGS.ALL_FRAMES, TexHelper.Instance.GetWICCodec(codec));
                                    }
                                }
                                if (frame >= 0)
                                {
                                    stream = scratch.SaveToWICMemory(frame, WIC_FLAGS.NONE, TexHelper.Instance.GetWICCodec(codec));
                                }

                                byte[] tex = new byte[stream.Length];
                                stream.Read(tex, 0, tex.Length);
                                scratch.Dispose();
                                return(tex);
                            }
                        }
                    }
                }
                catch
                {
                    if (scratch != null && scratch.IsDisposed == false)
                    {
                        scratch?.Dispose();
                    }
                }
            }
            catch
            {
            }
            return(null);
        }
示例#6
0
        public static unsafe byte[] ConvertDDS(Stream ddsSteam, DXGI_FORMAT targetFormat, ImageFormat imageFormat, int frame)
        {
            try {
                CoInitializeEx(IntPtr.Zero, CoInit.MultiThreaded | CoInit.SpeedOverMemory);

                byte[] data = new byte[ddsSteam.Length];
                ddsSteam.Read(data, 0, data.Length);
                ScratchImage scratch = null;
                try
                {
                    fixed(byte *dataPin = data)
                    {
                        scratch = TexHelper.Instance.LoadFromDDSMemory((IntPtr)dataPin, data.Length, DDS_FLAGS.NONE);
                        TexMetadata info = scratch.GetMetadata();

                        if (TexHelper.Instance.IsCompressed(info.Format))
                        {
                            ScratchImage temp = scratch.Decompress(frame, DXGI_FORMAT.UNKNOWN);
                            scratch.Dispose();
                            scratch = temp;
                        }

                        info = scratch.GetMetadata();

                        if (info.Format != targetFormat)
                        {
                            ScratchImage temp = scratch.Convert(targetFormat, TEX_FILTER_FLAGS.DEFAULT, 0.5f);
                            scratch.Dispose();
                            scratch = temp;
                        }

                        UnmanagedMemoryStream stream = null;

                        if (imageFormat == ImageFormat.TGA)
                        {
                            stream = scratch.SaveToTGAMemory(frame < 0 ? 0 : frame);
                        }
                        else
                        {
                            WICCodecs codec        = WICCodecs.PNG;
                            bool      isMultiFrame = false;
                            switch (imageFormat)
                            {
                            case ImageFormat.BMP:
                                codec = WICCodecs.BMP;
                                break;

                            case ImageFormat.GIF:
                                codec        = WICCodecs.GIF;
                                isMultiFrame = true;
                                break;

                            case ImageFormat.JPEG:
                                codec = WICCodecs.JPEG;
                                break;

                            case ImageFormat.PNG:
                                codec = WICCodecs.PNG;
                                break;

                            case ImageFormat.TIF:
                                codec        = WICCodecs.TIFF;
                                isMultiFrame = true;
                                break;

                            case ImageFormat.TGA:
                                break;

                            default:
                                throw new ArgumentOutOfRangeException(nameof(imageFormat), imageFormat, null);
                            }

                            if (frame < 0)
                            {
                                if (!isMultiFrame)
                                {
                                    frame = 0;
                                }
                                else
                                {
                                    stream = scratch.SaveToWICMemory(0, info.ArraySize, WIC_FLAGS.ALL_FRAMES, TexHelper.Instance.GetWICCodec(codec));
                                }
                            }

                            if (frame >= 0)
                            {
                                stream = scratch.SaveToWICMemory(frame, WIC_FLAGS.NONE, TexHelper.Instance.GetWICCodec(codec));
                            }
                        }

                        if (stream == null)
                        {
                            return(null);
                        }

                        byte[] tex = new byte[stream.Length];
                        stream.Read(tex, 0, tex.Length);
                        scratch.Dispose();
                        return(tex);
                    }
                } catch {
                    if (scratch != null && scratch.IsDisposed == false)
                    {
                        scratch.Dispose();
                    }
                }
            } catch {
                // ignored
            }

            return(null);
        }