Commit a70bb7f1 authored by Kenneth Moreland's avatar Kenneth Moreland

Add ICET_IMAGE_COLOR_RGB_FLOAT color format

Adds a color format that stores 3 channel RGB colors as floats. This is
really only good for z-buffer compositing.
parent 7feb9460
......@@ -102,6 +102,16 @@ void icetGLDrawCallbackFunction(const IceTDouble *projection_matrix,
GL_FLOAT,
colorBuffer + 4*( readback_viewport[0]
+ width*readback_viewport[1]));
} else if (color_format == ICET_IMAGE_COLOR_RGB_FLOAT) {
IceTFloat *colorBuffer = icetImageGetColorf(result);
glReadPixels((GLint)x_offset,
(GLint)y_offset,
(GLsizei)readback_viewport[2],
(GLsizei)readback_viewport[3],
GL_RGB,
GL_FLOAT,
colorBuffer + 3*( readback_viewport[0]
+ width*readback_viewport[1]));
} else if (color_format != ICET_IMAGE_COLOR_NONE) {
icetRaiseError(ICET_SANITY_CHECK_FAIL,
"Invalid color format 0x%X.", color_format);
......
......@@ -132,6 +132,41 @@
}
#define CCC_PIXEL_SIZE (5*sizeof(IceTFloat))
#include "cc_composite_template_body.h"
#undef UNPACK_PIXEL
} else if (_color_format == ICET_IMAGE_COLOR_RGB_FLOAT) {
#define UNPACK_PIXEL(pointer, color, depth) \
color = (IceTFloat *)pointer; \
pointer += 3*sizeof(IceTUInt); \
depth = (IceTFloat *)pointer; \
pointer += sizeof(IceTFloat);
#define CCC_FRONT_COMPRESSED_IMAGE FRONT_SPARSE_IMAGE
#define CCC_BACK_COMPRESSED_IMAGE BACK_SPARSE_IMAGE
#define CCC_DEST_COMPRESSED_IMAGE DEST_SPARSE_IMAGE
#define CCC_COMPOSITE(src1_pointer, src2_pointer, dest_pointer) \
{ \
const IceTFloat *src1_color; \
const IceTFloat *src1_depth; \
const IceTFloat *src2_color; \
const IceTFloat *src2_depth; \
IceTFloat *dest_color; \
IceTFloat *dest_depth; \
UNPACK_PIXEL(src1_pointer, src1_color, src1_depth); \
UNPACK_PIXEL(src2_pointer, src2_color, src2_depth); \
UNPACK_PIXEL(dest_pointer, dest_color, dest_depth); \
if (src1_depth[0] < src2_depth[0]) { \
dest_color[0] = src1_color[0]; \
dest_color[1] = src1_color[1]; \
dest_color[2] = src1_color[2]; \
dest_depth[0] = src1_depth[0]; \
} else { \
dest_color[0] = src2_color[0]; \
dest_color[1] = src2_color[1]; \
dest_color[2] = src2_color[2]; \
dest_depth[0] = src2_depth[0]; \
} \
}
#define CCC_PIXEL_SIZE (4*sizeof(IceTFloat))
#include "cc_composite_template_body.h"
#undef UNPACK_PIXEL
} else if (_color_format == ICET_IMAGE_COLOR_NONE) {
#define UNPACK_PIXEL(pointer, depth) \
......@@ -216,6 +251,10 @@
#define CCC_PIXEL_SIZE (4*sizeof(IceTFloat))
#include "cc_composite_template_body.h"
#undef UNPACK_PIXEL
} else if (_color_format == ICET_IMAGE_COLOR_RGB_FLOAT) {
icetRaiseError(
ICET_INVALID_VALUE,
"Cannot use blend composite without alpha channel");
} else if (_color_format == ICET_IMAGE_COLOR_NONE) {
icetRaiseWarning(ICET_INVALID_OPERATION,
"Compositing image with no data.");
......
......@@ -207,6 +207,48 @@
#define CT_FULL_WIDTH FULL_WIDTH
#define CT_FULL_HEIGHT FULL_HEIGHT
#endif
#include "compress_template_body.h"
} else if (_color_format == ICET_IMAGE_COLOR_RGB_FLOAT) {
const IceTFloat *_color;
IceTFloat *_out;
#ifdef REGION
IceTSizeType _region_count = 0;
#endif
_color = icetImageGetColorcf(INPUT_IMAGE);
#ifdef OFFSET
_color += 3*(OFFSET);
#endif
#define CT_COMPRESSED_IMAGE OUTPUT_SPARSE_IMAGE
#define CT_COLOR_FORMAT _color_format
#define CT_DEPTH_FORMAT _depth_format
#define CT_PIXEL_COUNT _pixel_count
#define CT_ACTIVE() (_depth[0] < 1.0)
#define CT_WRITE_PIXEL(dest) _out = (IceTFloat *)dest; \
_out[0] = _color[0]; \
_out[1] = _color[1]; \
_out[2] = _color[2]; \
_out[3] = _depth[0]; \
dest += 4*sizeof(IceTFloat);
#ifdef REGION
#define CT_INCREMENT_PIXEL() _color += 3; _depth++; \
_region_count++; \
if (_region_count >= _region_width) { \
_color += 3*_region_x_skip; \
_depth += _region_x_skip; \
_region_count = 0; \
}
#else
#define CT_INCREMENT_PIXEL() _color += 3; _depth++;
#endif
#ifdef PADDING
#define CT_PADDING
#define CT_SPACE_BOTTOM SPACE_BOTTOM
#define CT_SPACE_TOP SPACE_TOP
#define CT_SPACE_LEFT SPACE_LEFT
#define CT_SPACE_RIGHT SPACE_RIGHT
#define CT_FULL_WIDTH FULL_WIDTH
#define CT_FULL_HEIGHT FULL_HEIGHT
#endif
#include "compress_template_body.h"
} else if (_color_format == ICET_IMAGE_COLOR_NONE) {
IceTFloat *_out;
......@@ -341,6 +383,16 @@
#define CT_FULL_HEIGHT FULL_HEIGHT
#endif
#include "compress_template_body.h"
} else if (_color_format == ICET_IMAGE_COLOR_RGB_FLOAT) {
IceTUInt *_out;
icetRaiseError(
ICET_INVALID_VALUE,
"Compressing image for blending with no alpha channel.");
_out = ICET_IMAGE_DATA(OUTPUT_SPARSE_IMAGE);
INACTIVE_RUN_LENGTH(_out) = _pixel_count;
ACTIVE_RUN_LENGTH(_out) = 0;
_out++;
icetSparseImageSetActualSize(OUTPUT_SPARSE_IMAGE, _out);
} else if (_color_format == ICET_IMAGE_COLOR_NONE) {
IceTUInt *_out;
icetRaiseWarning(ICET_INVALID_OPERATION,
......
......@@ -204,6 +204,56 @@
}
#endif
#include "decompress_template_body.h"
#undef COPY_PIXEL
} else if (_color_format == ICET_IMAGE_COLOR_RGB_FLOAT) {
IceTFloat *_color;
const IceTFloat *_c_in;
const IceTFloat *_d_in;
IceTFloat _background_color[4];
_color = icetImageGetColorf(OUTPUT_IMAGE);
#ifdef OFFSET
_color += 3*(OFFSET);
#endif
icetGetFloatv(ICET_BACKGROUND_COLOR, _background_color);
#ifdef COMPOSITE
#define COPY_PIXEL(c_src, c_dest, d_src, d_dest) \
if (d_src[0] < d_dest[0]) { \
c_dest[0] = c_src[0]; \
c_dest[1] = c_src[1]; \
c_dest[2] = c_src[2]; \
d_dest[0] = d_src[0]; \
}
#else
#define COPY_PIXEL(c_src, c_dest, d_src, d_dest) \
c_dest[0] = c_src[0]; \
c_dest[1] = c_src[1]; \
c_dest[2] = c_src[2]; \
d_dest[0] = d_src[0];
#endif
#define DT_COMPRESSED_IMAGE INPUT_SPARSE_IMAGE
#define DT_READ_PIXEL(src) _c_in = (IceTFloat *)src; \
src += 3*sizeof(IceTFloat); \
_d_in = (IceTFloat *)src; \
src += sizeof(IceTFloat); \
COPY_PIXEL(_c_in, _color, \
_d_in, _depth); \
_color += 3; _depth++;
#ifdef COMPOSITE
#define DT_INCREMENT_INACTIVE_PIXELS(count) _color += 3*count; _depth += count;
#else
#define DT_INCREMENT_INACTIVE_PIXELS(count) \
{ \
IceTSizeType __i; \
for (__i = 0; __i < count; __i++) { \
_color[0] =_background_color[0];\
_color[1] =_background_color[1];\
_color[2] =_background_color[2];\
_color += 3; \
*(_depth++) = 1.0f; \
} \
}
#endif
#include "decompress_template_body.h"
#undef COPY_PIXEL
} else if (_color_format == ICET_IMAGE_COLOR_NONE) {
const IceTFloat *_d_in;
......@@ -346,6 +396,44 @@
}
#endif
#include "decompress_template_body.h"
#undef COPY_PIXEL
} else if (_color_format == ICET_IMAGE_COLOR_RGB_FLOAT) {
IceTFloat *_color;
const IceTFloat *_c_in;
IceTFloat _background_color[4];
_color = icetImageGetColorf(OUTPUT_IMAGE);
#ifdef OFFSET
_color += 3*(OFFSET);
#endif
#ifdef CORRECT_BACKGROUND
icetGetFloatv(ICET_TRUE_BACKGROUND_COLOR, _background_color);
#else
icetGetFloatv(ICET_BACKGROUND_COLOR, _background_color);
#endif
#define COPY_PIXEL(c_src, c_dest) \
c_dest[0] = c_src[0]; \
c_dest[1] = c_src[1]; \
c_dest[2] = c_src[2];
#define DT_COMPRESSED_IMAGE INPUT_SPARSE_IMAGE
#define DT_READ_PIXEL(src) _c_in = (IceTFloat *)src; \
src += 3*sizeof(IceTFloat); \
COPY_PIXEL(_c_in, _color); \
_color += 3;
#ifdef COMPOSITE
#define DT_INCREMENT_INACTIVE_PIXELS(count) _color += 3*count;
#else
#define DT_INCREMENT_INACTIVE_PIXELS(count) \
{ \
IceTSizeType __i; \
for (__i = 0; __i < count; __i++) { \
_color[0] =_background_color[0];\
_color[1] =_background_color[1];\
_color[2] =_background_color[2];\
_color += 3; \
} \
}
#endif
#include "decompress_template_body.h"
#undef COPY_PIXEL
} else if (_color_format == ICET_IMAGE_COLOR_NONE) {
icetRaiseWarning(ICET_INVALID_OPERATION,
......
......@@ -238,6 +238,7 @@ static IceTSizeType colorPixelSize(IceTEnum color_format)
switch (color_format) {
case ICET_IMAGE_COLOR_RGBA_UBYTE: return 4;
case ICET_IMAGE_COLOR_RGBA_FLOAT: return 4*sizeof(IceTFloat);
case ICET_IMAGE_COLOR_RGB_FLOAT: return 3*sizeof(IceTFloat);
case ICET_IMAGE_COLOR_NONE: return 0;
default:
icetRaiseError(ICET_INVALID_ENUM,
......@@ -387,6 +388,7 @@ IceTImage icetImageAssignBuffer(IceTVoid *buffer,
if ( (color_format != ICET_IMAGE_COLOR_RGBA_UBYTE)
&& (color_format != ICET_IMAGE_COLOR_RGBA_FLOAT)
&& (color_format != ICET_IMAGE_COLOR_RGB_FLOAT)
&& (color_format != ICET_IMAGE_COLOR_NONE) ) {
icetRaiseError(ICET_INVALID_ENUM,
"Invalid color format 0x%X.", color_format);
......@@ -522,6 +524,7 @@ IceTSparseImage icetSparseImageAssignBuffer(IceTVoid *buffer,
if ( (color_format != ICET_IMAGE_COLOR_RGBA_UBYTE)
&& (color_format != ICET_IMAGE_COLOR_RGBA_FLOAT)
&& (color_format != ICET_IMAGE_COLOR_RGB_FLOAT)
&& (color_format != ICET_IMAGE_COLOR_NONE) ) {
icetRaiseError(ICET_INVALID_ENUM,
"Invalid color format 0x%X.", color_format);
......@@ -828,7 +831,8 @@ const IceTFloat *icetImageGetColorcf(const IceTImage image)
{
IceTEnum color_format = icetImageGetColorFormat(image);
if (color_format != ICET_IMAGE_COLOR_RGBA_FLOAT) {
if ( (color_format != ICET_IMAGE_COLOR_RGBA_FLOAT)
&& (color_format != ICET_IMAGE_COLOR_RGB_FLOAT)) {
icetRaiseError(ICET_INVALID_OPERATION,
"Color format 0x%X is not of type float.",
color_format);
......@@ -841,7 +845,8 @@ IceTFloat *icetImageGetColorf(IceTImage image)
{
IceTEnum color_format = icetImageGetColorFormat(image);
if (color_format != ICET_IMAGE_COLOR_RGBA_FLOAT) {
if ( (color_format != ICET_IMAGE_COLOR_RGBA_FLOAT)
&& (color_format != ICET_IMAGE_COLOR_RGB_FLOAT)) {
icetRaiseError(ICET_INVALID_OPERATION,
"Color format 0x%X is not of type float.",
color_format);
......@@ -958,6 +963,21 @@ void icetImageCopyColorub(const IceTImage image,
i++, in++, out++) {
out[0] = (IceTUByte)(255*in[0]);
}
} else if ( (in_color_format == ICET_IMAGE_COLOR_RGB_FLOAT)
&& (out_color_format == ICET_IMAGE_COLOR_RGBA_UBYTE) ) {
const IceTFloat *in_buffer = icetImageGetColorcf(image);
IceTSizeType num_pixels = icetImageGetNumPixels(image);
IceTSizeType i;
const IceTFloat *in = in_buffer;
IceTUByte *out = color_buffer;
for (i = 0; i < num_pixels; i++) {
out[0] = (IceTUByte)(255*in[0]);
out[1] = (IceTUByte)(255*in[1]);
out[2] = (IceTUByte)(255*in[2]);
out[3] = (IceTUByte)255;
in += 3;
out += 4;
}
} else {
icetRaiseError(ICET_SANITY_CHECK_FAIL,
"Encountered unexpected color format combination "
......@@ -972,7 +992,8 @@ void icetImageCopyColorf(const IceTImage image,
{
IceTEnum in_color_format = icetImageGetColorFormat(image);
if (out_color_format != ICET_IMAGE_COLOR_RGBA_FLOAT) {
if ( (out_color_format != ICET_IMAGE_COLOR_RGBA_FLOAT)
&& (out_color_format != ICET_IMAGE_COLOR_RGB_FLOAT)) {
icetRaiseError(ICET_INVALID_ENUM,
"Color format 0x%X is not of type float.",
out_color_format);
......@@ -1000,6 +1021,49 @@ void icetImageCopyColorf(const IceTImage image,
i++, in++, out++) {
out[0] = (IceTFloat)in[0]/255.0f;
}
} else if ( (in_color_format == ICET_IMAGE_COLOR_RGBA_UBYTE)
&& (out_color_format == ICET_IMAGE_COLOR_RGB_FLOAT) ) {
const IceTUByte *in_buffer = icetImageGetColorcub(image);
IceTSizeType num_pixels = icetImageGetNumPixels(image);
IceTSizeType i;
const IceTUByte *in = in_buffer;
IceTFloat *out = color_buffer;
for (i = 0; i < num_pixels; i++) {
out[0] = (IceTFloat)in[0]/255.0f;
out[1] = (IceTFloat)in[1]/255.0f;
out[2] = (IceTFloat)in[2]/255.0f;
in += 4;
out += 3;
}
} else if ( (in_color_format == ICET_IMAGE_COLOR_RGBA_FLOAT)
&& (out_color_format == ICET_IMAGE_COLOR_RGB_FLOAT) ) {
const IceTFloat *in_buffer = icetImageGetColorcf(image);
IceTSizeType num_pixels = icetImageGetNumPixels(image);
IceTSizeType i;
const IceTFloat *in = in_buffer;
IceTFloat *out = color_buffer;
for (i = 0; i < num_pixels; i++) {
out[0] = (IceTFloat)in[0];
out[1] = (IceTFloat)in[1];
out[2] = (IceTFloat)in[2];
in += 4;
out += 3;
}
} else if ( (in_color_format == ICET_IMAGE_COLOR_RGB_FLOAT)
&& (out_color_format == ICET_IMAGE_COLOR_RGBA_FLOAT) ) {
const IceTFloat *in_buffer = icetImageGetColorcf(image);
IceTSizeType num_pixels = icetImageGetNumPixels(image);
IceTSizeType i;
const IceTFloat *in = in_buffer;
IceTFloat *out = color_buffer;
for (i = 0; i < num_pixels; i++) {
out[0] = (IceTFloat)in[0];
out[1] = (IceTFloat)in[1];
out[2] = (IceTFloat)in[2];
out[3] = 1.0f;
in += 3;
out += 4;
}
} else {
icetRaiseError(ICET_SANITY_CHECK_FAIL,
"Unexpected format combination "
......@@ -1236,6 +1300,43 @@ void icetImageClearAroundRegion(IceTImage image, const IceTInt *region)
color_buffer[4*(y*width + x) + 3] = background_color[3];
}
}
} else if (color_format == ICET_IMAGE_COLOR_RGB_FLOAT) {
IceTFloat *color_buffer = icetImageGetColorf(image);
IceTFloat background_color[4];
icetGetFloatv(ICET_BACKGROUND_COLOR, background_color);
/* Clear out bottom. */
for (y = 0; y < region[1]; y++) {
for (x = 0; x < width; x++) {
color_buffer[3*(y*width + x) + 0] = background_color[0];
color_buffer[3*(y*width + x) + 1] = background_color[1];
color_buffer[3*(y*width + x) + 2] = background_color[2];
}
}
/* Clear out left and right. */
if ((region[0] > 0) || (region[0]+region[2] < width)) {
for (y = region[1]; y < region[1]+region[3]; y++) {
for (x = 0; x < region[0]; x++) {
color_buffer[3*(y*width + x) + 0] = background_color[0];
color_buffer[3*(y*width + x) + 1] = background_color[1];
color_buffer[3*(y*width + x) + 2] = background_color[2];
}
for (x = region[0]+region[2]; x < width; x++) {
color_buffer[3*(y*width + x) + 0] = background_color[0];
color_buffer[3*(y*width + x) + 1] = background_color[1];
color_buffer[3*(y*width + x) + 2] = background_color[2];
}
}
}
/* Clear out top. */
for (y = region[1]+region[3]; y < height; y++) {
for (x = 0; x < width; x++) {
color_buffer[3*(y*width + x) + 0] = background_color[0];
color_buffer[3*(y*width + x) + 1] = background_color[1];
color_buffer[3*(y*width + x) + 2] = background_color[2];
}
}
} else if (color_format != ICET_IMAGE_COLOR_NONE) {
icetRaiseError(ICET_SANITY_CHECK_FAIL,
"Invalid color format 0x%X.", color_format);
......@@ -1320,6 +1421,7 @@ IceTImage icetImageUnpackageFromReceive(IceTVoid *buffer)
color_format = icetImageGetColorFormat(image);
if ( (color_format != ICET_IMAGE_COLOR_RGBA_UBYTE)
&& (color_format != ICET_IMAGE_COLOR_RGBA_FLOAT)
&& (color_format != ICET_IMAGE_COLOR_RGB_FLOAT)
&& (color_format != ICET_IMAGE_COLOR_NONE) ) {
icetRaiseError(ICET_INVALID_VALUE,
"Invalid image buffer: invalid color format 0x%X.",
......@@ -1408,6 +1510,7 @@ IceTSparseImage icetSparseImageUnpackageFromReceive(IceTVoid *buffer)
color_format = icetSparseImageGetColorFormat(image);
if ( (color_format != ICET_IMAGE_COLOR_RGBA_UBYTE)
&& (color_format != ICET_IMAGE_COLOR_RGBA_FLOAT)
&& (color_format != ICET_IMAGE_COLOR_RGB_FLOAT)
&& (color_format != ICET_IMAGE_COLOR_NONE) ) {
icetRaiseError(ICET_INVALID_VALUE,
"Invalid image buffer: invalid color format 0x%X.",
......@@ -2058,6 +2161,7 @@ void icetSetColorFormat(IceTEnum color_format)
if ( (color_format == ICET_IMAGE_COLOR_RGBA_UBYTE)
|| (color_format == ICET_IMAGE_COLOR_RGBA_FLOAT)
|| (color_format == ICET_IMAGE_COLOR_RGB_FLOAT)
|| (color_format == ICET_IMAGE_COLOR_NONE) ) {
icetStateSetInteger(ICET_COLOR_FORMAT, color_format);
} else {
......@@ -2317,6 +2421,17 @@ void icetComposite(IceTImage destBuffer, const IceTImage srcBuffer,
destColorBuffer[4*i+3] = srcColorBuffer[4*i+3];
}
}
} else if (color_format == ICET_IMAGE_COLOR_RGB_FLOAT) {
const IceTFloat *srcColorBuffer = icetImageGetColorf(srcBuffer);
IceTFloat *destColorBuffer = icetImageGetColorf(destBuffer);
for (i = 0; i < pixels; i++) {
if (srcDepthBuffer[i] < destDepthBuffer[i]) {
destDepthBuffer[i] = srcDepthBuffer[i];
destColorBuffer[3*i+0] = srcColorBuffer[3*i+0];
destColorBuffer[3*i+1] = srcColorBuffer[3*i+1];
destColorBuffer[3*i+2] = srcColorBuffer[3*i+2];
}
}
} else if (color_format == ICET_IMAGE_COLOR_NONE) {
for (i = 0; i < pixels; i++) {
if (srcDepthBuffer[i] < destDepthBuffer[i]) {
......@@ -2371,6 +2486,19 @@ void icetComposite(IceTImage destBuffer, const IceTImage srcBuffer,
destColorBuffer + i*4);
}
}
} else if (color_format == ICET_IMAGE_COLOR_RGB_FLOAT) {
const IceTFloat *srcColorBuffer = icetImageGetColorf(srcBuffer);
IceTFloat *destColorBuffer = icetImageGetColorf(destBuffer);
icetRaiseWarning(ICET_INVALID_VALUE,
"No alpha channel for blending. "
"On top image used.");
if (srcOnTop) {
for (i = 0; i < pixels; i++) {
destColorBuffer[3*i+0] = srcColorBuffer[3*i+0];
destColorBuffer[3*i+1] = srcColorBuffer[3*i+1];
destColorBuffer[3*i+2] = srcColorBuffer[3*i+2];
}
}
} else if (color_format == ICET_IMAGE_COLOR_NONE) {
icetRaiseWarning(ICET_INVALID_OPERATION,
"Compositing image with no data.");
......@@ -2491,6 +2619,8 @@ void icetImageCorrectBackground(IceTImage image)
ICET_UNDER_FLOAT(background_color, color);
color += 4;
}
} else if (color_format == ICET_IMAGE_COLOR_RGB_FLOAT) {
/* Nothing to fix. */
} else {
icetRaiseError(ICET_SANITY_CHECK_FAIL,
"Encountered invalid color buffer type 0x%X"
......
......@@ -172,6 +172,7 @@ typedef struct { IceTVoid *opaque_internals; } IceTImage;
#define ICET_IMAGE_COLOR_RGBA_UBYTE (IceTEnum)0xC001
#define ICET_IMAGE_COLOR_RGBA_FLOAT (IceTEnum)0xC002
#define ICET_IMAGE_COLOR_RGB_FLOAT (IceTEnum)0xC003
#define ICET_IMAGE_COLOR_NONE (IceTEnum)0xC000
#define ICET_IMAGE_DEPTH_FLOAT (IceTEnum)0xD001
......
......@@ -47,6 +47,7 @@ SET(IceTTestSrcs
BackgroundCorrect.c
CompressionSize.c
FloatingViewport.c
ImageConvert.c
Interlace.c
MaxImageSplit.c
OddImageSizes.c
......
......@@ -13,6 +13,7 @@
#include "test_util.h"
#include <IceTDevImage.h>
#include <IceTDevPorting.h>
#include <IceTDevState.h>
#include <stdlib.h>
......@@ -25,7 +26,135 @@ static IceTDouble IdentityMatrix[16] = {
0.0, 0.0, 1.0, 0.0,
0.0, 0.0, 0.0, 1.0
};
static IceTFloat Black[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
static IceTFloat Black[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
#define DIFF(x, y) ((x) < (y) ? (y) - (x) : (x) - (y))
static int compare_color_buffers(IceTImage refimage, IceTImage testimage)
{
IceTSizeType bad_pixel_count;
IceTSizeType x, y;
char filename[FILENAME_MAX];
IceTUByte *refcbuf, *cb;
IceTInt rank;
IceTSizeType local_width;
IceTSizeType local_height;
printstat("Checking returned image.\n");
icetGetIntegerv(ICET_RANK, &rank);
local_width = icetImageGetWidth(refimage);
local_height = icetImageGetHeight(refimage);
if ( (local_width != icetImageGetWidth(testimage))
|| (local_height != icetImageGetHeight(testimage)) ) {
printrank("Image dimensions not what is expected!!!!!\n");
printrank("Expected %dx%d, received %dx%d\n",
(int)local_width, (int)local_height,
(int)icetImageGetWidth(testimage),
(int)icetImageGetHeight(testimage));
return 0;
}
refcbuf = malloc(icetImageGetNumPixels(refimage)*4);
icetImageCopyColorub(refimage, refcbuf, ICET_IMAGE_COLOR_RGBA_UBYTE);
cb = malloc(icetImageGetNumPixels(testimage)*4);
icetImageCopyColorub(testimage, cb, ICET_IMAGE_COLOR_RGBA_UBYTE);
bad_pixel_count = 0;
#define CBR(x, y) (cb[(y)*local_width*4 + (x)*4 + 0])
#define CBG(x, y) (cb[(y)*local_width*4 + (x)*4 + 1])
#define CBB(x, y) (cb[(y)*local_width*4 + (x)*4 + 2])
#define CBA(x, y) (cb[(y)*local_width*4 + (x)*4 + 3])
#define REFCBUFR(x, y) (refcbuf[(y)*SCREEN_WIDTH*4 + (x)*4 + 0])
#define REFCBUFG(x, y) (refcbuf[(y)*SCREEN_WIDTH*4 + (x)*4 + 1])
#define REFCBUFB(x, y) (refcbuf[(y)*SCREEN_WIDTH*4 + (x)*4 + 2])
#define REFCBUFA(x, y) (refcbuf[(y)*SCREEN_WIDTH*4 + (x)*4 + 3])
#define CB_EQUALS_REF(x, y) \
( (DIFF(CBR((x), (y)), REFCBUFR((x), (y))) < 5) \
&& (DIFF(CBG((x), (y)), REFCBUFG((x), (y))) < 5) \
&& (DIFF(CBB((x), (y)), REFCBUFB((x), (y))) < 5) \
&& (DIFF(CBA((x), (y)), REFCBUFA((x), (y))) < 5) )
for (y = 0; y < local_height; y++) {
for (x = 0; x < local_width; x++) {
if (!CB_EQUALS_REF(x, y)) {
printrank("%d %d [%d %d %d %d] [%d %d %d %d]\n", x, y,
CBR(x, y), CBG(x,y), CBB(x,y), CBA(x,y),
REFCBUFR(x,y), REFCBUFG(x,y), REFCBUFB(x,y), REFCBUFA(x,y) );
/* Uh, oh. Pixels don't match. This could be a genuine
* error or it could be a floating point offset when
* projecting edge boundries to pixels. If the latter is the
* case, there will be very few errors. Count the errors,
* and make sure there are not too many. */
bad_pixel_count++;
}
}
}
/* Check to make sure there were not too many errors. */
if ( (bad_pixel_count > 0.001*local_width*local_height)
&& (bad_pixel_count > local_width)
&& (bad_pixel_count > local_height) )
{
/* Too many errors. Call it bad. */
printrank("Too many bad pixels!!!!!!\n");
/* Write current images. */
icetSnprintf(filename, FILENAME_MAX, "ref%03d.ppm", rank);
write_ppm(filename, refcbuf, (int)SCREEN_WIDTH, (int)SCREEN_HEIGHT);
icetSnprintf(filename, FILENAME_MAX, "bad%03d.ppm", rank);
write_ppm(filename, cb, (int)local_width, (int)local_height);
/* Write difference image. */
for (y = 0; y < local_height; y++) {
for (x = 0; x < local_width; x++) {
if (CBR(x, y) < REFCBUFR(x, y)){
CBR(x,y) = REFCBUFR(x,y) - CBR(x,y);
} else {
CBR(x,y) = CBR(x,y) - REFCBUFR(x,y);
}
if (CBG(x, y) < REFCBUFG(x, y)){
CBG(x,y) = REFCBUFG(x,y) - CBG(x,y);
} else {
CBG(x,y) = CBG(x,y) - REFCBUFG(x,y);
}
if (CBB(x, y) < REFCBUFB(x, y)){
CBB(x,y) = REFCBUFB(x,y) - CBB(x,y);
} else {
CBB(x,y) = CBB(x,y) - REFCBUFB(x,y);
}
}
}
icetSnprintf(filename, FILENAME_MAX, "diff%03d.ppm", rank);
write_ppm(filename, cb, (int)local_width, (int)local_height);
return 0;
}
#undef CBR