Beispiel #1
0
        /// <summary>
        /// Compresses the specified image.
        /// </summary>
        /// <param name="image">The image.</param>
        /// <param name="libraryData">The library data.</param>
        /// <param name="compress">The compress.</param>
        /// <exception cref="TexLibraryException">Compression failed</exception>
        private void Compress(TexImage image, PvrTextureLibraryData libraryData, CompressingRequest compress)
        {
            Log.Info("Compressing to " + compress.Format + " ...");

            ulong             format     = RetrieveNativeFormat(compress.Format);
            EPVRTColourSpace  colorSpace = RetrieveNativeColorSpace(compress.Format);
            EPVRTVariableType pixelType  = RetrieveNativePixelType(compress.Format);

            lock (lockObject)
            {
                if (!Utilities.Transcode(libraryData.Texture, format, pixelType, colorSpace, (ECompressorQuality)compress.Quality, false))
                {
                    Log.Error("Compression failed!");
                    throw new TextureToolsException("Compression failed!");
                }
            }

            image.Format = compress.Format;
            int pitch, slice;

            Tools.ComputePitch(image.Format, image.Width, image.Height, out pitch, out slice);
            image.RowPitch   = pitch;
            image.SlicePitch = slice;

            UpdateImage(image, libraryData);
        }
Beispiel #2
0
        /// <summary>
        /// Generates the mip maps.
        /// </summary>
        /// <param name="image">The image.</param>
        /// <param name="libraryData">The library data.</param>
        /// <param name="request">The request.</param>
        private void GenerateMipMaps(TexImage image, PvrTextureLibraryData libraryData, MipMapsGenerationRequest request)
        {
            Log.Info("Generating Mipmaps ... ");

            EResizeMode filter;

            switch (request.Filter)
            {
            case Filter.MipMapGeneration.Linear:
                filter = EResizeMode.eResizeLinear;
                break;

            case Filter.MipMapGeneration.Cubic:
                filter = EResizeMode.eResizeCubic;
                break;

            case Filter.MipMapGeneration.Nearest:
                filter = EResizeMode.eResizeNearest;
                break;

            default:
                filter = EResizeMode.eResizeCubic;
                break;
            }

            libraryData.Texture.GenerateMIPMaps(filter);

            UpdateImage(image, libraryData);
        }
Beispiel #3
0
        /// <summary>
        /// Flips the specified image vertically or horizontally.
        /// </summary>
        /// <param name="image">The image.</param>
        /// <param name="libraryData">The library data.</param>
        /// <param name="request">The request.</param>
        /// <exception cref="TexLibraryException">Flipping failed.</exception>
        private void Flip(TexImage image, PvrTextureLibraryData libraryData, FlippingRequest request)
        {
            Log.Info("Flipping texture : " + request.Flip + " ... ");

            switch (request.Flip)
            {
            case Orientation.Horizontal:
                if (!Utilities.Flip(libraryData.Texture, EPVRTAxis.ePVRTAxisX))
                {
                    Log.Error("Flipping failed.");
                    throw new TextureToolsException("Flipping failed.");
                }
                break;

            case Orientation.Vertical:
                if (!Utilities.Flip(libraryData.Texture, EPVRTAxis.ePVRTAxisY))
                {
                    Log.Error("Flipping failed.");
                    throw new TextureToolsException("Flipping failed.");
                }
                break;
            }

            image.Flip(request.Flip);

            UpdateImage(image, libraryData);
        }
Beispiel #4
0
        /// <summary>
        /// Generates the normal map.
        /// </summary>
        /// <param name="image">The image.</param>
        /// <param name="libraryData">The library data.</param>
        /// <param name="request">The request.</param>
        /// <exception cref="TexLibraryException">Failed to generate normal map.</exception>
        public void GenerateNormalMap(TexImage image, PvrTextureLibraryData libraryData, NormalMapGenerationRequest request)
        {
            Log.Info("Generating Normal Map ... ");

            // Creating new TexImage with the normal map data.
            request.NormalMap = new TexImage();
            PvrTextureLibraryData normalMapLibraryData = new PvrTextureLibraryData();

            request.NormalMap.LibraryData[this] = normalMapLibraryData;

            normalMapLibraryData.Texture       = new PVRTexture(libraryData.Header, libraryData.Texture.GetDataPtr());
            request.NormalMap.Format           = SiliconStudio.Paradox.Graphics.PixelFormat.R8G8B8A8_UNorm;
            request.NormalMap.CurrentLibrary   = this;
            request.NormalMap.DisposingLibrary = this;

            if (!Utilities.GenerateNormalMap(normalMapLibraryData.Texture, request.Amplitude, "xyzh"))
            {
                Log.Error("Failed to generate normal map.");
                throw new TextureToolsException("Failed to generate normal map.");
            }

            UpdateImage(request.NormalMap, normalMapLibraryData);
            EndLibrary(request.NormalMap);
            request.NormalMap.DisposingLibrary = this;
        }
Beispiel #5
0
        /// <summary>
        /// Rescales the specified image.
        /// </summary>
        /// <param name="image">The image.</param>
        /// <param name="libraryData">The library data.</param>
        /// <param name="request">The request.</param>
        private void Rescale(TexImage image, PvrTextureLibraryData libraryData, RescalingRequest request)
        {
            int width  = request.ComputeWidth(image);
            int height = request.ComputeHeight(image);

            Log.Info("Rescaling to " + width + "x" + height + " ...");

            EResizeMode filter;

            switch (request.Filter)
            {
            case Filter.Rescaling.Bilinear:
                filter = EResizeMode.eResizeLinear;
                break;

            case Filter.Rescaling.Bicubic:
                filter = EResizeMode.eResizeCubic;
                break;

            case Filter.Rescaling.Nearest:
                filter = EResizeMode.eResizeNearest;
                break;

            default:
                filter = EResizeMode.eResizeCubic;
                break;
            }

            Utilities.Resize(libraryData.Texture, (uint)width, (uint)height, (uint)image.Depth, filter);
            UpdateImage(image, libraryData);

            // Updating image data
            image.Rescale(width, height);
        }
