From e18d0f82b6271103e292fde5bab6fceccb96f90a Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 6 Oct 2006 03:49:46 +0000 Subject: deal with union/aliasing in convert_color_type() --- src/mesa/swrast/s_span.c | 64 ++++++++++++++++++++++++++++++------------------ 1 file changed, 40 insertions(+), 24 deletions(-) (limited to 'src') diff --git a/src/mesa/swrast/s_span.c b/src/mesa/swrast/s_span.c index 7ae9f7f..0adab5e 100644 --- a/src/mesa/swrast/s_span.c +++ b/src/mesa/swrast/s_span.c @@ -1212,11 +1212,15 @@ add_specular(GLcontext *ctx, SWspan *span) /** * Convert the span's color arrays to the given type. + * XXX this could be put into image.c and reused in several places. */ static void convert_color_type(GLcontext *ctx, SWspan *span, GLenum newType) { const GLubyte *mask = span->array->mask; + /* XXX NOTE: These all point to the same memory! + * We need to use temporaray storage when converting, below. + */ GLubyte (*rgba1)[4] = span->array->color.sz1.rgba; GLushort (*rgba2)[4] = span->array->color.sz2.rgba; GLfloat (*rgba4)[4] = span->array->color.sz4.rgba; @@ -1226,77 +1230,89 @@ convert_color_type(GLcontext *ctx, SWspan *span, GLenum newType) switch (span->array->ChanType) { case GL_UNSIGNED_BYTE: if (newType == GL_UNSIGNED_SHORT) { + GLushort newVals[MAX_WIDTH][4]; GLuint i; for (i = 0; i < span->end; i++) { if (mask[i]) { - rgba2[i][RCOMP] = UBYTE_TO_USHORT(rgba1[i][RCOMP]); - rgba2[i][GCOMP] = UBYTE_TO_USHORT(rgba1[i][GCOMP]); - rgba2[i][BCOMP] = UBYTE_TO_USHORT(rgba1[i][BCOMP]); - rgba2[i][ACOMP] = UBYTE_TO_USHORT(rgba1[i][ACOMP]); + newVals[i][RCOMP] = UBYTE_TO_USHORT(rgba1[i][RCOMP]); + newVals[i][GCOMP] = UBYTE_TO_USHORT(rgba1[i][GCOMP]); + newVals[i][BCOMP] = UBYTE_TO_USHORT(rgba1[i][BCOMP]); + newVals[i][ACOMP] = UBYTE_TO_USHORT(rgba1[i][ACOMP]); } } + _mesa_memcpy(rgba2, newVals, span->end * 4 * sizeof(GLushort)); } else { + GLfloat newVals[MAX_WIDTH][4]; GLuint i; ASSERT(newType == GL_FLOAT); for (i = 0; i < span->end; i++) { if (mask[i]) { - rgba4[i][RCOMP] = UBYTE_TO_FLOAT(rgba1[i][RCOMP]); - rgba4[i][GCOMP] = UBYTE_TO_FLOAT(rgba1[i][GCOMP]); - rgba4[i][BCOMP] = UBYTE_TO_FLOAT(rgba1[i][BCOMP]); - rgba4[i][ACOMP] = UBYTE_TO_FLOAT(rgba1[i][ACOMP]); + newVals[i][RCOMP] = UBYTE_TO_FLOAT(rgba1[i][RCOMP]); + newVals[i][GCOMP] = UBYTE_TO_FLOAT(rgba1[i][GCOMP]); + newVals[i][BCOMP] = UBYTE_TO_FLOAT(rgba1[i][BCOMP]); + newVals[i][ACOMP] = UBYTE_TO_FLOAT(rgba1[i][ACOMP]); } } + _mesa_memcpy(rgba4, newVals, span->end * 4 * sizeof(GLfloat)); } break; case GL_UNSIGNED_SHORT: if (newType == GL_UNSIGNED_BYTE) { + GLubyte newVals[MAX_WIDTH][4]; GLuint i; for (i = 0; i < span->end; i++) { if (mask[i]) { - rgba1[i][RCOMP] = USHORT_TO_UBYTE(rgba2[i][RCOMP]); - rgba1[i][GCOMP] = USHORT_TO_UBYTE(rgba2[i][GCOMP]); - rgba1[i][BCOMP] = USHORT_TO_UBYTE(rgba2[i][BCOMP]); - rgba1[i][ACOMP] = USHORT_TO_UBYTE(rgba2[i][ACOMP]); + newVals[i][RCOMP] = USHORT_TO_UBYTE(rgba2[i][RCOMP]); + newVals[i][GCOMP] = USHORT_TO_UBYTE(rgba2[i][GCOMP]); + newVals[i][BCOMP] = USHORT_TO_UBYTE(rgba2[i][BCOMP]); + newVals[i][ACOMP] = USHORT_TO_UBYTE(rgba2[i][ACOMP]); } } + _mesa_memcpy(rgba1, newVals, span->end * 4 * sizeof(GLubyte)); } else { + GLfloat newVals[MAX_WIDTH][4]; GLuint i; ASSERT(newType == GL_FLOAT); for (i = 0; i < span->end; i++) { if (mask[i]) { - rgba4[i][RCOMP] = USHORT_TO_FLOAT(rgba2[i][RCOMP]); - rgba4[i][GCOMP] = USHORT_TO_FLOAT(rgba2[i][GCOMP]); - rgba4[i][BCOMP] = USHORT_TO_FLOAT(rgba2[i][BCOMP]); - rgba4[i][ACOMP] = USHORT_TO_FLOAT(rgba2[i][ACOMP]); + newVals[i][RCOMP] = USHORT_TO_FLOAT(rgba2[i][RCOMP]); + newVals[i][GCOMP] = USHORT_TO_FLOAT(rgba2[i][GCOMP]); + newVals[i][BCOMP] = USHORT_TO_FLOAT(rgba2[i][BCOMP]); + newVals[i][ACOMP] = USHORT_TO_FLOAT(rgba2[i][ACOMP]); } } + _mesa_memcpy(rgba4, newVals, span->end * 4 * sizeof(GLfloat)); } break; case GL_FLOAT: if (newType == GL_UNSIGNED_BYTE) { + GLubyte newVals[MAX_WIDTH][4]; GLuint i; for (i = 0; i < span->end; i++) { if (mask[i]) { - UNCLAMPED_FLOAT_TO_UBYTE(rgba1[i][RCOMP], rgba4[i][RCOMP]); - UNCLAMPED_FLOAT_TO_UBYTE(rgba1[i][GCOMP], rgba4[i][GCOMP]); - UNCLAMPED_FLOAT_TO_UBYTE(rgba1[i][BCOMP], rgba4[i][BCOMP]); - UNCLAMPED_FLOAT_TO_UBYTE(rgba1[i][ACOMP], rgba4[i][ACOMP]); + UNCLAMPED_FLOAT_TO_UBYTE(newVals[i][RCOMP], rgba4[i][RCOMP]); + UNCLAMPED_FLOAT_TO_UBYTE(newVals[i][GCOMP], rgba4[i][GCOMP]); + UNCLAMPED_FLOAT_TO_UBYTE(newVals[i][BCOMP], rgba4[i][BCOMP]); + UNCLAMPED_FLOAT_TO_UBYTE(newVals[i][ACOMP], rgba4[i][ACOMP]); } } + _mesa_memcpy(rgba1, newVals, span->end * 4 * sizeof(GLubyte)); } else { + GLushort newVals[MAX_WIDTH][4]; GLuint i; ASSERT(newType == GL_UNSIGNED_SHORT); for (i = 0; i < span->end; i++) { if (mask[i]) { - UNCLAMPED_FLOAT_TO_USHORT(rgba2[i][RCOMP], rgba4[i][RCOMP]); - UNCLAMPED_FLOAT_TO_USHORT(rgba2[i][GCOMP], rgba4[i][GCOMP]); - UNCLAMPED_FLOAT_TO_USHORT(rgba2[i][BCOMP], rgba4[i][BCOMP]); - UNCLAMPED_FLOAT_TO_USHORT(rgba2[i][ACOMP], rgba4[i][ACOMP]); + UNCLAMPED_FLOAT_TO_USHORT(newVals[i][RCOMP], rgba4[i][RCOMP]); + UNCLAMPED_FLOAT_TO_USHORT(newVals[i][GCOMP], rgba4[i][GCOMP]); + UNCLAMPED_FLOAT_TO_USHORT(newVals[i][BCOMP], rgba4[i][BCOMP]); + UNCLAMPED_FLOAT_TO_USHORT(newVals[i][ACOMP], rgba4[i][ACOMP]); } } + _mesa_memcpy(rgba2, newVals, span->end * 4 * sizeof(GLushort)); } break; default: -- cgit v1.1