Родитель
85cd9e2b0b
Коммит
0f82028001
|
@ -604,7 +604,9 @@ K4A_EXPORT float k4a_capture_get_temperature_c(k4a_capture_t capture_handle);
|
|||
* compressed formats that may not be represented by the same number of bytes per line.
|
||||
*
|
||||
* \remarks
|
||||
* The function will allocate an image buffer of size \p height_pixels * \p stride_bytes.
|
||||
* For most image formats, the function will allocate an image buffer of size \p height_pixels * \p stride_bytes.
|
||||
* Buffers #K4A_IMAGE_FORMAT_COLOR_NV12 format will allocate an additional \p height_pixels / 2 set of lines (each of \p
|
||||
* stride_bytes). This function cannot be used to allocate #K4A_IMAGE_FORMAT_COLOR_MJPG buffers.
|
||||
*
|
||||
* \remarks
|
||||
* To create an image object without the API allocating memory, or to represent an image that has a non-deterministic
|
||||
|
|
|
@ -171,10 +171,140 @@ k4a_result_t image_create(k4a_image_format_t format,
|
|||
|
||||
image_context_t *image = NULL;
|
||||
k4a_result_t result;
|
||||
size_t size = (size_t)height_pixels * (size_t)stride_bytes;
|
||||
size_t size = 0;
|
||||
|
||||
*image_handle = NULL;
|
||||
result = TRACE_CALL(image_create_empty_image(source, size, image_handle));
|
||||
|
||||
switch (format)
|
||||
{
|
||||
case K4A_IMAGE_FORMAT_COLOR_MJPG:
|
||||
{
|
||||
LOG_ERROR("K4A_IMAGE_FORMAT_COLOR_MJPG does not have a constant stride. Buffer size cannot be calculated.", 0);
|
||||
result = K4A_RESULT_FAILED;
|
||||
break;
|
||||
}
|
||||
|
||||
case K4A_IMAGE_FORMAT_COLOR_NV12:
|
||||
{
|
||||
if (height_pixels % 2 != 0)
|
||||
{
|
||||
LOG_ERROR("NV12 requires an even number of lines. Height %d is invalid.", height_pixels);
|
||||
result = K4A_RESULT_FAILED;
|
||||
}
|
||||
else if (width_pixels % 2 != 0)
|
||||
{
|
||||
LOG_ERROR("NV12 requires an even number of pixels per line. Width of %d is invalid.", width_pixels);
|
||||
result = K4A_RESULT_FAILED;
|
||||
}
|
||||
else if (stride_bytes < 1 * width_pixels)
|
||||
{
|
||||
LOG_ERROR("Insufficient stride (%d bytes) to represent image width (%d pixels).",
|
||||
stride_bytes,
|
||||
width_pixels);
|
||||
result = K4A_RESULT_FAILED;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Calculate correct size for NV12 (extra color lines follow Y samples)
|
||||
size = 3 * (size_t)height_pixels * (size_t)stride_bytes / 2;
|
||||
result = K4A_RESULT_SUCCEEDED;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// 1 Byte per pixel
|
||||
case K4A_IMAGE_FORMAT_CUSTOM8:
|
||||
{
|
||||
if (stride_bytes < 1 * width_pixels)
|
||||
{
|
||||
LOG_ERROR("Insufficient stride (%d bytes) to represent image width (%d pixels).",
|
||||
stride_bytes,
|
||||
width_pixels);
|
||||
result = K4A_RESULT_FAILED;
|
||||
}
|
||||
else
|
||||
{
|
||||
size = (size_t)height_pixels * (size_t)stride_bytes;
|
||||
result = K4A_RESULT_SUCCEEDED;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// 2 Bytes per pixel
|
||||
case K4A_IMAGE_FORMAT_DEPTH16:
|
||||
case K4A_IMAGE_FORMAT_IR16:
|
||||
case K4A_IMAGE_FORMAT_CUSTOM16:
|
||||
{
|
||||
if (stride_bytes < 2 * width_pixels)
|
||||
{
|
||||
LOG_ERROR("Insufficient stride (%d bytes) to represent image width (%d pixels).",
|
||||
stride_bytes,
|
||||
width_pixels);
|
||||
result = K4A_RESULT_FAILED;
|
||||
}
|
||||
else
|
||||
{
|
||||
size = (size_t)height_pixels * (size_t)stride_bytes;
|
||||
result = K4A_RESULT_SUCCEEDED;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// 2 Bytes per pixel
|
||||
case K4A_IMAGE_FORMAT_COLOR_YUY2:
|
||||
{
|
||||
if (width_pixels % 2 != 0)
|
||||
{
|
||||
LOG_ERROR("YUY2 requires an even number of pixels per line. Width of %d is invalid.", width_pixels);
|
||||
result = K4A_RESULT_FAILED;
|
||||
}
|
||||
else if (stride_bytes < 2 * width_pixels)
|
||||
{
|
||||
LOG_ERROR("Insufficient stride (%d bytes) to represent image width (%d pixels).",
|
||||
stride_bytes,
|
||||
width_pixels);
|
||||
result = K4A_RESULT_FAILED;
|
||||
}
|
||||
else
|
||||
{
|
||||
size = (size_t)height_pixels * (size_t)stride_bytes;
|
||||
result = K4A_RESULT_SUCCEEDED;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// 4 Bytes per pixel
|
||||
case K4A_IMAGE_FORMAT_COLOR_BGRA32:
|
||||
{
|
||||
if (stride_bytes < 4 * width_pixels)
|
||||
{
|
||||
LOG_ERROR("Insufficient stride (%d bytes) to represent image width (%d pixels).",
|
||||
stride_bytes,
|
||||
width_pixels);
|
||||
result = K4A_RESULT_FAILED;
|
||||
}
|
||||
else
|
||||
{
|
||||
size = (size_t)height_pixels * (size_t)stride_bytes;
|
||||
result = K4A_RESULT_SUCCEEDED;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Unknown
|
||||
case K4A_IMAGE_FORMAT_CUSTOM:
|
||||
default:
|
||||
{
|
||||
size = (size_t)height_pixels * (size_t)stride_bytes;
|
||||
result = K4A_RESULT_SUCCEEDED;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (K4A_SUCCEEDED(result))
|
||||
{
|
||||
result = TRACE_CALL(image_create_empty_image(source, size, image_handle));
|
||||
}
|
||||
|
||||
if (K4A_SUCCEEDED(result))
|
||||
{
|
||||
|
@ -188,7 +318,7 @@ k4a_result_t image_create(k4a_image_format_t format,
|
|||
image->stride_bytes = stride_bytes;
|
||||
}
|
||||
|
||||
if (K4A_FAILED(result) && image_handle)
|
||||
if (K4A_FAILED(result) && *image_handle)
|
||||
{
|
||||
image_dec_ref(*image_handle);
|
||||
*image_handle = NULL;
|
||||
|
|
|
@ -181,54 +181,108 @@ TEST(allocator_ut, image_api_validation)
|
|||
|
||||
{
|
||||
// Unsupported formats for this creation API.
|
||||
|
||||
// Invalid FORMAT
|
||||
k4a_image_format_t bad_format = (k4a_image_format_t)99;
|
||||
ASSERT_EQ(K4A_RESULT_FAILED, image_create(bad_format, 10, 10, 1, ALLOCATION_SOURCE_USER, &image));
|
||||
|
||||
// No output argument
|
||||
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));
|
||||
ASSERT_EQ(K4A_RESULT_FAILED,
|
||||
image_create(K4A_IMAGE_FORMAT_COLOR_NV12, 10, 10, 0, ALLOCATION_SOURCE_USER, NULL));
|
||||
ASSERT_EQ(K4A_RESULT_FAILED,
|
||||
image_create(K4A_IMAGE_FORMAT_COLOR_NV12, 10, 0, 1, ALLOCATION_SOURCE_USER, &image));
|
||||
ASSERT_EQ(K4A_RESULT_FAILED, image_create(K4A_IMAGE_FORMAT_COLOR_NV12, 10, 0, 1, ALLOCATION_SOURCE_USER, NULL));
|
||||
ASSERT_EQ(K4A_RESULT_FAILED,
|
||||
image_create(K4A_IMAGE_FORMAT_COLOR_NV12, 10, 0, 0, ALLOCATION_SOURCE_USER, &image));
|
||||
ASSERT_EQ(K4A_RESULT_FAILED, image_create(K4A_IMAGE_FORMAT_COLOR_NV12, 10, 0, 0, ALLOCATION_SOURCE_USER, NULL));
|
||||
ASSERT_EQ(K4A_RESULT_FAILED,
|
||||
image_create(K4A_IMAGE_FORMAT_COLOR_NV12, 0, 10, 1, ALLOCATION_SOURCE_USER, &image));
|
||||
ASSERT_EQ(K4A_RESULT_FAILED, image_create(K4A_IMAGE_FORMAT_COLOR_NV12, 0, 10, 1, ALLOCATION_SOURCE_USER, NULL));
|
||||
ASSERT_EQ(K4A_RESULT_FAILED,
|
||||
image_create(K4A_IMAGE_FORMAT_COLOR_NV12, 0, 10, 0, ALLOCATION_SOURCE_USER, &image));
|
||||
ASSERT_EQ(K4A_RESULT_FAILED, image_create(K4A_IMAGE_FORMAT_COLOR_NV12, 0, 10, 0, ALLOCATION_SOURCE_USER, NULL));
|
||||
ASSERT_EQ(K4A_RESULT_FAILED,
|
||||
image_create(K4A_IMAGE_FORMAT_COLOR_NV12, 0, 0, 1, ALLOCATION_SOURCE_USER, &image));
|
||||
ASSERT_EQ(K4A_RESULT_FAILED, image_create(K4A_IMAGE_FORMAT_COLOR_NV12, 0, 0, 1, ALLOCATION_SOURCE_USER, NULL));
|
||||
ASSERT_EQ(K4A_RESULT_FAILED,
|
||||
image_create(K4A_IMAGE_FORMAT_COLOR_NV12, 0, 0, 0, ALLOCATION_SOURCE_USER, &image));
|
||||
ASSERT_EQ(K4A_RESULT_FAILED, image_create(K4A_IMAGE_FORMAT_COLOR_NV12, 0, 0, 0, ALLOCATION_SOURCE_USER, NULL));
|
||||
|
||||
ASSERT_EQ(K4A_RESULT_FAILED, image_create(bad_format, 10, 10, 1, ALLOCATION_SOURCE_USER, &image));
|
||||
ASSERT_EQ(K4A_RESULT_FAILED, image_create(bad_format, 10, 10, 1, ALLOCATION_SOURCE_USER, NULL));
|
||||
ASSERT_EQ(K4A_RESULT_FAILED, image_create(bad_format, 10, 10, 0, ALLOCATION_SOURCE_USER, &image));
|
||||
ASSERT_EQ(K4A_RESULT_FAILED, image_create(bad_format, 10, 10, 0, ALLOCATION_SOURCE_USER, NULL));
|
||||
ASSERT_EQ(K4A_RESULT_FAILED, image_create(bad_format, 10, 0, 1, ALLOCATION_SOURCE_USER, &image));
|
||||
ASSERT_EQ(K4A_RESULT_FAILED, image_create(bad_format, 10, 0, 1, ALLOCATION_SOURCE_USER, NULL));
|
||||
ASSERT_EQ(K4A_RESULT_FAILED, image_create(bad_format, 10, 0, 0, ALLOCATION_SOURCE_USER, &image));
|
||||
ASSERT_EQ(K4A_RESULT_FAILED, image_create(bad_format, 10, 0, 0, ALLOCATION_SOURCE_USER, NULL));
|
||||
ASSERT_EQ(K4A_RESULT_FAILED, image_create(bad_format, 0, 10, 1, ALLOCATION_SOURCE_USER, &image));
|
||||
ASSERT_EQ(K4A_RESULT_FAILED, image_create(bad_format, 0, 10, 1, ALLOCATION_SOURCE_USER, NULL));
|
||||
ASSERT_EQ(K4A_RESULT_FAILED, image_create(bad_format, 0, 10, 0, ALLOCATION_SOURCE_USER, &image));
|
||||
ASSERT_EQ(K4A_RESULT_FAILED, image_create(bad_format, 0, 10, 0, ALLOCATION_SOURCE_USER, NULL));
|
||||
ASSERT_EQ(K4A_RESULT_FAILED, image_create(bad_format, 0, 0, 1, ALLOCATION_SOURCE_USER, &image));
|
||||
ASSERT_EQ(K4A_RESULT_FAILED, image_create(bad_format, 0, 0, 1, ALLOCATION_SOURCE_USER, NULL));
|
||||
ASSERT_EQ(K4A_RESULT_FAILED, image_create(bad_format, 0, 0, 0, ALLOCATION_SOURCE_USER, &image));
|
||||
ASSERT_EQ(K4A_RESULT_FAILED, image_create(bad_format, 0, 0, 0, ALLOCATION_SOURCE_USER, NULL));
|
||||
// Stride length
|
||||
// Validate a valid length and an invalid length
|
||||
|
||||
// NV12
|
||||
// Minimum stride
|
||||
ASSERT_EQ(K4A_RESULT_SUCCEEDED,
|
||||
image_create(K4A_IMAGE_FORMAT_COLOR_NV12, 10, 10, 1, ALLOCATION_SOURCE_USER, &image));
|
||||
image_create(K4A_IMAGE_FORMAT_COLOR_NV12, 10, 10, 10, ALLOCATION_SOURCE_USER, &image));
|
||||
ASSERT_EQ(10 * 10 * 3 / 2, (int)image_get_size(image));
|
||||
image_dec_ref(image);
|
||||
// Extra stride
|
||||
ASSERT_EQ(K4A_RESULT_SUCCEEDED,
|
||||
image_create(K4A_IMAGE_FORMAT_COLOR_NV12, 10, 10, 11, ALLOCATION_SOURCE_USER, &image));
|
||||
ASSERT_EQ(10 * 11 * 3 / 2, (int)image_get_size(image));
|
||||
image_dec_ref(image);
|
||||
// Insufficient stride
|
||||
ASSERT_EQ(K4A_RESULT_FAILED,
|
||||
image_create(K4A_IMAGE_FORMAT_COLOR_NV12, 10, 10, 9, ALLOCATION_SOURCE_USER, &image));
|
||||
// Odd number of rows
|
||||
ASSERT_EQ(K4A_RESULT_FAILED,
|
||||
image_create(K4A_IMAGE_FORMAT_COLOR_NV12, 10, 11, 20, ALLOCATION_SOURCE_USER, &image));
|
||||
// Odd number of columns
|
||||
ASSERT_EQ(K4A_RESULT_FAILED,
|
||||
image_create(K4A_IMAGE_FORMAT_COLOR_NV12, 11, 10, 20, ALLOCATION_SOURCE_USER, &image));
|
||||
|
||||
// YUY2
|
||||
// Minimum stride
|
||||
ASSERT_EQ(K4A_RESULT_SUCCEEDED,
|
||||
image_create(K4A_IMAGE_FORMAT_COLOR_YUY2, 10, 10, 20, ALLOCATION_SOURCE_USER, &image));
|
||||
ASSERT_EQ(/* lines * stride*/ 10 * 20, (int)image_get_size(image));
|
||||
image_dec_ref(image);
|
||||
// Extra stride
|
||||
ASSERT_EQ(K4A_RESULT_SUCCEEDED,
|
||||
image_create(K4A_IMAGE_FORMAT_COLOR_YUY2, 10, 10, 22, ALLOCATION_SOURCE_USER, &image));
|
||||
ASSERT_EQ(/* lines * stride*/ 10 * 22, (int)image_get_size(image));
|
||||
image_dec_ref(image);
|
||||
// Insufficient stride
|
||||
ASSERT_EQ(K4A_RESULT_FAILED,
|
||||
image_create(K4A_IMAGE_FORMAT_COLOR_YUY2, 10, 10, 19, ALLOCATION_SOURCE_USER, &image));
|
||||
// Odd number of rows
|
||||
ASSERT_EQ(K4A_RESULT_SUCCEEDED,
|
||||
image_create(K4A_IMAGE_FORMAT_COLOR_YUY2, 10, 11, 20, ALLOCATION_SOURCE_USER, &image));
|
||||
ASSERT_EQ(/* lines * stride*/ 11 * 20, (int)image_get_size(image));
|
||||
image_dec_ref(image);
|
||||
// Odd number of columns
|
||||
ASSERT_EQ(K4A_RESULT_FAILED,
|
||||
image_create(K4A_IMAGE_FORMAT_COLOR_YUY2, 11, 10, 20, ALLOCATION_SOURCE_USER, &image));
|
||||
|
||||
// BGRA32
|
||||
// Minimum stride
|
||||
ASSERT_EQ(K4A_RESULT_SUCCEEDED,
|
||||
image_create(K4A_IMAGE_FORMAT_COLOR_BGRA32, 10, 10, 40, ALLOCATION_SOURCE_USER, &image));
|
||||
ASSERT_EQ(/* lines * stride*/ 10 * 40, (int)image_get_size(image));
|
||||
image_dec_ref(image);
|
||||
// Insufficient stride
|
||||
ASSERT_EQ(K4A_RESULT_FAILED,
|
||||
image_create(K4A_IMAGE_FORMAT_COLOR_BGRA32, 10, 10, 39, ALLOCATION_SOURCE_USER, &image));
|
||||
|
||||
// MJPEG (no length is valid)
|
||||
ASSERT_EQ(K4A_RESULT_FAILED,
|
||||
image_create(K4A_IMAGE_FORMAT_COLOR_MJPG, 10, 10, 100, ALLOCATION_SOURCE_USER, &image));
|
||||
|
||||
// DEPTH16
|
||||
// Minimum stride
|
||||
ASSERT_EQ(K4A_RESULT_SUCCEEDED,
|
||||
image_create(K4A_IMAGE_FORMAT_DEPTH16, 10, 10, 20, ALLOCATION_SOURCE_USER, &image));
|
||||
ASSERT_EQ(10 * 10 * 2, (int)image_get_size(image));
|
||||
image_dec_ref(image);
|
||||
// Insufficient stride
|
||||
ASSERT_EQ(K4A_RESULT_FAILED,
|
||||
image_create(K4A_IMAGE_FORMAT_DEPTH16, 10, 10, 19, ALLOCATION_SOURCE_USER, &image));
|
||||
|
||||
// Custom8
|
||||
// Minimum stride
|
||||
ASSERT_EQ(K4A_RESULT_SUCCEEDED,
|
||||
image_create(K4A_IMAGE_FORMAT_CUSTOM8, 10, 10, 10, ALLOCATION_SOURCE_USER, &image));
|
||||
ASSERT_EQ(10 * 10, (int)image_get_size(image));
|
||||
image_dec_ref(image);
|
||||
// Insufficient stride
|
||||
ASSERT_EQ(K4A_RESULT_FAILED,
|
||||
(int)image_create(K4A_IMAGE_FORMAT_CUSTOM8, 10, 10, 9, ALLOCATION_SOURCE_USER, &image));
|
||||
|
||||
// Height of zero
|
||||
ASSERT_EQ(K4A_RESULT_FAILED,
|
||||
(int)image_create(K4A_IMAGE_FORMAT_CUSTOM8, 10, 0, 10, ALLOCATION_SOURCE_USER, &image));
|
||||
|
||||
// Width of zero
|
||||
ASSERT_EQ(K4A_RESULT_FAILED,
|
||||
(int)image_create(K4A_IMAGE_FORMAT_CUSTOM8, 0, 10, 10, ALLOCATION_SOURCE_USER, &image));
|
||||
|
||||
ASSERT_EQ(allocator_test_for_leaks(), 0);
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче