diff options
| author | Brian Paul <brian.paul@tungstengraphics.com> | 2006-10-06 03:49:46 +0000 | 
|---|---|---|
| committer | Brian Paul <brian.paul@tungstengraphics.com> | 2006-10-06 03:49:46 +0000 | 
| commit | e18d0f82b6271103e292fde5bab6fceccb96f90a (patch) | |
| tree | 665abb3afa613f71e36974873dd7f485bcab645f | |
| parent | 6e138dfa361c33b8e0adcf1cafa9781fb53e219d (diff) | |
deal with union/aliasing in convert_color_type()
| -rw-r--r-- | src/mesa/swrast/s_span.c | 64 | 
1 files changed, 40 insertions, 24 deletions
| diff --git a/src/mesa/swrast/s_span.c b/src/mesa/swrast/s_span.c index 7ae9f7ffb6..0adab5ef16 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: | 
