}
-/*
- * Unpack a row of color image data from a client buffer according to
- * the pixel unpacking parameters.
- * Return GLubyte values in the specified dest image format.
- * This is used by glDrawPixels and glTexImage?D().
- * \param ctx - the context
- * n - number of pixels in the span
- * dstFormat - format of destination color array
- * dest - the destination color array
- * srcFormat - source image format
- * srcType - source image data type
- * source - source image pointer
- * srcPacking - pixel unpacking parameters
- * transferOps - bitmask of IMAGE_*_BIT values of operations to apply
- *
- * XXX perhaps expand this to process whole images someday.
- */
-void
-_mesa_unpack_color_span_ubyte(struct gl_context *ctx,
- GLuint n, GLenum dstFormat, GLubyte dest[],
- GLenum srcFormat, GLenum srcType,
- const GLvoid *source,
- const struct gl_pixelstore_attrib *srcPacking,
- GLbitfield transferOps )
-{
- GLboolean intFormat = _mesa_is_enum_format_integer(srcFormat);
- ASSERT(dstFormat == GL_ALPHA ||
- dstFormat == GL_LUMINANCE ||
- dstFormat == GL_LUMINANCE_ALPHA ||
- dstFormat == GL_INTENSITY ||
- dstFormat == GL_RED ||
- dstFormat == GL_RG ||
- dstFormat == GL_RGB ||
- dstFormat == GL_RGBA);
-
- ASSERT(srcFormat == GL_RED ||
- srcFormat == GL_GREEN ||
- srcFormat == GL_BLUE ||
- srcFormat == GL_ALPHA ||
- srcFormat == GL_LUMINANCE ||
- srcFormat == GL_LUMINANCE_ALPHA ||
- srcFormat == GL_INTENSITY ||
- srcFormat == GL_RG ||
- srcFormat == GL_RGB ||
- srcFormat == GL_BGR ||
- srcFormat == GL_RGBA ||
- srcFormat == GL_BGRA ||
- srcFormat == GL_ABGR_EXT ||
- srcFormat == GL_COLOR_INDEX);
-
- ASSERT(srcType == GL_BITMAP ||
- srcType == GL_UNSIGNED_BYTE ||
- srcType == GL_BYTE ||
- srcType == GL_UNSIGNED_SHORT ||
- srcType == GL_SHORT ||
- srcType == GL_UNSIGNED_INT ||
- srcType == GL_INT ||
- srcType == GL_HALF_FLOAT_ARB ||
- srcType == GL_FLOAT ||
- srcType == GL_UNSIGNED_BYTE_3_3_2 ||
- srcType == GL_UNSIGNED_BYTE_2_3_3_REV ||
- srcType == GL_UNSIGNED_SHORT_5_6_5 ||
- srcType == GL_UNSIGNED_SHORT_5_6_5_REV ||
- srcType == GL_UNSIGNED_SHORT_4_4_4_4 ||
- srcType == GL_UNSIGNED_SHORT_4_4_4_4_REV ||
- srcType == GL_UNSIGNED_SHORT_5_5_5_1 ||
- srcType == GL_UNSIGNED_SHORT_1_5_5_5_REV ||
- srcType == GL_UNSIGNED_INT_8_8_8_8 ||
- srcType == GL_UNSIGNED_INT_8_8_8_8_REV ||
- srcType == GL_UNSIGNED_INT_10_10_10_2 ||
- srcType == GL_UNSIGNED_INT_2_10_10_10_REV ||
- srcType == GL_UNSIGNED_INT_5_9_9_9_REV ||
- srcType == GL_UNSIGNED_INT_10F_11F_11F_REV);
-
- /* EXT_texture_integer specifies no transfer ops on integer
- * types in the resolved issues section. Just set them to 0
- * for integer surfaces.
- */
- if (intFormat)
- transferOps = 0;
-
- /* Try simple cases first */
- if (transferOps == 0) {
- if (srcType == GL_UNSIGNED_BYTE) {
- if (dstFormat == GL_RGBA) {
- if (srcFormat == GL_RGBA) {
- memcpy( dest, source, n * 4 * sizeof(GLubyte) );
- return;
- }
- else if (srcFormat == GL_RGB) {
- GLuint i;
- const GLubyte *src = (const GLubyte *) source;
- GLubyte *dst = dest;
- for (i = 0; i < n; i++) {
- dst[0] = src[0];
- dst[1] = src[1];
- dst[2] = src[2];
- dst[3] = 255;
- src += 3;
- dst += 4;
- }
- return;
- }
- }
- else if (dstFormat == GL_RGB) {
- if (srcFormat == GL_RGB) {
- memcpy( dest, source, n * 3 * sizeof(GLubyte) );
- return;
- }
- else if (srcFormat == GL_RGBA) {
- GLuint i;
- const GLubyte *src = (const GLubyte *) source;
- GLubyte *dst = dest;
- for (i = 0; i < n; i++) {
- dst[0] = src[0];
- dst[1] = src[1];
- dst[2] = src[2];
- src += 4;
- dst += 3;
- }
- return;
- }
- }
- else if (dstFormat == srcFormat) {
- GLint comps = _mesa_components_in_format(srcFormat);
- assert(comps > 0);
- memcpy( dest, source, n * comps * sizeof(GLubyte) );
- return;
- }
- }
- }
-
-
- /* general solution begins here */
- {
- GLint dstComponents;
- GLint rDst, gDst, bDst, aDst, lDst, iDst;
- GLfloat (*rgba)[4] = malloc(4 * n * sizeof(GLfloat));
-
- if (!rgba) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel unpacking");
- return;
- }
-
- dstComponents = _mesa_components_in_format( dstFormat );
- /* source & dest image formats should have been error checked by now */
- assert(dstComponents > 0);
-
- /*
- * Extract image data and convert to RGBA floats
- */
- if (srcFormat == GL_COLOR_INDEX) {
- GLuint *indexes = malloc(n * sizeof(GLuint));
-
- if (!indexes) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "pixel unpacking");
- free(rgba);
- return;
- }
-
- extract_uint_indexes(n, indexes, srcFormat, srcType, source,
- srcPacking);
-
- /* Convert indexes to RGBA */
- if (transferOps & IMAGE_SHIFT_OFFSET_BIT) {
- _mesa_shift_and_offset_ci(ctx, n, indexes);
- }
- _mesa_map_ci_to_rgba(ctx, n, indexes, rgba);
-
- /* Don't do RGBA scale/bias or RGBA->RGBA mapping if starting
- * with color indexes.
- */
- transferOps &= ~(IMAGE_SCALE_BIAS_BIT | IMAGE_MAP_COLOR_BIT);
-
- free(indexes);
- }
- else {
- /* non-color index data */
- extract_float_rgba(n, rgba, srcFormat, srcType, source,
- srcPacking->SwapBytes);
- }
-
- /* Need to clamp if returning GLubytes */
- transferOps |= IMAGE_CLAMP_BIT;
-
- if (transferOps) {
- _mesa_apply_rgba_transfer_ops(ctx, transferOps, n, rgba);
- }
-
- get_component_indexes(dstFormat,
- &rDst, &gDst, &bDst, &aDst, &lDst, &iDst);
-
- /* Now return the GLubyte data in the requested dstFormat */
- if (rDst >= 0) {
- GLubyte *dst = dest;
- GLuint i;
- for (i = 0; i < n; i++) {
- CLAMPED_FLOAT_TO_UBYTE(dst[rDst], rgba[i][RCOMP]);
- dst += dstComponents;
- }
- }
-
- if (gDst >= 0) {
- GLubyte *dst = dest;
- GLuint i;
- for (i = 0; i < n; i++) {
- CLAMPED_FLOAT_TO_UBYTE(dst[gDst], rgba[i][GCOMP]);
- dst += dstComponents;
- }
- }
-
- if (bDst >= 0) {
- GLubyte *dst = dest;
- GLuint i;
- for (i = 0; i < n; i++) {
- CLAMPED_FLOAT_TO_UBYTE(dst[bDst], rgba[i][BCOMP]);
- dst += dstComponents;
- }
- }
-
- if (aDst >= 0) {
- GLubyte *dst = dest;
- GLuint i;
- for (i = 0; i < n; i++) {
- CLAMPED_FLOAT_TO_UBYTE(dst[aDst], rgba[i][ACOMP]);
- dst += dstComponents;
- }
- }
-
- if (iDst >= 0) {
- GLubyte *dst = dest;
- GLuint i;
- assert(iDst == 0);
- assert(dstComponents == 1);
- for (i = 0; i < n; i++) {
- /* Intensity comes from red channel */
- CLAMPED_FLOAT_TO_UBYTE(dst[i], rgba[i][RCOMP]);
- }
- }
-
- if (lDst >= 0) {
- GLubyte *dst = dest;
- GLuint i;
- assert(lDst == 0);
- for (i = 0; i < n; i++) {
- /* Luminance comes from red channel */
- CLAMPED_FLOAT_TO_UBYTE(dst[0], rgba[i][RCOMP]);
- dst += dstComponents;
- }
- }
-
- free(rgba);
- }
-}
-
-
/**
* Same as _mesa_unpack_color_span_ubyte(), but return GLfloat data
* instead of GLubyte.