image.c

来自「mesa-6.5-minigui源码」· C语言 代码 · 共 1,907 行 · 第 1/5 页

C
1,907
字号
   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. * NOTE: it's assumed the incoming float colors are all in [0,1]. */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 */      GLfloat rgbaCopy[MAX_WIDTH][4];      _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) {         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) {         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]);                     dst[i*3+2] = FLOAT_TO_UBYTE(rgba[i][BCOMP]);                  }                  break;               case GL_RGBA:                  for (i=0;i<n;i++) {                     dst[i*4+0] = FLOAT_TO_UBYTE(rgba[i][RCOMP]);                     dst[i*4+1] = FLOAT_TO_UBYTE(rgba[i][GCOMP]);                     dst[i*4+2] = FLOAT_TO_UBYTE(rgba[i][BCOMP]);                     dst[i*4+3] = FLOAT_TO_UBYTE(rgba[i][ACOMP]);                  }                  break;               case GL_BGR:                  for (i=0;i<n;i++) {                     dst[i*3+0] = FLOAT_TO_UBYTE(rgba[i][BCOMP]);

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?