⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 image.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 5 页
字号:
    * 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 + -