/// <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); }
/// <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); }
/// <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); }
/// <summary> /// Exports the specified image into regular DDS file or a Stride 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, StrideTextureLibraryData libraryDataf, ExportRequest request) { Log.Verbose("Exporting to " + request.FilePath + " ..."); Image sdImage = 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 sdImage = 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(sdImage.PixelBuffer[ct2].DataPointer, sdImage.PixelBuffer[j + i * SubImagePerArrayElement].DataPointer, sdImage.PixelBuffer[j + i * SubImagePerArrayElement].BufferStride); ++ct2; } } } catch (AccessViolationException e) { sdImage.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: sdImage = Image.New1D(image.Width, image.MipmapCount, image.Format, image.ArraySize); break; case TexImage.TextureDimension.Texture2D: sdImage = Image.New2D(image.Width, image.Height, newMipMapCount, image.Format, image.ArraySize); break; case TexImage.TextureDimension.TextureCube: sdImage = Image.NewCube(image.Width, newMipMapCount, image.Format); break; } if (sdImage == null) { Log.Error("Image could not be created."); throw new InvalidOperationException("Image could not be created."); } if (sdImage.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(sdImage.PixelBuffer[i].DataPointer, image.SubImageArray[j].Data, image.SubImageArray[j].DataSize); ++j; } } catch (AccessViolationException e) { sdImage.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: sdImage = Image.New1D(image.Width, image.MipmapCount, image.Format, image.ArraySize); break; case TexImage.TextureDimension.Texture2D: sdImage = Image.New2D(image.Width, image.Height, image.MipmapCount, image.Format, image.ArraySize); break; case TexImage.TextureDimension.Texture3D: sdImage = Image.New3D(image.Width, image.Height, image.Depth, image.MipmapCount, image.Format); break; case TexImage.TextureDimension.TextureCube: sdImage = Image.NewCube(image.Width, image.MipmapCount, image.Format); break; } if (sdImage == null) { Log.Error("Image could not be created."); throw new InvalidOperationException("Image could not be created."); } if (sdImage.TotalSizeInBytes != image.DataSize) { Log.Error("Image size different than expected."); throw new InvalidOperationException("Image size different than expected."); } Utilities.CopyMemory(sdImage.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)) { sdImage.Save(fileStream, ImageFileType.Stride); } else if (extension.Equals(".dds")) { sdImage.Save(fileStream, ImageFileType.Dds); } else { Log.Error("Unsupported file extension."); throw new TextureToolsException("Unsupported file extension."); } } sdImage.Dispose(); image.Save(request.FilePath); }
/// <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.Debug("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); }
/// <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); }
/// <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); }