gobj: Support integer texture formats in TexturePeeker

This commit is contained in:
rdb 2021-01-17 15:27:19 +01:00
parent 4783c2902d
commit a5a0809949
2 changed files with 173 additions and 23 deletions

View File

@ -14,6 +14,58 @@
#include "texturePeeker.h" #include "texturePeeker.h"
static double get_unsigned_byte_i(const unsigned char *&p) {
return *p++;
}
static double get_signed_byte_i(const unsigned char *&p) {
return *(signed char *)p++;
}
static double get_unsigned_short_i(const unsigned char *&p) {
union {
unsigned short us;
unsigned char uc[2];
} v;
v.uc[0] = (*p++);
v.uc[1] = (*p++);
return (double)v.us;
}
static double get_signed_short_i(const unsigned char *&p) {
union {
signed short ss;
unsigned char uc[2];
} v;
v.uc[0] = (*p++);
v.uc[1] = (*p++);
return (double)v.ss;
}
static double get_unsigned_int_i(const unsigned char *&p) {
union {
unsigned int ui;
unsigned char uc[4];
} v;
v.uc[0] = (*p++);
v.uc[1] = (*p++);
v.uc[2] = (*p++);
v.uc[3] = (*p++);
return (double)v.ui;
}
static double get_signed_int_i(const unsigned char *&p) {
union {
signed int si;
unsigned char uc[4];
} v;
v.uc[0] = (*p++);
v.uc[1] = (*p++);
v.uc[2] = (*p++);
v.uc[3] = (*p++);
return (double)v.si;
}
/** /**
* Use Texture::peek() to construct a TexturePeeker. * Use Texture::peek() to construct a TexturePeeker.
* *
@ -73,35 +125,69 @@ TexturePeeker(Texture *tex, Texture::CData *cdata) {
} }
_pixel_width = _component_width * _num_components; _pixel_width = _component_width * _num_components;
switch (_component_type) { if (Texture::is_integer(_format)) {
case Texture::T_unsigned_byte: switch (_component_type) {
_get_component = Texture::get_unsigned_byte; case Texture::T_unsigned_byte:
break; _get_component = get_unsigned_byte_i;
break;
case Texture::T_unsigned_short: case Texture::T_unsigned_short:
_get_component = Texture::get_unsigned_short; _get_component = get_unsigned_short_i;
break; break;
case Texture::T_unsigned_int: case Texture::T_unsigned_int:
_get_component = Texture::get_unsigned_int; _get_component = get_unsigned_int_i;
break; break;
case Texture::T_float: case Texture::T_byte:
_get_component = Texture::get_float; _get_component = get_signed_byte_i;
break; break;
case Texture::T_half_float: case Texture::T_short:
_get_component = Texture::get_half_float; _get_component = get_signed_short_i;
break; break;
case Texture::T_unsigned_int_24_8: case Texture::T_int:
_get_component = Texture::get_unsigned_int_24; _get_component = get_signed_int_i;
break; break;
default: default:
// Not supported. // Not supported.
_image.clear(); _image.clear();
return; return;
}
}
else {
switch (_component_type) {
case Texture::T_unsigned_byte:
_get_component = Texture::get_unsigned_byte;
break;
case Texture::T_unsigned_short:
_get_component = Texture::get_unsigned_short;
break;
case Texture::T_unsigned_int:
_get_component = Texture::get_unsigned_int;
break;
case Texture::T_float:
_get_component = Texture::get_float;
break;
case Texture::T_half_float:
_get_component = Texture::get_half_float;
break;
case Texture::T_unsigned_int_24_8:
_get_component = Texture::get_unsigned_int_24;
break;
default:
// Not supported.
_image.clear();
return;
}
} }
switch (_format) { switch (_format) {

View File

@ -94,3 +94,67 @@ def test_texture_peek_srgba():
# We allow some imprecision. # We allow some imprecision.
assert col.almost_equal((0.5, 0.5, 0.5, 188 / 255.0), 1 / 255.0) assert col.almost_equal((0.5, 0.5, 0.5, 188 / 255.0), 1 / 255.0)
def test_texture_peek_ubyte_i():
maxval = 255
data = array('B', (2, 1, 0, maxval))
peeker = peeker_from_pixel(Texture.T_unsigned_byte, Texture.F_rgba8i, data)
col = LColor()
peeker.fetch_pixel(col, 0, 0)
assert col == (0, 1, 2, maxval)
def test_texture_peek_byte_i():
minval = -128
maxval = 127
data = array('b', (0, -1, minval, maxval))
peeker = peeker_from_pixel(Texture.T_byte, Texture.F_rgba8i, data)
col = LColor()
peeker.fetch_pixel(col, 0, 0)
assert col == (minval, -1, 0, maxval)
def test_texture_peek_ushort_i():
maxval = 65535
data = array('H', (2, 1, 0, maxval))
peeker = peeker_from_pixel(Texture.T_unsigned_short, Texture.F_rgba16i, data)
col = LColor()
peeker.fetch_pixel(col, 0, 0)
assert col == (0, 1, 2, maxval)
def test_texture_peek_short_i():
minval = -32768
maxval = 32767
data = array('h', (0, -1, minval, maxval))
peeker = peeker_from_pixel(Texture.T_short, Texture.F_rgba16i, data)
col = LColor()
peeker.fetch_pixel(col, 0, 0)
assert col == (minval, -1, 0, maxval)
def test_texture_peek_uint_i():
# Highest integer that fits inside float
maxval = 2147483648
data = array('I', (2, 1, 0, maxval))
peeker = peeker_from_pixel(Texture.T_unsigned_int, Texture.F_rgba32i, data)
col = LColor()
peeker.fetch_pixel(col, 0, 0)
assert col == (0, 1, 2, maxval)
def test_texture_peek_int_i():
minval = -2147483648
maxval = 2147483647
data = array('i', (0, -1, minval, maxval))
peeker = peeker_from_pixel(Texture.T_int, Texture.F_rgba32i, data)
col = LColor()
peeker.fetch_pixel(col, 0, 0)
assert col == (minval, -1, 0, maxval)