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

  1. /* $Id: texutil.c,v 1.34 2002/10/29 20:28:53 brianp Exp $ */
  2.  
  3. /*
  4.  * Mesa 3-D graphics library
  5.  * Version:  4.1
  6.  *
  7.  * Copyright (C) 1999-2002  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.  * Authors:
  27.  *    Gareth Hughes
  28.  */
  29.  
  30. /*
  31.  * Description:
  32.  * Functions for texture image conversion.  This takes care of converting
  33.  * typical GL_RGBA/GLubyte textures into hardware-specific formats.
  34.  * We can handle non-standard row strides and pixel unpacking parameters.
  35.  */
  36.  
  37.  
  38. #include "glheader.h"
  39. #include "context.h"
  40. #include "enums.h"
  41. #include "image.h"
  42. #include "imports.h"
  43. #include "macros.h"
  44. #include "mtypes.h"
  45. #include "texformat.h"
  46. #include "texutil.h"
  47.  
  48.  
  49. #define DEBUG_TEXUTIL 0
  50.  
  51.  
  52. #ifdef MESA_BIG_ENDIAN
  53. #define APPEND16( a, b )    ( (a) << 16 | (b) )
  54. #else
  55. #define APPEND16( a, b )    ( (a) | (b) << 16 )
  56. #endif
  57.  
  58.  
  59. struct convert_info {
  60.    GLint xoffset, yoffset, zoffset;    /* Subimage offset */
  61.    GLint width, height, depth;        /* Subimage region */
  62.  
  63.    GLint dstImageWidth, dstImageHeight;    /* Dest image size */
  64.                                         /* Needed for subimage replacement */
  65.    GLenum format, type;                 /* Source (user) format and type */
  66.  
  67.    const struct gl_pixelstore_attrib *unpacking;
  68.  
  69.    const GLvoid *srcImage;
  70.    GLvoid *dstImage;
  71.  
  72.    GLint index;
  73. };
  74.  
  75. typedef GLboolean (*convert_func)( const struct convert_info *convert );
  76.  
  77. /* bitvalues for convert->index */
  78. #define CONVERT_STRIDE_BIT    0x1
  79. #define CONVERT_UNPACKING_BIT    0x2
  80.  
  81.  
  82.  
  83. /* =============================================================
  84.  * Convert to RGBA8888 textures:
  85.  */
  86.  
  87. #define DST_TYPE        GLuint
  88. #define DST_TEXELS_PER_DWORD    1
  89.  
  90. #define CONVERT_TEXEL( dst, src )                    \
  91.     dst = PACK_COLOR_8888_LE( src[3], src[2], src[1], src[0] )
  92.  
  93. #define CONVERT_DIRECT
  94.  
  95. #define SRC_TEXEL_BYTES        4
  96.  
  97. #define TAG(x) x##_rgba8888_direct
  98. #define PRESERVE_DST_TYPE
  99. #include "texutil_tmp.h"
  100.  
  101.  
  102. #define CONVERT_TEXEL( dst, src )                    \
  103.     dst = PACK_COLOR_8888_LE( src[0], src[1], src[2], src[3] )
  104.  
  105. #define CONVERT_TEXEL_DWORD( dst, src )        CONVERT_TEXEL( dst, src )
  106.  
  107. #define SRC_TEXEL_BYTES        4
  108.  
  109. #define TAG(x) x##_abgr8888_to_rgba8888
  110. #define PRESERVE_DST_TYPE
  111. #include "texutil_tmp.h"
  112.  
  113.  
  114. #define CONVERT_TEXEL( dst, src )                    \
  115.     dst = PACK_COLOR_8888_LE( src[0], src[1], src[2], 0xff )
  116.  
  117. #define CONVERT_TEXEL_DWORD( dst, src )        CONVERT_TEXEL( dst, src )
  118.  
  119. #define SRC_TEXEL_BYTES        3
  120.  
  121. #define TAG(x) x##_bgr888_to_rgba8888
  122. #include "texutil_tmp.h"
  123.  
  124.  
  125. #define CONVERT_RGBA8888( name )                    \
  126. static GLboolean                            \
  127. convert_##name##_rgba8888( const struct convert_info *convert )        \
  128. {                                    \
  129.    convert_func *tab;                            \
  130.    GLint index = convert->index;                    \
  131.                                     \
  132.    if ( convert->format == GL_ABGR_EXT &&                \
  133.     convert->type == GL_UNSIGNED_INT_8_8_8_8_REV )            \
  134.    {                                    \
  135.       tab = name##_tab_rgba8888_direct;                    \
  136.    }                                    \
  137.    else if ( convert->format == GL_RGBA &&                \
  138.          ( convert->type == GL_UNSIGNED_BYTE ||            \
  139.            convert->type == GL_UNSIGNED_INT_8_8_8_8 ) )        \
  140.    {                                    \
  141.       tab = name##_tab_abgr8888_to_rgba8888;                \
  142.    }                                    \
  143.    else if ( convert->format == GL_RGB &&                \
  144.          convert->type == GL_UNSIGNED_BYTE )            \
  145.    {                                    \
  146.       tab = name##_tab_bgr888_to_rgba8888;                \
  147.    }                                    \
  148.    else                                    \
  149.    {                                    \
  150.       /* Can't handle this source format/type combination */        \
  151.       return GL_FALSE;                            \
  152.    }                                    \
  153.                                     \
  154.    return tab[index]( convert );                    \
  155. }
  156.  
  157. CONVERT_RGBA8888( texsubimage2d )
  158. CONVERT_RGBA8888( texsubimage3d )
  159.  
  160.  
  161.  
  162. /* =============================================================
  163.  * Convert to ARGB8888 textures:
  164.  */
  165.  
  166. #define DST_TYPE        GLuint
  167. #define DST_TEXELS_PER_DWORD    1
  168.  
  169. #define CONVERT_TEXEL( dst, src )                    \
  170.     dst = PACK_COLOR_8888_LE( src[3], src[2], src[1], src[0] )
  171.  
  172. #define CONVERT_DIRECT
  173.  
  174. #define SRC_TEXEL_BYTES        4
  175.  
  176. #define TAG(x) x##_argb8888_direct
  177. #define PRESERVE_DST_TYPE
  178. #include "texutil_tmp.h"
  179.  
  180.  
  181. #define CONVERT_TEXEL( dst, src )                    \
  182.     dst = PACK_COLOR_8888_LE( src[3], src[0], src[1], src[2] )
  183.  
  184. #define CONVERT_TEXEL_DWORD( dst, src )        CONVERT_TEXEL( dst, src )
  185.  
  186. #define SRC_TEXEL_BYTES        4
  187.  
  188. #define TAG(x) x##_abgr8888_to_argb8888
  189. #define PRESERVE_DST_TYPE
  190. #include "texutil_tmp.h"
  191.  
  192.  
  193. #define CONVERT_TEXEL( dst, src )                    \
  194.     dst = PACK_COLOR_8888_LE( 0xff, src[0], src[1], src[2] )
  195.  
  196. #define CONVERT_TEXEL_DWORD( dst, src )        CONVERT_TEXEL( dst, src )
  197.  
  198. #define SRC_TEXEL_BYTES        3
  199.  
  200. #define TAG(x) x##_bgr888_to_argb8888
  201. #include "texutil_tmp.h"
  202.  
  203.  
  204. #define CONVERT_ARGB8888( name )                    \
  205. static GLboolean                            \
  206. convert_##name##_argb8888( const struct convert_info *convert )        \
  207. {                                    \
  208.    convert_func *tab;                            \
  209.    GLint index = convert->index;                    \
  210.                                     \
  211.    if ( convert->format == GL_BGRA &&                    \
  212.     convert->type == GL_UNSIGNED_INT_8_8_8_8_REV )            \
  213.    {                                    \
  214.       tab = name##_tab_argb8888_direct;                    \
  215.    }                                    \
  216.    else if ( convert->format == GL_RGBA &&                \
  217.          convert->type == GL_UNSIGNED_BYTE )            \
  218.    {                                    \
  219.       tab = name##_tab_abgr8888_to_argb8888;                \
  220.    }                                    \
  221.    else if ( convert->format == GL_RGB &&                \
  222.          convert->type == GL_UNSIGNED_BYTE )            \
  223.    {                                    \
  224.       tab = name##_tab_bgr888_to_argb8888;                \
  225.    }                                    \
  226.    else                                    \
  227.    {                                    \
  228.       /* Can't handle this source format/type combination */        \
  229.       return GL_FALSE;                            \
  230.    }                                    \
  231.                                     \
  232.    return tab[index]( convert );                    \
  233. }
  234.  
  235. CONVERT_ARGB8888( texsubimage2d )
  236. CONVERT_ARGB8888( texsubimage3d )
  237.  
  238.  
  239.  
  240. /* =============================================================
  241.  * Convert to RGB888 textures:
  242.  */
  243.  
  244. static GLboolean
  245. convert_texsubimage2d_rgb888( const struct convert_info *convert )
  246. {
  247.    /* This is a placeholder for now...
  248.     */
  249.    return GL_FALSE;
  250. }
  251.  
  252. static GLboolean
  253. convert_texsubimage3d_rgb888( const struct convert_info *convert )
  254. {
  255.    /* This is a placeholder for now...
  256.     */
  257.    return GL_FALSE;
  258. }
  259.  
  260.  
  261.  
  262. /* =============================================================
  263.  * Convert to RGB565 textures:
  264.  */
  265.  
  266. #define DST_TYPE        GLushort
  267. #define DST_TEXELS_PER_DWORD    2
  268.  
  269. #define CONVERT_TEXEL( dst, src )                    \
  270.     dst = PACK_COLOR_565_LE( src[0], src[1], src[2] )
  271.  
  272. #define CONVERT_DIRECT
  273.  
  274. #define SRC_TEXEL_BYTES        2
  275.  
  276. #define TAG(x) x##_rgb565_direct
  277. #define PRESERVE_DST_TYPE
  278. #include "texutil_tmp.h"
  279.  
  280.  
  281. #define CONVERT_TEXEL( dst, src )                    \
  282.     dst = PACK_COLOR_565_LE( src[0], src[1], src[2] )
  283.  
  284. #define CONVERT_TEXEL_DWORD( dst, src )                    \
  285.     dst = APPEND16( PACK_COLOR_565_LE( src[0], src[1], src[2] ),    \
  286.             PACK_COLOR_565_LE( src[3], src[4], src[5] ) )
  287.  
  288. #define SRC_TEXEL_BYTES        3
  289.  
  290. #define TAG(x) x##_bgr888_to_rgb565
  291. #define PRESERVE_DST_TYPE
  292. #include "texutil_tmp.h"
  293.  
  294.  
  295. #define CONVERT_TEXEL( dst, src )                    \
  296.     dst = PACK_COLOR_565_LE( src[0], src[1], src[2] )
  297.  
  298. #define CONVERT_TEXEL_DWORD( dst, src )                    \
  299.     dst = APPEND16( PACK_COLOR_565_LE( src[0], src[1], src[2] ),    \
  300.             PACK_COLOR_565_LE( src[4], src[5], src[6] ) )
  301.  
  302. #define SRC_TEXEL_BYTES        4
  303.  
  304. #define TAG(x) x##_abgr8888_to_rgb565
  305. #include "texutil_tmp.h"
  306.  
  307.  
  308. #define CONVERT_RGB565( name )                        \
  309. static GLboolean                            \
  310. convert_##name##_rgb565( const struct convert_info *convert )        \
  311. {                                    \
  312.    convert_func *tab;                            \
  313.    GLint index = convert->index;                    \
  314.                                     \
  315.    if ( convert->format == GL_RGB &&                    \
  316.     convert->type == GL_UNSIGNED_SHORT_5_6_5 )            \
  317.    {                                    \
  318.       tab = name##_tab_rgb565_direct;                    \
  319.    }                                    \
  320.    else if ( convert->format == GL_RGB &&                \
  321.          convert->type == GL_UNSIGNED_BYTE )            \
  322.    {                                    \
  323.       tab = name##_tab_bgr888_to_rgb565;                \
  324.    }                                    \
  325.    else if ( convert->format == GL_RGBA &&                \
  326.          convert->type == GL_UNSIGNED_BYTE )            \
  327.    {                                    \
  328.       tab = name##_tab_abgr8888_to_rgb565;                \
  329.    }                                    \
  330.    else                                    \
  331.    {                                    \
  332.       /* Can't handle this source format/type combination */        \
  333.       return GL_FALSE;                            \
  334.    }                                    \
  335.                                     \
  336.    return tab[index]( convert );                    \
  337. }
  338.  
  339. CONVERT_RGB565( texsubimage2d )
  340. CONVERT_RGB565( texsubimage3d )
  341.  
  342.  
  343.  
  344. /* =============================================================
  345.  * Convert to ARGB4444 textures:
  346.  */
  347.  
  348. #define DST_TYPE        GLushort
  349. #define DST_TEXELS_PER_DWORD    2
  350.  
  351. #define CONVERT_TEXEL( dst, src )                    \
  352.     dst = PACK_COLOR_4444_LE( src[3], src[0], src[1], src[2] )
  353.  
  354. #define CONVERT_DIRECT
  355.  
  356. #define SRC_TEXEL_BYTES        2
  357.  
  358. #define TAG(x) x##_argb4444_direct
  359. #define PRESERVE_DST_TYPE
  360. #include "texutil_tmp.h"
  361.  
  362.  
  363. #define CONVERT_TEXEL( dst, src )                    \
  364.     dst = PACK_COLOR_4444_LE( src[3], src[0], src[1], src[2] )
  365.  
  366. #define CONVERT_TEXEL_DWORD( dst, src )                    \
  367.     dst = APPEND16( PACK_COLOR_4444_LE( src[3], src[0], src[1], src[2] ),    \
  368.             PACK_COLOR_4444_LE( src[7], src[4], src[5], src[6] ) )
  369.  
  370. #define SRC_TEXEL_BYTES        4
  371.  
  372. #define TAG(x) x##_abgr8888_to_argb4444
  373. #include "texutil_tmp.h"
  374.  
  375.  
  376. #define CONVERT_ARGB4444( name )                    \
  377. static GLboolean                            \
  378. convert_##name##_argb4444( const struct convert_info *convert )        \
  379. {                                    \
  380.    convert_func *tab;                            \
  381.    GLint index = convert->index;                    \
  382.                                     \
  383.    if ( convert->format == GL_BGRA &&                    \
  384.     convert->type == GL_UNSIGNED_SHORT_4_4_4_4_REV )        \
  385.    {                                    \
  386.       tab = name##_tab_argb4444_direct;                    \
  387.    }                                    \
  388.    else if ( convert->format == GL_RGBA &&                \
  389.          convert->type == GL_UNSIGNED_BYTE )            \
  390.    {                                    \
  391.       tab = name##_tab_abgr8888_to_argb4444;                \
  392.    }                                    \
  393.    else                                    \
  394.    {                                    \
  395.       /* Can't handle this source format/type combination */        \
  396.       return GL_FALSE;                            \
  397.    }                                    \
  398.                                     \
  399.    return tab[index]( convert );                    \
  400. }
  401.  
  402. CONVERT_ARGB4444( texsubimage2d )
  403. CONVERT_ARGB4444( texsubimage3d )
  404.  
  405.  
  406.  
  407. /* =============================================================
  408.  * Convert to ARGB1555 textures:
  409.  */
  410.  
  411. #define DST_TYPE        GLushort
  412. #define DST_TEXELS_PER_DWORD    2
  413.  
  414. #define CONVERT_TEXEL( dst, src )                    \
  415.     dst = PACK_COLOR_1555_LE( src[3], src[0], src[1], src[2] )
  416.  
  417. #define CONVERT_DIRECT
  418.  
  419. #define SRC_TEXEL_BYTES        2
  420.  
  421. #define TAG(x) x##_argb1555_direct
  422. #define PRESERVE_DST_TYPE
  423. #include "texutil_tmp.h"
  424.  
  425.  
  426. #ifdef MESA_BIG_ENDIAN
  427.  
  428. #define CONVERT_TEXEL( dst, src )                    \
  429.     { const GLushort s = *(GLushort *)src;                \
  430.       dst = (s >> 9) | ((s & 0x1ff) << 7); }
  431.  
  432. #define CONVERT_TEXEL_DWORD( dst, src )                    \
  433.     { const GLuint s = ((fi_type *)src)->i;                \
  434.       dst = (((s & 0xfe00fe00) >> 9) |                \
  435.          ((s & 0x01ff01ff) << 7)); }
  436.  
  437. #else
  438.  
  439. #define CONVERT_TEXEL( dst, src )                    \
  440.     { const GLushort s = *(GLushort *)src;                \
  441.       dst = (s >> 1) | ((s & 1) << 15); }
  442.  
  443. #define CONVERT_TEXEL_DWORD( dst, src )                    \
  444.     { const GLuint s = ((fi_type *)src)->i;                \
  445.       dst = (((s & 0xfffefffe) >> 1) |                \
  446.          ((s & 0x00010001) << 15)); }
  447.  
  448. #endif
  449.  
  450. #define SRC_TEXEL_BYTES        2
  451.  
  452. #define TAG(x) x##_rgba5551_to_argb1555
  453. #define PRESERVE_DST_TYPE
  454. #include "texutil_tmp.h"
  455.  
  456.  
  457. #define CONVERT_TEXEL( dst, src )                    \
  458.     dst = PACK_COLOR_1555_LE( src[3], src[0], src[1], src[2] )
  459.  
  460. #define CONVERT_TEXEL_DWORD( dst, src )                    \
  461.     dst = APPEND16( PACK_COLOR_1555_LE( src[3], src[0], src[1], src[2] ),    \
  462.             PACK_COLOR_1555_LE( src[7], src[4], src[5], src[6] ) )
  463.  
  464. #define SRC_TEXEL_BYTES        4
  465.  
  466. #define TAG(x) x##_abgr8888_to_argb1555
  467. #include "texutil_tmp.h"
  468.  
  469.  
  470. #define CONVERT_ARGB1555( name )                    \
  471. static GLboolean                            \
  472. convert_##name##_argb1555( const struct convert_info *convert )        \
  473. {                                    \
  474.    convert_func *tab;                            \
  475.    GLint index = convert->index;                    \
  476.                                     \
  477.    if ( convert->format == GL_BGRA &&                    \
  478.     convert->type == GL_UNSIGNED_SHORT_1_5_5_5_REV )        \
  479.    {                                    \
  480.       tab = name##_tab_argb1555_direct;                    \
  481.    }                                    \
  482.    else if ( convert->format == GL_RGBA &&                \
  483.          convert->type == GL_UNSIGNED_SHORT_5_5_5_1 )        \
  484.    {                                    \
  485.       tab = name##_tab_rgba5551_to_argb1555;                \
  486.    }                                    \
  487.    else if ( convert->format == GL_RGBA &&                \
  488.          convert->type == GL_UNSIGNED_BYTE )            \
  489.    {                                    \
  490.       tab = name##_tab_abgr8888_to_argb1555;                \
  491.    }                                    \
  492.    else                                    \
  493.    {                                    \
  494.       /* Can't handle this source format/type combination */        \
  495.       return GL_FALSE;                            \
  496.    }                                    \
  497.                                     \
  498.    return tab[index]( convert );                    \
  499. }
  500.  
  501. CONVERT_ARGB1555( texsubimage2d )
  502. CONVERT_ARGB1555( texsubimage3d )
  503.  
  504.  
  505.  
  506. /* =============================================================
  507.  * AL88 textures:
  508.  */
  509.  
  510. #define DST_TYPE        GLushort
  511. #define DST_TEXELS_PER_DWORD    2
  512.  
  513. #define CONVERT_TEXEL( dst, src )                    \
  514.     dst = PACK_COLOR_88_LE( src[0], src[1] )
  515.  
  516. #define CONVERT_DIRECT
  517.  
  518. #define SRC_TEXEL_BYTES        2
  519.  
  520. #define TAG(x) x##_al88_direct
  521. #define PRESERVE_DST_TYPE
  522. #include "texutil_tmp.h"
  523.  
  524.  
  525. #define CONVERT_TEXEL( dst, src )                    \
  526.     dst = PACK_COLOR_88_LE( src[0], 0x00 )
  527.  
  528. #define CONVERT_TEXEL_DWORD( dst, src )                    \
  529.     dst = APPEND16( PACK_COLOR_88_LE( src[0], 0x00 ),            \
  530.             PACK_COLOR_88_LE( src[1], 0x00 ) )
  531.  
  532. #define SRC_TEXEL_BYTES        1
  533.  
  534. #define TAG(x) x##_a8_to_al88
  535. #define PRESERVE_DST_TYPE
  536. #include "texutil_tmp.h"
  537.  
  538.  
  539. #define CONVERT_TEXEL( dst, src )                    \
  540.     dst = PACK_COLOR_88_LE( 0xff, src[0] )
  541.  
  542. #define CONVERT_TEXEL_DWORD( dst, src )                    \
  543.     dst = APPEND16( PACK_COLOR_88_LE( 0xff, src[0] ),            \
  544.             PACK_COLOR_88_LE( 0xff, src[1] ) )
  545.  
  546. #define SRC_TEXEL_BYTES        1
  547.  
  548. #define TAG(x) x##_l8_to_al88
  549. #define PRESERVE_DST_TYPE
  550. #include "texutil_tmp.h"
  551.  
  552.  
  553. #define CONVERT_TEXEL( dst, src )                    \
  554.     dst = PACK_COLOR_88_LE( src[3], src[0] )
  555.  
  556. #define CONVERT_TEXEL_DWORD( dst, src )                    \
  557.     dst = APPEND16( PACK_COLOR_88_LE( src[3], src[0] ),        \
  558.             PACK_COLOR_88_LE( src[7], src[4] ) )
  559.  
  560. #define SRC_TEXEL_BYTES        4
  561.  
  562. #define TAG(x) x##_abgr8888_to_al88
  563. #include "texutil_tmp.h"
  564.  
  565.  
  566. #define CONVERT_AL88( name )                        \
  567. static GLboolean                            \
  568. convert_##name##_al88( const struct convert_info *convert )        \
  569. {                                    \
  570.    convert_func *tab;                            \
  571.    GLint index = convert->index;                    \
  572.                                     \
  573.    if ( convert->format == GL_LUMINANCE_ALPHA &&            \
  574.     convert->type == GL_UNSIGNED_BYTE )                \
  575.    {                                    \
  576.       tab = name##_tab_al88_direct;                    \
  577.    }                                    \
  578.    else if ( convert->format == GL_ALPHA &&                \
  579.          convert->type == GL_UNSIGNED_BYTE )            \
  580.    {                                    \
  581.       tab = name##_tab_a8_to_al88;                    \
  582.    }                                    \
  583.    else if ( convert->format == GL_LUMINANCE &&                \
  584.          convert->type == GL_UNSIGNED_BYTE )            \
  585.    {                                    \
  586.       tab = name##_tab_l8_to_al88;                    \
  587.    }                                    \
  588.    else if ( convert->format == GL_RGBA &&                \
  589.          convert->type == GL_UNSIGNED_BYTE )            \
  590.    {                                    \
  591.       tab = name##_tab_abgr8888_to_al88;                \
  592.    }                                    \
  593.    else                                    \
  594.    {                                    \
  595.       /* Can't handle this source format/type combination */        \
  596.       return GL_FALSE;                            \
  597.    }                                    \
  598.                                     \
  599.    return tab[index]( convert );                    \
  600. }
  601.  
  602. CONVERT_AL88( texsubimage2d )
  603. CONVERT_AL88( texsubimage3d )
  604.  
  605.  
  606.  
  607. /* =============================================================
  608.  * Convert to RGB332 textures:
  609.  */
  610.  
  611. static GLboolean
  612. convert_texsubimage2d_rgb332( const struct convert_info *convert )
  613. {
  614.    /* This is a placeholder for now...
  615.     */
  616.    return GL_FALSE;
  617. }
  618.  
  619. static GLboolean
  620. convert_texsubimage3d_rgb332( const struct convert_info *convert )
  621. {
  622.    /* This is a placeholder for now...
  623.     */
  624.    return GL_FALSE;
  625. }
  626.  
  627.  
  628.  
  629. /* =============================================================
  630.  * CI8 (and all other single-byte texel) textures:
  631.  */
  632.  
  633. #define DST_TYPE        GLubyte
  634. #define DST_TEXELS_PER_DWORD    4
  635.  
  636. #define CONVERT_TEXEL( dst, src )    dst = src[0]
  637.  
  638. #define CONVERT_DIRECT
  639.  
  640. #define SRC_TEXEL_BYTES        1
  641.  
  642. #define TAG(x) x##_ci8_direct
  643. #include "texutil_tmp.h"
  644.  
  645.  
  646. #define CONVERT_CI8( name )                        \
  647. static GLboolean                            \
  648. convert_##name##_ci8( const struct convert_info *convert )        \
  649. {                                    \
  650.    convert_func *tab;                            \
  651.    GLint index = convert->index;                    \
  652.                                     \
  653.    if ( ( convert->format == GL_ALPHA ||                \
  654.       convert->format == GL_LUMINANCE ||                \
  655.       convert->format == GL_INTENSITY ||                \
  656.       convert->format == GL_COLOR_INDEX ) &&            \
  657.     convert->type == GL_UNSIGNED_BYTE )                \
  658.    {                                    \
  659.       tab = name##_tab_ci8_direct;                    \
  660.    }                                    \
  661.    else                                    \
  662.    {                                    \
  663.       /* Can't handle this source format/type combination */        \
  664.       return GL_FALSE;                            \
  665.    }                                    \
  666.                                     \
  667.    return tab[index]( convert );                    \
  668. }
  669.  
  670. CONVERT_CI8( texsubimage2d )
  671. CONVERT_CI8( texsubimage3d )
  672.  
  673.  
  674. /* =============================================================
  675.  * convert to YCBCR textures:
  676.  */
  677.  
  678. #define DST_TYPE        GLushort
  679. #define DST_TEXELS_PER_DWORD    2
  680.  
  681. #define CONVERT_TEXEL( dst, src ) \
  682.    dst = (src[0] << 8) | src[1];
  683.  
  684. #define CONVERT_DIRECT
  685.  
  686. #define SRC_TEXEL_BYTES        2
  687.  
  688. #define TAG(x) x##_ycbcr_direct
  689. #include "texutil_tmp.h"
  690.  
  691.  
  692. #define CONVERT_YCBCR( name )                        \
  693. static GLboolean                            \
  694. convert_##name##_ycbcr( const struct convert_info *convert )        \
  695. {                                    \
  696.    convert_func *tab;                            \
  697.    GLint index = convert->index;                    \
  698.                                     \
  699.    if (convert->format != GL_YCBCR_MESA) {                \
  700.       /* Can't handle this source format/type combination */        \
  701.       return GL_FALSE;                            \
  702.    }                                      \
  703.    tab = name##_tab_ycbcr_direct;                    \
  704.                                     \
  705.    return tab[index]( convert );                    \
  706. }
  707.  
  708. CONVERT_YCBCR( texsubimage2d )
  709. CONVERT_YCBCR( texsubimage3d )
  710.  
  711.  
  712. /* =============================================================
  713.  * convert to YCBCR_REV textures:
  714.  */
  715.  
  716. #define DST_TYPE        GLushort
  717. #define DST_TEXELS_PER_DWORD    2
  718.  
  719. #define CONVERT_TEXEL( dst, src ) \
  720.    dst = (src[1] << 8) | src[0];
  721.  
  722. #define CONVERT_DIRECT
  723.  
  724. #define SRC_TEXEL_BYTES        2
  725.  
  726. #define TAG(x) x##_ycbcr_rev_direct
  727. #include "texutil_tmp.h"
  728.  
  729.  
  730. #define CONVERT_YCBCR_REV( name )                    \
  731. static GLboolean                            \
  732. convert_##name##_ycbcr_rev( const struct convert_info *convert )    \
  733. {                                    \
  734.    convert_func *tab;                            \
  735.    GLint index = convert->index;                    \
  736.                                     \
  737.    if (convert->format != GL_YCBCR_MESA) {                \
  738.       /* Can't handle this source format/type combination */        \
  739.       return GL_FALSE;                            \
  740.    }                                      \
  741.    tab = name##_tab_ycbcr_rev_direct;                    \
  742.                                     \
  743.    return tab[index]( convert );                    \
  744. }
  745.  
  746. CONVERT_YCBCR_REV( texsubimage2d )
  747. CONVERT_YCBCR_REV( texsubimage3d )
  748.  
  749.  
  750.  
  751. /* =============================================================
  752.  * Global entry points
  753.  */
  754.  
  755. static convert_func convert_texsubimage2d_tab[] = {
  756.    convert_texsubimage2d_rgba8888,
  757.    convert_texsubimage2d_argb8888,
  758.    convert_texsubimage2d_rgb888,
  759.    convert_texsubimage2d_rgb565,
  760.    convert_texsubimage2d_argb4444,
  761.    convert_texsubimage2d_argb1555,
  762.    convert_texsubimage2d_al88,
  763.    convert_texsubimage2d_rgb332,
  764.    convert_texsubimage2d_ci8,        /* These are all the same... */
  765.    convert_texsubimage2d_ci8,
  766.    convert_texsubimage2d_ci8,
  767.    convert_texsubimage2d_ci8,
  768.    convert_texsubimage2d_ycbcr,
  769.    convert_texsubimage2d_ycbcr_rev,
  770. };
  771.  
  772. static convert_func convert_texsubimage3d_tab[] = {
  773.    convert_texsubimage3d_rgba8888,
  774.    convert_texsubimage3d_argb8888,
  775.    convert_texsubimage3d_rgb888,
  776.    convert_texsubimage3d_rgb565,
  777.    convert_texsubimage3d_argb4444,
  778.    convert_texsubimage3d_argb1555,
  779.    convert_texsubimage3d_al88,
  780.    convert_texsubimage3d_rgb332,
  781.    convert_texsubimage3d_ci8,        /* These are all the same... */
  782.    convert_texsubimage3d_ci8,
  783.    convert_texsubimage3d_ci8,
  784.    convert_texsubimage3d_ci8,
  785.    convert_texsubimage3d_ycbcr,
  786.    convert_texsubimage3d_ycbcr_rev,
  787. };
  788.  
  789.  
  790. /* See if we need to care about the pixel store attributes when we're
  791.  * converting the texture image.  This should be stored as
  792.  * unpacking->_SomeBoolean and updated when the values change, to avoid
  793.  * testing every time...
  794.  */
  795. static INLINE GLboolean
  796. convert_needs_unpacking( const struct gl_pixelstore_attrib *unpacking,
  797.                GLenum format, GLenum type )
  798. {
  799.    if ( ( unpacking->Alignment == 1 ||
  800.       ( unpacking->Alignment == 4 &&   /* Pick up the common Q3A case... */
  801.         format == GL_RGBA && type == GL_UNSIGNED_BYTE ) ) &&
  802.     unpacking->RowLength == 0 &&
  803.     unpacking->SkipPixels == 0 &&
  804.     unpacking->SkipRows == 0 &&
  805.     unpacking->ImageHeight == 0 &&
  806.     unpacking->SkipImages == 0 &&
  807.     unpacking->SwapBytes == GL_FALSE &&
  808.     unpacking->LsbFirst == GL_FALSE ) {
  809.       return GL_FALSE;
  810.    } else {
  811.       return GL_TRUE;
  812.    }
  813. }
  814.  
  815.  
  816. GLboolean
  817. _mesa_convert_texsubimage1d( GLint mesaFormat,
  818.                  GLint xoffset,
  819.                  GLint width,
  820.                  GLenum format, GLenum type,
  821.                  const struct gl_pixelstore_attrib *unpacking,
  822.                  const GLvoid *srcImage, GLvoid *dstImage )
  823. {
  824.    struct convert_info convert;
  825.  
  826.    ASSERT( unpacking );
  827.    ASSERT( srcImage );
  828.    ASSERT( dstImage );
  829.  
  830.    ASSERT( mesaFormat >= MESA_FORMAT_RGBA8888 );
  831.    ASSERT( mesaFormat <= MESA_FORMAT_YCBCR_REV );
  832.  
  833.    /* Make it easier to pass all the parameters around.
  834.     */
  835.    convert.xoffset = xoffset;
  836.    convert.yoffset = 0;
  837.    convert.width = width;
  838.    convert.height = 1;
  839.    convert.format = format;
  840.    convert.type = type;
  841.    convert.unpacking = unpacking;
  842.    convert.srcImage = srcImage;
  843.    convert.dstImage = dstImage;
  844.  
  845.    convert.index = 0;
  846.  
  847.    if ( convert_needs_unpacking( unpacking, format, type ) )
  848.       convert.index |= CONVERT_UNPACKING_BIT;
  849.  
  850.    ASSERT(convert.index < 4);
  851.  
  852.    return convert_texsubimage2d_tab[mesaFormat]( &convert );
  853. }
  854.  
  855.  
  856. /* Convert a user's 2D image into a texture image.  This basically
  857.  * repacks pixel data into the special texture formats used by core Mesa
  858.  * and the DRI drivers.  This function can do full images or subimages.
  859.  *
  860.  * We return a boolean because this function may not accept some kinds
  861.  * of source image formats and/or types.  For example, if the incoming
  862.  * format/type = GL_BGR, GL_UNSIGNED_INT this function probably won't
  863.  * be able to do the conversion.
  864.  *
  865.  * In that case, the incoming image should first be simplified to one of
  866.  * the "canonical" formats (GL_ALPHA, GL_LUMINANCE, GL_LUMINANCE_ALPHA,
  867.  * GL_INTENSITY, GL_RGB, GL_RGBA) and types (GL_CHAN).  We can do that
  868.  * with the _mesa_transfer_teximage() function.  That function will also
  869.  * do image transfer operations such as scale/bias and convolution.
  870.  *
  871.  * Input:
  872.  *   mesaFormat - one of the MESA_FORMAT_* values from texformat.h
  873.  *   xoffset, yoffset - position in dest image to put data
  874.  *   width, height - incoming image size, also size of dest region.
  875.  *   dstImageWidth - width (row stride) of dest image in pixels
  876.  *   format, type - incoming image format and type
  877.  *   unpacking - describes incoming image unpacking
  878.  *   srcImage - pointer to source image
  879.  *   destImage - pointer to dest image
  880.  */
  881. GLboolean
  882. _mesa_convert_texsubimage2d( GLint mesaFormat,  /* dest */
  883.                  GLint xoffset, GLint yoffset,
  884.                  GLint width, GLint height,
  885.                  GLint destImageWidth,
  886.                  GLenum format, GLenum type,  /* source */
  887.                  const struct gl_pixelstore_attrib *unpacking,
  888.                  const GLvoid *srcImage, GLvoid *dstImage )
  889. {
  890.    struct convert_info convert;
  891.  
  892.    ASSERT( unpacking );
  893.    ASSERT( srcImage );
  894.    ASSERT( dstImage );
  895.  
  896.    ASSERT( mesaFormat >= MESA_FORMAT_RGBA8888 );
  897.    ASSERT( mesaFormat <= MESA_FORMAT_YCBCR_REV );
  898.  
  899.    /* Make it easier to pass all the parameters around.
  900.     */
  901.    convert.xoffset = xoffset;
  902.    convert.yoffset = yoffset;
  903.    convert.width = width;
  904.    convert.height = height;
  905.    convert.dstImageWidth = destImageWidth;
  906.    convert.format = format;
  907.    convert.type = type;
  908.    convert.unpacking = unpacking;
  909.    convert.srcImage = srcImage;
  910.    convert.dstImage = dstImage;
  911.  
  912.    convert.index = 0;
  913.  
  914.    if ( convert_needs_unpacking( unpacking, format, type ) )
  915.       convert.index |= CONVERT_UNPACKING_BIT;
  916.  
  917.    if ( width != destImageWidth )
  918.       convert.index |= CONVERT_STRIDE_BIT;
  919.  
  920.    return convert_texsubimage2d_tab[mesaFormat]( &convert );
  921. }
  922.  
  923. GLboolean
  924. _mesa_convert_texsubimage3d( GLint mesaFormat,  /* dest */
  925.                  GLint xoffset, GLint yoffset, GLint zoffset,
  926.                  GLint width, GLint height, GLint depth,
  927.                  GLint dstImageWidth, GLint dstImageHeight,
  928.                  GLenum format, GLenum type,  /* source */
  929.                  const struct gl_pixelstore_attrib *unpacking,
  930.                  const GLvoid *srcImage, GLvoid *dstImage )
  931. {
  932.    struct convert_info convert;
  933.  
  934.    ASSERT( unpacking );
  935.    ASSERT( srcImage );
  936.    ASSERT( dstImage );
  937.  
  938.    ASSERT( mesaFormat >= MESA_FORMAT_RGBA8888 );
  939.    ASSERT( mesaFormat <= MESA_FORMAT_YCBCR_REV );
  940.  
  941.    /* Make it easier to pass all the parameters around.
  942.     */
  943.    convert.xoffset = xoffset;
  944.    convert.yoffset = yoffset;
  945.    convert.zoffset = zoffset;
  946.    convert.width = width;
  947.    convert.height = height;
  948.    convert.depth = depth;
  949.    convert.dstImageWidth = dstImageWidth;
  950.    convert.dstImageHeight = dstImageHeight;
  951.    convert.format = format;
  952.    convert.type = type;
  953.    convert.unpacking = unpacking;
  954.    convert.srcImage = srcImage;
  955.    convert.dstImage = dstImage;
  956.  
  957.    convert.index = 0;
  958.  
  959.    if ( convert_needs_unpacking( unpacking, format, type ) )
  960.       convert.index |= CONVERT_UNPACKING_BIT;
  961.  
  962.    if ( width != dstImageWidth || height != dstImageHeight )
  963.       convert.index |= CONVERT_STRIDE_BIT;
  964.  
  965.    return convert_texsubimage3d_tab[mesaFormat]( &convert );
  966. }
  967.  
  968.  
  969.  
  970. /* Nearest filtering only (for broken hardware that can't support
  971.  * all aspect ratios).  This can be made a lot faster, but I don't
  972.  * really care enough...
  973.  */
  974. void _mesa_rescale_teximage2d( GLuint bytesPerPixel, GLuint dstRowStride,
  975.                    GLint srcWidth, GLint srcHeight,
  976.                    GLint dstWidth, GLint dstHeight,
  977.                    const GLvoid *srcImage, GLvoid *dstImage )
  978. {
  979.    GLint row, col;
  980.  
  981. #define INNER_LOOP( TYPE, HOP, WOP )                    \
  982.    for ( row = 0 ; row < dstHeight ; row++ ) {                \
  983.       GLint srcRow = row HOP hScale;                    \
  984.       for ( col = 0 ; col < dstWidth ; col++ ) {            \
  985.      GLint srcCol = col WOP wScale;                    \
  986.      dst[col] = src[srcRow * srcWidth + srcCol];            \
  987.       }                                    \
  988.       dst = (TYPE *) ((GLubyte *) dst + dstRowStride);            \
  989.    }                                    \
  990.  
  991. #define RESCALE_IMAGE( TYPE )                        \
  992. do {                                    \
  993.    const TYPE *src = (const TYPE *)srcImage;                \
  994.    TYPE *dst = (TYPE *)dstImage;                    \
  995.                                     \
  996.    if ( srcHeight <= dstHeight ) {                    \
  997.       const GLint hScale = dstHeight / srcHeight;            \
  998.       if ( srcWidth <= dstWidth ) {                    \
  999.      const GLint wScale = dstWidth / srcWidth;            \
  1000.      INNER_LOOP( TYPE, /, / );                    \
  1001.       }                                    \
  1002.       else {                                \
  1003.      const GLint wScale = srcWidth / dstWidth;            \
  1004.      INNER_LOOP( TYPE, /, * );                    \
  1005.       }                                    \
  1006.    }                                    \
  1007.    else {                                \
  1008.       const GLint hScale = srcHeight / dstHeight;            \
  1009.       if ( srcWidth <= dstWidth ) {                    \
  1010.      const GLint wScale = dstWidth / srcWidth;            \
  1011.      INNER_LOOP( TYPE, *, / );                    \
  1012.       }                                    \
  1013.       else {                                \
  1014.      const GLint wScale = srcWidth / dstWidth;            \
  1015.      INNER_LOOP( TYPE, *, * );                    \
  1016.       }                                    \
  1017.    }                                    \
  1018. } while (0)
  1019.  
  1020.    switch ( bytesPerPixel ) {
  1021.    case 4:
  1022.       RESCALE_IMAGE( GLuint );
  1023.       break;
  1024.  
  1025.    case 2:
  1026.       RESCALE_IMAGE( GLushort );
  1027.       break;
  1028.  
  1029.    case 1:
  1030.       RESCALE_IMAGE( GLubyte );
  1031.       break;
  1032.    default:
  1033.       _mesa_problem(NULL,"unexpected bytes/pixel in _mesa_rescale_teximage2d");
  1034.    }
  1035. }
  1036.