Beispiel #6
0
        /// <summary>
        /// Transposes face data since Pvrtt keeps the format of data [mipMap][face], but Paradox uses [face][mipMap]
        /// </summary>
        /// <param name="image"></param>
        /// <param name="libraryData"></param>
        private void TransposeFaceData(TexImage image, PvrTextureLibraryData libraryData)
        {
            var destPtr = Marshal.AllocHGlobal(image.DataSize);

            var targetRowSize = 0;

            // Build an array of slices for each mip levels
            var slices        = new int[image.MipmapCount];
            var aggregateSize = new int[image.MipmapCount];

            var currWidth  = image.Width;
            var currHeight = image.Height;

            for (var i = 0; i < image.MipmapCount; ++i)
            {
                int pitch, slice;
                Tools.ComputePitch(image.Format, currWidth, currHeight, out pitch, out slice);

                slices[i] = slice;

                aggregateSize[i] = targetRowSize;
                targetRowSize   += slice;

                currWidth  /= 2;
                currHeight /= 2;
            }

            var sourceRowOffset = 0;

            for (var currMip = 0; currMip < image.MipmapCount; ++currMip)
            {
                var slice = slices[currMip];

                for (var currFace = 0; currFace < image.FaceCount; ++currFace)
                {
                    var sourceOffset = sourceRowOffset + (currFace * slice);

                    var destOffset = (targetRowSize * currFace) + aggregateSize[currMip];

                    var source = new IntPtr(image.Data.ToInt64() + sourceOffset);
                    var dest   = new IntPtr(destPtr.ToInt64() + destOffset);

                    Core.Utilities.CopyMemory(dest, source, slice);
                }

                sourceRowOffset += slice * image.FaceCount;
            }

            // Copy data back to the library
            Core.Utilities.CopyMemory(
                libraryData.Texture.GetDataPtr(),                   // Dest
                destPtr,                                            // Source
                image.DataSize);                                    // Size

            image.Data = libraryData.Texture.GetDataPtr();

            Marshal.FreeHGlobal(destPtr);
        }
Beispiel #7
0
 /// <summary>
 /// Updates the image basic information with the native data.
 /// </summary>
 /// <param name="image">The image.</param>
 /// <param name="libraryData">The library data.</param>
 private void UpdateImage(TexImage image, PvrTextureLibraryData libraryData)
 {
     image.Data         = libraryData.Texture.GetDataPtr();
     libraryData.Header = libraryData.Texture.GetHeader();
     image.DataSize     = (int)libraryData.Header.GetDataSize();
     image.MipmapCount  = (int)libraryData.Header.GetNumMIPLevels();
     image.ArraySize    = (int)libraryData.Header.GetNumArrayMembers();
     image.FaceCount    = (int)libraryData.Header.GetNumFaces();
 }
Beispiel #8
0
        /// <summary>
        /// Premultiplies the alpha on the specified texture.
        /// </summary>
        /// <param name="image">The image.</param>
        /// <param name="libraryData">The library data.</param>
        /// <exception cref="TexLibraryException">Failed to premultiply the alpha.</exception>
        public void PreMultiplyAlpha(TexImage image, PvrTextureLibraryData libraryData)
        {
            Log.Info("Premultiplying alpha ... ");

            if (!Utilities.PreMultipliedAlpha(libraryData.Texture))
            {
                Log.Info("Failed to premultiply the alpha.");
                throw new TextureToolsException("Failed to premultiply the alpha.");
            }
        }
Beispiel #9
0
        public void StartLibrary(TexImage image)
        {
            PvrTextureLibraryData libraryData = new PvrTextureLibraryData();

            int imageArraySize = image.Dimension == TexImage.TextureDimension.TextureCube ? image.ArraySize / 6 : image.ArraySize;
            int imageFaceCount = image.Dimension == TexImage.TextureDimension.TextureCube ? 6 : 1;

            // Creating native header corresponding to the TexImage instance
            ulong             format     = RetrieveNativeFormat(image.Format);
            EPVRTColourSpace  colorSpace = RetrieveNativeColorSpace(image.Format);
            EPVRTVariableType pixelType  = RetrieveNativePixelType(image.Format);

            libraryData.Header = new PVRTextureHeader(format, image.Height, image.Width, image.Depth, image.MipmapCount, imageArraySize, imageFaceCount, colorSpace, pixelType);

            int imageCount = 0;
            int depth      = image.Depth;

            libraryData.Texture = new PVRTexture(libraryData.Header, IntPtr.Zero); // Initializing a new native texture, allocating memory.

            // Copying TexImage data into the native texture allocated memory
            try
            {
                for (uint i = 0; i < imageFaceCount; ++i)
                {
                    for (uint j = 0; j < imageArraySize; ++j)
                    {
                        for (uint k = 0; k < image.MipmapCount; ++k)
                        {
                            Core.Utilities.CopyMemory(libraryData.Texture.GetDataPtr(k, j, i), image.SubImageArray[imageCount].Data, image.SubImageArray[imageCount].DataSize * depth);
                            imageCount += depth;

                            depth = depth > 1 ? depth >>= 1 : depth;
                        }
                    }
                }
            }
            catch (AccessViolationException e)
            {
                libraryData.Texture.Dispose();
                Log.Error("Failed to convert texture to PvrTexLib native data, check your texture settings. ", e);
                throw new TextureToolsException("Failed to convert texture to PvrTexLib native data, check your texture settings. ", e);
            }

            // Freeing previous image data
            if (image.DisposingLibrary != null)
            {
                image.DisposingLibrary.Dispose(image);
            }

            image.LibraryData[this] = libraryData;

            image.DisposingLibrary = this;
        }
