mesa: Add helpers to extract GL_COLOR_INDEX to RGBA float/ubyte
authorIago Toral Quiroga <itoral@igalia.com>
Fri, 7 Nov 2014 07:32:14 +0000 (08:32 +0100)
committerIago Toral Quiroga <itoral@igalia.com>
Mon, 12 Jan 2015 10:20:29 +0000 (11:20 +0100)
We only use _mesa_make_temp_ubyte_image in texstore.c to convert
GL_COLOR_INDEX to RGBA, but this helper does more stuff than this.
All uses of this helper can be replaced with calls to
_mesa_format_convert except for this GL_COLOR_INDEX conversion.

This patch extracts the GL_COLOR_INDEX to RGBA logic to a separate
helper so we can use that instead from texstore.c.

In future patches we will replace all remaining calls to
_mesa_make_temp_ubyte_image in the repository (related to compressed
formats) with calls to _mesa_format_convert so we can remove
_mesa_make_temp_ubyte_image and related functions.

v2:
- Remove ‘for’ loop initial declaration. They are only allowed in C99 or C11
mode.

Reviewed-by: Jason Ekstrand <jason.ekstrand@intel.com>
src/mesa/main/pack.c
src/mesa/main/pack.h

index 140ba29e4fa10c5ab7c3926624babbd73500212b..a64535210b24aae3d8788b6f39bcf0e0fc02f0c4 100644 (file)
@@ -4549,3 +4549,88 @@ _mesa_pack_luminance_from_rgba_integer(GLuint n,
    }
 }
 
+GLfloat *
+_mesa_unpack_color_index_to_rgba_float(struct gl_context *ctx, GLuint dims,
+                                       const void *src, GLenum srcFormat, GLenum srcType,
+                                       int srcWidth, int srcHeight, int srcDepth,
+                                       const struct gl_pixelstore_attrib *srcPacking,
+                                       GLbitfield transferOps)
+{
+   int count, img;
+   GLuint *indexes;
+   GLfloat *rgba, *dstPtr;
+
+   count = srcWidth * srcHeight;
+   indexes = malloc(count * sizeof(GLuint));
+   if (!indexes) {
+      _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel unpacking");
+      return NULL;
+   }
+
+   rgba = malloc(4 * count * srcDepth * sizeof(GLfloat));
+   if (!rgba) {
+      free(indexes);
+      _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel unpacking");
+      return NULL;
+   }
+
+   /* Convert indexes to RGBA float */
+   dstPtr = rgba;
+   for (img = 0; img < srcDepth; img++) {
+      const GLubyte *srcPtr =
+         (const GLubyte *) _mesa_image_address(dims, srcPacking, src,
+                                               srcWidth, srcHeight,
+                                               srcFormat, srcType,
+                                               img, 0, 0);
+
+      extract_uint_indexes(count, indexes, srcFormat, srcType, srcPtr, srcPacking);
+
+      if (transferOps & IMAGE_SHIFT_OFFSET_BIT)
+         _mesa_shift_and_offset_ci(ctx, count, indexes);
+
+      _mesa_map_ci_to_rgba(ctx, count, indexes, (float (*)[4])dstPtr);
+
+      /* Don't do RGBA scale/bias or RGBA->RGBA mapping if starting
+       * with color indexes.
+       */
+      transferOps &= ~(IMAGE_SCALE_BIAS_BIT | IMAGE_MAP_COLOR_BIT);
+      _mesa_apply_rgba_transfer_ops(ctx, transferOps, count, (float (*)[4])dstPtr);
+
+      dstPtr += srcHeight * srcWidth * 4;
+   }
+
+   free(indexes);
+
+   return rgba;
+}
+
+GLubyte *
+_mesa_unpack_color_index_to_rgba_ubyte(struct gl_context *ctx, GLuint dims,
+                                       const void *src, GLenum srcFormat, GLenum srcType,
+                                       int srcWidth, int srcHeight, int srcDepth,
+                                       const struct gl_pixelstore_attrib *srcPacking,
+                                       GLbitfield transferOps)
+{
+   GLfloat *rgba;
+   GLubyte *dst;
+   int count, i;
+
+   transferOps |= IMAGE_CLAMP_BIT;
+   rgba = _mesa_unpack_color_index_to_rgba_float(ctx, dims,
+                                                 src, srcFormat, srcType,
+                                                 srcWidth, srcHeight, srcDepth,
+                                                 srcPacking, transferOps);
+
+   count = srcWidth * srcHeight * srcDepth;
+   dst = malloc(count * 4 * sizeof(GLubyte));
+   for (i = 0; i < count; i++) {
+      CLAMPED_FLOAT_TO_UBYTE(dst[i * 4 + 0], rgba[i * 4 + 0]);
+      CLAMPED_FLOAT_TO_UBYTE(dst[i * 4 + 1], rgba[i * 4 + 1]);
+      CLAMPED_FLOAT_TO_UBYTE(dst[i * 4 + 2], rgba[i * 4 + 2]);
+      CLAMPED_FLOAT_TO_UBYTE(dst[i * 4 + 3], rgba[i * 4 + 3]);
+   }
+
+   free(rgba);
+
+   return dst;
+}
index 9988bea4fd1314dcd37b7e358675c3e2cc554eef..ddba82eea545a8da10f9acb01c0c47357289cd44 100644 (file)
@@ -165,4 +165,18 @@ _mesa_pack_luminance_from_rgba_integer(GLuint n, GLuint rgba[][4], bool rgba_is_
                                        GLvoid *dstAddr, GLenum dst_format,
                                        GLenum dst_type);
 
+extern GLfloat *
+_mesa_unpack_color_index_to_rgba_float(struct gl_context *ctx, GLuint dims,
+                                       const void *src, GLenum srcFormat, GLenum srcType,
+                                       int srcWidth, int srcHeight, int srcDepth,
+                                       const struct gl_pixelstore_attrib *srcPacking,
+                                       GLbitfield transferOps);
+
+extern GLubyte *
+_mesa_unpack_color_index_to_rgba_ubyte(struct gl_context *ctx, GLuint dims,
+                                       const void *src, GLenum srcFormat, GLenum srcType,
+                                       int srcWidth, int srcHeight, int srcDepth,
+                                       const struct gl_pixelstore_attrib *srcPacking,
+                                       GLbitfield transferOps);
+
 #endif