Example #1
0
        /// <summary>
        /// Saves the specified <see cref="TexImage"/> into a file.
        /// </summary>
        /// <param name="image">The image.</param>
        /// <param name="fileName">Name of the file.</param>
        /// <param name="minimumMipMapSize">Minimum size of the mip map.</param>
        public void Save(TexImage image, String fileName, int minimumMipMapSize=1)
        {
            if (fileName == null || fileName.Equals(""))
            {
                Log.Error("No file name entered.");
                throw new TextureToolsException("No file name entered.");
            }

            var request = new ExportRequest(fileName, minimumMipMapSize);

            if (FindLibrary(image, request) == null && image.Format.IsCompressed())
            {
                Log.Warning("No library can export this texture with the actual compression format. We will try to decompress it first.");
                Decompress(image, image.Format.IsSRgb());
            }

            ExecuteRequest(image, request);
        }
Example #2
0
        /// <summary>
        /// Exports the specified image.
        /// </summary>
        /// <param name="image">The image.</param>
        /// <param name="libraryData">The library data.</param>
        /// <param name="request">The request.</param>
        /// <exception cref="TexLibraryException">
        /// Exporting texture failed
        /// </exception>
        private void Export(TexImage image, DxtTextureLibraryData libraryData, ExportRequest request)
        {
            Log.Info("Exporting to " + request.FilePath + " ...");

            if (request.MinimumMipMapSize > 1 && request.MinimumMipMapSize <= libraryData.Metadata.Width && request.MinimumMipMapSize <= libraryData.Metadata.Height) // if a mimimun mipmap size was requested
            {
                TexMetadata metadata = libraryData.Metadata;
                DxtImage[] dxtImages;

                if (image.Dimension == TexImage.TextureDimension.Texture3D)
                {

                    int newMipMapCount = 0; // the new mipmap count
                    int ct = 0; // ct will contain the number of SubImages per array element that we need to keep
                    int curDepth = image.Depth << 1;
                    for (int i = 0; i < image.MipmapCount; ++i)
                    {
                        curDepth = curDepth > 1 ? curDepth >>= 1 : curDepth;

                        if (libraryData.DxtImages[ct].Width <= request.MinimumMipMapSize || libraryData.DxtImages[ct].Height <= request.MinimumMipMapSize)
                        {
                            ct += curDepth;
                            ++newMipMapCount;
                            break;
                        }
                        ++newMipMapCount;
                        ct += curDepth;
                    }

                    int SubImagePerArrayElement = image.SubImageArray.Length / image.ArraySize; // number of SubImage in each texture array element.

                    // Initializing library native data according to the new mipmap level
                    metadata.MipLevels = newMipMapCount;
                    dxtImages = new DxtImage[metadata.ArraySize * ct];

                    int ct2 = 0;
                    for (int i = 0; i < image.ArraySize; ++i)
                    {
                        for (int j = 0; j < ct; ++j)
                        {
                            dxtImages[ct2] = libraryData.DxtImages[j + i * SubImagePerArrayElement];
                            ++ct2;
                        }
                    }
                }
                else
                {
                    int newMipMapCount = libraryData.Metadata.MipLevels;
                    for (int i = libraryData.Metadata.MipLevels - 1; i > 0; --i) // looking for the mipmap level corresponding to the minimum size requeted.
                    {
                        if (libraryData.DxtImages[i].Width >= request.MinimumMipMapSize || libraryData.DxtImages[i].Height >= request.MinimumMipMapSize)
                        {
                            break;
                        }
                        --newMipMapCount;
                    }
    
                    // Initializing library native data according to the new mipmap level
                    metadata.MipLevels = newMipMapCount;
                    dxtImages = new DxtImage[metadata.ArraySize * newMipMapCount];

                    // Assigning the right sub images for the texture to be exported (no need for memory to be adjacent)
                    int gap = libraryData.Metadata.MipLevels - newMipMapCount;
                    int j = 0;
                    for (int i = 0; i < dxtImages.Length; ++i)
                    {
                        if (i == newMipMapCount || (i > newMipMapCount && i%newMipMapCount == 0)) j += gap;
                        dxtImages[i] = libraryData.DxtImages[j];
                        ++j;
                    }
                }

                HRESULT hr = Utilities.SaveToDDSFile(dxtImages, dxtImages.Length, ref metadata, DDS_FLAGS.DDS_FLAGS_NONE, request.FilePath);

                if (hr != HRESULT.S_OK)
                {
                    Log.Error("Exporting texture failed: " + hr);
                    throw new TextureToolsException("Exporting texture failed: " + hr);
                }
            }
            else
            {
                HRESULT hr = Utilities.SaveToDDSFile(libraryData.DxtImages, libraryData.DxtImages.Length, ref libraryData.Metadata, DDS_FLAGS.DDS_FLAGS_NONE, request.FilePath);

                if (hr != HRESULT.S_OK)
                {
                    Log.Error("Exporting texture failed: " + hr);
                    throw new TextureToolsException("Exporting texture failed: " + hr);
                }
            }

            image.Save(request.FilePath);
        }