Beispiel #10
0
        public void Execute(TexImage image, IRequest request)
        {
            PvrTextureLibraryData libraryData = image.LibraryData.ContainsKey(this) ? (PvrTextureLibraryData)image.LibraryData[this] : null;

            switch (request.Type)
            {
            case RequestType.Loading:
                Load(image, (LoadingRequest)request);
                break;

            case RequestType.Compressing:
                Compress(image, libraryData, (CompressingRequest)request);
                break;

            case RequestType.Export:
                Export(image, libraryData, (ExportRequest)request);
                break;

            case RequestType.Decompressing:
                Decompress(image, libraryData);
                break;

            case RequestType.MipMapsGeneration:
                GenerateMipMaps(image, libraryData, (MipMapsGenerationRequest)request);
                break;

            case RequestType.SwitchingChannels:
                SwitchChannels(image, libraryData, (SwitchingBRChannelsRequest)request);
                break;

            case RequestType.Rescaling:
                Rescale(image, libraryData, (RescalingRequest)request);
                break;

            case RequestType.Flipping:
                Flip(image, libraryData, (FlippingRequest)request);
                break;

            case RequestType.NormalMapGeneration:
                GenerateNormalMap(image, libraryData, (NormalMapGenerationRequest)request);
                break;

            case RequestType.PreMultiplyAlpha:
                PreMultiplyAlpha(image, libraryData);
                break;

            default:
                Log.Error("FITexLib (FreeImage) can't handle this request: " + request.Type);
                throw new TextureToolsException("FITexLib (FreeImage) can't handle this request: " + request.Type);
            }
        }
Beispiel #11
0
        /// <summary>
        /// Exports the specified image.
        /// </summary>
        /// <param name="image">The image.</param>
        /// <param name="libraryData">The library data.</param>
        /// <param name="export">The export request.</param>
        private void Export(TexImage image, PvrTextureLibraryData libraryData, ExportRequest request)
        {
            Log.Info("Exporting to " + request.FilePath + " ...");

            if (request.MinimumMipMapSize > 1) // if a mimimun mipmap size was requested
            {
                int newMipMapCount = image.MipmapCount;
                for (int i = image.MipmapCount - 1; i > 0; --i) // looking for the mipmap level corresponding to the minimum size requeted.
                {
                    if (libraryData.Header.GetWidth((uint)i) >= request.MinimumMipMapSize || libraryData.Header.GetHeight((uint)i) >= request.MinimumMipMapSize)
                    {
                        break;
                    }
                    --newMipMapCount;
                }

                // Creating a new texture corresponding to the requested mipmap levels
                PVRTextureHeader header  = new PVRTextureHeader(RetrieveNativeFormat(image.Format), image.Height, image.Width, image.Depth, newMipMapCount, image.ArraySize, image.FaceCount);
                PVRTexture       texture = new PVRTexture(header, IntPtr.Zero);

                try
                {
                    for (uint i = 0; i < image.FaceCount; ++i)
                    {
                        for (uint j = 0; j < image.ArraySize; ++j)
                        {
                            for (uint k = 0; k < newMipMapCount; ++k)
                            {
                                Core.Utilities.CopyMemory(texture.GetDataPtr(k, j, i), libraryData.Texture.GetDataPtr(k, j, i), (int)libraryData.Header.GetDataSize((int)k, false, false));
                            }
                        }
                    }
                }
                catch (AccessViolationException e)
                {
                    texture.Dispose();
                    Log.Error("Failed to export texture with the mipmap minimum size request. ", e);
                    throw new TextureToolsException("Failed to export texture with the mipmap minimum size request. ", e);
                }

                // Saving the texture into a file and deleting it
                texture.Save(request.FilePath);
                texture.Dispose();
            }
            else
            {
                libraryData.Texture.Save(request.FilePath);
            }

            image.Save(request.FilePath);
        }
Beispiel #12
0
        public void Dispose(TexImage image)
        {
            if (!image.LibraryData.ContainsKey(this))
            {
                return;
            }
            PvrTextureLibraryData libraryData = (PvrTextureLibraryData)image.LibraryData[this];

            if (libraryData.Texture != null)
            {
                libraryData.Header = null;
                libraryData.Texture.Dispose();
            }
        }
Beispiel #13
0
        /// <summary>
        /// Loads the specified image.
        /// </summary>
        /// <param name="image">The image.</param>
        /// <param name="request">The request.</param>
        private void Load(TexImage image, LoadingRequest request)
        {
            Log.Verbose("Loading " + request.FilePath + " ...");

            var libraryData = new PvrTextureLibraryData();

            image.LibraryData[this] = libraryData;

            libraryData.Texture = new PVRTexture(request.FilePath);
            libraryData.Header  = libraryData.Texture.GetHeader();

            image.Width  = (int)libraryData.Header.GetWidth();
            image.Height = (int)libraryData.Header.GetHeight();
            image.Depth  = (int)libraryData.Header.GetDepth();

            var format = RetrieveFormatFromNativeData(libraryData.Header);

            image.Format             = request.LoadAsSRgb? format.ToSRgb(): format.ToNonSRgb();
            image.OriginalAlphaDepth = libraryData.Header.GetAlphaDepth();

            int pitch, slice;

            Tools.ComputePitch(image.Format, image.Width, image.Height, out pitch, out slice);
            image.RowPitch   = pitch;
            image.SlicePitch = slice;

            image.DisposingLibrary = this;

            UpdateImage(image, libraryData);

            if (image.FaceCount > 1 && image.FaceCount % 6 == 0)
            {
                image.Dimension = TexImage.TextureDimension.TextureCube;
            }
            else if (image.Depth > 1)
            {
                image.Dimension = TexImage.TextureDimension.Texture3D;
            }
            else if (image.Height > 0)
            {
                image.Dimension = TexImage.TextureDimension.Texture2D;
            }
            else
            {
                image.Dimension = TexImage.TextureDimension.Texture1D;
            }
        }
