Skip to content

Commit

Permalink
Fix CalulcateSize. use GetComponentById.
Browse files Browse the repository at this point in the history
  • Loading branch information
juliusfriedman committed Oct 19, 2024
1 parent 7f17dff commit a8167b5
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 21 deletions.
101 changes: 92 additions & 9 deletions Codecs/Image/Image.cs
Original file line number Diff line number Diff line change
Expand Up @@ -70,18 +70,52 @@ public static Image FromStream(Stream stream)

internal static int CalculateSize(ImageFormat format, int width, int height)
{
//The total size in bytes
int totalSize = 0;
int size = 0;

//Iterate each component in the ColorSpace
for (int i = 0, ie = format.Components.Length; i < ie; ++i)
switch (format.DataLayout)
{
//Increment the total size in bytes by calculating the size in bytes of that plane using the ColorSpace information
totalSize += (width >> format.Widths[i]) * (height >> format.Heights[i]);
case DataLayout.Planar:
// For planar layout, each component has its own plane
for (int i = 0; i < format.Components.Length; i++)
{
int componentWidth = width >> format.Widths[i];
int componentHeight = height >> format.Heights[i];
size += componentWidth * componentHeight * format.Components[i].Length;
}
break;

case DataLayout.SemiPlanar:
var fistComponentLength = format.Components[0].Length;
// For semi-planar layout, the first component has its own plane)
// the second plane is for the packed components
size = width >> format.Widths[0] * height >> format.Heights[0] * fistComponentLength;
width >>= format.Widths[1];
height >>= format.Heights[1];
goto case DataLayout.Packed;
case DataLayout.Packed:
// For packed layout, all components are interleaved
size += width * height * format.Length;
break;

default:
throw new NotSupportedException($"Data layout {format.DataLayout} is not supported.");
}

//Return the amount of bytes
return totalSize;
return size;
}

internal int CalculateStride(int alignment = Common.Binary.BytesPerInteger)
{
// Calculate the number of bits per pixel
int bitsPerPixel = ImageFormat.Size;

// Calculate the number of bytes per row before alignment
int bytesPerRow = (Width * bitsPerPixel + 7) / Binary.BitsPerByte;

// Align the stride to the specified alignment
int stride = (bytesPerRow + alignment - 1) & ~(alignment - 1);

return stride;
}

#endregion
Expand Down Expand Up @@ -388,7 +422,7 @@ public static void TestConstructor()
{
if (image.SampleCount != 1) throw new System.InvalidOperationException();

if (image.Data.Count != image.Width * image.Height * image.MediaFormat.Length) throw new System.InvalidOperationException();
if (image.Data.Count != Image.CalculateSize(image.ImageFormat, image.Width, image.Height)) throw new System.InvalidOperationException();
}
}
}
Expand Down Expand Up @@ -1233,5 +1267,54 @@ public static void TestSetComponentData()
var retrievedData = image[0, 0];
Console.WriteLine(retrievedData.SelectMany(arg => arg).SequenceEqual(data) ? "Pass" : "Fail");
}

public void CalculateStride_RGB8_ReturnsCorrectStride()
{
// Arrange
int width = 1920;
int height = 1080;
var imageFormat = ImageFormat.RGB(8);
var image = new Image(imageFormat, width, height);

// Act
int stride = image.CalculateStride();

// Assert
int expectedStride = ((width * 3) + 3) & ~3; // 3 bytes per pixel for RGB8, aligned to 4 bytes
System.Diagnostics.Debug.Assert(expectedStride == stride);
}

public void CalculateStride_ARGB8_ReturnsCorrectStride()
{
// Arrange
int width = 1920;
int height = 1080;
var imageFormat = ImageFormat.ARGB(8);
var image = new Image(imageFormat, width, height);

// Act
int stride = image.CalculateStride();

// Assert
int expectedStride = ((width * Common.Binary.BytesPerInteger) + 3) & ~3; // 4 bytes per pixel for ARGB8, aligned to 4 bytes
System.Diagnostics.Debug.Assert(expectedStride == stride);
}

public void CalculateStride_Monochrome1_ReturnsCorrectStride()
{
// Arrange
int width = 1920;
int height = 1080;
var imageFormat = ImageFormat.Monochrome(1);
var image = new Image(imageFormat, width, height);

// Act
int stride = image.CalculateStride();

// Assert
int rowSize = (width + 7) / Common.Binary.BitsPerByte; // 1 bit per pixel, convert width to bytes
int expectedStride = (rowSize + 3) & ~3; // Align to 4 bytes
System.Diagnostics.Debug.Assert(expectedStride == stride);
}
}
}
6 changes: 3 additions & 3 deletions Codecs/Image/Transformations/RgbToYuvImageTransformation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,8 @@ public VectorizedRgbToYuvImageTransformation(Image source, Image dest, Codec.Tra
private static bool IsRgbImage(ImageFormat format)
{
return format.Components.Length >= 3 &&
format.Components.Any(c => c.Id == ImageFormat.RedChannelId) &&
format.Components.Any(c => c.Id == ImageFormat.GreenChannelId) &&
format.GetComponentById(ImageFormat.RedChannelId) != null &&
format.GetComponentById(ImageFormat.GreenChannelId) != null &&
format.GetComponentById(ImageFormat.BlueChannelId) != null;
}

Expand All @@ -119,7 +119,7 @@ private static bool IsYuvImage(ImageFormat format)
{
return format.Components.Length >= 3 &&
format.GetComponentById(ImageFormat.LumaChannelId) != null &&
format.GetComponentById(ImageFormat.ChromaMajorChannelId) != null&&
format.GetComponentById(ImageFormat.ChromaMajorChannelId) != null &&
format.GetComponentById(ImageFormat.ChromaMinorChannelId) != null;
}

Expand Down
18 changes: 9 additions & 9 deletions Codecs/Image/Transformations/YuvToRgbTransformation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -107,21 +107,21 @@ public VectorizedYuvToRgbTransformation(Image source, Image dest, Codec.Transfor
}

// Check if the image format is a YUV format
private static bool IsYuvImage(ImageFormat format)
private static bool IsRgbImage(ImageFormat format)
{
return format.Components.Length >= 3 &&
format.Components.Any(c => c.Id == ImageFormat.LumaChannelId) &&
format.Components.Any(c => c.Id == ImageFormat.ChromaMajorChannelId) &&
format.Components.Any(c => c.Id == ImageFormat.ChromaMinorChannelId);
format.GetComponentById(ImageFormat.RedChannelId) != null &&
format.GetComponentById(ImageFormat.GreenChannelId) != null &&
format.GetComponentById(ImageFormat.BlueChannelId) != null;
}

// Check if the image format is an RGB format
private static bool IsRgbImage(ImageFormat format)
// Check if the image format is a YUV format
private static bool IsYuvImage(ImageFormat format)
{
return format.Components.Length >= 3 &&
format.Components.Any(c => c.Id == ImageFormat.RedChannelId) &&
format.Components.Any(c => c.Id == ImageFormat.GreenChannelId) &&
format.Components.Any(c => c.Id == ImageFormat.BlueChannelId);
format.GetComponentById(ImageFormat.LumaChannelId) != null &&
format.GetComponentById(ImageFormat.ChromaMajorChannelId) != null &&
format.GetComponentById(ImageFormat.ChromaMinorChannelId) != null;
}

public override void Transform()
Expand Down

0 comments on commit a8167b5

Please sign in to comment.