Example #3
0
        /// <summary>
        /// Exports the specified image into regular DDS file or a Xenko own file format.
        /// </summary>
        /// <param name="image">The image.</param>
        /// <param name="libraryData">The library data.</param>
        /// <param name="request">The request.</param>
        /// <exception cref="System.InvalidOperationException">
        /// Image size different than expected.
        /// or
        /// Image could not be created.
        /// </exception>
        /// <exception cref="System.NotImplementedException"></exception>
        /// <exception cref="TexLibraryException">Unsupported file extension.</exception>
        private void Export(TexImage image, XenkoTextureLibraryData libraryDataf, ExportRequest request)
        {
            Log.Debug("Exporting to " + request.FilePath + " ...");

            Image xkImage = null;

            if (request.MinimumMipMapSize > 1) // Check whether a minimum mipmap size was requested
            {
                if (image.Dimension == TexImage.TextureDimension.Texture3D)
                {

                    int newMipMapCount = 0; // the new mipmap count
                    int ct = 0; // ct will contain the number of SubImages per array element that we need to keep
                    int curDepth = image.Depth << 1;
                    for (int i = 0; i < image.MipmapCount; ++i)
                    {
                        curDepth = curDepth > 1 ? curDepth >>= 1 : curDepth;

                        if (image.SubImageArray[ct].Width <= request.MinimumMipMapSize || image.SubImageArray[ct].Height <= request.MinimumMipMapSize)
                        {
                            ct += curDepth;
                            ++newMipMapCount;
                            break;
                        }
                        ++newMipMapCount;
                        ct += curDepth;
                    }

                    int SubImagePerArrayElement = image.SubImageArray.Length / image.ArraySize; // number of SubImage in each texture array element.

                    // Initializing library native data according to the new mipmap level
                    xkImage = Image.New3D(image.Width, image.Height, image.Depth, newMipMapCount, image.Format);

                    try
                    {
                        int ct2 = 0;
                        for (int i = 0; i < image.ArraySize; ++i)
                        {
                            for (int j = 0; j < ct; ++j)
                            {
                                Utilities.CopyMemory(xkImage.PixelBuffer[ct2].DataPointer, xkImage.PixelBuffer[j + i * SubImagePerArrayElement].DataPointer, xkImage.PixelBuffer[j + i * SubImagePerArrayElement].BufferStride);
                                ++ct2;
                            }
                        }
                    }
                    catch (AccessViolationException e)
                    {
                        xkImage.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);
                    }
                }
                else
                {

                    int newMipMapCount = image.MipmapCount;
                    int dataSize = image.DataSize;
                    for (int i = image.MipmapCount - 1; i > 0; --i)
                    {
                        if (image.SubImageArray[i].Width >= request.MinimumMipMapSize || image.SubImageArray[i].Height >= request.MinimumMipMapSize)
                        {
                            break;
                        }
                        dataSize -= image.SubImageArray[i].DataSize * image.ArraySize;
                        --newMipMapCount;
                    }

                    switch (image.Dimension)
                    {
                        case TexImage.TextureDimension.Texture1D:
                            xkImage = Image.New1D(image.Width, image.MipmapCount, image.Format, image.ArraySize); break;
                        case TexImage.TextureDimension.Texture2D:
                            xkImage = Image.New2D(image.Width, image.Height, newMipMapCount, image.Format, image.ArraySize); break;
                        case TexImage.TextureDimension.TextureCube:
                            xkImage = Image.NewCube(image.Width, newMipMapCount, image.Format); break;
                    }
                    if (xkImage == null)
                    {
                        Log.Error("Image could not be created.");
                        throw new InvalidOperationException("Image could not be created.");
                    }

                    if (xkImage.TotalSizeInBytes != dataSize)
                    {
                        Log.Error("Image size different than expected.");
                        throw new InvalidOperationException("Image size different than expected.");
                    }

                    try
                    {
                        int gap = image.MipmapCount - newMipMapCount;
                        int j = 0;
                        for (int i = 0; i < image.ArraySize * newMipMapCount; ++i)
                        {
                            if (i == newMipMapCount || (i > newMipMapCount && (i % newMipMapCount == 0))) j += gap;
                            Utilities.CopyMemory(xkImage.PixelBuffer[i].DataPointer, image.SubImageArray[j].Data, image.SubImageArray[j].DataSize);
                            ++j;
                        }
                    }
                    catch (AccessViolationException e)
                    {
                        xkImage.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);
                    }
                }
            }
            else
            {
                switch (image.Dimension)
                {
                    case TexImage.TextureDimension.Texture1D:
                        xkImage = Image.New1D(image.Width, image.MipmapCount, image.Format, image.ArraySize); break;
                    case TexImage.TextureDimension.Texture2D:
                        xkImage = Image.New2D(image.Width, image.Height, image.MipmapCount, image.Format, image.ArraySize); break;
                    case TexImage.TextureDimension.Texture3D:
                        xkImage = Image.New3D(image.Width, image.Height, image.Depth, image.MipmapCount, image.Format); break;
                    case TexImage.TextureDimension.TextureCube:
                        xkImage = Image.NewCube(image.Width, image.MipmapCount, image.Format); break;
                }
                if (xkImage == null)
                {
                    Log.Error("Image could not be created.");
                    throw new InvalidOperationException("Image could not be created.");
                }

                if (xkImage.TotalSizeInBytes != image.DataSize)
                {
                    Log.Error("Image size different than expected.");
                    throw new InvalidOperationException("Image size different than expected.");
                }

                Utilities.CopyMemory(xkImage.DataPointer, image.Data, image.DataSize);
            }

            using (var fileStream = new FileStream(request.FilePath, FileMode.Create, FileAccess.Write))
            {
                String extension = Path.GetExtension(request.FilePath);
                if(extension.Equals(Extension))
                    xkImage.Save(fileStream, ImageFileType.Xenko);
                else if (extension.Equals(".dds"))
                    xkImage.Save(fileStream, ImageFileType.Dds);
                else
                {
                    Log.Error("Unsupported file extension.");
                    throw new TextureToolsException("Unsupported file extension.");
                }
            }

            xkImage.Dispose();
            image.Save(request.FilePath);
        }