Beispiel #14
0
        /// <summary>
        /// Decompresses the specified image.
        /// </summary>
        /// <param name="image">The image.</param>
        /// <param name="libraryData">The library data.</param>
        /// <exception cref="TexLibraryException">Decompression failed!</exception>
        public void Decompress(TexImage image, PvrTextureLibraryData libraryData)
        {
            Log.Info("Decompressing texture ...");

            if (!Utilities.Transcode(libraryData.Texture, PixelType.Standard8PixelType, libraryData.Header.GetChannelType(), libraryData.Header.GetColourSpace(), ECompressorQuality.ePVRTCNormal, true))
            {
                Log.Error("Decompression failed!");
                throw new TextureToolsException("Decompression failed!");
            }

            image.Format = SiliconStudio.Paradox.Graphics.PixelFormat.R8G8B8A8_UNorm;

            int pitch, slice;

            Tools.ComputePitch(image.Format, image.Width, image.Height, out pitch, out slice);
            image.RowPitch   = pitch;
            image.SlicePitch = slice;

            UpdateImage(image, libraryData);
        }
Beispiel #15
0
        /// <summary>
        /// Decompresses the specified image.
        /// </summary>
        /// <param name="image">The image.</param>
        /// <param name="libraryData">The library data.</param>
        /// <param name="request">The decompression request</param>
        /// <exception cref="TextureToolsException">Decompression failed!</exception>
        public void Decompress(TexImage image, PvrTextureLibraryData libraryData, DecompressingRequest request)
        {
            Log.Verbose("Decompressing texture ...");

            if (!Utilities.Transcode(libraryData.Texture, PixelType.Standard8PixelType, libraryData.Header.GetChannelType(), libraryData.Header.GetColourSpace(), ECompressorQuality.ePVRTCNormal, true))
            {
                Log.Error("Decompression failed!");
                throw new TextureToolsException("Decompression failed!");
            }

            image.Format = request.DecompressedFormat;

            int pitch, slice;

            Tools.ComputePitch(image.Format, image.Width, image.Height, out pitch, out slice);
            image.RowPitch   = pitch;
            image.SlicePitch = slice;

            UpdateImage(image, libraryData);
        }
Beispiel #16
0
        /// <summary>
        /// Switches the channels R and B.
        /// </summary>
        /// <param name="image">The image.</param>
        /// <param name="libraryData">The library data.</param>
        /// <param name="request">The request.</param>
        /// <exception cref="TexLibraryException">Unsuported format for channel switching.</exception>
        private void SwitchChannels(TexImage image, PvrTextureLibraryData libraryData, SwitchingBRChannelsRequest request)
        {
            Log.Info("Switching channels B and R ...");

            switch (image.Format)
            {
            case SiliconStudio.Paradox.Graphics.PixelFormat.B8G8R8A8_UNorm:
                image.Format = SiliconStudio.Paradox.Graphics.PixelFormat.R8G8B8A8_UNorm; break;

            case SiliconStudio.Paradox.Graphics.PixelFormat.B8G8R8A8_Typeless:
                image.Format = SiliconStudio.Paradox.Graphics.PixelFormat.R8G8B8A8_Typeless; break;

            case SiliconStudio.Paradox.Graphics.PixelFormat.B8G8R8A8_UNorm_SRgb:
                image.Format = SiliconStudio.Paradox.Graphics.PixelFormat.R8G8B8A8_UNorm_SRgb; break;

            case SiliconStudio.Paradox.Graphics.PixelFormat.R8G8B8A8_Typeless:
                image.Format = SiliconStudio.Paradox.Graphics.PixelFormat.B8G8R8A8_Typeless; break;

            case SiliconStudio.Paradox.Graphics.PixelFormat.R8G8B8A8_UNorm:
                image.Format = SiliconStudio.Paradox.Graphics.PixelFormat.B8G8R8A8_UNorm; break;

            case SiliconStudio.Paradox.Graphics.PixelFormat.R8G8B8A8_UNorm_SRgb:
                image.Format = SiliconStudio.Paradox.Graphics.PixelFormat.B8G8R8A8_UNorm_SRgb; break;

            default:
                Log.Error("Unsuported format for channel switching.");
                throw new TextureToolsException("Unsuported format for channel switching.");
            }

            PVRTexture textureTemp = new PVRTexture(libraryData.Header, libraryData.Texture.GetDataPtr());

            EChannelName e1 = EChannelName.eBlue;
            EChannelName e2 = EChannelName.eRed;

            Utilities.CopyChannels(libraryData.Texture, textureTemp, 1, out e1, out e2);
            Utilities.CopyChannels(libraryData.Texture, textureTemp, 1, out e2, out e1);

            textureTemp.Dispose();

            UpdateImage(image, libraryData);
        }
