k4a_result_t image_create()

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;
}