static void copy_ci_pixels( GLcontext *ctx, GLint srcx, GLint srcy, GLint width, GLint height, GLint destx, GLint desty ) { SWcontext *swrast = SWRAST_CONTEXT(ctx); GLuint *tmpImage,*p; GLint sy, dy, stepy; GLint j; const GLboolean zoom = ctx->Pixel.ZoomX != 1.0F || ctx->Pixel.ZoomY != 1.0F; const GLboolean shift_or_offset = ctx->Pixel.IndexShift || ctx->Pixel.IndexOffset; GLint overlapping; struct sw_span span; if (!ctx->ReadBuffer->_ColorReadBuffer) { /* no readbuffer - OK */ return; } INIT_SPAN(span, GL_BITMAP, 0, 0, SPAN_INDEX); /* Determine if copy should be bottom-to-top or top-to-bottom */ if (srcy<desty) { /* top-down max-to-min */ sy = srcy + height - 1; dy = desty + height - 1; stepy = -1; } else { /* bottom-up min-to-max */ sy = srcy; dy = desty; stepy = 1; } if (ctx->DrawBuffer == ctx->ReadBuffer) { overlapping = regions_overlap(srcx, srcy, destx, desty, width, height, ctx->Pixel.ZoomX, ctx->Pixel.ZoomY); } else { overlapping = GL_FALSE; } if (ctx->Depth.Test) _swrast_span_default_z(ctx, &span); if (swrast->_FogEnabled) _swrast_span_default_fog(ctx, &span); if (overlapping) { GLint ssy = sy; tmpImage = (GLuint *) _mesa_malloc(width * height * sizeof(GLuint)); if (!tmpImage) { _mesa_error( ctx, GL_OUT_OF_MEMORY, "glCopyPixels" ); return; } /* read the image */ p = tmpImage; for (j = 0; j < height; j++, ssy += stepy) { _swrast_read_index_span( ctx, ctx->ReadBuffer->_ColorReadBuffer, width, srcx, ssy, p ); p += width; } p = tmpImage; } else { tmpImage = NULL; /* silence compiler warning */ p = NULL; } for (j = 0; j < height; j++, sy += stepy, dy += stepy) { /* Get color indexes */ if (overlapping) { _mesa_memcpy(span.array->index, p, width * sizeof(GLuint)); p += width; } else { _swrast_read_index_span( ctx, ctx->ReadBuffer->_ColorReadBuffer, width, srcx, sy, span.array->index ); } /* Apply shift, offset, look-up table */ if (shift_or_offset) { _mesa_shift_and_offset_ci( ctx, width, span.array->index ); } if (ctx->Pixel.MapColorFlag) { _mesa_map_ci( ctx, width, span.array->index ); } /* write color indexes */ span.x = destx; span.y = dy; span.end = width; if (zoom) _swrast_write_zoomed_index_span(ctx, destx, desty, &span); else _swrast_write_index_span(ctx, &span); } if (overlapping) _mesa_free(tmpImage); }
static void copy_ci_pixels( GLcontext *ctx, GLint srcx, GLint srcy, GLint width, GLint height, GLint destx, GLint desty ) { GLuint *tmpImage,*p; GLint sy, dy, stepy; GLint j; const GLboolean zoom = ctx->Pixel.ZoomX != 1.0F || ctx->Pixel.ZoomY != 1.0F; GLint overlapping; SWspan span; if (!ctx->ReadBuffer->_ColorReadBuffer) { /* no readbuffer - OK */ return; } INIT_SPAN(span, GL_BITMAP); _swrast_span_default_attribs(ctx, &span); span.arrayMask = SPAN_INDEX; if (ctx->DrawBuffer == ctx->ReadBuffer) { overlapping = regions_overlap(srcx, srcy, destx, desty, width, height, ctx->Pixel.ZoomX, ctx->Pixel.ZoomY); } else { overlapping = GL_FALSE; } /* Determine if copy should be bottom-to-top or top-to-bottom */ if (!overlapping && srcy < desty) { /* top-down max-to-min */ sy = srcy + height - 1; dy = desty + height - 1; stepy = -1; } else { /* bottom-up min-to-max */ sy = srcy; dy = desty; stepy = 1; } if (overlapping) { GLint ssy = sy; tmpImage = (GLuint *) _mesa_malloc(width * height * sizeof(GLuint)); if (!tmpImage) { _mesa_error( ctx, GL_OUT_OF_MEMORY, "glCopyPixels" ); return; } /* read the image */ p = tmpImage; for (j = 0; j < height; j++, ssy += stepy) { _swrast_read_index_span( ctx, ctx->ReadBuffer->_ColorReadBuffer, width, srcx, ssy, p ); p += width; } p = tmpImage; } else { tmpImage = NULL; /* silence compiler warning */ p = NULL; } for (j = 0; j < height; j++, sy += stepy, dy += stepy) { /* Get color indexes */ if (overlapping) { _mesa_memcpy(span.array->index, p, width * sizeof(GLuint)); p += width; } else { _swrast_read_index_span( ctx, ctx->ReadBuffer->_ColorReadBuffer, width, srcx, sy, span.array->index ); } if (ctx->_ImageTransferState) _mesa_apply_ci_transfer_ops(ctx, ctx->_ImageTransferState, width, span.array->index); /* write color indexes */ span.x = destx; span.y = dy; span.end = width; if (zoom) _swrast_write_zoomed_index_span(ctx, destx, desty, &span); else _swrast_write_index_span(ctx, &span); } if (overlapping) _mesa_free(tmpImage); }