/// <summary> /// Compresses the specified image into the specified format. /// </summary> /// <remarks> /// If the image is in a compressed format, it will be first decompressed. /// If the compressing library doesn't support BGRA order and the current image format is in this order, the channels R and B will be switched. /// </remarks> /// <param name="image">The image.</param> /// <param name="format">The format.</param> public void Compress(TexImage image, PixelFormat format, TextureQuality quality = TextureQuality.Fast) { if (image.Format == format) return; if (image.Format.IsCompressed()) { Log.Warning("You can't compress an already compressed texture. It will be decompressed first.."); Decompress(image, format.IsSRgb()); } var request = new CompressingRequest(format, quality); ExecuteRequest(image, request); }
/// <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); }
/// <summary> /// Compresses 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="TextureToolsException">Compression failed</exception> private void Compress(TexImage image, DxtTextureLibraryData libraryData, CompressingRequest request) { Log.Info("Converting/Compressing with " + request.Format + " ..."); if(libraryData.DxtImages == null || libraryData.DxtImages.Length == 0) return; ScratchImage scratchImage = new ScratchImage(); HRESULT hr; if (request.Format.IsCompressed()) { var topImage = libraryData.DxtImages[0]; if (topImage.Width % 4 != 0 || topImage.Height % 4 != 0) throw new TextureToolsException(string.Format("The provided texture cannot be compressed into format '{0}' " + "because its top resolution ({1}-{2}) is not a multiple of 4.", request.Format, topImage.Width, topImage.Height)); hr = Utilities.Compress(libraryData.DxtImages, libraryData.DxtImages.Length, ref libraryData.Metadata, RetrieveNativeFormat(request.Format), TEX_COMPRESS_FLAGS.TEX_COMPRESS_DEFAULT, 0.5f, scratchImage); } else { hr = Utilities.Convert(libraryData.DxtImages, libraryData.DxtImages.Length, ref libraryData.Metadata, RetrieveNativeFormat(request.Format), TEX_FILTER_FLAGS.TEX_FILTER_DEFAULT, 0.5f, scratchImage); } if (hr != HRESULT.S_OK) { Log.Error("Compression failed: " + hr); throw new TextureToolsException("Compression failed: " + hr); } if (image.DisposingLibrary != null) image.DisposingLibrary.Dispose(image); // Updating attributes libraryData.Image = scratchImage; libraryData.DxtImages = libraryData.Image.GetImages(); libraryData.Metadata = libraryData.Image.metadata; image.DisposingLibrary = this; UpdateImage(image, libraryData); }
/// <summary> /// Compresses 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">Compression failed</exception> private void Compress(TexImage image, AtitcTextureLibraryData libraryData, CompressingRequest request) { Log.Info("Converting/Compressing with " + request.Format + " ..."); int totalSize = 0; Texture[] texOut = new Texture[image.SubImageArray.Length]; int pitch, slice; // Setting the new Texture array that will contained the compressed data for (int i = 0; i < libraryData.Textures.Length; ++i) { Tools.ComputePitch(request.Format, libraryData.Textures[i].dwWidth, libraryData.Textures[i].dwHeight, out pitch, out slice); texOut[i] = new Texture(libraryData.Textures[i].dwWidth, libraryData.Textures[i].dwHeight, pitch, RetrieveNativeFormat(request.Format), 0, IntPtr.Zero); texOut[i].dwDataSize = Utilities.CalculateBufferSize(out texOut[i]); totalSize += texOut[i].dwDataSize; } // Allocating memory to store the compressed data image.Data = Marshal.AllocHGlobal(totalSize); libraryData.Options = new CompressOptions(false, 0, 0, 0, false, false, 0, false, Speed.ATI_TC_Speed_Normal); Result res; int offset = 0; // Compressing each sub image into the new allocated memory for (int i = 0; i < libraryData.Textures.Length; ++i) { texOut[i].pData = new IntPtr(image.Data.ToInt64() + offset); offset += texOut[i].dwDataSize; res = Utilities.ConvertTexture(out libraryData.Textures[i], out texOut[i], out libraryData.Options); if (res != Result.ATI_TC_OK) { Log.Error("Compression failed: " + res); throw new TextureToolsException("Compression failed: " + res); } libraryData.Textures[i] = texOut[i]; } // Deleting old uncompressed data if (image.DisposingLibrary != null) image.DisposingLibrary.Dispose(image); // Assigning the new compressed data to the current instance of <see cref="LibraryData" /> libraryData.Data = image.Data; // udpating various features image.DataSize = totalSize; image.RowPitch = libraryData.Textures[0].dwPitch; image.Format = request.Format; image.DisposingLibrary = this; }