- img, row, 0);
- GLint col;
-
- for (col = 0; col < width; col++) {
- texImage->FetchTexelf(texImage, col, row, img, rgba[col]);
- if (texImage->_BaseFormat == GL_ALPHA) {
- rgba[col][RCOMP] = 0.0F;
- rgba[col][GCOMP] = 0.0F;
- rgba[col][BCOMP] = 0.0F;
- }
- else if (texImage->_BaseFormat == GL_LUMINANCE) {
- rgba[col][GCOMP] = 0.0F;
- rgba[col][BCOMP] = 0.0F;
- rgba[col][ACOMP] = 1.0F;
- }
- else if (texImage->_BaseFormat == GL_LUMINANCE_ALPHA) {
- rgba[col][GCOMP] = 0.0F;
- rgba[col][BCOMP] = 0.0F;
- }
- else if (texImage->_BaseFormat == GL_INTENSITY) {
- rgba[col][GCOMP] = 0.0F;
- rgba[col][BCOMP] = 0.0F;
- rgba[col][ACOMP] = 1.0F;
- }
+ slice, row, 0);
+
+ _mesa_pack_rgba_span_float(ctx, width, (GLfloat (*)[4]) srcRow,
+ format, type, dest, &ctx->Pack, transferOps);
+ srcRow += 4 * width;
+ }
+ tempSlice += 4 * width * height;
+ }
+
+ free(tempImage);
+}
+
+
+/**
+ * Return a base GL format given the user-requested format
+ * for glGetTexImage().
+ */
+GLenum
+_mesa_base_pack_format(GLenum format)
+{
+ switch (format) {
+ case GL_ABGR_EXT:
+ case GL_BGRA:
+ case GL_BGRA_INTEGER:
+ case GL_RGBA_INTEGER:
+ return GL_RGBA;
+ case GL_BGR:
+ case GL_BGR_INTEGER:
+ case GL_RGB_INTEGER:
+ return GL_RGB;
+ case GL_RED_INTEGER:
+ return GL_RED;
+ case GL_GREEN_INTEGER:
+ return GL_GREEN;
+ case GL_BLUE_INTEGER:
+ return GL_BLUE;
+ case GL_ALPHA_INTEGER:
+ return GL_ALPHA;
+ case GL_LUMINANCE_INTEGER_EXT:
+ return GL_LUMINANCE;
+ case GL_LUMINANCE_ALPHA_INTEGER_EXT:
+ return GL_LUMINANCE_ALPHA;
+ default:
+ return format;
+ }
+}
+
+
+/**
+ * Get an uncompressed color texture image.
+ */
+static void
+get_tex_rgba_uncompressed(struct gl_context *ctx, GLuint dimensions,
+ GLenum format, GLenum type, GLvoid *pixels,
+ struct gl_texture_image *texImage,
+ GLbitfield transferOps)
+{
+ /* don't want to apply sRGB -> RGB conversion here so override the format */
+ const mesa_format texFormat =
+ _mesa_get_srgb_format_linear(texImage->TexFormat);
+ const GLuint width = texImage->Width;
+ GLenum destBaseFormat = _mesa_base_pack_format(format);
+ GLenum rebaseFormat = GL_NONE;
+ GLuint height = texImage->Height;
+ GLuint depth = texImage->Depth;
+ GLuint img, row;
+ GLfloat (*rgba)[4];
+ GLuint (*rgba_uint)[4];
+ GLboolean tex_is_integer = _mesa_is_format_integer_color(texImage->TexFormat);
+ GLboolean tex_is_uint = _mesa_is_format_unsigned(texImage->TexFormat);
+ GLenum texBaseFormat = _mesa_get_format_base_format(texImage->TexFormat);
+
+ /* Allocate buffer for one row of texels */
+ rgba = malloc(4 * width * sizeof(GLfloat));
+ rgba_uint = (GLuint (*)[4]) rgba;
+ if (!rgba) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage()");
+ return;
+ }
+
+ if (texImage->TexObject->Target == GL_TEXTURE_1D_ARRAY) {
+ depth = height;
+ height = 1;
+ }
+
+ if (texImage->_BaseFormat == GL_LUMINANCE ||
+ texImage->_BaseFormat == GL_INTENSITY ||
+ texImage->_BaseFormat == GL_LUMINANCE_ALPHA) {
+ /* If a luminance (or intensity) texture is read back as RGB(A), the
+ * returned value should be (L,0,0,1), not (L,L,L,1). Set rebaseFormat
+ * here to get G=B=0.
+ */
+ rebaseFormat = texImage->_BaseFormat;
+ }
+ else if ((texImage->_BaseFormat == GL_RGBA ||
+ texImage->_BaseFormat == GL_RGB ||
+ texImage->_BaseFormat == GL_RG) &&
+ (destBaseFormat == GL_LUMINANCE ||
+ destBaseFormat == GL_LUMINANCE_ALPHA ||
+ destBaseFormat == GL_LUMINANCE_INTEGER_EXT ||
+ destBaseFormat == GL_LUMINANCE_ALPHA_INTEGER_EXT)) {
+ /* If we're reading back an RGB(A) texture as luminance then we need
+ * to return L=tex(R). Note, that's different from glReadPixels which
+ * returns L=R+G+B.
+ */
+ rebaseFormat = GL_LUMINANCE_ALPHA; /* this covers GL_LUMINANCE too */
+ }
+ else if (texImage->_BaseFormat != texBaseFormat) {
+ /* The internal format and the real format differ, so we can't rely
+ * on the unpack functions setting the correct constant values.
+ * (e.g. reading back GL_RGB8 which is actually RGBA won't set alpha=1)
+ */
+ switch (texImage->_BaseFormat) {
+ case GL_RED:
+ if ((texBaseFormat == GL_RGBA ||
+ texBaseFormat == GL_RGB ||
+ texBaseFormat == GL_RG) &&
+ (destBaseFormat == GL_RGBA ||
+ destBaseFormat == GL_RGB ||
+ destBaseFormat == GL_RG ||
+ destBaseFormat == GL_GREEN)) {
+ rebaseFormat = texImage->_BaseFormat;
+ break;
+ }
+ /* fall through */
+ case GL_RG:
+ if ((texBaseFormat == GL_RGBA ||
+ texBaseFormat == GL_RGB) &&
+ (destBaseFormat == GL_RGBA ||
+ destBaseFormat == GL_RGB ||
+ destBaseFormat == GL_BLUE)) {
+ rebaseFormat = texImage->_BaseFormat;
+ break;
+ }
+ /* fall through */
+ case GL_RGB:
+ if (texBaseFormat == GL_RGBA &&
+ (destBaseFormat == GL_RGBA ||
+ destBaseFormat == GL_ALPHA ||
+ destBaseFormat == GL_LUMINANCE_ALPHA)) {
+ rebaseFormat = texImage->_BaseFormat;
+ }
+ break;
+
+ case GL_ALPHA:
+ if (destBaseFormat != GL_ALPHA) {
+ rebaseFormat = texImage->_BaseFormat;