Bläddra i källkod

Fixed RGB 16-bit PNG decoding.

Branimir Karadžić 8 år sedan
förälder
incheckning
9031242773
2 ändrade filer med 57 tillägg och 10 borttagningar
  1. 43 5
      src/image_decode.cpp
  2. 14 5
      src/image_encode.cpp

+ 43 - 5
src/image_decode.cpp

@@ -100,7 +100,7 @@ namespace bimg
 			{
 				case 1:
 					format    = bimg::TextureFormat::R1;
-					palette   = true;
+					palette   = false;
 					supported = true;
 					break;
 
@@ -159,6 +159,18 @@ namespace bimg
 							supported = true;
 							break;
 
+						case LCT_RGB:
+							for (uint32_t ii = 0, num = width*height; ii < num; ++ii)
+							{
+								uint16_t* rgba = (uint16_t*)data + ii*3;
+								rgba[0] = bx::toHostEndian(rgba[0], false);
+								rgba[1] = bx::toHostEndian(rgba[1], false);
+								rgba[2] = bx::toHostEndian(rgba[2], false);
+							}
+							format = bimg::TextureFormat::RGBA16;
+							supported = true;
+							break;
+
 						case LCT_RGBA:
 							for (uint32_t ii = 0, num = width*height; ii < num; ++ii)
 							{
@@ -172,7 +184,6 @@ namespace bimg
 							supported = true;
 							break;
 
-						case LCT_RGB:
 						case LCT_PALETTE:
 							break;
 					}
@@ -184,18 +195,37 @@ namespace bimg
 
 			if (supported)
 			{
+				const uint8_t* copyData = data;
+
+				TextureFormat::Enum dstFormat = format;
+				if (1 == state.info_raw.bitdepth)
+				{
+					dstFormat = bimg::TextureFormat::R8;
+					copyData  = NULL;
+				}
+				else if (16      == state.info_raw.bitdepth
+					 &&  LCT_RGB == state.info_raw.colortype)
+				{
+					dstFormat = bimg::TextureFormat::RGBA16;
+					copyData  = NULL;
+				}
+				else if (palette)
+				{
+					copyData = NULL;
+				}
+
 				output = imageAlloc(_allocator
-					, bimg::TextureFormat::R1 == format ? bimg::TextureFormat::R8 : format
+					, dstFormat
 					, uint16_t(width)
 					, uint16_t(height)
 					, 0
 					, 1
 					, false
 					, false
-					, palette ? NULL : data
+					, copyData
 					);
 
-				if (bimg::TextureFormat::R1 == format)
+				if (1 == state.info_raw.bitdepth)
 				{
 					for (uint32_t ii = 0, num = width*height/8; ii < num; ++ii)
 					{
@@ -211,6 +241,14 @@ namespace bimg
 						dst[7] = value & 0x80 ? 255 : 0;
 					}
 				}
+				else if (16      == state.info_raw.bitdepth
+					 &&  LCT_RGB == state.info_raw.colortype)
+				{
+					for (uint32_t ii = 0, num = width*height; ii < num; ++ii)
+					{
+						bx::memCopy( (uint16_t*)output->m_data + ii*4, (uint16_t*)data + ii*3, 6);
+					}
+				}
 				else if (palette)
 				{
 					for (uint32_t ii = 0, num = width*height; ii < num; ++ii)

+ 14 - 5
src/image_encode.cpp

@@ -135,13 +135,13 @@ namespace bimg
 		}
 	}
 
-	void imageEncodeFromRgba32f(bx::AllocatorI* _allocator, void* _dst, const void* _src, uint32_t _width, uint32_t _height, TextureFormat::Enum _format, Quality::Enum _quality, bx::Error* _err)
+	void imageEncodeFromRgba32f(bx::AllocatorI* _allocator, void* _dst, const void* _src, uint32_t _width, uint32_t _height, TextureFormat::Enum _dstFormat, Quality::Enum _quality, bx::Error* _err)
 	{
 		BX_ERROR_SCOPE(_err);
 
 		const uint8_t* src = (const uint8_t*)_src;
 
-		switch (_format)
+		switch (_dstFormat)
 		{
 		case TextureFormat::RGBA8:
 			{
@@ -179,15 +179,24 @@ namespace bimg
 					}
 				}
 
-				imageEncodeFromRgba8(_dst, temp, _width, _height, _format, _quality);
+				imageEncodeFromRgba8(_dst, temp, _width, _height, _dstFormat, _quality);
 				BX_FREE(_allocator, temp);
 			}
 			break;
 
 		default:
-			if (!imageConvert(_dst, _format, _src, TextureFormat::RGBA32F, _width, _height) )
+			if (!imageConvert(_dst, _dstFormat, _src, TextureFormat::RGBA32F, _width, _height) )
 			{
-				BX_ERROR_SET(_err, BIMG_ERROR, "Unable to convert between input/output formats!");
+				uint8_t* temp = (uint8_t*)BX_ALLOC(_allocator, _width*_height*4);
+				if (imageConvert(temp, TextureFormat::RGBA8, _src, TextureFormat::RGBA32F, _width, _height) )
+				{
+					imageEncodeFromRgba8(_dst, temp, _width, _height, _dstFormat, _quality, _err);
+				}
+				else
+				{
+					BX_ERROR_SET(_err, BIMG_ERROR, "Unable to convert between input/output formats!");
+				}
+				BX_FREE(_allocator, temp);
 			}
 			break;
 		}