Commit e82c62d5 authored by Kenneth Moreland's avatar Kenneth Moreland
Browse files

Add an image format for pointers to color/depth buffers

The IceTImage object expects a single allocated buffer in which both the
color and depth is encoded. This is convienient for passing images in a
single message. However, when interfacing with client code, it is
typical to have them in separate buffers. Thus, we have a secondary
dense image format that has pointers to these two buffers. It should be
able to do everything a normal image can do except be packaged for a
send or be written to.
parent f91550ff
......@@ -21,6 +21,7 @@
#include <string.h>
#define ICET_IMAGE_MAGIC_NUM (IceTEnum)0x004D5000
#define ICET_IMAGE_POINTERS_MAGIC_NUM (IceTEnum)0x004D5100
#define ICET_SPARSE_IMAGE_MAGIC_NUM (IceTEnum)0x004D6000
#define ICET_IMAGE_MAGIC_NUM_INDEX 0
......@@ -46,8 +47,10 @@ typedef IceTUnsignedInt32 IceTRunLengthType;
static void ICET_TEST_IMAGE_HEADER(IceTImage image)
{
if (!icetImageIsNull(image)) {
if ( ICET_IMAGE_HEADER(image)[ICET_IMAGE_MAGIC_NUM_INDEX]
!= ICET_IMAGE_MAGIC_NUM ) {
IceTEnum magic_num =
ICET_IMAGE_HEADER(image)[ICET_IMAGE_MAGIC_NUM_INDEX];
if ( (magic_num != ICET_IMAGE_MAGIC_NUM)
&& (magic_num != ICET_IMAGE_POINTERS_MAGIC_NUM) ) {
icetRaiseError("Detected invalid image header.",
ICET_SANITY_CHECK_FAIL);
}
......@@ -254,6 +257,12 @@ IceTSizeType icetImageBufferSizeType(IceTEnum color_format,
+ width*height*(color_pixel_size + depth_pixel_size) );
}
IceTSizeType icetImagePointerBufferSize(void)
{
return ( ICET_IMAGE_DATA_START_INDEX*sizeof(IceTUInt)
+ 2*(sizeof(const IceTVoid *)) );
}
IceTSizeType icetSparseImageBufferSize(IceTSizeType width, IceTSizeType height)
{
IceTEnum color_format, depth_format;
......@@ -309,6 +318,22 @@ IceTImage icetGetStateBufferImage(IceTEnum pname,
return icetImageAssignBuffer(buffer, width, height);
}
IceTImage icetGetStatePointerImage(IceTEnum pname,
IceTSizeType width,
IceTSizeType height,
const IceTVoid *color_buffer,
const IceTVoid *depth_buffer)
{
IceTVoid *buffer;
IceTSizeType buffer_size;
buffer_size = icetImagePointerBufferSize();
buffer = icetGetStateBuffer(pname, buffer_size);
return icetImagePointerAssignBuffer(
buffer, width, height, color_buffer, depth_buffer);
}
IceTImage icetImageAssignBuffer(IceTVoid *buffer,
IceTSizeType width,
IceTSizeType height)
......@@ -357,6 +382,62 @@ IceTImage icetImageAssignBuffer(IceTVoid *buffer,
return image;
}
IceTImage icetImagePointerAssignBuffer(IceTVoid *buffer,
IceTSizeType width,
IceTSizeType height,
const IceTVoid *color_buffer,
const IceTVoid *depth_buffer)
{
/* This is a bit hacky, but most of the entries for regular images and
* pointer images are the same. Use that function to fill in most of
* the entries and fix those that are different. */
IceTImage image = icetImageAssignBuffer(buffer, width, height);
{
IceTInt *header = ICET_IMAGE_HEADER(image);
/* Our magic number is different. */
header[ICET_IMAGE_MAGIC_NUM_INDEX] = ICET_IMAGE_POINTERS_MAGIC_NUM;
/* It is invalid to use this type of image as a single buffer. */
header[ICET_IMAGE_ACTUAL_BUFFER_SIZE_INDEX] = -1;
}
/* Check that the image buffers make sense. */
if (icetImageGetColorFormat(image) == ICET_IMAGE_COLOR_NONE) {
if (color_buffer != NULL) {
icetRaiseError(
"Given a color buffer when color format is set to none.",
ICET_INVALID_VALUE);
}
} else {
if (color_buffer == NULL) {
icetRaiseError(
"Not given a color buffer when color format requires one.",
ICET_INVALID_VALUE);
}
}
if (icetImageGetDepthFormat(image) == ICET_IMAGE_DEPTH_NONE) {
if (depth_buffer != NULL) {
icetRaiseError(
"Given a depth buffer when depth format is set to none.",
ICET_INVALID_VALUE);
}
} else {
if (depth_buffer == NULL) {
icetRaiseError(
"Not given a depth buffer when depth format requires one.",
ICET_INVALID_VALUE);
}
}
{
const IceTVoid **data = ICET_IMAGE_DATA(image);
data[0] = color_buffer;
data[1] = depth_buffer;
}
return image;
}
IceTImage icetImageNull(void)
{
IceTImage image;
......@@ -584,11 +665,14 @@ void icetImageSetDimensions(IceTImage image,
ICET_IMAGE_HEADER(image)[ICET_IMAGE_WIDTH_INDEX] = (IceTInt)width;
ICET_IMAGE_HEADER(image)[ICET_IMAGE_HEIGHT_INDEX] = (IceTInt)height;
ICET_IMAGE_HEADER(image)[ICET_IMAGE_ACTUAL_BUFFER_SIZE_INDEX]
= (IceTInt)icetImageBufferSizeType(icetImageGetColorFormat(image),
icetImageGetDepthFormat(image),
width,
height);
if ( ICET_IMAGE_HEADER(image)[ICET_IMAGE_MAGIC_NUM_INDEX]
== ICET_IMAGE_MAGIC_NUM) {
ICET_IMAGE_HEADER(image)[ICET_IMAGE_ACTUAL_BUFFER_SIZE_INDEX]
= (IceTInt)icetImageBufferSizeType(icetImageGetColorFormat(image),
icetImageGetDepthFormat(image),
width,
height);
}
}
void icetSparseImageSetDimensions(IceTSparseImage image,
......@@ -638,12 +722,29 @@ const IceTVoid *icetImageGetColorConstVoid(const IceTImage image,
*pixel_size = colorPixelSize(color_format);
}
return ICET_IMAGE_DATA(image);
switch (ICET_IMAGE_HEADER(image)[ICET_IMAGE_MAGIC_NUM_INDEX]) {
case ICET_IMAGE_MAGIC_NUM:
return ICET_IMAGE_DATA(image);
case ICET_IMAGE_POINTERS_MAGIC_NUM:
return ((const IceTVoid **)ICET_IMAGE_DATA(image))[0];
default:
icetRaiseError("Detected invalid image header.",
ICET_SANITY_CHECK_FAIL);
return NULL;
}
}
IceTVoid *icetImageGetColorVoid(IceTImage image, IceTSizeType *pixel_size)
{
const IceTVoid *const_buffer = icetImageGetColorConstVoid(image, pixel_size);
/* Raise an exception for images made of pointers, which we set as constant
* since all internally made pointers are single buffers. */
if ( ICET_IMAGE_HEADER(image)[ICET_IMAGE_MAGIC_NUM_INDEX]
== ICET_IMAGE_POINTERS_MAGIC_NUM) {
icetRaiseError("Images of pointers are for reading only.",
ICET_SANITY_CHECK_FAIL);
}
/* This const cast is OK because we actually got the pointer from a
non-const image. */
return (IceTVoid *)const_buffer;
......@@ -663,11 +764,15 @@ const IceTUByte *icetImageGetColorcub(const IceTImage image)
}
IceTUByte *icetImageGetColorub(IceTImage image)
{
const IceTUByte *const_buffer = icetImageGetColorcub(image);
IceTEnum color_format = icetImageGetColorFormat(image);
/* This const cast is OK because we actually got the pointer from a
non-const image. */
return (IceTUByte *)const_buffer;
if (color_format != ICET_IMAGE_COLOR_RGBA_UBYTE) {
icetRaiseError("Color format is not of type ubyte.",
ICET_INVALID_OPERATION);
return NULL;
}
return icetImageGetColorVoid(image, NULL);
}
const IceTUInt *icetImageGetColorcui(const IceTImage image)
{
......@@ -691,38 +796,59 @@ const IceTFloat *icetImageGetColorcf(const IceTImage image)
}
IceTFloat *icetImageGetColorf(IceTImage image)
{
const IceTFloat *const_buffer = icetImageGetColorcf(image);
IceTEnum color_format = icetImageGetColorFormat(image);
if (color_format != ICET_IMAGE_COLOR_RGBA_FLOAT) {
icetRaiseError("Color format is not of type float.",
ICET_INVALID_OPERATION);
return NULL;
}
/* This const cast is OK because we actually got the pointer from a
non-const image. */
return (IceTFloat *)const_buffer;
return icetImageGetColorVoid(image, NULL);
}
const IceTVoid *icetImageGetDepthConstVoid(const IceTImage image,
IceTSizeType *pixel_size)
{
IceTEnum color_format = icetImageGetColorFormat(image);
IceTSizeType color_format_bytes;
const IceTByte *image_data_pointer;
if (pixel_size) {
IceTEnum depth_format = icetImageGetDepthFormat(image);
*pixel_size = depthPixelSize(depth_format);
}
color_format_bytes = ( icetImageGetNumPixels(image)
* colorPixelSize(color_format) );
switch (ICET_IMAGE_HEADER(image)[ICET_IMAGE_MAGIC_NUM_INDEX]) {
case ICET_IMAGE_MAGIC_NUM:
{
IceTSizeType color_format_bytes = ( icetImageGetNumPixels(image)
* colorPixelSize(color_format) );
/* Cast to IceTByte to ensure pointer arithmetic is correct. */
image_data_pointer = (const IceTByte*)ICET_IMAGE_DATA(image);
/* Cast to IceTByte to ensure pointer arithmetic is correct. */
const IceTByte *image_data_pointer =
(const IceTByte*)ICET_IMAGE_DATA(image);
return image_data_pointer + color_format_bytes;
return image_data_pointer + color_format_bytes;
}
case ICET_IMAGE_POINTERS_MAGIC_NUM:
return ((const IceTVoid **)ICET_IMAGE_DATA(image))[0];
default:
icetRaiseError("Detected invalid image header.",
ICET_SANITY_CHECK_FAIL);
return NULL;
}
}
IceTVoid *icetImageGetDepthVoid(IceTImage image, IceTSizeType *pixel_size)
{
const IceTVoid *const_buffer =icetImageGetDepthConstVoid(image, pixel_size);
/* Raise an exception for images made of pointers, which we set as constant
* since all internally made pointers are single buffers. */
if ( ICET_IMAGE_HEADER(image)[ICET_IMAGE_MAGIC_NUM_INDEX]
== ICET_IMAGE_POINTERS_MAGIC_NUM) {
icetRaiseError("Images of pointers are for reading only.",
ICET_SANITY_CHECK_FAIL);
}
/* This const cast is OK because we actually got the pointer from a
non-const image. */
return (IceTVoid *)const_buffer;
......@@ -741,12 +867,15 @@ const IceTFloat *icetImageGetDepthcf(const IceTImage image)
}
IceTFloat *icetImageGetDepthf(IceTImage image)
{
const IceTFloat *const_buffer = icetImageGetDepthcf(image);
IceTEnum depth_format = icetImageGetDepthFormat(image);
if (depth_format != ICET_IMAGE_DEPTH_FLOAT) {
icetRaiseError("Depth format is not of type float.",
ICET_INVALID_OPERATION);
return NULL;
}
/* This const cast is OK because we actually got the pointer from a
non-const image. */
return (IceTFloat *)const_buffer;
return icetImageGetDepthVoid(image, NULL);
}
void icetImageCopyColorub(const IceTImage image,
......@@ -1096,6 +1225,14 @@ void icetImagePackageForSend(IceTImage image,
*buffer = image.opaque_internals;
*size = ICET_IMAGE_HEADER(image)[ICET_IMAGE_ACTUAL_BUFFER_SIZE_INDEX];
if (*size < 0) {
/* Images of pointers have less than zero size to alert they are not
* real buffers. */
icetRaiseError(
"Attempting to package an image that is not a single buffer.",
ICET_SANITY_CHECK_FAIL);
}
if (*size != icetImageBufferSizeType(icetImageGetColorFormat(image),
icetImageGetDepthFormat(image),
icetImageGetWidth(image),
......
......@@ -23,9 +23,9 @@ extern "C" {
#define ICET_SRC_ON_TOP ICET_TRUE
#define ICET_DEST_ON_TOP ICET_FALSE
ICET_EXPORT IceTImage icetGetStateBufferImage(IceTEnum pname,
IceTSizeType width,
IceTSizeType height);
ICET_EXPORT IceTImage icetGetStateBufferImage(IceTEnum pname,
IceTSizeType width,
IceTSizeType height);
ICET_EXPORT IceTSizeType icetImageBufferSize(IceTSizeType width,
IceTSizeType height);
ICET_EXPORT IceTSizeType icetImageBufferSizeType(IceTEnum color_format,
......@@ -35,6 +35,17 @@ ICET_EXPORT IceTSizeType icetImageBufferSizeType(IceTEnum color_format,
ICET_EXPORT IceTImage icetImageAssignBuffer(IceTVoid *buffer,
IceTSizeType width,
IceTSizeType height);
ICET_EXPORT IceTImage icetGetStatePointerImage(IceTEnum pname,
IceTSizeType width,
IceTSizeType height,
const IceTVoid *color_buffer,
const IceTVoid *depth_buffer);
ICET_EXPORT IceTSizeType icetImagePointerBufferSize(void);
ICET_EXPORT IceTImage icetImagePointerAssignBuffer(IceTVoid *buffer,
IceTSizeType width,
IceTSizeType height,
const IceTVoid *color_buf,
const IceTVoid *depth_buf);
ICET_EXPORT void icetImageAdjustForOutput(IceTImage image);
ICET_EXPORT void icetImageAdjustForInput(IceTImage image);
ICET_EXPORT void icetImageSetDimensions(IceTImage image,
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment