Skip to content
This repository was archived by the owner on Aug 22, 2024. It is now read-only.
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Enabled implicit stride in k4a_image_create
  • Loading branch information
Brent-A committed Oct 8, 2019
commit f876d18dd4466dc0f3e3aa3b453b82af8d1b3563
1 change: 1 addition & 0 deletions include/k4a/k4a.h
Original file line number Diff line number Diff line change
Expand Up @@ -595,6 +595,7 @@ K4A_EXPORT float k4a_capture_get_temperature_c(k4a_capture_t capture_handle);
*
* \param stride_bytes
* The number of bytes per horizontal line of the image.
* If set to 0, the stride will be set to the minimum size given the \p format and \p width_pixels.
*
* \param image_handle
* Pointer to store image handle in.
Expand Down
46 changes: 2 additions & 44 deletions src/csharp/SDK/Image.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@ public class Image : IMemoryOwner<byte>, IDisposable
/// <param name="format">The pixel format of the image. Must be a format with a constant pixel size.</param>
/// <param name="widthPixels">Width of the image in pixels.</param>
/// <param name="heightPixels">Height of the image in pixels.</param>
/// <param name="strideBytes">Stride of the image in bytes. Must be as large as the width times the size of a pixel.</param>
public Image(ImageFormat format, int widthPixels, int heightPixels, int strideBytes)
/// <param name="strideBytes">Stride of the image in bytes. Must be as large as the width times the size of a pixel. Set to zero for the default if available for that format.</param>
public Image(ImageFormat format, int widthPixels, int heightPixels, int strideBytes = 0)
{
// Hook the native allocator and register this object.
// .Dispose() will be called on this object when the allocator is shut down.
Expand All @@ -61,48 +61,6 @@ public Image(ImageFormat format, int widthPixels, int heightPixels, int strideBy
out this.handle));
}

/// <summary>
/// Initializes a new instance of the <see cref="Image"/> class.
/// </summary>
/// <param name="format">The pixel format of the image. Must be a format with a constant pixel size.</param>
/// <param name="widthPixels">Width of the image in pixels.</param>
/// <param name="heightPixels">Height of the image in pixels.</param>
public Image(ImageFormat format, int widthPixels, int heightPixels)
{
int pixelSize;
switch (format)
{
case ImageFormat.ColorBGRA32:
pixelSize = 4;
break;
case ImageFormat.Depth16:
case ImageFormat.IR16:
case ImageFormat.Custom16:
pixelSize = 2;
break;
case ImageFormat.Custom8:
pixelSize = 1;
break;
default:
throw new AzureKinectException($"Unable to allocate array for format {format}");
}

int stride_bytes = widthPixels * pixelSize;

// Hook the native allocator and register this object.
// .Dispose() will be called on this object when the allocator is shut down.
Allocator.Singleton.RegisterForDisposal(this);

#pragma warning disable CA2000 // Dispose objects before losing scope
AzureKinectException.ThrowIfNotSuccess(() => NativeMethods.k4a_image_create(
format,
widthPixels,
heightPixels,
stride_bytes,
image_handle: out this.handle));
#pragma warning restore CA2000 // Dispose objects before losing scope
}