Beispiel #17
0
        /// <summary>
        /// Compresses the specified image.
        /// </summary>
        /// <param name="image">The image.</param>
        /// <param name="libraryData">The library data.</param>
        /// <param name="compress">The compress.</param>
        /// <exception cref="TexLibraryException">Compression failed</exception>
        private void Compress(TexImage image, PvrTextureLibraryData libraryData, CompressingRequest compress)
        {
            Log.Info("Compressing to " + compress.Format + " ...");

            ulong format = RetrieveNativeFormat(compress.Format);
            EPVRTColourSpace colorSpace = RetrieveNativeColorSpace(compress.Format);
            EPVRTVariableType pixelType = RetrieveNativePixelType(compress.Format);

            lock (lockObject)
            {
                if (!Utilities.Transcode(libraryData.Texture, format, pixelType, colorSpace, (ECompressorQuality)compress.Quality, false))
                {
                    Log.Error("Compression failed!");
                    throw new TextureToolsException("Compression failed!");
                }
            }

            image.Format = compress.Format;
            int pitch, slice;
            Tools.ComputePitch(image.Format, image.Width, image.Height, out pitch, out slice);
            image.RowPitch = pitch;
            image.SlicePitch = slice;

            UpdateImage(image, libraryData);
        }
Beispiel #18
0
        /// <summary>
        /// Transposes face data since Pvrtt keeps the format of data [mipMap][face], but Paradox uses [face][mipMap]
        /// </summary>
        /// <param name="image"></param>
        /// <param name="libraryData"></param>
        private void TransposeFaceData(TexImage image, PvrTextureLibraryData libraryData)
        {
            var destPtr = Marshal.AllocHGlobal(image.DataSize);

            var targetRowSize = 0;

            // Build an array of slices for each mip levels
            var slices = new int[image.MipmapCount];
            var aggregateSize = new int[image.MipmapCount];

            var currWidth = image.Width;
            var currHeight = image.Height;

            for (var i = 0; i < image.MipmapCount; ++i)
            {
                int pitch, slice;
                Tools.ComputePitch(image.Format, currWidth, currHeight, out pitch, out slice);

                slices[i] = slice;

                aggregateSize[i] = targetRowSize;
                targetRowSize += slice;

                currWidth /= 2;
                currHeight /= 2;
            }

            var sourceRowOffset = 0;

            for (var currMip = 0; currMip < image.MipmapCount; ++currMip)
            {
                var slice = slices[currMip];

                for (var currFace = 0; currFace < image.FaceCount; ++currFace)
                {
                    var sourceOffset = sourceRowOffset + (currFace * slice);

                    var destOffset = (targetRowSize * currFace) + aggregateSize[currMip];

                    var source = new IntPtr(image.Data.ToInt64() + sourceOffset);
                    var dest = new IntPtr(destPtr.ToInt64() + destOffset);
 
                    Core.Utilities.CopyMemory(dest, source, slice);       
                }

                sourceRowOffset += slice * image.FaceCount;
            }

            // Copy data back to the library
            Core.Utilities.CopyMemory(
                                libraryData.Texture.GetDataPtr(),   // Dest
                                destPtr,                            // Source
                                image.DataSize);                    // Size

            image.Data = libraryData.Texture.GetDataPtr();

            Marshal.FreeHGlobal(destPtr);
        }
Beispiel #19
0
        /// <summary>
        /// Decompresses the specified image.
        /// </summary>
        /// <param name="image">The image.</param>
        /// <param name="libraryData">The library data.</param>
        /// <param name="request">The decompression request</param>
        /// <exception cref="TextureToolsException">Decompression failed!</exception>
        public void Decompress(TexImage image, PvrTextureLibraryData libraryData, DecompressingRequest request)
        {
            Log.Info("Decompressing texture ...");

            if (!Utilities.Transcode(libraryData.Texture, PixelType.Standard8PixelType, libraryData.Header.GetChannelType(), libraryData.Header.GetColourSpace(), ECompressorQuality.ePVRTCNormal, true))
            {
                Log.Error("Decompression failed!");
                throw new TextureToolsException("Decompression failed!");
            }

            image.Format = request.DecompressedFormat;

            int pitch,slice;
            Tools.ComputePitch(image.Format, image.Width, image.Height, out pitch, out slice);
            image.RowPitch = pitch;
            image.SlicePitch = slice;
 
            UpdateImage(image, libraryData);
        }
Beispiel #20
0
        /// <summary>
        /// Generates the normal map.
        /// </summary>
        /// <param name="image">The image.</param>
        /// <param name="libraryData">The library data.</param>
        /// <param name="request">The request.</param>
        /// <exception cref="TexLibraryException">Failed to generate normal map.</exception>
        public void GenerateNormalMap(TexImage image, PvrTextureLibraryData libraryData, NormalMapGenerationRequest request)
        {
            Log.Info("Generating Normal Map ... ");

            // Creating new TexImage with the normal map data.
            request.NormalMap = new TexImage();
            PvrTextureLibraryData normalMapLibraryData = new PvrTextureLibraryData();
            request.NormalMap.LibraryData[this] = normalMapLibraryData;

            normalMapLibraryData.Texture = new PVRTexture(libraryData.Header, libraryData.Texture.GetDataPtr());
            request.NormalMap.Format = SiliconStudio.Paradox.Graphics.PixelFormat.R8G8B8A8_UNorm;
            request.NormalMap.CurrentLibrary = this;
            request.NormalMap.DisposingLibrary = this;

            if (!Utilities.GenerateNormalMap(normalMapLibraryData.Texture, request.Amplitude, "xyzh"))
            {
                Log.Error("Failed to generate normal map.");
                throw new TextureToolsException("Failed to generate normal map.");
            }

            UpdateImage(request.NormalMap, normalMapLibraryData);
            EndLibrary(request.NormalMap);
            request.NormalMap.DisposingLibrary = this;
        }
