home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / mesa5.zip / mesa5src.zip / MesaDLL / histogram.cpp < prev    next >
C/C++ Source or Header  |  2002-10-24  |  35KB  |  1,032 lines

  1. /* $Id: histogram.c,v 1.11 2002/10/24 23:57:21 brianp Exp $ */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  3.5
  6.  *
  7.  * Copyright (C) 1999-2001  Brian Paul   All Rights Reserved.
  8.  *
  9.  * Permission is hereby granted, free of charge, to any person obtaining a
  10.  * copy of this software and associated documentation files (the "Software"),
  11.  * to deal in the Software without restriction, including without limitation
  12.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  13.  * and/or sell copies of the Software, and to permit persons to whom the
  14.  * Software is furnished to do so, subject to the following conditions:
  15.  *
  16.  * The above copyright notice and this permission notice shall be included
  17.  * in all copies or substantial portions of the Software.
  18.  *
  19.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  20.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  21.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  22.  * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
  23.  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  24.  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  25.  */
  26.  
  27.  
  28. #include "glheader.h"
  29. #include "colormac.h"
  30. #include "context.h"
  31. #include "image.h"
  32. #include "histogram.h"
  33. #include "mmath.h"
  34.  
  35.  
  36. /*
  37.  * XXX the packed pixel formats haven't been tested.
  38.  */
  39. static void
  40. pack_histogram( GLcontext *ctx,
  41.                 GLuint n, CONST GLuint rgba[][4],
  42.                 GLenum format, GLenum type, GLvoid *destination,
  43.                 const struct gl_pixelstore_attrib *packing )
  44. {
  45.    const GLint comps = _mesa_components_in_format(format);
  46.    GLuint luminance[MAX_WIDTH];
  47.  
  48.    if (format == GL_LUMINANCE || format == GL_LUMINANCE_ALPHA) {
  49.       GLuint i;
  50.       for (i = 0; i < n; i++) {
  51.          luminance[i] = rgba[i][RCOMP] + rgba[i][GCOMP] + rgba[i][BCOMP];
  52.       }
  53.    }
  54.  
  55. #define PACK_MACRO(TYPE)                    \
  56.    {                                \
  57.       GLuint i;                            \
  58.       switch (format) {                        \
  59.          case GL_RED:                        \
  60.             for (i=0;i<n;i++)                    \
  61.                dst[i] = (TYPE) rgba[i][RCOMP];            \
  62.             break;                        \
  63.          case GL_GREEN:                        \
  64.             for (i=0;i<n;i++)                    \
  65.                dst[i] = (TYPE) rgba[i][GCOMP];            \
  66.             break;                        \
  67.          case GL_BLUE:                        \
  68.             for (i=0;i<n;i++)                    \
  69.                dst[i] = (TYPE) rgba[i][BCOMP];            \
  70.             break;                        \
  71.          case GL_ALPHA:                        \
  72.             for (i=0;i<n;i++)                    \
  73.                dst[i] = (TYPE) rgba[i][ACOMP];            \
  74.             break;                        \
  75.          case GL_LUMINANCE:                    \
  76.             for (i=0;i<n;i++)                    \
  77.                dst[i] = (TYPE) luminance[i];            \
  78.             break;                        \
  79.          case GL_LUMINANCE_ALPHA:                \
  80.             for (i=0;i<n;i++) {                    \
  81.                dst[i*2+0] = (TYPE) luminance[i];        \
  82.                dst[i*2+1] = (TYPE) rgba[i][ACOMP];        \
  83.             }                            \
  84.             break;                        \
  85.          case GL_RGB:                        \
  86.             for (i=0;i<n;i++) {                    \
  87.                dst[i*3+0] = (TYPE) rgba[i][RCOMP];        \
  88.                dst[i*3+1] = (TYPE) rgba[i][GCOMP];        \
  89.                dst[i*3+2] = (TYPE) rgba[i][BCOMP];        \
  90.             }                            \
  91.             break;                        \
  92.          case GL_RGBA:                        \
  93.             for (i=0;i<n;i++) {                    \
  94.                dst[i*4+0] = (TYPE) rgba[i][RCOMP];        \
  95.                dst[i*4+1] = (TYPE) rgba[i][GCOMP];        \
  96.                dst[i*4+2] = (TYPE) rgba[i][BCOMP];        \
  97.                dst[i*4+3] = (TYPE) rgba[i][ACOMP];        \
  98.             }                            \
  99.             break;                        \
  100.          case GL_BGR:                        \
  101.             for (i=0;i<n;i++) {                    \
  102.                dst[i*3+0] = (TYPE) rgba[i][BCOMP];        \
  103.                dst[i*3+1] = (TYPE) rgba[i][GCOMP];        \
  104.                dst[i*3+2] = (TYPE) rgba[i][RCOMP];        \
  105.             }                            \
  106.             break;                        \
  107.          case GL_BGRA:                        \
  108.             for (i=0;i<n;i++) {                    \
  109.                dst[i*4+0] = (TYPE) rgba[i][BCOMP];        \
  110.                dst[i*4+1] = (TYPE) rgba[i][GCOMP];        \
  111.                dst[i*4+2] = (TYPE) rgba[i][RCOMP];        \
  112.                dst[i*4+3] = (TYPE) rgba[i][ACOMP];        \
  113.             }                            \
  114.             break;                        \
  115.          case GL_ABGR_EXT:                    \
  116.             for (i=0;i<n;i++) {                    \
  117.                dst[i*4+0] = (TYPE) rgba[i][ACOMP];        \
  118.                dst[i*4+1] = (TYPE) rgba[i][BCOMP];        \
  119.                dst[i*4+2] = (TYPE) rgba[i][GCOMP];        \
  120.                dst[i*4+3] = (TYPE) rgba[i][RCOMP];        \
  121.             }                            \
  122.             break;                        \
  123.          default:                        \
  124.             _mesa_problem(ctx, "bad format in pack_histogram");    \
  125.       }                                \
  126.    }
  127.  
  128.    switch (type) {
  129.       case GL_UNSIGNED_BYTE:
  130.          {
  131.             GLubyte *dst = (GLubyte *) destination;
  132.             PACK_MACRO(GLubyte);
  133.          }
  134.          break;
  135.       case GL_BYTE:
  136.          {
  137.             GLbyte *dst = (GLbyte *) destination;
  138.             PACK_MACRO(GLbyte);
  139.          }
  140.          break;
  141.       case GL_UNSIGNED_SHORT:
  142.          {
  143.             GLushort *dst = (GLushort *) destination;
  144.             PACK_MACRO(GLushort);
  145.             if (packing->SwapBytes) {
  146.                _mesa_swap2(dst, n * comps);
  147.             }
  148.          }
  149.          break;
  150.       case GL_SHORT:
  151.          {
  152.             GLshort *dst = (GLshort *) destination;
  153.             PACK_MACRO(GLshort);
  154.             if (packing->SwapBytes) {
  155.                _mesa_swap2((GLushort *) dst, n * comps);
  156.             }
  157.          }
  158.          break;
  159.       case GL_UNSIGNED_INT:
  160.          {
  161.             GLuint *dst = (GLuint *) destination;
  162.             PACK_MACRO(GLuint);
  163.             if (packing->SwapBytes) {
  164.                _mesa_swap4(dst, n * comps);
  165.             }
  166.          }
  167.          break;
  168.       case GL_INT:
  169.          {
  170.             GLint *dst = (GLint *) destination;
  171.             PACK_MACRO(GLint);
  172.             if (packing->SwapBytes) {
  173.                _mesa_swap4((GLuint *) dst, n * comps);
  174.             }
  175.          }
  176.          break;
  177.       case GL_FLOAT:
  178.          {
  179.             GLfloat *dst = (GLfloat *) destination;
  180.             PACK_MACRO(GLfloat);
  181.             if (packing->SwapBytes) {
  182.                _mesa_swap4((GLuint *) dst, n * comps);
  183.             }
  184.          }
  185.          break;
  186.       case GL_UNSIGNED_BYTE_3_3_2:
  187.          if (format == GL_RGB) {
  188.             GLubyte *dst = (GLubyte *) destination;
  189.             GLuint i;
  190.             for (i = 0; i < n; i++) {
  191.                dst[i] = ((rgba[i][RCOMP] & 0x7) << 5)
  192.                       | ((rgba[i][GCOMP] & 0x7) << 2)
  193.                       | ((rgba[i][BCOMP] & 0x3)     );
  194.             }
  195.          }
  196.          else {
  197.             GLubyte *dst = (GLubyte *) destination;
  198.             GLuint i;
  199.             ASSERT(format == GL_BGR);
  200.             for (i = 0; i < n; i++) {
  201.                dst[i] = ((rgba[i][BCOMP] & 0x7) << 5)
  202.                       | ((rgba[i][GCOMP] & 0x7) << 2)
  203.                       | ((rgba[i][RCOMP] & 0x3)     );
  204.             }
  205.          }
  206.          break;
  207.       case GL_UNSIGNED_BYTE_2_3_3_REV:
  208.          if (format == GL_RGB) {
  209.             GLubyte *dst = (GLubyte *) destination;
  210.             GLuint i;
  211.             for (i = 0; i < n; i++) {
  212.                dst[i] = ((rgba[i][RCOMP] & 0x3) << 6)
  213.                       | ((rgba[i][GCOMP] & 0x7) << 3)
  214.                       | ((rgba[i][BCOMP] & 0x7)     );
  215.             }
  216.          }
  217.          else {
  218.             GLubyte *dst = (GLubyte *) destination;
  219.             GLuint i;
  220.             ASSERT(format == GL_BGR);
  221.             for (i = 0; i < n; i++) {
  222.                dst[i] = ((rgba[i][BCOMP] & 0x3) << 6)
  223.                       | ((rgba[i][GCOMP] & 0x7) << 3)
  224.                       | ((rgba[i][RCOMP] & 0x7)     );
  225.             }
  226.          }
  227.          break;
  228.       case GL_UNSIGNED_SHORT_5_6_5:
  229.          if (format == GL_RGB) {
  230.             GLushort *dst = (GLushort *) destination;
  231.             GLuint i;
  232.             for (i = 0; i < n; i++) {
  233.                dst[i] = ((rgba[i][RCOMP] & 0x1f) << 11)
  234.                       | ((rgba[i][GCOMP] & 0x3f) <<  5)
  235.                       | ((rgba[i][BCOMP] & 0x1f)      );
  236.             }
  237.          }
  238.          else {
  239.             GLushort *dst = (GLushort *) destination;
  240.             GLuint i;
  241.             ASSERT(format == GL_BGR);
  242.             for (i = 0; i < n; i++) {
  243.                dst[i] = ((rgba[i][BCOMP] & 0x1f) << 11)
  244.                       | ((rgba[i][GCOMP] & 0x3f) <<  5)
  245.                       | ((rgba[i][RCOMP] & 0x1f)      );
  246.             }
  247.          }
  248.          break;
  249.       case GL_UNSIGNED_SHORT_5_6_5_REV:
  250.          if (format == GL_RGB) {
  251.             GLushort *dst = (GLushort *) destination;
  252.             GLuint i;
  253.             for (i = 0; i < n; i++) {
  254.                dst[i] = ((rgba[i][BCOMP] & 0x1f) << 11)
  255.                       | ((rgba[i][GCOMP] & 0x3f) <<  5)
  256.                       | ((rgba[i][RCOMP] & 0x1f)      );
  257.             }
  258.          }
  259.          else {
  260.             GLushort *dst = (GLushort *) destination;
  261.             GLuint i;
  262.             ASSERT(format == GL_BGR);
  263.             for (i = 0; i < n; i++) {
  264.                dst[i] = ((rgba[i][RCOMP] & 0x1f) << 11)
  265.                       | ((rgba[i][GCOMP] & 0x3f) <<  5)
  266.                       | ((rgba[i][BCOMP] & 0x1f)      );
  267.             }
  268.          }
  269.          break;
  270.       case GL_UNSIGNED_SHORT_4_4_4_4:
  271.          if (format == GL_RGBA) {
  272.             GLushort *dst = (GLushort *) destination;
  273.             GLuint i;
  274.             for (i = 0; i < n; i++) {
  275.                dst[i] = ((rgba[i][RCOMP] & 0xf) << 12)
  276.                       | ((rgba[i][GCOMP] & 0xf) <<  8)
  277.                       | ((rgba[i][BCOMP] & 0xf) <<  4)
  278.                       | ((rgba[i][ACOMP] & 0xf)      );
  279.             }
  280.          }
  281.          else if (format == GL_BGRA) {
  282.             GLushort *dst = (GLushort *) destination;
  283.             GLuint i;
  284.             for (i = 0; i < n; i++) {
  285.                dst[i] = ((rgba[i][BCOMP] & 0xf) << 12)
  286.                       | ((rgba[i][GCOMP] & 0xf) <<  8)
  287.                       | ((rgba[i][RCOMP] & 0xf) <<  4)
  288.                       | ((rgba[i][ACOMP] & 0xf)      );
  289.             }
  290.          }
  291.          else {
  292.             GLushort *dst = (GLushort *) destination;
  293.             GLuint i;
  294.             ASSERT(format == GL_ABGR_EXT);
  295.             for (i = 0; i < n; i++) {
  296.                dst[i] = ((rgba[i][ACOMP] & 0xf) << 12)
  297.                       | ((rgba[i][BCOMP] & 0xf) <<  8)
  298.                       | ((rgba[i][GCOMP] & 0xf) <<  4)
  299.                       | ((rgba[i][RCOMP] & 0xf)      );
  300.             }
  301.          }
  302.          break;
  303.       case GL_UNSIGNED_SHORT_4_4_4_4_REV:
  304.          if (format == GL_RGBA) {
  305.             GLushort *dst = (GLushort *) destination;
  306.             GLuint i;
  307.             for (i = 0; i < n; i++) {
  308.                dst[i] = ((rgba[i][ACOMP] & 0xf) << 12)
  309.                       | ((rgba[i][BCOMP] & 0xf) <<  8)
  310.                       | ((rgba[i][GCOMP] & 0xf) <<  4)
  311.                       | ((rgba[i][RCOMP] & 0xf)      );
  312.             }
  313.          }
  314.          else if (format == GL_BGRA) {
  315.             GLushort *dst = (GLushort *) destination;
  316.             GLuint i;
  317.             for (i = 0; i < n; i++) {
  318.                dst[i] = ((rgba[i][ACOMP] & 0xf) << 12)
  319.                       | ((rgba[i][RCOMP] & 0xf) <<  8)
  320.                       | ((rgba[i][GCOMP] & 0xf) <<  4)
  321.                       | ((rgba[i][BCOMP] & 0xf)      );
  322.             }
  323.          }
  324.          else {
  325.             GLushort *dst = (GLushort *) destination;
  326.             GLuint i;
  327.             ASSERT(format == GL_ABGR_EXT);
  328.             for (i = 0; i < n; i++) {
  329.                dst[i] = ((rgba[i][RCOMP] & 0xf) << 12)
  330.                       | ((rgba[i][GCOMP] & 0xf) <<  8)
  331.                       | ((rgba[i][BCOMP] & 0xf) <<  4)
  332.                       | ((rgba[i][ACOMP] & 0xf)      );
  333.             }
  334.          }
  335.          break;
  336.       case GL_UNSIGNED_SHORT_5_5_5_1:
  337.          if (format == GL_RGBA) {
  338.             GLushort *dst = (GLushort *) destination;
  339.             GLuint i;
  340.             for (i = 0; i < n; i++) {
  341.                dst[i] = ((rgba[i][RCOMP] & 0x1f) << 11)
  342.                       | ((rgba[i][GCOMP] & 0x1f) <<  6)
  343.                       | ((rgba[i][BCOMP] & 0x1f) <<  1)
  344.                       | ((rgba[i][ACOMP] & 0x1)       );
  345.             }
  346.          }
  347.          else if (format == GL_BGRA) {
  348.             GLushort *dst = (GLushort *) destination;
  349.             GLuint i;
  350.             for (i = 0; i < n; i++) {
  351.                dst[i] = ((rgba[i][BCOMP] & 0x1f) << 11)
  352.                       | ((rgba[i][GCOMP] & 0x1f) <<  6)
  353.                       | ((rgba[i][RCOMP] & 0x1f) <<  1)
  354.                       | ((rgba[i][ACOMP] & 0x1)       );
  355.             }
  356.          }
  357.          else {
  358.             GLushort *dst = (GLushort *) destination;
  359.             GLuint i;
  360.             ASSERT(format == GL_ABGR_EXT);
  361.             for (i = 0; i < n; i++) {
  362.                dst[i] = ((rgba[i][ACOMP] & 0x1f) << 11)
  363.                       | ((rgba[i][BCOMP] & 0x1f) <<  6)
  364.                       | ((rgba[i][GCOMP] & 0x1f) <<  1)
  365.                       | ((rgba[i][RCOMP] & 0x1)       );
  366.             }
  367.          }
  368.          break;
  369.       case GL_UNSIGNED_SHORT_1_5_5_5_REV:
  370.          if (format == GL_RGBA) {
  371.             GLushort *dst = (GLushort *) destination;
  372.             GLuint i;
  373.             for (i = 0; i < n; i++) {
  374.                dst[i] = ((rgba[i][ACOMP] & 0x1f) << 11)
  375.                       | ((rgba[i][BCOMP] & 0x1f) <<  6)
  376.                       | ((rgba[i][GCOMP] & 0x1f) <<  1)
  377.                       | ((rgba[i][RCOMP] & 0x1)       );
  378.             }
  379.          }
  380.          else if (format == GL_BGRA) {
  381.             GLushort *dst = (GLushort *) destination;
  382.             GLuint i;
  383.             for (i = 0; i < n; i++) {
  384.                dst[i] = ((rgba[i][ACOMP] & 0x1f) << 11)
  385.                       | ((rgba[i][RCOMP] & 0x1f) <<  6)
  386.                       | ((rgba[i][GCOMP] & 0x1f) <<  1)
  387.                       | ((rgba[i][BCOMP] & 0x1)       );
  388.             }
  389.          }
  390.          else {
  391.             GLushort *dst = (GLushort *) destination;
  392.             GLuint i;
  393.             ASSERT(format == GL_ABGR_EXT);
  394.             for (i = 0; i < n; i++) {
  395.                dst[i] = ((rgba[i][RCOMP] & 0x1f) << 11)
  396.                       | ((rgba[i][GCOMP] & 0x1f) <<  6)
  397.                       | ((rgba[i][BCOMP] & 0x1f) <<  1)
  398.                       | ((rgba[i][ACOMP] & 0x1)       );
  399.             }
  400.          }
  401.          break;
  402.       case GL_UNSIGNED_INT_8_8_8_8:
  403.          if (format == GL_RGBA) {
  404.             GLuint *dst = (GLuint *) destination;
  405.             GLuint i;
  406.             for (i = 0; i < n; i++) {
  407.                dst[i] = ((rgba[i][RCOMP] & 0xff) << 24)
  408.                       | ((rgba[i][GCOMP] & 0xff) << 16)
  409.                       | ((rgba[i][BCOMP] & 0xff) <<  8)
  410.                       | ((rgba[i][ACOMP] & 0xff)      );
  411.             }
  412.          }
  413.          else if (format == GL_BGRA) {
  414.             GLuint *dst = (GLuint *) destination;
  415.             GLuint i;
  416.             for (i = 0; i < n; i++) {
  417.                dst[i] = ((rgba[i][BCOMP] & 0xff) << 24)
  418.                       | ((rgba[i][GCOMP] & 0xff) << 16)
  419.                       | ((rgba[i][RCOMP] & 0xff) <<  8)
  420.                       | ((rgba[i][ACOMP] & 0xff)      );
  421.             }
  422.          }
  423.          else {
  424.             GLuint *dst = (GLuint *) destination;
  425.             GLuint i;
  426.             ASSERT(format == GL_ABGR_EXT);
  427.             for (i = 0; i < n; i++) {
  428.                dst[i] = ((rgba[i][ACOMP] & 0xff) << 24)
  429.                       | ((rgba[i][BCOMP] & 0xff) << 16)
  430.                       | ((rgba[i][GCOMP] & 0xff) <<  8)
  431.                       | ((rgba[i][RCOMP] & 0xff)      );
  432.             }
  433.          }
  434.          break;
  435.       case GL_UNSIGNED_INT_8_8_8_8_REV:
  436.          if (format == GL_RGBA) {
  437.             GLuint *dst = (GLuint *) destination;
  438.             GLuint i;
  439.             for (i = 0; i < n; i++) {
  440.                dst[i] = ((rgba[i][ACOMP] & 0xff) << 24)
  441.                       | ((rgba[i][BCOMP] & 0xff) << 16)
  442.                       | ((rgba[i][GCOMP] & 0xff) <<  8)
  443.                       | ((rgba[i][RCOMP] & 0xff)      );
  444.             }
  445.          }
  446.          else if (format == GL_BGRA) {
  447.             GLuint *dst = (GLuint *) destination;
  448.             GLuint i;
  449.             for (i = 0; i < n; i++) {
  450.                dst[i] = ((rgba[i][ACOMP] & 0xff) << 24)
  451.                       | ((rgba[i][RCOMP] & 0xff) << 16)
  452.                       | ((rgba[i][GCOMP] & 0xff) <<  8)
  453.                       | ((rgba[i][BCOMP] & 0xff)      );
  454.             }
  455.          }
  456.          else {
  457.             GLuint *dst = (GLuint *) destination;
  458.             GLuint i;
  459.             ASSERT(format == GL_ABGR_EXT);
  460.             for (i = 0; i < n; i++) {
  461.                dst[i] = ((rgba[i][RCOMP] & 0xff) << 24)
  462.                       | ((rgba[i][GCOMP] & 0xff) << 16)
  463.                       | ((rgba[i][BCOMP] & 0xff) <<  8)
  464.                       | ((rgba[i][ACOMP] & 0xff)      );
  465.             }
  466.          }
  467.          break;
  468.       case GL_UNSIGNED_INT_10_10_10_2:
  469.          if (format == GL_RGBA) {
  470.             GLuint *dst = (GLuint *) destination;
  471.             GLuint i;
  472.             for (i = 0; i < n; i++) {
  473.                dst[i] = ((rgba[i][RCOMP] & 0x3ff) << 22)
  474.                       | ((rgba[i][GCOMP] & 0x3ff) << 12)
  475.                       | ((rgba[i][BCOMP] & 0x3ff) <<  2)
  476.                       | ((rgba[i][ACOMP] & 0x3)        );
  477.             }
  478.          }
  479.          else if (format == GL_BGRA) {
  480.             GLuint *dst = (GLuint *) destination;
  481.             GLuint i;
  482.             for (i = 0; i < n; i++) {
  483.                dst[i] = ((rgba[i][BCOMP] & 0x3ff) << 22)
  484.                       | ((rgba[i][GCOMP] & 0x3ff) << 12)
  485.                       | ((rgba[i][RCOMP] & 0x3ff) <<  2)
  486.                       | ((rgba[i][ACOMP] & 0x3)        );
  487.             }
  488.          }
  489.          else {
  490.             GLuint *dst = (GLuint *) destination;
  491.             GLuint i;
  492.             ASSERT(format == GL_ABGR_EXT);
  493.             for (i = 0; i < n; i++) {
  494.                dst[i] = ((rgba[i][ACOMP] & 0x3ff) << 22)
  495.                       | ((rgba[i][BCOMP] & 0x3ff) << 12)
  496.                       | ((rgba[i][GCOMP] & 0x3ff) <<  2)
  497.                       | ((rgba[i][RCOMP] & 0x3)        );
  498.             }
  499.          }
  500.          break;
  501.       case GL_UNSIGNED_INT_2_10_10_10_REV:
  502.          if (format == GL_RGBA) {
  503.             GLuint *dst = (GLuint *) destination;
  504.             GLuint i;
  505.             for (i = 0; i < n; i++) {
  506.                dst[i] = ((rgba[i][ACOMP] & 0x3ff) << 22)
  507.                       | ((rgba[i][BCOMP] & 0x3ff) << 12)
  508.                       | ((rgba[i][GCOMP] & 0x3ff) <<  2)
  509.                       | ((rgba[i][RCOMP] & 0x3)        );
  510.             }
  511.          }
  512.          else if (format == GL_BGRA) {
  513.             GLuint *dst = (GLuint *) destination;
  514.             GLuint i;
  515.             for (i = 0; i < n; i++) {
  516.                dst[i] = ((rgba[i][ACOMP] & 0x3ff) << 22)
  517.                       | ((rgba[i][RCOMP] & 0x3ff) << 12)
  518.                       | ((rgba[i][GCOMP] & 0x3ff) <<  2)
  519.                       | ((rgba[i][BCOMP] & 0x3)        );
  520.             }
  521.          }
  522.          else {
  523.             GLuint *dst = (GLuint *) destination;
  524.             GLuint i;
  525.             ASSERT(format == GL_ABGR_EXT);
  526.             for (i = 0; i < n; i++) {
  527.                dst[i] = ((rgba[i][RCOMP] & 0x3ff) << 22)
  528.                       | ((rgba[i][GCOMP] & 0x3ff) << 12)
  529.                       | ((rgba[i][BCOMP] & 0x3ff) <<  2)
  530.                       | ((rgba[i][ACOMP] & 0x3)        );
  531.             }
  532.          }
  533.          break;
  534.       default:
  535.          _mesa_problem(ctx, "Bad type in pack_histogram");
  536.    }
  537.  
  538. #undef PACK_MACRO
  539. }
  540.  
  541.  
  542. /*
  543.  * Given an internalFormat token passed to glHistogram or glMinMax,
  544.  * return the corresponding base format.
  545.  * Return -1 if invalid token.
  546.  */
  547. static GLint
  548. base_histogram_format( GLenum format )
  549. {
  550.    switch (format) {
  551.       case GL_ALPHA:
  552.       case GL_ALPHA4:
  553.       case GL_ALPHA8:
  554.       case GL_ALPHA12:
  555.       case GL_ALPHA16:
  556.          return GL_ALPHA;
  557.       case GL_LUMINANCE:
  558.       case GL_LUMINANCE4:
  559.       case GL_LUMINANCE8:
  560.       case GL_LUMINANCE12:
  561.       case GL_LUMINANCE16:
  562.          return GL_LUMINANCE;
  563.       case GL_LUMINANCE_ALPHA:
  564.       case GL_LUMINANCE4_ALPHA4:
  565.       case GL_LUMINANCE6_ALPHA2:
  566.       case GL_LUMINANCE8_ALPHA8:
  567.       case GL_LUMINANCE12_ALPHA4:
  568.       case GL_LUMINANCE12_ALPHA12:
  569.       case GL_LUMINANCE16_ALPHA16:
  570.          return GL_LUMINANCE_ALPHA;
  571.       case GL_RGB:
  572.       case GL_R3_G3_B2:
  573.       case GL_RGB4:
  574.       case GL_RGB5:
  575.       case GL_RGB8:
  576.       case GL_RGB10:
  577.       case GL_RGB12:
  578.       case GL_RGB16:
  579.          return GL_RGB;
  580.       case GL_RGBA:
  581.       case GL_RGBA2:
  582.       case GL_RGBA4:
  583.       case GL_RGB5_A1:
  584.       case GL_RGBA8:
  585.       case GL_RGB10_A2:
  586.       case GL_RGBA12:
  587.       case GL_RGBA16:
  588.          return GL_RGBA;
  589.       default:
  590.          return -1;  /* error */
  591.    }
  592. }
  593.  
  594.  
  595. void
  596. _mesa_GetMinmax(GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values)
  597. {
  598.    GET_CURRENT_CONTEXT(ctx);
  599.    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
  600.  
  601.    if (!ctx->Extensions.EXT_histogram && !ctx->Extensions.ARB_imaging) {
  602.       _mesa_error(ctx, GL_INVALID_OPERATION, "glGetMinmax");
  603.       return;
  604.    }
  605.  
  606.    if (target != GL_MINMAX) {
  607.       _mesa_error(ctx, GL_INVALID_ENUM, "glGetMinmax(target)");
  608.       return;
  609.    }
  610.  
  611.    if (!_mesa_is_legal_format_and_type(format, type)) {
  612.       _mesa_error(ctx, GL_INVALID_OPERATION, "glGetMinmax(format or type)");
  613.       return;
  614.    }
  615.  
  616.    if (type != GL_UNSIGNED_BYTE &&
  617.        type != GL_BYTE &&
  618.        type != GL_UNSIGNED_SHORT &&
  619.        type != GL_SHORT &&
  620.        type != GL_UNSIGNED_INT &&
  621.        type != GL_INT &&
  622.        type != GL_FLOAT &&
  623.        type != GL_UNSIGNED_BYTE_3_3_2 &&
  624.        type != GL_UNSIGNED_BYTE_2_3_3_REV &&
  625.        type != GL_UNSIGNED_SHORT_5_6_5 &&
  626.        type != GL_UNSIGNED_SHORT_5_6_5_REV &&
  627.        type != GL_UNSIGNED_SHORT_4_4_4_4 &&
  628.        type != GL_UNSIGNED_SHORT_4_4_4_4_REV &&
  629.        type != GL_UNSIGNED_SHORT_5_5_5_1 &&
  630.        type != GL_UNSIGNED_SHORT_1_5_5_5_REV &&
  631.        type != GL_UNSIGNED_INT_8_8_8_8 &&
  632.        type != GL_UNSIGNED_INT_8_8_8_8_REV &&
  633.        type != GL_UNSIGNED_INT_10_10_10_2 &&
  634.        type != GL_UNSIGNED_INT_2_10_10_10_REV) {
  635.       _mesa_error(ctx, GL_INVALID_ENUM, "glGetMinmax(type)");
  636.       return;
  637.    }
  638.  
  639.    if (!values)
  640.       return;
  641.  
  642.    {
  643.       GLfloat minmax[2][4];
  644.       minmax[0][RCOMP] = CLAMP(ctx->MinMax.Min[RCOMP], 0.0F, 1.0F);
  645.       minmax[0][GCOMP] = CLAMP(ctx->MinMax.Min[GCOMP], 0.0F, 1.0F);
  646.       minmax[0][BCOMP] = CLAMP(ctx->MinMax.Min[BCOMP], 0.0F, 1.0F);
  647.       minmax[0][ACOMP] = CLAMP(ctx->MinMax.Min[ACOMP], 0.0F, 1.0F);
  648.       minmax[1][RCOMP] = CLAMP(ctx->MinMax.Max[RCOMP], 0.0F, 1.0F);
  649.       minmax[1][GCOMP] = CLAMP(ctx->MinMax.Max[GCOMP], 0.0F, 1.0F);
  650.       minmax[1][BCOMP] = CLAMP(ctx->MinMax.Max[BCOMP], 0.0F, 1.0F);
  651.       minmax[1][ACOMP] = CLAMP(ctx->MinMax.Max[ACOMP], 0.0F, 1.0F);
  652.       _mesa_pack_float_rgba_span(ctx, 2, (CONST GLfloat (*)[4]) minmax,
  653.                                  format, type, values, &ctx->Pack, 0);
  654.    }
  655.  
  656.    if (reset) {
  657.       _mesa_ResetMinmax(GL_MINMAX);
  658.    }
  659. }
  660.  
  661.  
  662. void
  663. _mesa_GetHistogram(GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid *values)
  664. {
  665.    GET_CURRENT_CONTEXT(ctx);
  666.    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
  667.  
  668.    if (!ctx->Extensions.EXT_histogram && !ctx->Extensions.ARB_imaging) {
  669.       _mesa_error(ctx, GL_INVALID_OPERATION, "glGetHistogram");
  670.       return;
  671.    }
  672.  
  673.    if (target != GL_HISTOGRAM) {
  674.       _mesa_error(ctx, GL_INVALID_ENUM, "glGetHistogram(target)");
  675.       return;
  676.    }
  677.  
  678.    if (!_mesa_is_legal_format_and_type(format, type)) {
  679.       _mesa_error(ctx, GL_INVALID_OPERATION, "glGetHistogram(format or type)");
  680.       return;
  681.    }
  682.  
  683.    if (type != GL_UNSIGNED_BYTE &&
  684.        type != GL_BYTE &&
  685.        type != GL_UNSIGNED_SHORT &&
  686.        type != GL_SHORT &&
  687.        type != GL_UNSIGNED_INT &&
  688.        type != GL_INT &&
  689.        type != GL_FLOAT &&
  690.        type != GL_UNSIGNED_BYTE_3_3_2 &&
  691.        type != GL_UNSIGNED_BYTE_2_3_3_REV &&
  692.        type != GL_UNSIGNED_SHORT_5_6_5 &&
  693.        type != GL_UNSIGNED_SHORT_5_6_5_REV &&
  694.        type != GL_UNSIGNED_SHORT_4_4_4_4 &&
  695.        type != GL_UNSIGNED_SHORT_4_4_4_4_REV &&
  696.        type != GL_UNSIGNED_SHORT_5_5_5_1 &&
  697.        type != GL_UNSIGNED_SHORT_1_5_5_5_REV &&
  698.        type != GL_UNSIGNED_INT_8_8_8_8 &&
  699.        type != GL_UNSIGNED_INT_8_8_8_8_REV &&
  700.        type != GL_UNSIGNED_INT_10_10_10_2 &&
  701.        type != GL_UNSIGNED_INT_2_10_10_10_REV) {
  702.       _mesa_error(ctx, GL_INVALID_ENUM, "glGetHistogram(type)");
  703.       return;
  704.    }
  705.  
  706.    if (!values)
  707.       return;
  708.  
  709.    pack_histogram(ctx, ctx->Histogram.Width,
  710.                   (CONST GLuint (*)[4]) ctx->Histogram.Count,
  711.                   format, type, values, &ctx->Pack);
  712.  
  713.    if (reset) {
  714.       GLuint i;
  715.       for (i = 0; i < HISTOGRAM_TABLE_SIZE; i++) {
  716.          ctx->Histogram.Count[i][0] = 0;
  717.          ctx->Histogram.Count[i][1] = 0;
  718.          ctx->Histogram.Count[i][2] = 0;
  719.          ctx->Histogram.Count[i][3] = 0;
  720.       }
  721.    }
  722. }
  723.  
  724.  
  725. void
  726. _mesa_GetHistogramParameterfv(GLenum target, GLenum pname, GLfloat *params)
  727. {
  728.    GET_CURRENT_CONTEXT(ctx);
  729.    ASSERT_OUTSIDE_BEGIN_END(ctx);
  730.  
  731.    if (!ctx->Extensions.EXT_histogram && !ctx->Extensions.ARB_imaging) {
  732.       _mesa_error(ctx, GL_INVALID_OPERATION, "glGetHistogramParameterfv");
  733.       return;
  734.    }
  735.  
  736.    if (target != GL_HISTOGRAM && target != GL_PROXY_HISTOGRAM) {
  737.       _mesa_error(ctx, GL_INVALID_ENUM, "glGetHistogramParameterfv(target)");
  738.       return;
  739.    }
  740.  
  741.    switch (pname) {
  742.       case GL_HISTOGRAM_WIDTH:
  743.          *params = (GLfloat) ctx->Histogram.Width;
  744.          break;
  745.       case GL_HISTOGRAM_FORMAT:
  746.          *params = (GLfloat) ctx->Histogram.Format;
  747.          break;
  748.       case GL_HISTOGRAM_RED_SIZE:
  749.          *params = (GLfloat) ctx->Histogram.RedSize;
  750.          break;
  751.       case GL_HISTOGRAM_GREEN_SIZE:
  752.          *params = (GLfloat) ctx->Histogram.GreenSize;
  753.          break;
  754.       case GL_HISTOGRAM_BLUE_SIZE:
  755.          *params = (GLfloat) ctx->Histogram.BlueSize;
  756.          break;
  757.       case GL_HISTOGRAM_ALPHA_SIZE:
  758.          *params = (GLfloat) ctx->Histogram.AlphaSize;
  759.          break;
  760.       case GL_HISTOGRAM_LUMINANCE_SIZE:
  761.          *params = (GLfloat) ctx->Histogram.LuminanceSize;
  762.          break;
  763.       case GL_HISTOGRAM_SINK:
  764.          *params = (GLfloat) ctx->Histogram.Sink;
  765.          break;
  766.       default:
  767.          _mesa_error(ctx, GL_INVALID_ENUM, "glGetHistogramParameterfv(pname)");
  768.    }
  769. }
  770.  
  771.  
  772. void
  773. _mesa_GetHistogramParameteriv(GLenum target, GLenum pname, GLint *params)
  774. {
  775.    GET_CURRENT_CONTEXT(ctx);
  776.    ASSERT_OUTSIDE_BEGIN_END(ctx);
  777.  
  778.    if (!ctx->Extensions.EXT_histogram && !ctx->Extensions.ARB_imaging) {
  779.       _mesa_error(ctx, GL_INVALID_OPERATION, "glGetHistogramParameteriv");
  780.       return;
  781.    }
  782.  
  783.    if (target != GL_HISTOGRAM && target != GL_PROXY_HISTOGRAM) {
  784.       _mesa_error(ctx, GL_INVALID_ENUM, "glGetHistogramParameteriv(target)");
  785.       return;
  786.    }
  787.  
  788.    switch (pname) {
  789.       case GL_HISTOGRAM_WIDTH:
  790.          *params = (GLint) ctx->Histogram.Width;
  791.          break;
  792.       case GL_HISTOGRAM_FORMAT:
  793.          *params = (GLint) ctx->Histogram.Format;
  794.          break;
  795.       case GL_HISTOGRAM_RED_SIZE:
  796.          *params = (GLint) ctx->Histogram.RedSize;
  797.          break;
  798.       case GL_HISTOGRAM_GREEN_SIZE:
  799.          *params = (GLint) ctx->Histogram.GreenSize;
  800.          break;
  801.       case GL_HISTOGRAM_BLUE_SIZE:
  802.          *params = (GLint) ctx->Histogram.BlueSize;
  803.          break;
  804.       case GL_HISTOGRAM_ALPHA_SIZE:
  805.          *params = (GLint) ctx->Histogram.AlphaSize;
  806.          break;
  807.       case GL_HISTOGRAM_LUMINANCE_SIZE:
  808.          *params = (GLint) ctx->Histogram.LuminanceSize;
  809.          break;
  810.       case GL_HISTOGRAM_SINK:
  811.          *params = (GLint) ctx->Histogram.Sink;
  812.          break;
  813.       default:
  814.          _mesa_error(ctx, GL_INVALID_ENUM, "glGetHistogramParameteriv(pname)");
  815.    }
  816. }
  817.  
  818.  
  819. void
  820. _mesa_GetMinmaxParameterfv(GLenum target, GLenum pname, GLfloat *params)
  821. {
  822.    GET_CURRENT_CONTEXT(ctx);
  823.    ASSERT_OUTSIDE_BEGIN_END(ctx);
  824.  
  825.    if (!ctx->Extensions.EXT_histogram && !ctx->Extensions.ARB_imaging) {
  826.       _mesa_error(ctx, GL_INVALID_OPERATION, "glGetMinmaxParameterfv");
  827.       return;
  828.    }
  829.    if (target != GL_MINMAX) {
  830.       _mesa_error(ctx, GL_INVALID_ENUM, "glGetMinmaxParameterfv(target)");
  831.       return;
  832.    }
  833.    if (pname == GL_MINMAX_FORMAT) {
  834.       *params = (GLfloat) ctx->MinMax.Format;
  835.    }
  836.    else if (pname == GL_MINMAX_SINK) {
  837.       *params = (GLfloat) ctx->MinMax.Sink;
  838.    }
  839.    else {
  840.       _mesa_error(ctx, GL_INVALID_ENUM, "glGetMinMaxParameterfv(pname)");
  841.    }
  842. }
  843.  
  844.  
  845. void
  846. _mesa_GetMinmaxParameteriv(GLenum target, GLenum pname, GLint *params)
  847. {
  848.    GET_CURRENT_CONTEXT(ctx);
  849.    ASSERT_OUTSIDE_BEGIN_END(ctx);
  850.  
  851.    if (!ctx->Extensions.EXT_histogram && !ctx->Extensions.ARB_imaging) {
  852.       _mesa_error(ctx, GL_INVALID_OPERATION, "glGetMinmaxParameteriv");
  853.       return;
  854.    }
  855.    if (target != GL_MINMAX) {
  856.       _mesa_error(ctx, GL_INVALID_ENUM, "glGetMinmaxParameteriv(target)");
  857.       return;
  858.    }
  859.    if (pname == GL_MINMAX_FORMAT) {
  860.       *params = (GLint) ctx->MinMax.Format;
  861.    }
  862.    else if (pname == GL_MINMAX_SINK) {
  863.       *params = (GLint) ctx->MinMax.Sink;
  864.    }
  865.    else {
  866.       _mesa_error(ctx, GL_INVALID_ENUM, "glGetMinMaxParameteriv(pname)");
  867.    }
  868. }
  869.  
  870.  
  871. void
  872. _mesa_Histogram(GLenum target, GLsizei width, GLenum internalFormat, GLboolean sink)
  873. {
  874.    GLuint i;
  875.    GLboolean error = GL_FALSE;
  876.    GET_CURRENT_CONTEXT(ctx);
  877.    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); /* sideeffects */
  878.  
  879.    if (!ctx->Extensions.EXT_histogram && !ctx->Extensions.ARB_imaging) {
  880.       _mesa_error(ctx, GL_INVALID_OPERATION, "glHistogram");
  881.       return;
  882.    }
  883.  
  884.    if (target != GL_HISTOGRAM && target != GL_PROXY_HISTOGRAM) {
  885.       _mesa_error(ctx, GL_INVALID_ENUM, "glHistogram(target)");
  886.       return;
  887.    }
  888.  
  889.    if (width < 0 || width > HISTOGRAM_TABLE_SIZE) {
  890.       if (target == GL_PROXY_HISTOGRAM) {
  891.          error = GL_TRUE;
  892.       }
  893.       else {
  894.          if (width < 0)
  895.             _mesa_error(ctx, GL_INVALID_VALUE, "glHistogram(width)");
  896.          else
  897.             _mesa_error(ctx, GL_TABLE_TOO_LARGE, "glHistogram(width)");
  898.          return;
  899.       }
  900.    }
  901.  
  902.    if (width != 0 && _mesa_bitcount(width) != 1) {
  903.       if (target == GL_PROXY_HISTOGRAM) {
  904.          error = GL_TRUE;
  905.       }
  906.       else {
  907.          _mesa_error(ctx, GL_INVALID_VALUE, "glHistogram(width)");
  908.          return;
  909.       }
  910.    }
  911.  
  912.    if (base_histogram_format(internalFormat) < 0) {
  913.       if (target == GL_PROXY_HISTOGRAM) {
  914.          error = GL_TRUE;
  915.       }
  916.       else {
  917.          _mesa_error(ctx, GL_INVALID_ENUM, "glHistogram(internalFormat)");
  918.          return;
  919.       }
  920.    }
  921.  
  922.    /* reset histograms */
  923.    for (i = 0; i < HISTOGRAM_TABLE_SIZE; i++) {
  924.       ctx->Histogram.Count[i][0] = 0;
  925.       ctx->Histogram.Count[i][1] = 0;
  926.       ctx->Histogram.Count[i][2] = 0;
  927.       ctx->Histogram.Count[i][3] = 0;
  928.    }
  929.  
  930.    if (error) {
  931.       ctx->Histogram.Width = 0;
  932.       ctx->Histogram.Format = 0;
  933.       ctx->Histogram.RedSize       = 0;
  934.       ctx->Histogram.GreenSize     = 0;
  935.       ctx->Histogram.BlueSize      = 0;
  936.       ctx->Histogram.AlphaSize     = 0;
  937.       ctx->Histogram.LuminanceSize = 0;
  938.    }
  939.    else {
  940.       ctx->Histogram.Width = width;
  941.       ctx->Histogram.Format = internalFormat;
  942.       ctx->Histogram.Sink = sink;
  943.       ctx->Histogram.RedSize       = 8 * sizeof(GLuint);
  944.       ctx->Histogram.GreenSize     = 8 * sizeof(GLuint);
  945.       ctx->Histogram.BlueSize      = 8 * sizeof(GLuint);
  946.       ctx->Histogram.AlphaSize     = 8 * sizeof(GLuint);
  947.       ctx->Histogram.LuminanceSize = 8 * sizeof(GLuint);
  948.    }
  949.  
  950.    ctx->NewState |= _NEW_PIXEL;
  951. }
  952.  
  953.  
  954. void
  955. _mesa_Minmax(GLenum target, GLenum internalFormat, GLboolean sink)
  956. {
  957.    GET_CURRENT_CONTEXT(ctx);
  958.    ASSERT_OUTSIDE_BEGIN_END(ctx);
  959.  
  960.    if (!ctx->Extensions.EXT_histogram && !ctx->Extensions.ARB_imaging) {
  961.       _mesa_error(ctx, GL_INVALID_OPERATION, "glMinmax");
  962.       return;
  963.    }
  964.  
  965.    if (target != GL_MINMAX) {
  966.       _mesa_error(ctx, GL_INVALID_ENUM, "glMinMax(target)");
  967.       return;
  968.    }
  969.  
  970.    if (base_histogram_format(internalFormat) < 0) {
  971.       _mesa_error(ctx, GL_INVALID_ENUM, "glMinMax(internalFormat)");
  972.       return;
  973.    }
  974.  
  975.    if (ctx->MinMax.Sink == sink)
  976.       return;
  977.    FLUSH_VERTICES(ctx, _NEW_PIXEL);
  978.    ctx->MinMax.Sink = sink;
  979. }
  980.  
  981.  
  982. void
  983. _mesa_ResetHistogram(GLenum target)
  984. {
  985.    GLuint i;
  986.    GET_CURRENT_CONTEXT(ctx);
  987.    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); /* sideeffects */
  988.  
  989.    if (!ctx->Extensions.EXT_histogram && !ctx->Extensions.ARB_imaging) {
  990.       _mesa_error(ctx, GL_INVALID_OPERATION, "glResetHistogram");
  991.       return;
  992.    }
  993.  
  994.    if (target != GL_HISTOGRAM) {
  995.       _mesa_error(ctx, GL_INVALID_ENUM, "glResetHistogram(target)");
  996.       return;
  997.    }
  998.  
  999.    for (i = 0; i < HISTOGRAM_TABLE_SIZE; i++) {
  1000.       ctx->Histogram.Count[i][0] = 0;
  1001.       ctx->Histogram.Count[i][1] = 0;
  1002.       ctx->Histogram.Count[i][2] = 0;
  1003.       ctx->Histogram.Count[i][3] = 0;
  1004.    }
  1005.  
  1006.    ctx->NewState |= _NEW_PIXEL;
  1007. }
  1008.  
  1009.  
  1010. void
  1011. _mesa_ResetMinmax(GLenum target)
  1012. {
  1013.    GET_CURRENT_CONTEXT(ctx);
  1014.    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
  1015.  
  1016.    if (!ctx->Extensions.EXT_histogram && !ctx->Extensions.ARB_imaging) {
  1017.       _mesa_error(ctx, GL_INVALID_OPERATION, "glResetMinmax");
  1018.       return;
  1019.    }
  1020.  
  1021.    if (target != GL_MINMAX) {
  1022.       _mesa_error(ctx, GL_INVALID_ENUM, "glResetMinMax(target)");
  1023.       return;
  1024.    }
  1025.  
  1026.    ctx->MinMax.Min[RCOMP] = 1000;    ctx->MinMax.Max[RCOMP] = -1000;
  1027.    ctx->MinMax.Min[GCOMP] = 1000;    ctx->MinMax.Max[GCOMP] = -1000;
  1028.    ctx->MinMax.Min[BCOMP] = 1000;    ctx->MinMax.Max[BCOMP] = -1000;
  1029.    ctx->MinMax.Min[ACOMP] = 1000;    ctx->MinMax.Max[ACOMP] = -1000;
  1030.    ctx->NewState |= _NEW_PIXEL;
  1031. }
  1032.