From fcb71bd12d6cd515e68915eca4f1025eaa71daf2 Mon Sep 17 00:00:00 2001 From: nooperation Date: Sat, 26 Apr 2025 00:30:49 -0400 Subject: [PATCH] PortableImage has 32-bit components, but ManagedImage only supports 8-bit values. A direct BlockCopy of the two is invalid and needs to be done by manually converting each 32-bit color value to an 8-bit color (just simple truncation/casting) --- LibreMetaverse/Imaging/ManagedImage.cs | 49 ++++++++++++++------------ 1 file changed, 26 insertions(+), 23 deletions(-) diff --git a/LibreMetaverse/Imaging/ManagedImage.cs b/LibreMetaverse/Imaging/ManagedImage.cs index 5ca75c26..44858d89 100644 --- a/LibreMetaverse/Imaging/ManagedImage.cs +++ b/LibreMetaverse/Imaging/ManagedImage.cs @@ -114,6 +114,20 @@ namespace OpenMetaverse.Imaging Bump = new byte[n]; } + /// + /// Converts an array of 32-bit color values to an array of 8-bit color values + /// + /// The input array of 32-bit color values + /// The output array of 8-bit color values + private static void ConvertTo8BitChannel(int[] sourceData, out byte[] destinationData) + { + destinationData = new byte[sourceData.Length]; + for (var i = 0; i < sourceData.Length; i++) + { + destinationData[i] = (byte)sourceData[i]; + } + } + /// /// Constructs ManagedImage class from /// Currently only supporting 8-bit channels; @@ -123,46 +137,35 @@ namespace OpenMetaverse.Imaging { Width = image.Width; Height = image.Height; - - var pixelCount = Width * Height; + var numComp = image.NumberOfComponents; switch (numComp) { case 1: Channels = ImageChannels.Gray; - Red = new byte[pixelCount * sizeof(int)]; - Buffer.BlockCopy(image.GetComponent(0), 0, Red, 0, Red.Length); + ConvertTo8BitChannel(image.GetComponent(0), out Red); break; case 2: Channels = ImageChannels.Color; - Red = new byte[pixelCount * sizeof(int)]; - Green = new byte[pixelCount * sizeof(int)]; - Buffer.BlockCopy(image.GetComponent(0), 0, Red, 0, Red.Length); - Buffer.BlockCopy(image.GetComponent(1), 0, Green, 0, Green.Length); + ConvertTo8BitChannel(image.GetComponent(0), out Red); + ConvertTo8BitChannel(image.GetComponent(1), out Green); break; case 3: Channels = ImageChannels.Color; - Red = new byte[pixelCount * sizeof(int)]; - Green = new byte[pixelCount * sizeof(int)]; - Blue = new byte[pixelCount * sizeof(int)]; - Buffer.BlockCopy(image.GetComponent(0), 0, Red, 0, Red.Length); - Buffer.BlockCopy(image.GetComponent(1), 0, Green, 0, Green.Length); - Buffer.BlockCopy(image.GetComponent(2), 0, Blue, 0, Blue.Length); + ConvertTo8BitChannel(image.GetComponent(0), out Red); + ConvertTo8BitChannel(image.GetComponent(1), out Green); + ConvertTo8BitChannel(image.GetComponent(2), out Blue); break; case 4: Channels = ImageChannels.Alpha | ImageChannels.Color; - Red = new byte[pixelCount * sizeof(int)]; - Green = new byte[pixelCount * sizeof(int)]; - Blue = new byte[pixelCount * sizeof(int)]; - Alpha = new byte[pixelCount * sizeof(int)]; - Buffer.BlockCopy(image.GetComponent(0), 0, Red, 0, Red.Length); - Buffer.BlockCopy(image.GetComponent(1), 0, Green, 0, Green.Length); - Buffer.BlockCopy(image.GetComponent(2), 0, Blue, 0, Blue.Length); - Buffer.BlockCopy(image.GetComponent(3), 0, Alpha, 0, Alpha.Length); + ConvertTo8BitChannel(image.GetComponent(0), out Red); + ConvertTo8BitChannel(image.GetComponent(1), out Green); + ConvertTo8BitChannel(image.GetComponent(2), out Blue); + ConvertTo8BitChannel(image.GetComponent(3), out Alpha); break; } } - + /// /// Constructs ManagedImage class from ///