Beispiel #21
0
        /// <summary>
        /// Rescales the specified image.
        /// </summary>
        /// <param name="image">The image.</param>
        /// <param name="libraryData">The library data.</param>
        /// <param name="request">The request.</param>
        private void Rescale(TexImage image, PvrTextureLibraryData libraryData, RescalingRequest request)
        {
            int width = request.ComputeWidth(image);
            int height = request.ComputeHeight(image);

            Log.Info("Rescaling to " + width + "x" + height + " ...");

            EResizeMode filter;
            switch(request.Filter)
            {
                case Filter.Rescaling.Bilinear:
                    filter = EResizeMode.eResizeLinear;
                    break;
                case Filter.Rescaling.Bicubic:
                    filter = EResizeMode.eResizeCubic;
                    break;
                case Filter.Rescaling.Nearest:
                    filter = EResizeMode.eResizeNearest;
                    break;
                default:
                    filter = EResizeMode.eResizeCubic;
                    break;
            }

            Utilities.Resize(libraryData.Texture, (uint)width, (uint)height, (uint)image.Depth, filter);
            UpdateImage(image, libraryData);

            // Updating image data
            image.Rescale(width, height);
        }
Beispiel #22
0
        /// <summary>
        /// Switches the channels R and B.
        /// </summary>
        /// <param name="image">The image.</param>
        /// <param name="libraryData">The library data.</param>
        /// <param name="request">The request.</param>
        /// <exception cref="TexLibraryException">Unsuported format for channel switching.</exception>
        private void SwitchChannels(TexImage image, PvrTextureLibraryData libraryData, SwitchingBRChannelsRequest request)
        {
            Log.Info("Switching channels B and R ...");

            switch (image.Format)
            {
                case SiliconStudio.Paradox.Graphics.PixelFormat.B8G8R8A8_UNorm:
                    image.Format = SiliconStudio.Paradox.Graphics.PixelFormat.R8G8B8A8_UNorm; break;
                case SiliconStudio.Paradox.Graphics.PixelFormat.B8G8R8A8_Typeless:
                    image.Format = SiliconStudio.Paradox.Graphics.PixelFormat.R8G8B8A8_Typeless; break;
                case SiliconStudio.Paradox.Graphics.PixelFormat.B8G8R8A8_UNorm_SRgb:
                    image.Format = SiliconStudio.Paradox.Graphics.PixelFormat.R8G8B8A8_UNorm_SRgb; break;
                case SiliconStudio.Paradox.Graphics.PixelFormat.R8G8B8A8_Typeless:
                    image.Format = SiliconStudio.Paradox.Graphics.PixelFormat.B8G8R8A8_Typeless; break;
                case SiliconStudio.Paradox.Graphics.PixelFormat.R8G8B8A8_UNorm:
                    image.Format = SiliconStudio.Paradox.Graphics.PixelFormat.B8G8R8A8_UNorm; break;
                case SiliconStudio.Paradox.Graphics.PixelFormat.R8G8B8A8_UNorm_SRgb:
                    image.Format = SiliconStudio.Paradox.Graphics.PixelFormat.B8G8R8A8_UNorm_SRgb; break;
                default:
                    Log.Error("Unsuported format for channel switching.");
                    throw new TextureToolsException("Unsuported format for channel switching.");
            }

            PVRTexture textureTemp = new PVRTexture(libraryData.Header, libraryData.Texture.GetDataPtr());

            EChannelName e1 = EChannelName.eBlue;
            EChannelName e2 = EChannelName.eRed;

            Utilities.CopyChannels(libraryData.Texture, textureTemp, 1, out e1, out e2);
            Utilities.CopyChannels(libraryData.Texture, textureTemp, 1, out e2, out e1);

            textureTemp.Dispose();

            UpdateImage(image, libraryData);
        }
Beispiel #23
0
        public void EndLibrary(TexImage image)
        {
            // Retrieving native Data.
            if (!image.LibraryData.ContainsKey(this))
            {
                return;
            }
            PvrTextureLibraryData libraryData = (PvrTextureLibraryData)image.LibraryData[this];

            // Updating current instance of TexImage with the native Data
            UpdateImage(image, libraryData);

            // If the data contains more than one face and mipmaps, swap them
            if (image.Dimension == TexImage.TextureDimension.TextureCube && image.FaceCount > 1 && image.MipmapCount > 1)
            {
                TransposeFaceData(image, libraryData);
            }

            /*
             * in a 3D texture, the number of sub images will be different than for 2D : with 2D texture, you just have to multiply the mipmap levels with the array size.
             * For 3D, when generating mip map, you generate mip maps for each slice of your texture, but the depth is decreasing by half (like the width and height) at
             * each level. Then the number of sub images won't be mipmapCount * arraySize * depth, but arraySize * ( depth + depth/2 + depth/4 ... )
             *                                                                                                       ---- at each mipmap level ----
             */
            int imageCount, depth;

            if (image.Dimension == TexImage.TextureDimension.Texture3D) // Counting the number of sub images according to the texture dimension
            {
                int subImagePerArrayElementCount = 0;
                int curDepth = image.Depth;
                for (int i = 0; i < image.MipmapCount; ++i)
                {
                    subImagePerArrayElementCount += curDepth;
                    curDepth = curDepth > 1 ? curDepth >>= 1 : curDepth;
                }

                imageCount = (int)(image.ArraySize * image.FaceCount * subImagePerArrayElementCount); // PvrTexLib added a "face" count above the texture array..
            }
            else
            {
                imageCount = (int)(image.ArraySize * image.FaceCount * image.MipmapCount);
            }

            image.SubImageArray = new TexImage.SubImage[imageCount];
            int ct = 0;
            int rowPitch, slicePitch, height, width;

            for (uint i = 0; i < image.FaceCount; ++i) // Recreating the sub images
            {
                for (uint j = 0; j < image.ArraySize; ++j)
                {
                    depth = image.Depth;
                    for (uint k = 0; k < image.MipmapCount; ++k)
                    {
                        width  = (int)libraryData.Header.GetWidth(k);
                        height = (int)libraryData.Header.GetHeight(k);
                        Tools.ComputePitch(image.Format, width, height, out rowPitch, out slicePitch);

                        for (int l = 0; l < depth; ++l)
                        {
                            image.SubImageArray[ct]            = new TexImage.SubImage();
                            image.SubImageArray[ct].Width      = width;
                            image.SubImageArray[ct].Height     = height;
                            image.SubImageArray[ct].RowPitch   = rowPitch;
                            image.SubImageArray[ct].SlicePitch = slicePitch;
                            image.SubImageArray[ct].DataSize   = slicePitch;
                            image.SubImageArray[ct].Data       = new IntPtr(libraryData.Texture.GetDataPtr(k, j, i).ToInt64() + l * slicePitch);
                            ++ct;
                        }
                        depth = depth > 1 ? depth >>= 1 : depth;
                    }
                }
            }

            // PVRTT uses a "face count" for CubeMap texture, the other librairies doesn't, it's just included in the arraySize
            image.ArraySize = image.ArraySize * image.FaceCount;

            // This library is now the "owner" of the TexImage data, and must be used to handle the image data memory
            image.DisposingLibrary = this;
        }
