u_pack_color.h

Go to the documentation of this file.
00001 /**************************************************************************
00002  *
00003  * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
00004  * All Rights Reserved.
00005  *
00006  * Permission is hereby granted, free of charge, to any person obtaining a
00007  * copy of this software and associated documentation files (the
00008  * "Software"), to deal in the Software without restriction, including
00009  * without limitation the rights to use, copy, modify, merge, publish,
00010  * distribute, sub license, and/or sell copies of the Software, and to
00011  * permit persons to whom the Software is furnished to do so, subject to
00012  * the following conditions:
00013  *
00014  * The above copyright notice and this permission notice (including the
00015  * next paragraph) shall be included in all copies or substantial portions
00016  * of the Software.
00017  *
00018  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00019  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00020  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
00021  * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
00022  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
00023  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
00024  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00025  *
00026  **************************************************************************/
00027 
00034 #ifndef U_PACK_COLOR_H
00035 #define U_PACK_COLOR_H
00036 
00037 
00038 #include "pipe/p_compiler.h"
00039 #include "pipe/p_format.h"
00040 #include "util/u_math.h"
00041 
00042 
00046 static INLINE void
00047 util_pack_color_ub(ubyte r, ubyte g, ubyte b, ubyte a,
00048                    enum pipe_format format, void *dest)
00049 {
00050    switch (format) {
00051    case PIPE_FORMAT_R8G8B8A8_UNORM:
00052       {
00053          uint *d = (uint *) dest;
00054          *d = (r << 24) | (g << 16) | (b << 8) | a;
00055       }
00056       return;
00057    case PIPE_FORMAT_R8G8B8X8_UNORM:
00058       {
00059          uint *d = (uint *) dest;
00060          *d = (r << 24) | (g << 16) | (b << 8) | 0xff;
00061       }
00062       return;
00063    case PIPE_FORMAT_A8R8G8B8_UNORM:
00064       {
00065          uint *d = (uint *) dest;
00066          *d = (a << 24) | (r << 16) | (g << 8) | b;
00067       }
00068       return;
00069    case PIPE_FORMAT_X8R8G8B8_UNORM:
00070       {
00071          uint *d = (uint *) dest;
00072          *d = (0xff << 24) | (r << 16) | (g << 8) | b;
00073       }
00074       return;
00075    case PIPE_FORMAT_B8G8R8A8_UNORM:
00076       {
00077          uint *d = (uint *) dest;
00078          *d = (b << 24) | (g << 16) | (r << 8) | a;
00079       }
00080       return;
00081    case PIPE_FORMAT_B8G8R8X8_UNORM:
00082       {
00083          uint *d = (uint *) dest;
00084          *d = (b << 24) | (g << 16) | (r << 8) | 0xff;
00085       }
00086       return;
00087    case PIPE_FORMAT_R5G6B5_UNORM:
00088       {
00089          ushort *d = (ushort *) dest;
00090          *d = ((r & 0xf8) << 8) | ((g & 0xfc) << 3) | (b >> 3);
00091       }
00092       return;
00093    case PIPE_FORMAT_A1R5G5B5_UNORM:
00094       {
00095          ushort *d = (ushort *) dest;
00096          *d = ((a & 0x80) << 8) | ((r & 0xf8) << 7) | ((g & 0xf8) << 2) | (b >> 3);
00097       }
00098       return;
00099    case PIPE_FORMAT_A4R4G4B4_UNORM:
00100       {
00101          ushort *d = (ushort *) dest;
00102          *d = ((a & 0xf0) << 8) | ((r & 0xf0) << 4) | ((g & 0xf0) << 0) | (b >> 4);
00103       }
00104       return;
00105    case PIPE_FORMAT_A8_UNORM:
00106       {
00107          ubyte *d = (ubyte *) dest;
00108          *d = a;
00109       }
00110       return;
00111    case PIPE_FORMAT_L8_UNORM:
00112    case PIPE_FORMAT_I8_UNORM:
00113       {
00114          ubyte *d = (ubyte *) dest;
00115          *d = r;
00116       }
00117       return;
00118    case PIPE_FORMAT_R32G32B32A32_FLOAT:
00119       {
00120          float *d = (float *) dest;
00121          d[0] = (float)r / 255.0f;
00122          d[1] = (float)g / 255.0f;
00123          d[2] = (float)b / 255.0f;
00124          d[3] = (float)a / 255.0f;
00125       }
00126       return;
00127    case PIPE_FORMAT_R32G32B32_FLOAT:
00128       {
00129          float *d = (float *) dest;
00130          d[0] = (float)r / 255.0f;
00131          d[1] = (float)g / 255.0f;
00132          d[2] = (float)b / 255.0f;
00133       }
00134       return;
00135 
00136    /* XXX lots more cases to add */
00137    default:
00138       debug_print_format("gallium: unhandled format in util_pack_color_ub()", format);
00139       assert(0);
00140    }
00141 }
00142  
00143 
00147 static INLINE void
00148 util_unpack_color_ub(enum pipe_format format, const void *src,
00149                      ubyte *r, ubyte *g, ubyte *b, ubyte *a)
00150 {
00151    switch (format) {
00152    case PIPE_FORMAT_R8G8B8A8_UNORM:
00153       {
00154          uint p = ((const uint *) src)[0];
00155          *r = (ubyte) ((p >> 24) & 0xff);
00156          *g = (ubyte) ((p >> 16) & 0xff);
00157          *b = (ubyte) ((p >>  8) & 0xff);
00158          *a = (ubyte) ((p >>  0) & 0xff);
00159       }
00160       return;
00161    case PIPE_FORMAT_R8G8B8X8_UNORM:
00162       {
00163          uint p = ((const uint *) src)[0];
00164          *r = (ubyte) ((p >> 24) & 0xff);
00165          *g = (ubyte) ((p >> 16) & 0xff);
00166          *b = (ubyte) ((p >>  8) & 0xff);
00167          *a = (ubyte) 0xff;
00168       }
00169       return;
00170    case PIPE_FORMAT_A8R8G8B8_UNORM:
00171       {
00172          uint p = ((const uint *) src)[0];
00173          *r = (ubyte) ((p >> 16) & 0xff);
00174          *g = (ubyte) ((p >>  8) & 0xff);
00175          *b = (ubyte) ((p >>  0) & 0xff);
00176          *a = (ubyte) ((p >> 24) & 0xff);
00177       }
00178       return;
00179    case PIPE_FORMAT_X8R8G8B8_UNORM:
00180       {
00181          uint p = ((const uint *) src)[0];
00182          *r = (ubyte) ((p >> 16) & 0xff);
00183          *g = (ubyte) ((p >>  8) & 0xff);
00184          *b = (ubyte) ((p >>  0) & 0xff);
00185          *a = (ubyte) 0xff;
00186       }
00187       return;
00188    case PIPE_FORMAT_B8G8R8A8_UNORM:
00189       {
00190          uint p = ((const uint *) src)[0];
00191          *r = (ubyte) ((p >>  8) & 0xff);
00192          *g = (ubyte) ((p >> 16) & 0xff);
00193          *b = (ubyte) ((p >> 24) & 0xff);
00194          *a = (ubyte) ((p >>  0) & 0xff);
00195       }
00196       return;
00197    case PIPE_FORMAT_B8G8R8X8_UNORM:
00198       {
00199          uint p = ((const uint *) src)[0];
00200          *r = (ubyte) ((p >>  8) & 0xff);
00201          *g = (ubyte) ((p >> 16) & 0xff);
00202          *b = (ubyte) ((p >> 24) & 0xff);
00203          *a = (ubyte) 0xff;
00204       }
00205       return;
00206    case PIPE_FORMAT_R5G6B5_UNORM:
00207       {
00208          ushort p = ((const ushort *) src)[0];
00209          *r = (ubyte) (((p >> 8) & 0xf8) | ((p >> 13) & 0x7));
00210          *g = (ubyte) (((p >> 3) & 0xfc) | ((p >>  9) & 0x3));
00211          *b = (ubyte) (((p << 3) & 0xf8) | ((p >>  2) & 0x7));
00212          *a = (ubyte) 0xff;
00213       }
00214       return;
00215    case PIPE_FORMAT_A1R5G5B5_UNORM:
00216       {
00217          ushort p = ((const ushort *) src)[0];
00218          *r = (ubyte) (((p >>  7) & 0xf8) | ((p >> 12) & 0x7));
00219          *g = (ubyte) (((p >>  2) & 0xf8) | ((p >>  7) & 0x7));
00220          *b = (ubyte) (((p <<  3) & 0xf8) | ((p >>  2) & 0x7));
00221          *a = (ubyte) (0xff * (p >> 15));
00222       }
00223       return;
00224    case PIPE_FORMAT_A4R4G4B4_UNORM:
00225       {
00226          ushort p = ((const ushort *) src)[0];
00227          *r = (ubyte) (((p >> 4) & 0xf0) | ((p >>  8) & 0xf));
00228          *g = (ubyte) (((p >> 0) & 0xf0) | ((p >>  4) & 0xf));
00229          *b = (ubyte) (((p << 4) & 0xf0) | ((p >>  0) & 0xf));
00230          *a = (ubyte) (((p >> 8) & 0xf0) | ((p >> 12) & 0xf));
00231       }
00232       return;
00233    case PIPE_FORMAT_A8_UNORM:
00234       {
00235          ubyte p = ((const ubyte *) src)[0];
00236          *r = *g = *b = (ubyte) 0xff;
00237          *a = p;
00238       }
00239       return;
00240    case PIPE_FORMAT_L8_UNORM:
00241       {
00242          ubyte p = ((const ubyte *) src)[0];
00243          *r = *g = *b = p;
00244          *a = (ubyte) 0xff;
00245       }
00246       return;
00247    case PIPE_FORMAT_I8_UNORM:
00248       {
00249          ubyte p = ((const ubyte *) src)[0];
00250          *r = *g = *b = *a = p;
00251       }
00252       return;
00253    case PIPE_FORMAT_R32G32B32A32_FLOAT:
00254       {
00255          const float *p = (const float *) src;
00256          *r = float_to_ubyte(p[0]);
00257          *g = float_to_ubyte(p[1]);
00258          *b = float_to_ubyte(p[2]);
00259          *a = float_to_ubyte(p[3]);
00260       }
00261       return;
00262    case PIPE_FORMAT_R32G32B32_FLOAT:
00263       {
00264          const float *p = (const float *) src;
00265          *r = float_to_ubyte(p[0]);
00266          *g = float_to_ubyte(p[1]);
00267          *b = float_to_ubyte(p[2]);
00268          *a = (ubyte) 0xff;
00269       }
00270       return;
00271 
00272    case PIPE_FORMAT_R32G32_FLOAT:
00273       {
00274          const float *p = (const float *) src;
00275          *r = float_to_ubyte(p[0]);
00276          *g = float_to_ubyte(p[1]);
00277          *b = *a = (ubyte) 0xff;
00278       }
00279       return;
00280 
00281    case PIPE_FORMAT_R32_FLOAT:
00282       {
00283          const float *p = (const float *) src;
00284          *r = float_to_ubyte(p[0]);
00285          *g = *b = *a = (ubyte) 0xff;
00286       }
00287       return;
00288 
00289    /* XXX lots more cases to add */
00290    default:
00291       debug_print_format("gallium: unhandled format in util_unpack_color_ub()",
00292                          format);
00293       assert(0);
00294    }
00295 }
00296  
00297 
00298 
00302 static INLINE void
00303 util_pack_color(const float rgba[4], enum pipe_format format, void *dest)
00304 {
00305    ubyte r, g, b, a;
00306 
00307    if (pf_size_x(format) <= 8) {
00308       /* format uses 8-bit components or less */
00309       r = float_to_ubyte(rgba[0]);
00310       g = float_to_ubyte(rgba[1]);
00311       b = float_to_ubyte(rgba[2]);
00312       a = float_to_ubyte(rgba[3]);
00313    }
00314 
00315    switch (format) {
00316    case PIPE_FORMAT_R8G8B8A8_UNORM:
00317       {
00318          uint *d = (uint *) dest;
00319          *d = (r << 24) | (g << 16) | (b << 8) | a;
00320       }
00321       return;
00322    case PIPE_FORMAT_R8G8B8X8_UNORM:
00323       {
00324          uint *d = (uint *) dest;
00325          *d = (r << 24) | (g << 16) | (b << 8) | 0xff;
00326       }
00327       return;
00328    case PIPE_FORMAT_A8R8G8B8_UNORM:
00329       {
00330          uint *d = (uint *) dest;
00331          *d = (a << 24) | (r << 16) | (g << 8) | b;
00332       }
00333       return;
00334    case PIPE_FORMAT_X8R8G8B8_UNORM:
00335       {
00336          uint *d = (uint *) dest;
00337          *d = (0xff << 24) | (r << 16) | (g << 8) | b;
00338       }
00339       return;
00340    case PIPE_FORMAT_B8G8R8A8_UNORM:
00341       {
00342          uint *d = (uint *) dest;
00343          *d = (b << 24) | (g << 16) | (r << 8) | a;
00344       }
00345       return;
00346    case PIPE_FORMAT_B8G8R8X8_UNORM:
00347       {
00348          uint *d = (uint *) dest;
00349          *d = (b << 24) | (g << 16) | (r << 8) | 0xff;
00350       }
00351       return;
00352    case PIPE_FORMAT_R5G6B5_UNORM:
00353       {
00354          ushort *d = (ushort *) dest;
00355          *d = ((r & 0xf8) << 8) | ((g & 0xfc) << 3) | (b >> 3);
00356       }
00357       return;
00358    case PIPE_FORMAT_A1R5G5B5_UNORM:
00359       {
00360          ushort *d = (ushort *) dest;
00361          *d = ((a & 0x80) << 8) | ((r & 0xf8) << 7) | ((g & 0xf8) << 2) | (b >> 3);
00362       }
00363       return;
00364    case PIPE_FORMAT_A4R4G4B4_UNORM:
00365       {
00366          ushort *d = (ushort *) dest;
00367          *d = ((a & 0xf0) << 8) | ((r & 0xf0) << 4) | ((g & 0xf0) << 0) | (b >> 4);
00368       }
00369       return;
00370    case PIPE_FORMAT_A8_UNORM:
00371       {
00372          ubyte *d = (ubyte *) dest;
00373          *d = a;
00374       }
00375       return;
00376    case PIPE_FORMAT_L8_UNORM:
00377    case PIPE_FORMAT_I8_UNORM:
00378       {
00379          ubyte *d = (ubyte *) dest;
00380          *d = r;
00381       }
00382       return;
00383    case PIPE_FORMAT_R32G32B32A32_FLOAT:
00384       {
00385          float *d = (float *) dest;
00386          d[0] = rgba[0];
00387          d[1] = rgba[1];
00388          d[2] = rgba[2];
00389          d[3] = rgba[3];
00390       }
00391       return;
00392    case PIPE_FORMAT_R32G32B32_FLOAT:
00393       {
00394          float *d = (float *) dest;
00395          d[0] = rgba[0];
00396          d[1] = rgba[1];
00397          d[2] = rgba[2];
00398       }
00399       return;
00400    /* XXX lots more cases to add */
00401    default:
00402       debug_print_format("gallium: unhandled format in util_pack_color()", format);
00403       assert(0);
00404    }
00405 }
00406  
00407 
00411 static INLINE uint
00412 util_pack_z(enum pipe_format format, double z)
00413 {
00414    if (z == 0.0)
00415       return 0;
00416 
00417    switch (format) {
00418    case PIPE_FORMAT_Z16_UNORM:
00419       if (z == 1.0)
00420          return 0xffff;
00421       return (uint) (z * 0xffff);
00422    case PIPE_FORMAT_Z32_UNORM:
00423       /* special-case to avoid overflow */
00424       if (z == 1.0)
00425          return 0xffffffff;
00426       return (uint) (z * 0xffffffff);
00427    case PIPE_FORMAT_S8Z24_UNORM:
00428    case PIPE_FORMAT_X8Z24_UNORM:
00429       if (z == 1.0)
00430          return 0xffffff;
00431       return (uint) (z * 0xffffff);
00432    case PIPE_FORMAT_Z24S8_UNORM:
00433    case PIPE_FORMAT_Z24X8_UNORM:
00434       if (z == 1.0)
00435          return 0xffffff00;
00436       return ((uint) (z * 0xffffff)) << 8;
00437    default:
00438       debug_print_format("gallium: unhandled format in util_pack_z()", format);
00439       assert(0);
00440       return 0;
00441    }
00442 }
00443 
00444 
00448 static INLINE unsigned
00449 pack_ub4(ubyte b0, ubyte b1, ubyte b2, ubyte b3)
00450 {
00451    return ((((unsigned int)b0) << 0) |
00452            (((unsigned int)b1) << 8) |
00453            (((unsigned int)b2) << 16) |
00454            (((unsigned int)b3) << 24));
00455 }
00456 
00457 
00461 static INLINE unsigned
00462 pack_ui32_float4(float a, float b, float c, float d)
00463 {
00464    return pack_ub4( float_to_ubyte(a),
00465                     float_to_ubyte(b),
00466                     float_to_ubyte(c),
00467                     float_to_ubyte(d) );
00468 }
00469 
00470 
00471 
00472 #endif /* U_PACK_COLOR_H */

Generated on Tue Sep 29 06:25:15 2009 for Gallium3D by  doxygen 1.5.4