ソースを参照

texturec: Allow pass thru texture to change format.

Branimir Karadžić 8 年 前
コミット
886ba55a25
4 ファイル変更127 行追加9 行削除
  1. 22 0
      include/bimg/encode.h
  2. 7 7
      src/image.cpp
  3. 88 0
      src/image_encode.cpp
  4. 10 2
      tools/texturec/texturec.cpp

+ 22 - 0
include/bimg/encode.h

@@ -47,6 +47,28 @@ namespace bimg
 		, bx::Error* _err = NULL
 		);
 
+	///
+	void imageEncode(
+		  bx::AllocatorI* _allocator
+		, void* _dst
+		, const void* _src
+		, TextureFormat::Enum _srcFormat
+		, uint32_t _width
+		, uint32_t _height
+		, uint32_t _depth
+		, TextureFormat::Enum _dstFormat
+		, Quality::Enum _quality
+		, bx::Error* _err
+		);
+
+	///
+	ImageContainer* imageEncode(
+		  bx::AllocatorI* _allocator
+		, TextureFormat::Enum _dstFormat
+		, Quality::Enum _quality
+		, const ImageContainer& _input
+		);
+
 	///
 	void imageRgba32f11to01(
 		  void* _dst

+ 7 - 7
src/image.cpp

@@ -786,7 +786,7 @@ namespace bimg
 		{ bx::packRgba4,      bx::unpackRgba4      }, // RGBA4
 		{ bx::packRgb5a1,     bx::unpackRgb5a1     }, // RGB5A1
 		{ bx::packRgb10A2,    bx::unpackRgb10A2    }, // RGB10A2
-		{ bx::packRG11B10F, bx::unpackRG11B10F }, // RG11B10F
+		{ bx::packRG11B10F,   bx::unpackRG11B10F   }, // RG11B10F
 		{ NULL,               NULL                 }, // UnknownDepth
 		{ bx::packR16,        bx::unpackR16        }, // D16
 		{ bx::packR24,        bx::unpackR24        }, // D24
@@ -3089,17 +3089,17 @@ namespace bimg
 		}
 	}
 
