added _mesa_unconvert_teximage()
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
/* $Id: texutil.c,v 1.1 2000/03/24 20:54:21 brianp Exp $ */
|
||||
/* $Id: texutil.c,v 1.2 2000/03/27 18:56:26 brianp Exp $ */
|
||||
|
||||
/*
|
||||
* Mesa 3-D graphics library
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "all.h"
|
||||
#else
|
||||
#include "glheader.h"
|
||||
#include "context.h"
|
||||
#include "image.h"
|
||||
#include "mem.h"
|
||||
#include "texutil.h"
|
||||
@@ -535,3 +536,285 @@ _mesa_convert_teximage(MesaIntTexFormat dstFormat,
|
||||
}
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Used to convert 16-bit texels into GLubyte color components.
|
||||
*/
|
||||
static GLubyte R5G6B5toRed[0xffff];
|
||||
static GLubyte R5G6B5toGreen[0xffff];
|
||||
static GLubyte R5G6B5toBlue[0xffff];
|
||||
|
||||
static GLubyte A4R4G4B4toRed[0xffff];
|
||||
static GLubyte A4R4G4B4toGreen[0xffff];
|
||||
static GLubyte A4R4G4B4toBlue[0xffff];
|
||||
static GLubyte A4R4G4B4toAlpha[0xffff];
|
||||
|
||||
static GLubyte A1R5G5B5toRed[0xffff];
|
||||
static GLubyte A1R5G5B5toGreen[0xffff];
|
||||
static GLubyte A1R5G5B5toBlue[0xffff];
|
||||
static GLubyte A1R5G5B5toAlpha[0xffff];
|
||||
|
||||
static void
|
||||
generate_lookup_tables(void)
|
||||
{
|
||||
GLint i;
|
||||
for (i = 0; i <= 0xffff; i++) {
|
||||
GLint r = (i >> 8) & 0xf8;
|
||||
GLint g = (i >> 3) & 0xfc;
|
||||
GLint b = (i << 3) & 0xf8;
|
||||
r = r * 255 / 0xf8;
|
||||
g = g * 255 / 0xfc;
|
||||
b = b * 255 / 0xf8;
|
||||
R5G6B5toRed[i] = r;
|
||||
R5G6B5toGreen[i] = g;
|
||||
R5G6B5toBlue[i] = b;
|
||||
}
|
||||
|
||||
for (i = 0; i <= 0xffff; i++) {
|
||||
GLint r = (i >> 8) & 0xf;
|
||||
GLint g = (i >> 4) & 0xf;
|
||||
GLint b = (i ) & 0xf;
|
||||
GLint a = (i >> 12) & 0xf;
|
||||
r = r * 255 / 0xf;
|
||||
g = g * 255 / 0xf;
|
||||
b = b * 255 / 0xf;
|
||||
a = a * 255 / 0xf;
|
||||
A4R4G4B4toRed[i] = r;
|
||||
A4R4G4B4toGreen[i] = g;
|
||||
A4R4G4B4toBlue[i] = b;
|
||||
A4R4G4B4toAlpha[i] = b;
|
||||
}
|
||||
|
||||
for (i = 0; i <= 0xffff; i++) {
|
||||
GLint r = (i >> 10) & 0xf8;
|
||||
GLint g = (i >> 5) & 0xf8;
|
||||
GLint b = (i ) & 0xf8;
|
||||
GLint a = (i >> 15) & 0x1;
|
||||
r = r * 255 / 0xf8;
|
||||
g = g * 255 / 0xf8;
|
||||
b = b * 255 / 0xf8;
|
||||
a = a * 255;
|
||||
A1R5G5B5toRed[i] = r;
|
||||
A1R5G5B5toGreen[i] = g;
|
||||
A1R5G5B5toBlue[i] = b;
|
||||
A1R5G5B5toAlpha[i] = b;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Convert a texture image from an internal format to one of Mesa's
|
||||
* core internal formats. This is likely to be used by glGetTexImage
|
||||
* and for fetching texture images when falling back to software rendering.
|
||||
*
|
||||
* Notes:
|
||||
* This function will do power of two image down-scaling to accomodate
|
||||
* drivers with limited texture image aspect ratios.
|
||||
* The implicit dest data type is GL_UNSIGNED_BYTE.
|
||||
*/
|
||||
void
|
||||
_mesa_unconvert_teximage(MesaIntTexFormat srcFormat,
|
||||
GLint srcWidth, GLint srcHeight,
|
||||
const GLvoid *srcImage,
|
||||
GLsizei dstWidth, GLsizei dstHeight,
|
||||
GLenum dstFormat, GLubyte *dstImage)
|
||||
{
|
||||
static GLboolean firstCall = GL_TRUE;
|
||||
const GLint wScale = srcWidth / dstWidth; /* must be power of two */
|
||||
const GLint hScale = srcHeight / dstHeight; /* must be power of two */
|
||||
ASSERT(srcWidth >= dstWidth);
|
||||
ASSERT(srcHeight >= dstHeight);
|
||||
ASSERT(dstImage);
|
||||
ASSERT(srcImage);
|
||||
|
||||
if (firstCall) {
|
||||
generate_lookup_tables();
|
||||
firstCall = GL_FALSE;
|
||||
}
|
||||
|
||||
switch (srcFormat) {
|
||||
case MESA_I8:
|
||||
case MESA_L8:
|
||||
case MESA_A8:
|
||||
case MESA_C8:
|
||||
#ifdef DEBUG
|
||||
if (srcFormat == MESA_I8) {
|
||||
ASSERT(dstFormat == GL_INTENSITY);
|
||||
}
|
||||
else if (srcFormat == MESA_L8) {
|
||||
ASSERT(dstFormat == GL_LUMINANCE);
|
||||
}
|
||||
else if (srcFormat == MESA_A8) {
|
||||
ASSERT(dstFormat == GL_ALPHA);
|
||||
}
|
||||
else if (srcFormat == MESA_C8) {
|
||||
ASSERT(dstFormat == GL_COLOR_INDEX);
|
||||
}
|
||||
#endif
|
||||
if (wScale == 1 && hScale == 1) {
|
||||
/* easy! */
|
||||
MEMCPY(dstImage, srcImage, dstWidth * dstHeight * sizeof(GLubyte));
|
||||
}
|
||||
else {
|
||||
/* rescale */
|
||||
const GLubyte *src8 = (const GLubyte *) srcImage;
|
||||
GLint row, col;
|
||||
for (row = 0; row < dstHeight; row++) {
|
||||
GLint srcRow = row * hScale;
|
||||
for (col = 0; col < dstWidth; col++) {
|
||||
GLint srcCol = col * wScale;
|
||||
*dstImage++ = src8[srcRow * srcWidth + srcCol];
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case MESA_L8_A8:
|
||||
ASSERT(dstFormat == GL_LUMINANCE_ALPHA);
|
||||
if (wScale == 1 && hScale == 1) {
|
||||
GLint i, n = dstWidth * dstHeight;
|
||||
const GLushort *texel = (const GLushort *) srcImage;
|
||||
for (i = 0; i < n; i++) {
|
||||
const GLushort tex = *texel++;
|
||||
*dstImage++ = (tex >> 8); /* luminance */
|
||||
*dstImage++ = (tex & 0xff); /* alpha */
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* rescale */
|
||||
const GLushort *src16 = (const GLushort *) srcImage;
|
||||
GLint row, col;
|
||||
for (row = 0; row < dstHeight; row++) {
|
||||
GLint srcRow = row * hScale;
|
||||
for (col = 0; col < dstWidth; col++) {
|
||||
GLint srcCol = col * wScale;
|
||||
const GLushort tex = src16[srcRow * srcWidth + srcCol];
|
||||
*dstImage++ = (tex >> 8); /* luminance */
|
||||
*dstImage++ = (tex & 0xff); /* alpha */
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case MESA_R5_G6_B5:
|
||||
ASSERT(dstFormat == GL_RGB);
|
||||
if (wScale == 1 && hScale == 1) {
|
||||
GLint i, n = dstWidth * dstHeight;
|
||||
const GLushort *texel = (const GLushort *) srcImage;
|
||||
for (i = 0; i < n; i++) {
|
||||
const GLushort tex = *texel++;
|
||||
*dstImage++ = R5G6B5toRed[tex];
|
||||
*dstImage++ = R5G6B5toGreen[tex];
|
||||
*dstImage++ = R5G6B5toBlue[tex];
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* rescale */
|
||||
const GLushort *src16 = (const GLushort *) srcImage;
|
||||
GLint row, col;
|
||||
for (row = 0; row < dstHeight; row++) {
|
||||
GLint srcRow = row * hScale;
|
||||
for (col = 0; col < dstWidth; col++) {
|
||||
GLint srcCol = col * wScale;
|
||||
const GLushort tex = src16[srcRow * srcWidth + srcCol];
|
||||
*dstImage++ = R5G6B5toRed[tex];
|
||||
*dstImage++ = R5G6B5toGreen[tex];
|
||||
*dstImage++ = R5G6B5toBlue[tex];
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case MESA_A4_R4_G4_B4:
|
||||
ASSERT(dstFormat == GL_RGBA);
|
||||
if (wScale == 1 && hScale == 1) {
|
||||
GLint i, n = dstWidth * dstHeight;
|
||||
const GLushort *texel = (const GLushort *) srcImage;
|
||||
for (i = 0; i < n; i++) {
|
||||
const GLushort tex = *texel++;
|
||||
*dstImage++ = A4R4G4B4toRed[tex];
|
||||
*dstImage++ = A4R4G4B4toGreen[tex];
|
||||
*dstImage++ = A4R4G4B4toBlue[tex];
|
||||
*dstImage++ = A4R4G4B4toAlpha[tex];
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* rescale */
|
||||
const GLushort *src16 = (const GLushort *) srcImage;
|
||||
GLint row, col;
|
||||
for (row = 0; row < dstHeight; row++) {
|
||||
GLint srcRow = row * hScale;
|
||||
for (col = 0; col < dstWidth; col++) {
|
||||
GLint srcCol = col * wScale;
|
||||
const GLushort tex = src16[srcRow * srcWidth + srcCol];
|
||||
*dstImage++ = A4R4G4B4toRed[tex];
|
||||
*dstImage++ = A4R4G4B4toGreen[tex];
|
||||
*dstImage++ = A4R4G4B4toBlue[tex];
|
||||
*dstImage++ = A4R4G4B4toAlpha[tex];
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case MESA_A1_R5_G5_B5:
|
||||
ASSERT(dstFormat == GL_RGBA);
|
||||
if (wScale == 1 && hScale == 1) {
|
||||
GLint i, n = dstWidth * dstHeight;
|
||||
const GLushort *texel = (const GLushort *) srcImage;
|
||||
for (i = 0; i < n; i++) {
|
||||
const GLushort tex = *texel++;
|
||||
*dstImage++ = A1R5G5B5toRed[tex];
|
||||
*dstImage++ = A1R5G5B5toGreen[tex];
|
||||
*dstImage++ = A1R5G5B5toBlue[tex];
|
||||
*dstImage++ = A1R5G5B5toAlpha[tex];
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* rescale */
|
||||
const GLushort *src16 = (const GLushort *) srcImage;
|
||||
GLint row, col;
|
||||
for (row = 0; row < dstHeight; row++) {
|
||||
GLint srcRow = row * hScale;
|
||||
for (col = 0; col < dstWidth; col++) {
|
||||
GLint srcCol = col * wScale;
|
||||
const GLushort tex = src16[srcRow * srcWidth + srcCol];
|
||||
*dstImage++ = A1R5G5B5toRed[tex];
|
||||
*dstImage++ = A1R5G5B5toGreen[tex];
|
||||
*dstImage++ = A1R5G5B5toBlue[tex];
|
||||
*dstImage++ = A1R5G5B5toAlpha[tex];
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case MESA_A8_R8_G8_B8:
|
||||
ASSERT(dstFormat == GL_RGBA);
|
||||
if (wScale == 1 && hScale == 1) {
|
||||
GLint i, n = dstWidth * dstHeight;
|
||||
const GLushort *texel = (const GLushort *) srcImage;
|
||||
for (i = 0; i < n; i++) {
|
||||
const GLuint tex = *texel++;
|
||||
*dstImage++ = (tex >> 16) & 0xff; /* R */
|
||||
*dstImage++ = (tex >> 8) & 0xff; /* G */
|
||||
*dstImage++ = (tex ) & 0xff; /* B */
|
||||
*dstImage++ = (tex >> 24) & 0xff; /* A */
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* rescale */
|
||||
const GLushort *src16 = (const GLushort *) srcImage;
|
||||
GLint row, col;
|
||||
for (row = 0; row < dstHeight; row++) {
|
||||
GLint srcRow = row * hScale;
|
||||
for (col = 0; col < dstWidth; col++) {
|
||||
GLint srcCol = col * wScale;
|
||||
const GLuint tex = src16[srcRow * srcWidth + srcCol];
|
||||
*dstImage++ = (tex >> 16) & 0xff; /* R */
|
||||
*dstImage++ = (tex >> 8) & 0xff; /* G */
|
||||
*dstImage++ = (tex ) & 0xff; /* B */
|
||||
*dstImage++ = (tex >> 24) & 0xff; /* A */
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
gl_problem(NULL, "bad srcFormat in _mesa_uncovert_teximage()");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* $Id: texutil.h,v 1.1 2000/03/24 20:54:21 brianp Exp $ */
|
||||
/* $Id: texutil.h,v 1.2 2000/03/27 18:56:26 brianp Exp $ */
|
||||
|
||||
/*
|
||||
* Mesa 3-D graphics library
|
||||
@@ -58,5 +58,13 @@ _mesa_convert_teximage(MesaIntTexFormat dstFormat,
|
||||
const struct gl_pixelstore_attrib *packing);
|
||||
|
||||
|
||||
extern void
|
||||
_mesa_unconvert_teximage(MesaIntTexFormat srcFormat,
|
||||
GLint srcWidth, GLint srcHeight,
|
||||
const GLvoid *srcImage,
|
||||
GLsizei dstWidth, GLsizei dstHeight,
|
||||
GLenum dstFormat, GLubyte *dstImage);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
Reference in New Issue
Block a user