* as indicated by the transferOps bitmask
*/
void
-_mesa_apply_rgba_transfer_ops(GLcontext *ctx, GLuint transferOps,
+_mesa_apply_rgba_transfer_ops(GLcontext *ctx, GLbitfield transferOps,
GLuint n, GLfloat rgba[][4])
{
/* scale & bias */
}
+/*
+ * Apply color index shift and offset to an array of pixels.
+ */
+static void
+shift_and_offset_ci( const GLcontext *ctx, GLuint n, GLuint indexes[] )
+{
+ GLint shift = ctx->Pixel.IndexShift;
+ GLint offset = ctx->Pixel.IndexOffset;
+ GLuint i;
+ if (shift > 0) {
+ for (i=0;i<n;i++) {
+ indexes[i] = (indexes[i] << shift) + offset;
+ }
+ }
+ else if (shift < 0) {
+ shift = -shift;
+ for (i=0;i<n;i++) {
+ indexes[i] = (indexes[i] >> shift) + offset;
+ }
+ }
+ else {
+ for (i=0;i<n;i++) {
+ indexes[i] = indexes[i] + offset;
+ }
+ }
+}
+
+
+
+/**
+ * Apply color index shift, offset and table lookup to an array
+ * of color indexes;
+ */
+void
+_mesa_apply_ci_transfer_ops(const GLcontext *ctx, GLbitfield transferOps,
+ GLuint n, GLuint indexes[])
+{
+ if (transferOps & IMAGE_SHIFT_OFFSET_BIT) {
+ shift_and_offset_ci(ctx, n, indexes);
+ }
+ if (transferOps & IMAGE_MAP_COLOR_BIT) {
+ const GLuint mask = ctx->Pixel.MapItoIsize - 1;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ const GLuint j = indexes[i] & mask;
+ indexes[i] = IROUND(ctx->Pixel.MapItoI[j]);
+ }
+ }
+}
+
+
+/**
+ * Apply stencil index shift, offset and table lookup to an array
+ * of stencil values.
+ */
+void
+_mesa_apply_stencil_transfer_ops(const GLcontext *ctx, GLuint n,
+ GLstencil stencil[])
+{
+ if (ctx->Pixel.IndexShift != 0 || ctx->Pixel.IndexOffset != 0) {
+ const GLint offset = ctx->Pixel.IndexOffset;
+ GLint shift = ctx->Pixel.IndexShift;
+ GLuint i;
+ if (shift > 0) {
+ for (i = 0; i < n; i++) {
+ stencil[i] = (stencil[i] << shift) + offset;
+ }
+ }
+ else if (shift < 0) {
+ shift = -shift;
+ for (i = 0; i < n; i++) {
+ stencil[i] = (stencil[i] >> shift) + offset;
+ }
+ }
+ else {
+ for (i = 0; i < n; i++) {
+ stencil[i] = stencil[i] + offset;
+ }
+ }
+ }
+ if (ctx->Pixel.MapStencilFlag) {
+ GLuint mask = ctx->Pixel.MapStoSsize - 1;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ stencil[i] = ctx->Pixel.MapStoS[ stencil[i] & mask ];
+ }
+ }
+}
+
/**
* Used to pack an array [][4] of RGBA float colors as specified
* by the dstFormat, dstType and dstPacking. Used by glReadPixels,
* glGetConvolutionFilter(), etc.
* Incoming colors will be clamped to [0,1] if needed.
+ * Note: the rgba values will be modified by this function when any pixel
+ * transfer ops are enabled.
*/
void
-_mesa_pack_rgba_span_float( GLcontext *ctx,
- GLuint n, CONST GLfloat rgbaIn[][4],
- GLenum dstFormat, GLenum dstType,
- GLvoid *dstAddr,
- const struct gl_pixelstore_attrib *dstPacking,
- GLuint transferOps )
+_mesa_pack_rgba_span_float(GLcontext *ctx, GLuint n, GLfloat rgba[][4],
+ GLenum dstFormat, GLenum dstType,
+ GLvoid *dstAddr,
+ const struct gl_pixelstore_attrib *dstPacking,
+ GLbitfield transferOps)
{
+ GLfloat luminance[MAX_WIDTH];
const GLint comps = _mesa_components_in_format(dstFormat);
- GLfloat rgbaCopy[MAX_WIDTH][4], luminance[MAX_WIDTH];
- const GLfloat (*rgba)[4];
GLuint i;
- if (dstType != GL_FLOAT) {
+ if (dstType != GL_FLOAT || ctx->Color.ClampReadColor == GL_TRUE) {
/* need to clamp to [0, 1] */
transferOps |= IMAGE_CLAMP_BIT;
}
if (transferOps) {
- /* make copy of incoming data */
- _mesa_memcpy(rgbaCopy, rgbaIn, n * 4 * sizeof(GLfloat));
- _mesa_apply_rgba_transfer_ops(ctx, transferOps, n, rgbaCopy);
- rgba = (const GLfloat (*)[4]) rgbaCopy;
-
+ _mesa_apply_rgba_transfer_ops(ctx, transferOps, n, rgba);
if ((transferOps & IMAGE_MIN_MAX_BIT) && ctx->MinMax.Sink) {
return;
}
}
- else {
- /* use incoming data, not a copy */
- rgba = (const GLfloat (*)[4]) rgbaIn;
- }
if (dstFormat == GL_LUMINANCE || dstFormat == GL_LUMINANCE_ALPHA) {
/* compute luminance values */
- if (ctx->Color.ClampReadColor == GL_TRUE || dstType != GL_FLOAT) {
+ if (dstType != GL_FLOAT || ctx->Color.ClampReadColor == GL_TRUE) {
for (i = 0; i < n; i++) {
GLfloat sum = rgba[i][RCOMP] + rgba[i][GCOMP] + rgba[i][BCOMP];
luminance[i] = CLAMP(sum, 0.0F, 1.0F);
}
-/*
- * Pack the given RGBA span into client memory at 'dest' address
- * in the given pixel format and type.
- * Optionally apply the enabled pixel transfer ops.
- * Pack into memory using the given packing params struct.
- * This is used by glReadPixels and glGetTexImage?D()
- * \param ctx - the context
- * n - number of pixels in the span
- * rgba - the pixels
- * format - dest packing format
- * type - dest packing data type
- * destination - destination packing address
- * packing - pixel packing parameters
- * transferOps - bitmask of IMAGE_*_BIT operations to apply
- */
-void
-_mesa_pack_rgba_span_chan( GLcontext *ctx,
- GLuint n, CONST GLchan srcRgba[][4],
- GLenum dstFormat, GLenum dstType,
- GLvoid *dstAddr,
- const struct gl_pixelstore_attrib *dstPacking,
- GLuint transferOps)
-{
- ASSERT((ctx->NewState & _NEW_PIXEL) == 0 || transferOps == 0);
-
- /* Test for optimized case first */
- if (transferOps == 0 && dstFormat == GL_RGBA && dstType == CHAN_TYPE) {
- /* common simple case */
- _mesa_memcpy(dstAddr, srcRgba, n * 4 * sizeof(GLchan));
- }
- else if (transferOps == 0 && dstFormat == GL_RGB && dstType == CHAN_TYPE) {
- /* common simple case */
- GLuint i;
- GLchan *dest = (GLchan *) dstAddr;
- for (i = 0; i < n; i++) {
- dest[0] = srcRgba[i][RCOMP];
- dest[1] = srcRgba[i][GCOMP];
- dest[2] = srcRgba[i][BCOMP];
- dest += 3;
- }
- }
- else if (transferOps == 0 && dstFormat == GL_RGBA && dstType == GL_UNSIGNED_BYTE) {
- /* common simple case */
- GLuint i;
- GLubyte *dest = (GLubyte *) dstAddr;
- for (i = 0; i < n; i++) {
- dest[0] = CHAN_TO_UBYTE(srcRgba[i][RCOMP]);
- dest[1] = CHAN_TO_UBYTE(srcRgba[i][GCOMP]);
- dest[2] = CHAN_TO_UBYTE(srcRgba[i][BCOMP]);
- dest[3] = CHAN_TO_UBYTE(srcRgba[i][ACOMP]);
- dest += 4;
- }
- }
- else {
- /* general solution */
- GLuint i;
- GLfloat rgba[MAX_WIDTH][4];
- assert(n <= MAX_WIDTH);
- /* convert color components to floating point */
- for (i = 0; i < n; i++) {
- rgba[i][RCOMP] = CHAN_TO_FLOAT(srcRgba[i][RCOMP]);
- rgba[i][GCOMP] = CHAN_TO_FLOAT(srcRgba[i][GCOMP]);
- rgba[i][BCOMP] = CHAN_TO_FLOAT(srcRgba[i][BCOMP]);
- rgba[i][ACOMP] = CHAN_TO_FLOAT(srcRgba[i][ACOMP]);
- }
- _mesa_pack_rgba_span_float(ctx, n, (const GLfloat (*)[4]) rgba,
- dstFormat, dstType, dstAddr,
- dstPacking, transferOps);
- }
-}
-
-
#define SWAP2BYTE(VALUE) \
{ \
GLubyte *bytes = (GLubyte *) &(VALUE); \
GLenum srcFormat, GLenum srcType, const GLvoid *src,
const struct gl_pixelstore_attrib *unpack )
{
- assert(srcFormat == GL_COLOR_INDEX);
+ ASSERT(srcFormat == GL_COLOR_INDEX || srcFormat == GL_STENCIL_INDEX);
ASSERT(srcType == GL_BITMAP ||
srcType == GL_UNSIGNED_BYTE ||
GLenum srcFormat, GLenum srcType,
const GLvoid *source,
const struct gl_pixelstore_attrib *srcPacking,
- GLuint transferOps )
+ GLbitfield transferOps )
{
ASSERT(dstFormat == GL_ALPHA ||
dstFormat == GL_LUMINANCE ||
extract_uint_indexes(n, indexes, srcFormat, srcType, source,
srcPacking);
- if (dstFormat == GL_COLOR_INDEX
- && (transferOps & IMAGE_MAP_COLOR_BIT)) {
- _mesa_map_ci(ctx, n, indexes);
- }
- if (transferOps & IMAGE_SHIFT_OFFSET_BIT) {
- _mesa_shift_and_offset_ci(ctx, n, indexes);
- }
-
if (dstFormat == GL_COLOR_INDEX) {
- /* convert to GLchan and return */
GLuint i;
+ _mesa_apply_ci_transfer_ops(ctx, transferOps, n, indexes);
+ /* convert to GLchan and return */
for (i = 0; i < n; i++) {
dest[i] = (GLchan) (indexes[i] & 0xff);
}
}
else {
/* Convert indexes to RGBA */
+ if (transferOps & IMAGE_SHIFT_OFFSET_BIT) {
+ shift_and_offset_ci(ctx, n, indexes);
+ }
_mesa_map_ci_to_rgba(ctx, n, indexes, rgba);
}
GLenum srcFormat, GLenum srcType,
const GLvoid *source,
const struct gl_pixelstore_attrib *srcPacking,
- GLuint transferOps )
+ GLbitfield transferOps )
{
ASSERT(dstFormat == GL_ALPHA ||
dstFormat == GL_LUMINANCE ||
extract_uint_indexes(n, indexes, srcFormat, srcType, source,
srcPacking);
- if (dstFormat == GL_COLOR_INDEX
- && (transferOps & IMAGE_MAP_COLOR_BIT)) {
- _mesa_map_ci(ctx, n, indexes);
- }
- if (transferOps & IMAGE_SHIFT_OFFSET_BIT) {
- _mesa_shift_and_offset_ci(ctx, n, indexes);
- }
-
if (dstFormat == GL_COLOR_INDEX) {
- /* convert to GLchan and return */
GLuint i;
+ _mesa_apply_ci_transfer_ops(ctx, transferOps, n, indexes);
+ /* convert to GLchan and return */
for (i = 0; i < n; i++) {
dest[i] = (GLchan) (indexes[i] & 0xff);
}
}
else {
/* Convert indexes to RGBA */
+ if (transferOps & IMAGE_SHIFT_OFFSET_BIT) {
+ shift_and_offset_ci(ctx, n, indexes);
+ }
_mesa_map_ci_to_rgba(ctx, n, indexes, rgba);
}
GLenum dstType, GLvoid *dest,
GLenum srcType, const GLvoid *source,
const struct gl_pixelstore_attrib *srcPacking,
- GLuint transferOps )
+ GLbitfield transferOps )
{
ASSERT(srcType == GL_BITMAP ||
srcType == GL_UNSIGNED_BYTE ||
extract_uint_indexes(n, indexes, GL_COLOR_INDEX, srcType, source,
srcPacking);
- if (transferOps & IMAGE_SHIFT_OFFSET_BIT) {
- /* shift and offset indexes */
- _mesa_shift_and_offset_ci(ctx, n, indexes);
- }
- if (transferOps & IMAGE_MAP_COLOR_BIT) {
- /* Apply lookup table */
- _mesa_map_ci(ctx, n, indexes);
- }
+ if (transferOps)
+ _mesa_apply_ci_transfer_ops(ctx, transferOps, n, indexes);
/* convert to dest type */
switch (dstType) {
_mesa_pack_index_span( const GLcontext *ctx, GLuint n,
GLenum dstType, GLvoid *dest, const GLuint *source,
const struct gl_pixelstore_attrib *dstPacking,
- GLuint transferOps )
+ GLbitfield transferOps )
{
GLuint indexes[MAX_WIDTH];
if (transferOps & (IMAGE_MAP_COLOR_BIT | IMAGE_SHIFT_OFFSET_BIT)) {
/* make a copy of input */
_mesa_memcpy(indexes, source, n * sizeof(GLuint));
- if (transferOps & IMAGE_SHIFT_OFFSET_BIT) {
- _mesa_shift_and_offset_ci( ctx, n, indexes);
- }
- if (transferOps & IMAGE_MAP_COLOR_BIT) {
- _mesa_map_ci(ctx, n, indexes);
- }
+ _mesa_apply_ci_transfer_ops(ctx, transferOps, n, indexes);
source = indexes;
}
GLenum dstType, GLvoid *dest,
GLenum srcType, const GLvoid *source,
const struct gl_pixelstore_attrib *srcPacking,
- GLuint transferOps )
+ GLbitfield transferOps )
{
ASSERT(srcType == GL_BITMAP ||
srcType == GL_UNSIGNED_BYTE ||
GLuint indexes[MAX_WIDTH];
assert(n <= MAX_WIDTH);
- extract_uint_indexes(n, indexes, GL_COLOR_INDEX, srcType, source,
+ extract_uint_indexes(n, indexes, GL_STENCIL_INDEX, srcType, source,
srcPacking);
if (transferOps) {
if (transferOps & IMAGE_SHIFT_OFFSET_BIT) {
/* shift and offset indexes */
- _mesa_shift_and_offset_ci(ctx, n, indexes);
+ shift_and_offset_ci(ctx, n, indexes);
}
if (ctx->Pixel.MapStencilFlag) {
ctx->Pixel.MapStencilFlag) {
/* make a copy of input */
_mesa_memcpy(stencil, source, n * sizeof(GLstencil));
- if (ctx->Pixel.IndexShift || ctx->Pixel.IndexOffset) {
- _mesa_shift_and_offset_stencil( ctx, n, stencil );
- }
- if (ctx->Pixel.MapStencilFlag) {
- _mesa_map_stencil( ctx, n, stencil );
- }
+ _mesa_apply_stencil_transfer_ops(ctx, n, stencil);
source = stencil;
}
depthVals = depthCopy;
}
- if (ctx->Pixel.IndexShift || ctx->Pixel.IndexOffset) {
+ if (ctx->Pixel.IndexShift ||
+ ctx->Pixel.IndexOffset ||
+ ctx->Pixel.MapStencilFlag) {
_mesa_memcpy(stencilCopy, stencilVals, n * sizeof(GLstencil));
- _mesa_shift_and_offset_stencil(ctx, n, stencilCopy);
- stencilVals = stencilCopy;
- }
- if (ctx->Pixel.MapStencilFlag) {
- if (stencilVals != stencilCopy)
- _mesa_memcpy(stencilCopy, stencilVals, n * sizeof(GLstencil));
- _mesa_map_stencil(ctx, n, stencilCopy);
+ _mesa_apply_stencil_transfer_ops(ctx, n, stencilCopy);
stencilVals = stencilCopy;
}
if (width <= 0 || height <= 0 || depth <= 0)
return NULL; /* generate error later */
- if (format == GL_BITMAP) {
+ if (type == GL_BITMAP) {
bytesPerRow = (width + 7) >> 3;
flipBytes = !unpack->LsbFirst;
swap2 = swap4 = GL_FALSE;