-	void imageDecodeToRgba32f(bx::AllocatorI* _allocator, void* _dst, const void* _src, uint32_t _width, uint32_t _height, uint32_t _depth, uint32_t _dstPitch, TextureFormat::Enum _format)
+	void imageDecodeToRgba32f(bx::AllocatorI* _allocator, void* _dst, const void* _src, uint32_t _width, uint32_t _height, uint32_t _depth, uint32_t _dstPitch, TextureFormat::Enum _srcFormat)
 	{
 		const uint8_t* src = (const uint8_t*)_src;
 		uint8_t* dst = (uint8_t*)_dst;
 
-		const uint32_t srcBpp   = s_imageBlockInfo[_format].bitsPerPixel;
+		const uint32_t srcBpp   = s_imageBlockInfo[_srcFormat].bitsPerPixel;
 		const uint32_t srcPitch = _width*srcBpp/8;
 
 		for (uint32_t zz = 0; zz < _depth; ++zz, src += _height*srcPitch, dst += _height*_dstPitch)
 		{
-			switch (_format)
+			switch (_srcFormat)
 			{
 			case TextureFormat::BC5:
 				{
@@ -3142,17 +3142,17 @@ namespace bimg
 				break;
 
 			default:
-				if (isCompressed(_format) )
+				if (isCompressed(_srcFormat) )
 				{
 					uint32_t size = imageGetSize(NULL, uint16_t(_width), uint16_t(_height), 0, false, false, 1, TextureFormat::RGBA8);
 					void* temp = BX_ALLOC(_allocator, size);
-					imageDecodeToRgba8(temp, src, _width, _height, _width*4, _format);
+					imageDecodeToRgba8(temp, src, _width, _height, _width*4, _srcFormat);
 					imageRgba8ToRgba32f(dst, _width, _height, _width*4, temp);
 					BX_FREE(_allocator, temp);
 				}
 				else
 				{
-					imageConvert(dst, TextureFormat::RGBA32F, src, _format, _width, _height, 1, srcPitch);
+					imageConvert(dst, TextureFormat::RGBA32F, src, _srcFormat, _width, _height, 1, srcPitch);
 				}
 				break;
 			}

+ 88 - 0
src/image_encode.cpp

@@ -196,6 +196,94 @@ namespace bimg
 		}
 	}
 
+	void imageEncode(bx::AllocatorI* _allocator, void* _dst, const void* _src, TextureFormat::Enum _srcFormat, uint32_t _width, uint32_t _height, uint32_t _depth, TextureFormat::Enum _dstFormat, Quality::Enum _quality, bx::Error* _err)
+	{
+		switch (_dstFormat)
+		{
+			case bimg::TextureFormat::BC1:
+			case bimg::TextureFormat::BC2:
+			case bimg::TextureFormat::BC3:
+			case bimg::TextureFormat::BC4:
+			case bimg::TextureFormat::BC5:
+			case bimg::TextureFormat::ETC1:
+			case bimg::TextureFormat::ETC2:
+			case bimg::TextureFormat::PTC14:
+			case bimg::TextureFormat::PTC14A:
+				{
+					uint8_t* temp = (uint8_t*)BX_ALLOC(_allocator, _width*_height*_depth*4);
+					imageDecodeToRgba8(temp, _src, _width, _height, _width*4, _srcFormat);
+					imageEncodeFromRgba8(_dst, temp, _width, _height, _depth, _dstFormat, _quality, _err);
+					BX_FREE(_allocator, temp);
+				}
+				break;
+
+			case bimg::TextureFormat::BC6H:
+			case bimg::TextureFormat::BC7:
+				{
+					uint8_t* temp = (uint8_t*)BX_ALLOC(_allocator, _width*_height*_depth*16);
+					imageDecodeToRgba32f(_allocator, temp, _src, _width, _height, _depth, _width*16, _srcFormat);
+					imageEncodeFromRgba32f(_allocator, _dst, temp, _width, _height, _depth, _dstFormat, _quality, _err);
+					BX_FREE(_allocator, temp);
+				}
+				break;
+
+			default:
+				BX_ERROR_SET(_err, BIMG_ERROR, "Unable to convert between input/output formats!");
+				break;
+		}
+	}
+
+	ImageContainer* imageEncode(bx::AllocatorI* _allocator, TextureFormat::Enum _dstFormat, Quality::Enum _quality, const ImageContainer& _input)
+	{
+		ImageContainer* output = imageAlloc(_allocator
+			, _dstFormat
+			, uint16_t(_input.m_width)
+			, uint16_t(_input.m_height)
+			, uint16_t(_input.m_depth)
+			, _input.m_numLayers
+			, _input.m_cubeMap
+			, 1 < _input.m_numMips
+			);
+
+		const uint16_t numSides = _input.m_numLayers * (_input.m_cubeMap ? 6 : 1);
+
+		bx::Error err;
+
+		for (uint16_t side = 0; side < numSides && err.isOk(); ++side)
+		{
+			for (uint8_t lod = 0, num = _input.m_numMips; lod < num && err.isOk(); ++lod)
+			{
+				ImageMip mip;
+				if (imageGetRawData(_input, side, lod, _input.m_data, _input.m_size, mip) )
+				{
+					ImageMip dstMip;
+					imageGetRawData(*output, side, lod, output->m_data, output->m_size, dstMip);
+					uint8_t* dstData = const_cast<uint8_t*>(dstMip.m_data);
+
+					imageEncode(_allocator
+							, dstData
+							, mip.m_data
+							, mip.m_format
+							, mip.m_width
+							, mip.m_height
+							, mip.m_depth
+							, _dstFormat
+							, _quality
+							, &err
+							);
+				}
+			}
+		}
+
+		if (err.isOk() )
+		{
+			return output;
+		}
+
+		imageFree(output);
+		return NULL;
+	}
+
 	void imageRgba32f11to01(void* _dst, uint32_t _width, uint32_t _height, uint32_t _depth, uint32_t _pitch, const void* _src)
 	{
 		const uint8_t* src = (const uint8_t*)_src;

+ 10 - 2
tools/texturec/texturec.cpp

@@ -148,7 +148,6 @@ bimg::ImageContainer* convert(bx::AllocatorI* _allocator, const void* _inputData
 			;
 
 		const bool passThru = true
-			&& inputFormat == outputFormat
 			&& !needResize
 			&& (1 < input->m_numMips) == _options.mips
 			&& !_options.sdf
@@ -183,7 +182,16 @@ bimg::ImageContainer* convert(bx::AllocatorI* _allocator, const void* _inputData
 
 		if (passThru)
 		{
-			output = bimg::imageConvert(_allocator, outputFormat, *input);
+			if (inputFormat != outputFormat
+			&&  bimg::isCompressed(outputFormat) )
+			{
+				output = bimg::imageEncode(_allocator, outputFormat, _options.quality, *input);
+			}
+			else
+			{
+				output = bimg::imageConvert(_allocator, outputFormat, *input);
+			}
+
 			bimg::imageFree(input);
 			return output;
 		}