Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Mesa 3-D graphics library
  3.  *
  4.  * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
  5.  *
  6.  * Permission is hereby granted, free of charge, to any person obtaining a
  7.  * copy of this software and associated documentation files (the "Software"),
  8.  * to deal in the Software without restriction, including without limitation
  9.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  10.  * and/or sell copies of the Software, and to permit persons to whom the
  11.  * Software is furnished to do so, subject to the following conditions:
  12.  *
  13.  * The above copyright notice and this permission notice shall be included
  14.  * in all copies or substantial portions of the Software.
  15.  *
  16.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  17.  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  19.  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
  20.  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  21.  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  22.  * OTHER DEALINGS IN THE SOFTWARE.
  23.  */
  24.  
  25. /**
  26.  * Code to convert compressed/paletted texture images to ordinary images.
  27.  * See the GL_OES_compressed_paletted_texture spec at
  28.  * http://khronos.org/registry/gles/extensions/OES/OES_compressed_paletted_texture.txt
  29.  *
  30.  * XXX this makes it impossible to add hardware support...
  31.  */
  32.  
  33.  
  34. #include "glheader.h"
  35. #include "compiler.h" /* for ASSERT */
  36. #include "context.h"
  37. #include "mtypes.h"
  38. #include "imports.h"
  39. #include "pixelstore.h"
  40. #include "texcompress_cpal.h"
  41. #include "teximage.h"
  42.  
  43.  
  44. static const struct cpal_format_info {
  45.    GLenum cpal_format;
  46.    GLenum format;
  47.    GLenum type;
  48.    GLuint palette_size;
  49.    GLuint size;
  50. } formats[] = {
  51.    { GL_PALETTE4_RGB8_OES,     GL_RGB,  GL_UNSIGNED_BYTE,           16, 3 },
  52.    { GL_PALETTE4_RGBA8_OES,    GL_RGBA, GL_UNSIGNED_BYTE,           16, 4 },
  53.    { GL_PALETTE4_R5_G6_B5_OES, GL_RGB,  GL_UNSIGNED_SHORT_5_6_5,    16, 2 },
  54.    { GL_PALETTE4_RGBA4_OES,    GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4,  16, 2 },
  55.    { GL_PALETTE4_RGB5_A1_OES,  GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1,  16, 2 },
  56.    { GL_PALETTE8_RGB8_OES,     GL_RGB,  GL_UNSIGNED_BYTE,          256, 3 },
  57.    { GL_PALETTE8_RGBA8_OES,    GL_RGBA, GL_UNSIGNED_BYTE,          256, 4 },
  58.    { GL_PALETTE8_R5_G6_B5_OES, GL_RGB,  GL_UNSIGNED_SHORT_5_6_5,   256, 2 },
  59.    { GL_PALETTE8_RGBA4_OES,    GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, 256, 2 },
  60.    { GL_PALETTE8_RGB5_A1_OES,  GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, 256, 2 }
  61. };
  62.  
  63.  
  64. /**
  65.  * Get a color/entry from the palette.
  66.  */
  67. static GLuint
  68. get_palette_entry(const struct cpal_format_info *info, const GLubyte *palette,
  69.                   GLuint index, GLubyte *pixel)
  70. {
  71.    memcpy(pixel, palette + info->size * index, info->size);
  72.    return info->size;
  73. }
  74.  
  75.  
  76. /**
  77.  * Convert paletted texture to color texture.
  78.  */
  79. static void
  80. paletted_to_color(const struct cpal_format_info *info, const GLubyte *palette,
  81.                   const void *indices, GLuint num_pixels, GLubyte *image)
  82. {
  83.    GLubyte *pix = image;
  84.    GLuint remain, i;
  85.  
  86.    if (info->palette_size == 16) {
  87.       /* 4 bits per index */
  88.       const GLubyte *ind = (const GLubyte *) indices;
  89.  
  90.       /* two pixels per iteration */
  91.       remain = num_pixels % 2;
  92.       for (i = 0; i < num_pixels / 2; i++) {
  93.          pix += get_palette_entry(info, palette, (ind[i] >> 4) & 0xf, pix);
  94.          pix += get_palette_entry(info, palette, ind[i] & 0xf, pix);
  95.       }
  96.       if (remain) {
  97.          get_palette_entry(info, palette, (ind[i] >> 4) & 0xf, pix);
  98.       }
  99.    }
  100.    else {
  101.       /* 8 bits per index */
  102.       const GLubyte *ind = (const GLubyte *) indices;
  103.       for (i = 0; i < num_pixels; i++)
  104.          pix += get_palette_entry(info, palette, ind[i], pix);
  105.    }
  106. }
  107.  
  108. unsigned
  109. _mesa_cpal_compressed_size(int level, GLenum internalFormat,
  110.                            unsigned width, unsigned height)
  111. {
  112.    const struct cpal_format_info *info;
  113.    const int num_levels = -level + 1;
  114.    int lvl;
  115.    unsigned w, h, expect_size;
  116.  
  117.    if (internalFormat < GL_PALETTE4_RGB8_OES
  118.        || internalFormat > GL_PALETTE8_RGB5_A1_OES) {
  119.       return 0;
  120.    }
  121.  
  122.    info = &formats[internalFormat - GL_PALETTE4_RGB8_OES];
  123.    ASSERT(info->cpal_format == internalFormat);
  124.  
  125.    expect_size = info->palette_size * info->size;
  126.    for (lvl = 0; lvl < num_levels; lvl++) {
  127.       w = width >> lvl;
  128.       if (!w)
  129.          w = 1;
  130.       h = height >> lvl;
  131.       if (!h)
  132.          h = 1;
  133.  
  134.       if (info->palette_size == 16)
  135.          expect_size += (w * h  + 1) / 2;
  136.       else
  137.          expect_size += w * h;
  138.    }
  139.  
  140.    return expect_size;
  141. }
  142.  
  143.  
  144. /**
  145.  * Convert a call to glCompressedTexImage2D() where internalFormat is a
  146.  *  compressed palette format into a regular GLubyte/RGBA glTexImage2D() call.
  147.  */
  148. void
  149. _mesa_cpal_compressed_teximage2d(GLenum target, GLint level,
  150.                                  GLenum internalFormat,
  151.                                  GLsizei width, GLsizei height,
  152.                                  GLsizei imageSize, const void *palette)
  153. {
  154.    const struct cpal_format_info *info;
  155.    GLint lvl, num_levels;
  156.    const GLubyte *indices;
  157.    GLint saved_align, align;
  158.    GET_CURRENT_CONTEXT(ctx);
  159.  
  160.    /* By this point, the internalFormat should have been validated.
  161.     */
  162.    assert(internalFormat >= GL_PALETTE4_RGB8_OES
  163.           && internalFormat <= GL_PALETTE8_RGB5_A1_OES);
  164.  
  165.    info = &formats[internalFormat - GL_PALETTE4_RGB8_OES];
  166.  
  167.    num_levels = -level + 1;
  168.  
  169.    /* first image follows the palette */
  170.    indices = (const GLubyte *) palette + info->palette_size * info->size;
  171.  
  172.    saved_align = ctx->Unpack.Alignment;
  173.    align = saved_align;
  174.  
  175.    for (lvl = 0; lvl < num_levels; lvl++) {
  176.       GLsizei w, h;
  177.       GLuint num_texels;
  178.       GLubyte *image = NULL;
  179.  
  180.       w = width >> lvl;
  181.       if (!w)
  182.          w = 1;
  183.       h = height >> lvl;
  184.       if (!h)
  185.          h = 1;
  186.       num_texels = w * h;
  187.       if (w * info->size % align) {
  188.          _mesa_PixelStorei(GL_UNPACK_ALIGNMENT, 1);
  189.          align = 1;
  190.       }
  191.  
  192.       /* allocate and fill dest image buffer */
  193.       if (palette) {
  194.          image = malloc(num_texels * info->size);
  195.          paletted_to_color(info, palette, indices, num_texels, image);
  196.       }
  197.  
  198.       _mesa_TexImage2D(target, lvl, info->format, w, h, 0,
  199.                        info->format, info->type, image);
  200.       free(image);
  201.  
  202.       /* advance index pointer to point to next src mipmap */
  203.       if (info->palette_size == 16)
  204.          indices += (num_texels + 1) / 2;
  205.       else
  206.          indices += num_texels;
  207.    }
  208.  
  209.    if (saved_align != align)
  210.       _mesa_PixelStorei(GL_UNPACK_ALIGNMENT, saved_align);
  211. }
  212.