Example #4
0
        /// <summary>
        /// Exports the specified image to the requested file name.
        /// </summary>
        /// <param name="image">The image.</param>
        /// <param name="libraryData">The library data.</param>
        /// <param name="request">The request.</param>
        /// <exception cref="TexLibraryException">
        /// Export failure.
        /// </exception>
        /// <remarks>
        /// In case of mipmapping or array texture, may images will be output.
        /// </remarks>
        private void Export(TexImage image, FreeImageTextureLibraryData libraryData, ExportRequest request)
        {
            String directory = Path.GetDirectoryName(request.FilePath);
            String fileName = Path.GetFileNameWithoutExtension(request.FilePath);
            String extension = Path.GetExtension(request.FilePath);
            String finalName;

            if (image.Dimension == TexImage.TextureDimension.Texture3D)
            {
                Log.Error("Not implemented.");
                throw new TextureToolsException("Not implemented.");
            }

            if(!image.Format.IsInBGRAOrder())
            {
                SwitchChannels(image, libraryData, new SwitchingBRChannelsRequest());
            }

            if (image.SubImageArray.Length > 1 && request.MinimumMipMapSize < FreeImage.GetWidth(libraryData.Bitmaps[0]) && request.MinimumMipMapSize < FreeImage.GetHeight(libraryData.Bitmaps[0]))
            {
                int imageCount = 0;
                for (int i = 0; i < image.ArraySize; ++i)
                {
                    for (int j = 0; j < image.MipmapCount; ++j)
                    {
                        if (FreeImage.GetWidth(libraryData.Bitmaps[imageCount]) < request.MinimumMipMapSize || FreeImage.GetHeight(libraryData.Bitmaps[imageCount]) < request.MinimumMipMapSize)
                            break;

                        finalName = directory + "/" + fileName + "-ind_" + i + "-mip_" + j + extension;
                        FreeImage.FlipVertical(libraryData.Bitmaps[imageCount]);
                        if (!FreeImage.SaveEx(libraryData.Bitmaps[imageCount], finalName))
                        {
                            Log.Error("Export failure.");
                            throw new TextureToolsException("Export failure.");
                        }
                        FreeImage.FlipVertical(libraryData.Bitmaps[imageCount]);
                        Log.Info("Exporting image to " + finalName + " ...");
                        ++imageCount;
                    }
                }
            }
            else
            {
                FreeImage.FlipVertical(libraryData.Bitmaps[0]);
                if (!FreeImage.SaveEx(libraryData.Bitmaps[0], request.FilePath))
                {
                    Log.Error("Export failure.");
                    throw new TextureToolsException("Export failure.");
                }
                FreeImage.FlipVertical(libraryData.Bitmaps[0]);
                Log.Info("Exporting image to " + request.FilePath + " ...");
            }

            image.Save(request.FilePath);
        }
Example #5
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);
        }