Beispiel #24
0
        /// <summary>
        /// Loads the specified image.
        /// </summary>
        /// <param name="image">The image.</param>
        /// <param name="request">The request.</param>
        private void Load(TexImage image, LoadingRequest request)
        {
            Log.Info("Loading " + request.FilePath + " ...");

            var libraryData = new PvrTextureLibraryData();
            image.LibraryData[this] = libraryData;

            libraryData.Texture = new PVRTexture(request.FilePath);
            libraryData.Header = libraryData.Texture.GetHeader();

            image.Width = (int)libraryData.Header.GetWidth();
            image.Height = (int)libraryData.Header.GetHeight();
            image.Depth = (int)libraryData.Header.GetDepth();
            
            var format = RetrieveFormatFromNativeData(libraryData.Header);
            image.Format = request.LoadAsSRgb? format.ToSRgb(): format.ToNonSRgb();
            image.OriginalAlphaDepth = libraryData.Header.GetAlphaDepth();

            int pitch, slice;
            Tools.ComputePitch(image.Format, image.Width, image.Height, out pitch, out slice);
            image.RowPitch = pitch;
            image.SlicePitch = slice;

            image.DisposingLibrary = this;

            UpdateImage(image, libraryData);

            if (image.FaceCount > 1 && image.FaceCount % 6 == 0)
                image.Dimension = TexImage.TextureDimension.TextureCube;
            else if(image.Depth > 1)
                image.Dimension = TexImage.TextureDimension.Texture3D;
            else if (image.Height > 0)
                image.Dimension = TexImage.TextureDimension.Texture2D;
            else
                image.Dimension = TexImage.TextureDimension.Texture1D;
        }
Beispiel #25
0
 /// <summary>
 /// Updates the image basic information with the native data.
 /// </summary>
 /// <param name="image">The image.</param>
 /// <param name="libraryData">The library data.</param>
 private void UpdateImage(TexImage image, PvrTextureLibraryData libraryData)
 {
     image.Data = libraryData.Texture.GetDataPtr();
     libraryData.Header = libraryData.Texture.GetHeader();
     image.DataSize = (int)libraryData.Header.GetDataSize();
     image.MipmapCount = (int)libraryData.Header.GetNumMIPLevels();
     image.ArraySize = (int)libraryData.Header.GetNumArrayMembers();
     image.FaceCount = (int)libraryData.Header.GetNumFaces();
 }
Beispiel #26
0
        /// <summary>
        /// Premultiplies the alpha on the specified texture.
        /// </summary>
        /// <param name="image">The image.</param>
        /// <param name="libraryData">The library data.</param>
        /// <exception cref="TexLibraryException">Failed to premultiply the alpha.</exception>
        public void PreMultiplyAlpha(TexImage image, PvrTextureLibraryData libraryData)
        {
            Log.Info("Premultiplying alpha ... ");

            if (!Utilities.PreMultipliedAlpha(libraryData.Texture))
            {
                Log.Info("Failed to premultiply the alpha.");
                throw new TextureToolsException("Failed to premultiply the alpha.");
            }
        }
