📄 image.c
字号:
* endian differences.
*/
GLubyte ptrn[32*4];
GLint i;
for (i = 0; i < 32; i++) {
ptrn[i * 4 + 0] = (GLubyte) ((pattern[i] >> 24) & 0xff);
ptrn[i * 4 + 1] = (GLubyte) ((pattern[i] >> 16) & 0xff);
ptrn[i * 4 + 2] = (GLubyte) ((pattern[i] >> 8 ) & 0xff);
ptrn[i * 4 + 3] = (GLubyte) ((pattern[i] ) & 0xff);
}
_mesa_pack_bitmap(32, 32, ptrn, dest, packing);
}
/*
* Unpack bitmap data. Resulting data will be in most-significant-bit-first
* order with row alignment = 1 byte.
*/
GLvoid *
_mesa_unpack_bitmap( GLint width, GLint height, const GLubyte *pixels,
const struct gl_pixelstore_attrib *packing )
{
GLint bytes, row, width_in_bytes;
GLubyte *buffer, *dst;
if (!pixels)
return NULL;
/* Alloc dest storage */
bytes = ((width + 7) / 8 * height);
buffer = (GLubyte *) MALLOC( bytes );
if (!buffer)
return NULL;
width_in_bytes = CEILING( width, 8 );
dst = buffer;
for (row = 0; row < height; row++) {
const GLubyte *src = (const GLubyte *)
_mesa_image_address2d(packing, pixels, width, height,
GL_COLOR_INDEX, GL_BITMAP, row, 0);
if (!src) {
FREE(buffer);
return NULL;
}
if (packing->SkipPixels == 0) {
MEMCPY( dst, src, width_in_bytes );
if (packing->LsbFirst) {
flip_bytes( dst, width_in_bytes );
}
}
else {
/* handling SkipPixels is a bit tricky (no pun intended!) */
GLint i;
if (packing->LsbFirst) {
GLubyte srcMask = 1 << (packing->SkipPixels & 0x7);
GLubyte dstMask = 128;
const GLubyte *s = src;
GLubyte *d = dst;
*d = 0;
for (i = 0; i < width; i++) {
if (*s & srcMask) {
*d |= dstMask;
}
if (srcMask == 128) {
srcMask = 1;
s++;
}
else {
srcMask = srcMask << 1;
}
if (dstMask == 1) {
dstMask = 128;
d++;
*d = 0;
}
else {
dstMask = dstMask >> 1;
}
}
}
else {
GLubyte srcMask = 128 >> (packing->SkipPixels & 0x7);
GLubyte dstMask = 128;
const GLubyte *s = src;
GLubyte *d = dst;
*d = 0;
for (i = 0; i < width; i++) {
if (*s & srcMask) {
*d |= dstMask;
}
if (srcMask == 1) {
srcMask = 128;
s++;
}
else {
srcMask = srcMask >> 1;
}
if (dstMask == 1) {
dstMask = 128;
d++;
*d = 0;
}
else {
dstMask = dstMask >> 1;
}
}
}
}
dst += width_in_bytes;
}
return buffer;
}
/*
* Pack bitmap data.
*/
void
_mesa_pack_bitmap( GLint width, GLint height, const GLubyte *source,
GLubyte *dest, const struct gl_pixelstore_attrib *packing )
{
GLint row, width_in_bytes;
const GLubyte *src;
if (!source)
return;
width_in_bytes = CEILING( width, 8 );
src = source;
for (row = 0; row < height; row++) {
GLubyte *dst = (GLubyte *) _mesa_image_address2d(packing, dest,
width, height, GL_COLOR_INDEX, GL_BITMAP, row, 0);
if (!dst)
return;
if (packing->SkipPixels == 0) {
MEMCPY( dst, src, width_in_bytes );
if (packing->LsbFirst) {
flip_bytes( dst, width_in_bytes );
}
}
else {
/* handling SkipPixels is a bit tricky (no pun intended!) */
GLint i;
if (packing->LsbFirst) {
GLubyte srcMask = 1 << (packing->SkipPixels & 0x7);
GLubyte dstMask = 128;
const GLubyte *s = src;
GLubyte *d = dst;
*d = 0;
for (i = 0; i < width; i++) {
if (*s & srcMask) {
*d |= dstMask;
}
if (srcMask == 128) {
srcMask = 1;
s++;
}
else {
srcMask = srcMask << 1;
}
if (dstMask == 1) {
dstMask = 128;
d++;
*d = 0;
}
else {
dstMask = dstMask >> 1;
}
}
}
else {
GLubyte srcMask = 128 >> (packing->SkipPixels & 0x7);
GLubyte dstMask = 128;
const GLubyte *s = src;
GLubyte *d = dst;
*d = 0;
for (i = 0; i < width; i++) {
if (*s & srcMask) {
*d |= dstMask;
}
if (srcMask == 1) {
srcMask = 128;
s++;
}
else {
srcMask = srcMask >> 1;
}
if (dstMask == 1) {
dstMask = 128;
d++;
*d = 0;
}
else {
dstMask = dstMask >> 1;
}
}
}
}
src += width_in_bytes;
}
}
/**
* Apply various pixel transfer operations to an array of RGBA pixels
* as indicated by the transferOps bitmask
*/
void
_mesa_apply_rgba_transfer_ops(GLcontext *ctx, GLuint transferOps,
GLuint n, GLfloat rgba[][4])
{
/* scale & bias */
if (transferOps & IMAGE_SCALE_BIAS_BIT) {
_mesa_scale_and_bias_rgba(n, rgba,
ctx->Pixel.RedScale, ctx->Pixel.GreenScale,
ctx->Pixel.BlueScale, ctx->Pixel.AlphaScale,
ctx->Pixel.RedBias, ctx->Pixel.GreenBias,
ctx->Pixel.BlueBias, ctx->Pixel.AlphaBias);
}
/* color map lookup */
if (transferOps & IMAGE_MAP_COLOR_BIT) {
_mesa_map_rgba( ctx, n, rgba );
}
/* GL_COLOR_TABLE lookup */
if (transferOps & IMAGE_COLOR_TABLE_BIT) {
_mesa_lookup_rgba_float(&ctx->ColorTable, n, rgba);
}
/* convolution */
if (transferOps & IMAGE_CONVOLUTION_BIT) {
/* this has to be done in the calling code */
_mesa_problem(ctx, "IMAGE_CONVOLUTION_BIT set in _mesa_apply_transfer_ops");
}
/* GL_POST_CONVOLUTION_RED/GREEN/BLUE/ALPHA_SCALE/BIAS */
if (transferOps & IMAGE_POST_CONVOLUTION_SCALE_BIAS) {
_mesa_scale_and_bias_rgba(n, rgba,
ctx->Pixel.PostConvolutionScale[RCOMP],
ctx->Pixel.PostConvolutionScale[GCOMP],
ctx->Pixel.PostConvolutionScale[BCOMP],
ctx->Pixel.PostConvolutionScale[ACOMP],
ctx->Pixel.PostConvolutionBias[RCOMP],
ctx->Pixel.PostConvolutionBias[GCOMP],
ctx->Pixel.PostConvolutionBias[BCOMP],
ctx->Pixel.PostConvolutionBias[ACOMP]);
}
/* GL_POST_CONVOLUTION_COLOR_TABLE lookup */
if (transferOps & IMAGE_POST_CONVOLUTION_COLOR_TABLE_BIT) {
_mesa_lookup_rgba_float(&ctx->PostConvolutionColorTable, n, rgba);
}
/* color matrix transform */
if (transferOps & IMAGE_COLOR_MATRIX_BIT) {
_mesa_transform_rgba(ctx, n, rgba);
}
/* GL_POST_COLOR_MATRIX_COLOR_TABLE lookup */
if (transferOps & IMAGE_POST_COLOR_MATRIX_COLOR_TABLE_BIT) {
_mesa_lookup_rgba_float(&ctx->PostColorMatrixColorTable, n, rgba);
}
/* update histogram count */
if (transferOps & IMAGE_HISTOGRAM_BIT) {
_mesa_update_histogram(ctx, n, (CONST GLfloat (*)[4]) rgba);
}
/* update min/max values */
if (transferOps & IMAGE_MIN_MAX_BIT) {
_mesa_update_minmax(ctx, n, (CONST GLfloat (*)[4]) rgba);
}
/* clamping to [0,1] */
if (transferOps & IMAGE_CLAMP_BIT) {
GLuint i;
for (i = 0; i < n; i++) {
rgba[i][RCOMP] = CLAMP(rgba[i][RCOMP], 0.0F, 1.0F);
rgba[i][GCOMP] = CLAMP(rgba[i][GCOMP], 0.0F, 1.0F);
rgba[i][BCOMP] = CLAMP(rgba[i][BCOMP], 0.0F, 1.0F);
rgba[i][ACOMP] = CLAMP(rgba[i][ACOMP], 0.0F, 1.0F);
}
}
}
/*
* Used to pack an array [][4] of RGBA float colors as specified
* by the dstFormat, dstType and dstPacking. Used by glReadPixels,
* glGetConvolutionFilter(), etc.
*/
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 )
{
const GLint comps = _mesa_components_in_format(dstFormat);
GLfloat luminance[MAX_WIDTH];
const GLfloat (*rgba)[4];
GLuint i;
if (transferOps) {
/* make copy of incoming data */
DEFMARRAY(GLfloat, rgbaCopy, MAX_WIDTH, 4); /* mac 32k limitation */
CHECKARRAY(rgbaCopy, return); /* mac 32k limitation */
_mesa_memcpy(rgbaCopy, rgbaIn, n * 4 * sizeof(GLfloat));
_mesa_apply_rgba_transfer_ops(ctx, transferOps, n, rgbaCopy);
rgba = (const GLfloat (*)[4]) rgbaCopy;
if ((transferOps & IMAGE_MIN_MAX_BIT) && ctx->MinMax.Sink) {
UNDEFARRAY(rgbaCopy); /* mac 32k limitation */
return;
}
UNDEFARRAY(rgbaCopy); /* mac 32k limitation */
}
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->ClampFragmentColors) {
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);
}
}
else {
for (i = 0; i < n; i++) {
luminance[i] = rgba[i][RCOMP] + rgba[i][GCOMP] + rgba[i][BCOMP];
}
}
}
/*
* Pack/store the pixels. Ugh! Lots of cases!!!
*/
switch (dstType) {
case GL_UNSIGNED_BYTE:
{
GLubyte *dst = (GLubyte *) dstAddr;
switch (dstFormat) {
case GL_RED:
for (i=0;i<n;i++)
dst[i] = FLOAT_TO_UBYTE(rgba[i][RCOMP]);
break;
case GL_GREEN:
for (i=0;i<n;i++)
dst[i] = FLOAT_TO_UBYTE(rgba[i][GCOMP]);
break;
case GL_BLUE:
for (i=0;i<n;i++)
dst[i] = FLOAT_TO_UBYTE(rgba[i][BCOMP]);
break;
case GL_ALPHA:
for (i=0;i<n;i++)
dst[i] = FLOAT_TO_UBYTE(rgba[i][ACOMP]);
break;
case GL_LUMINANCE:
for (i=0;i<n;i++)
dst[i] = FLOAT_TO_UBYTE(luminance[i]);
break;
case GL_LUMINANCE_ALPHA:
for (i=0;i<n;i++) {
dst[i*2+0] = FLOAT_TO_UBYTE(luminance[i]);
dst[i*2+1] = FLOAT_TO_UBYTE(rgba[i][ACOMP]);
}
break;
case GL_RGB:
for (i=0;i<n;i++) {
dst[i*3+0] = FLOAT_TO_UBYTE(rgba[i][RCOMP]);
dst[i*3+1] = FLOAT_TO_UBYTE(rgba[i][GCOMP]);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -