in src/image/image.c [158:359]
k4a_result_t image_create(k4a_image_format_t format,
int width_pixels,
int height_pixels,
int stride_bytes,
allocation_source_t source,
k4a_image_t *image_handle)
{
// User is special and only allowed to be used by the user through a public API.
RETURN_VALUE_IF_ARG(K4A_RESULT_FAILED, image_handle == NULL);
RETURN_VALUE_IF_ARG(K4A_RESULT_FAILED,
!(format >= K4A_IMAGE_FORMAT_COLOR_MJPG && format <= K4A_IMAGE_FORMAT_CUSTOM));
RETURN_VALUE_IF_ARG(K4A_RESULT_FAILED, !(width_pixels > 0 && width_pixels < 20000));
RETURN_VALUE_IF_ARG(K4A_RESULT_FAILED, !(height_pixels > 0 && height_pixels < 20000));
image_context_t *image = NULL;
k4a_result_t result;
size_t size = 0;
*image_handle = NULL;
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 (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);
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 == 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).",
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 == 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).",
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 (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);
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 == 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).",
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))
{
result = K4A_RESULT_FROM_BOOL((image = k4a_image_t_get_context(*image_handle)) != NULL);
}
if (K4A_SUCCEEDED(result))
{
image->format = format;
image->width_pixels = width_pixels;
image->height_pixels = height_pixels;
image->stride_bytes = stride_bytes;
}
if (K4A_FAILED(result) && *image_handle)
{
image_dec_ref(*image_handle);
*image_handle = NULL;
image = NULL;
}
return result;
}