Beispiel #27
0
        /// <summary>
        /// Exports the specified image.
        /// </summary>
        /// <param name="image">The image.</param>
        /// <param name="libraryData">The library data.</param>
        /// <param name="export">The export request.</param>
        private void Export(TexImage image, PvrTextureLibraryData libraryData, ExportRequest request)
        {
            Log.Info("Exporting to " + request.FilePath + " ...");

            if (request.MinimumMipMapSize > 1) // if a mimimun mipmap size was requested
            {
                int newMipMapCount = image.MipmapCount;
                for (int i = image.MipmapCount - 1; i > 0; --i) // looking for the mipmap level corresponding to the minimum size requeted.
                {
                    if (libraryData.Header.GetWidth((uint)i) >= request.MinimumMipMapSize || libraryData.Header.GetHeight((uint)i) >= request.MinimumMipMapSize)
                    {
                        break;
                    }
                    --newMipMapCount;
                }

                // Creating a new texture corresponding to the requested mipmap levels
                PVRTextureHeader header = new PVRTextureHeader(RetrieveNativeFormat(image.Format), image.Height, image.Width, image.Depth, newMipMapCount, image.ArraySize, image.FaceCount);
                PVRTexture texture = new PVRTexture(header, IntPtr.Zero);

                try
                {
                    for (uint i = 0; i < image.FaceCount; ++i)
                    {
                        for (uint j = 0; j < image.ArraySize; ++j)
                        {
                            for (uint k = 0; k < newMipMapCount; ++k)
                            {
                                Core.Utilities.CopyMemory(texture.GetDataPtr(k, j, i), libraryData.Texture.GetDataPtr(k, j, i), (int)libraryData.Header.GetDataSize((int)k, false, false));
                            }
                        }
                    }
                }
                catch (AccessViolationException e)
                {
                    texture.Dispose();
                    Log.Error("Failed to export texture with the mipmap minimum size request. ", e);
                    throw new TextureToolsException("Failed to export texture with the mipmap minimum size request. ", e);
                }

                // Saving the texture into a file and deleting it
                texture.Save(request.FilePath);
                texture.Dispose();
            }
            else
            {
                libraryData.Texture.Save(request.FilePath);
            }

            image.Save(request.FilePath);
        }
Beispiel #28
0
        /// <summary>
        /// Generates the mip maps.
        /// </summary>
        /// <param name="image">The image.</param>
        /// <param name="libraryData">The library data.</param>
        /// <param name="request">The request.</param>
        private void GenerateMipMaps(TexImage image, PvrTextureLibraryData libraryData, MipMapsGenerationRequest request)
        {
            Log.Info("Generating Mipmaps ... ");

            EResizeMode filter;
            switch (request.Filter)
            {
                case Filter.MipMapGeneration.Linear:
                    filter = EResizeMode.eResizeLinear;
                    break;
                case Filter.MipMapGeneration.Cubic:
                    filter = EResizeMode.eResizeCubic;
                    break;
                case Filter.MipMapGeneration.Nearest:
                    filter = EResizeMode.eResizeNearest;
                    break;
                default:
                    filter = EResizeMode.eResizeCubic;
                    break;
            }

            libraryData.Texture.GenerateMIPMaps(filter);

            UpdateImage(image, libraryData);
        }
Beispiel #29
0
        public void StartLibrary(TexImage image)
        {
            PvrTextureLibraryData libraryData = new PvrTextureLibraryData();

            int imageArraySize = image.Dimension == TexImage.TextureDimension.TextureCube ? image.ArraySize/6 : image.ArraySize;
            int imageFaceCount = image.Dimension == TexImage.TextureDimension.TextureCube ? 6 : 1;

            // Creating native header corresponding to the TexImage instance
            ulong format = RetrieveNativeFormat(image.Format);
            EPVRTColourSpace colorSpace = RetrieveNativeColorSpace(image.Format);
            EPVRTVariableType pixelType = RetrieveNativePixelType(image.Format);
            libraryData.Header = new PVRTextureHeader(format, image.Height, image.Width, image.Depth, image.MipmapCount, imageArraySize, imageFaceCount, colorSpace, pixelType);

            int imageCount = 0;
            int depth = image.Depth;
            libraryData.Texture = new PVRTexture(libraryData.Header, IntPtr.Zero); // Initializing a new native texture, allocating memory.

            // Copying TexImage data into the native texture allocated memory
            try
            {
                for (uint i = 0; i < imageFaceCount; ++i)
                {
                    for (uint j = 0; j < imageArraySize; ++j)
                    {
                        for (uint k = 0; k < image.MipmapCount; ++k)
                        {
                            Core.Utilities.CopyMemory(libraryData.Texture.GetDataPtr(k, j, i), image.SubImageArray[imageCount].Data, image.SubImageArray[imageCount].DataSize * depth);
                            imageCount += depth;

                            depth = depth > 1 ? depth >>= 1 : depth;
                        }
                    }
                }
            }
            catch (AccessViolationException e)
            {
                libraryData.Texture.Dispose();
                Log.Error("Failed to convert texture to PvrTexLib native data, check your texture settings. ", e);
                throw new TextureToolsException("Failed to convert texture to PvrTexLib native data, check your texture settings. ", e);
            }

            // Freeing previous image data
            if (image.DisposingLibrary != null) image.DisposingLibrary.Dispose(image);

            image.LibraryData[this] = libraryData;

            image.DisposingLibrary = this;
        }
Beispiel #30
0
        /// <summary>
        /// Flips the specified image vertically or horizontally.
        /// </summary>
        /// <param name="image">The image.</param>
        /// <param name="libraryData">The library data.</param>
        /// <param name="request">The request.</param>
        /// <exception cref="TexLibraryException">Flipping failed.</exception>
        private void Flip(TexImage image, PvrTextureLibraryData libraryData, FlippingRequest request)
        {
            Log.Info("Flipping texture : " + request.Flip + " ... ");

            switch(request.Flip)
            {
                case Orientation.Horizontal:
                    if (!Utilities.Flip(libraryData.Texture, EPVRTAxis.ePVRTAxisX))
                    {
                        Log.Error("Flipping failed.");
                        throw new TextureToolsException("Flipping failed.");
                    }
                    break;
                case Orientation.Vertical:
                    if (!Utilities.Flip(libraryData.Texture, EPVRTAxis.ePVRTAxisY))
                    {
                        Log.Error("Flipping failed.");
                        throw new TextureToolsException("Flipping failed.");
                    }
                    break;
            }

            image.Flip(request.Flip);

            UpdateImage(image, libraryData);
        }