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