/// <summary>
/// Initializes a new instance of the <see cref="Image"/> class.
/// </summary>
Expand Down
30 changes: 30 additions & 0 deletions src/image/image.c
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,12 @@ k4a_result_t image_create(k4a_image_format_t format,

case K4A_IMAGE_FORMAT_COLOR_NV12:
{
if (stride_bytes == 0)
{
// If stride isn't specified, assume the minimum stride
stride_bytes = width_pixels;
}

if (height_pixels % 2 != 0)
{
LOG_ERROR("NV12 requires an even number of lines. Height %d is invalid.", height_pixels);
Expand Down Expand Up @@ -215,6 +221,12 @@ k4a_result_t image_create(k4a_image_format_t format,
// 1 Byte per pixel
case K4A_IMAGE_FORMAT_CUSTOM8:
{
if (stride_bytes == 0)
{
// If stride isn't specified, assume the minimum stride
stride_bytes = width_pixels;
}

if (stride_bytes < 1 * width_pixels)
{
LOG_ERROR("Insufficient stride (%d bytes) to represent image width (%d pixels).",
Expand All @@ -235,6 +247,12 @@ k4a_result_t image_create(k4a_image_format_t format,
case K4A_IMAGE_FORMAT_IR16:
case K4A_IMAGE_FORMAT_CUSTOM16:
{
if (stride_bytes == 0)
{
// If stride isn't specified, assume the minimum stride
stride_bytes = width_pixels * 2;
}

if (stride_bytes < 2 * width_pixels)
{
LOG_ERROR("Insufficient stride (%d bytes) to represent image width (%d pixels).",
Expand All @@ -253,6 +271,12 @@ k4a_result_t image_create(k4a_image_format_t format,
// 2 Bytes per pixel
case K4A_IMAGE_FORMAT_COLOR_YUY2:
{
if (stride_bytes == 0)
{
// If stride isn't specified, assume the minimum stride
stride_bytes = width_pixels * 2;
}

if (width_pixels % 2 != 0)
{
LOG_ERROR("YUY2 requires an even number of pixels per line. Width of %d is invalid.", width_pixels);
Expand All @@ -276,6 +300,12 @@ k4a_result_t image_create(k4a_image_format_t format,
// 4 Bytes per pixel
case K4A_IMAGE_FORMAT_COLOR_BGRA32:
{
if (stride_bytes == 0)
{
// If stride isn't specified, assume the minimum stride
stride_bytes = width_pixels * 4;
}

if (stride_bytes < 4 * width_pixels)
{
LOG_ERROR("Insufficient stride (%d bytes) to represent image width (%d pixels).",
Expand Down
29 changes: 25 additions & 4 deletions tests/UnitTests/allocator_ut/allocator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -190,10 +190,6 @@ TEST(allocator_ut, image_api_validation)
ASSERT_EQ(K4A_RESULT_FAILED,
image_create(K4A_IMAGE_FORMAT_COLOR_NV12, 10, 10, 1, ALLOCATION_SOURCE_USER, NULL));

// Stride of zero
ASSERT_EQ(K4A_RESULT_FAILED,
image_create(K4A_IMAGE_FORMAT_COLOR_NV12, 10, 10, 0, ALLOCATION_SOURCE_USER, &image));

// Stride length
// Validate a valid length and an invalid length

Expand All @@ -217,6 +213,11 @@ TEST(allocator_ut, image_api_validation)
// Odd number of columns
ASSERT_EQ(K4A_RESULT_FAILED,
image_create(K4A_IMAGE_FORMAT_COLOR_NV12, 11, 10, 20, ALLOCATION_SOURCE_USER, &image));
// Stride of zero (should succeed and infer the minimum stride)
ASSERT_EQ(K4A_RESULT_SUCCEEDED,
image_create(K4A_IMAGE_FORMAT_COLOR_NV12, 10, 10, 0, ALLOCATION_SOURCE_USER, &image));
ASSERT_EQ(10, image_get_stride_bytes(image));
image_dec_ref(image);

// YUY2
// Minimum stride
Expand All @@ -240,6 +241,11 @@ TEST(allocator_ut, image_api_validation)
// Odd number of columns
ASSERT_EQ(K4A_RESULT_FAILED,
image_create(K4A_IMAGE_FORMAT_COLOR_YUY2, 11, 10, 20, ALLOCATION_SOURCE_USER, &image));
// Stride of zero (should succeed and infer the minimum stride)
ASSERT_EQ(K4A_RESULT_SUCCEEDED,
image_create(K4A_IMAGE_FORMAT_COLOR_YUY2, 10, 10, 0, ALLOCATION_SOURCE_USER, &image));
ASSERT_EQ(10 * 2, image_get_stride_bytes(image));
image_dec_ref(image);

// BGRA32
// Minimum stride
Expand All @@ -250,6 +256,11 @@ TEST(allocator_ut, image_api_validation)
// Insufficient stride
ASSERT_EQ(K4A_RESULT_FAILED,
image_create(K4A_IMAGE_FORMAT_COLOR_BGRA32, 10, 10, 39, ALLOCATION_SOURCE_USER, &image));
// Stride of zero (should succeed and infer the minimum stride)
ASSERT_EQ(K4A_RESULT_SUCCEEDED,
image_create(K4A_IMAGE_FORMAT_COLOR_BGRA32, 10, 10, 0, ALLOCATION_SOURCE_USER, &image));
ASSERT_EQ(10 * 4, image_get_stride_bytes(image));
image_dec_ref(image);

// MJPEG (no length is valid)
ASSERT_EQ(K4A_RESULT_FAILED,
Expand All @@ -264,6 +275,11 @@ TEST(allocator_ut, image_api_validation)
// Insufficient stride
ASSERT_EQ(K4A_RESULT_FAILED,
image_create(K4A_IMAGE_FORMAT_DEPTH16, 10, 10, 19, ALLOCATION_SOURCE_USER, &image));
// Stride of zero (should succeed and infer the minimum stride)
ASSERT_EQ(K4A_RESULT_SUCCEEDED,
image_create(K4A_IMAGE_FORMAT_DEPTH16, 10, 10, 0, ALLOCATION_SOURCE_USER, &image));
ASSERT_EQ(10 * 2, image_get_stride_bytes(image));
image_dec_ref(image);

// Custom8
// Minimum stride
Expand All @@ -274,6 +290,11 @@ TEST(allocator_ut, image_api_validation)
// Insufficient stride
ASSERT_EQ(K4A_RESULT_FAILED,
(int)image_create(K4A_IMAGE_FORMAT_CUSTOM8, 10, 10, 9, ALLOCATION_SOURCE_USER, &image));
// Stride of zero (should succeed and infer the minimum stride)
ASSERT_EQ(K4A_RESULT_SUCCEEDED,
image_create(K4A_IMAGE_FORMAT_CUSTOM8, 10, 10, 0, ALLOCATION_SOURCE_USER, &image));
ASSERT_EQ(10 * 1, image_get_stride_bytes(image));
image_dec_ref(image);

// Height of zero
ASSERT_EQ(K4A_RESULT_FAILED,
Expand Down