1edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project/* libs/opengles/dxt.cpp
2edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project**
3edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project** Copyright 2007, The Android Open Source Project
4edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project**
5edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project** Licensed under the Apache License, Version 2.0 (the "License");
6edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project** you may not use this file except in compliance with the License.
7edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project** You may obtain a copy of the License at
8edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project**
9edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project**     http://www.apache.org/licenses/LICENSE-2.0
10edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project**
11edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project** Unless required by applicable law or agreed to in writing, software
12edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project** distributed under the License is distributed on an "AS IS" BASIS,
13edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project** See the License for the specific language governing permissions and
15edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project** limitations under the License.
16edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project*/
17edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
18edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define TIMING 0
19edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
20edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#if TIMING
21edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <sys/time.h> // for optimization timing
22edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdio.h>
23edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <stdlib.h>
24edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#endif
25edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
26edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <GLES/gl.h>
27edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include <utils/Endian.h>
28edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
29edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#include "context.h"
30edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
31edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define TIMING 0
32edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
33edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectnamespace android {
34edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
35edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic uint8_t avg23tab[64*64];
36edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic volatile int tables_initialized = 0;
37edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
38edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// Definitions below are equivalent to these over the valid range of arguments
39edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project//  #define div5(x) ((x)/5)
40edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project//  #define div7(x) ((x)/7)
41edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
42edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// Use fixed-point to divide by 5 and 7
43edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// 3277 = 2^14/5 + 1
44edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// 2341 = 2^14/7 + 1
45edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define div5(x) (((x)*3277) >> 14)
46edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define div7(x) (((x)*2341) >> 14)
47edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
48edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// Table with entry [a << 6 | b] = (2*a + b)/3 for 0 <= a,b < 64
49edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define avg23(x0,x1) avg23tab[((x0) << 6) | (x1)]
50edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
51edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// Extract 5/6/5 RGB
52edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define red(x)   (((x) >> 11) & 0x1f)
53edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define green(x) (((x) >>  5) & 0x3f)
54edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#define blue(x)  ( (x)        & 0x1f)
55edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
56edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project/*
57edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Convert 5/6/5 RGB (as 3 ints) to 8/8/8
58edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
59edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Operation count: 8 <<, 0 &, 5 |
60edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */
61edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectinline static int rgb565SepTo888(int r, int g, int b)
62edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
63edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
64edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return ((((r << 3) | (r >> 2)) << 16) |
65edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            (((g << 2) | (g >> 4)) <<  8) |
66edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project             ((b << 3) | (b >> 2)));
67edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
68edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
69edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project/*
70edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Convert 5/6/5 RGB (as a single 16-bit word) to 8/8/8
71edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
72edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *                   r4r3r2r1 r0g5g4g3 g2g1g0b4 b3b2b1b0   rgb
73edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *            r4r3r2 r1r0g5g4 g3g2g1g0 b4b3b2b1 b0 0 0 0   rgb << 3
74edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * r4r3r2r1 r0r4r3r2 g5g4g3g2 g1g0g5g4 b4b3b2b1 b0b4b3b2   desired result
75edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
76edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Construct the 24-bit RGB word as:
77edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
78edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * r4r3r2r1 r0------ -------- -------- -------- --------  (rgb << 8) & 0xf80000
79edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *            r4r3r2 -------- -------- -------- --------  (rgb << 3) & 0x070000
80edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *                   g5g4g3g2 g1g0---- -------- --------  (rgb << 5) & 0x00fc00
81edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *                                g5g4 -------- --------  (rgb >> 1) & 0x000300
82edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *                                     b4b3b2b1 b0------  (rgb << 3) & 0x0000f8
83edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *                                                b4b3b2  (rgb >> 2) & 0x000007
84edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
85edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Operation count: 5 <<, 6 &, 5 | (n.b. rgb >> 3 is used twice)
86edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */
87edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectinline static int rgb565To888(int rgb)
88edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
89edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
90edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int rgb3 = rgb >> 3;
91edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return (((rgb << 8) & 0xf80000) |
92edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            ( rgb3      & 0x070000) |
93edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            ((rgb << 5) & 0x00fc00) |
94edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            ((rgb >> 1) & 0x000300) |
95edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            ( rgb3      & 0x0000f8) |
96edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            ((rgb >> 2) & 0x000007));
97edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
98edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
99edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#if __BYTE_ORDER == __BIG_ENDIAN
100edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic uint32_t swap(uint32_t x) {
101edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int b0 = (x >> 24) & 0xff;
102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int b1 = (x >> 16) & 0xff;
103edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int b2 = (x >>  8) & 0xff;
104edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int b3 = (x      ) & 0xff;
105edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
106edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return (uint32_t)((b3 << 24) | (b2 << 16) | (b1 << 8) | b0);
107edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
108edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#endif
109edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
110edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic void
111edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectinit_tables()
112edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
113edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    if (tables_initialized) {
114edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        return;
115edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
116edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
117edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (int i = 0; i < 64; i++) {
118edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        for (int j = 0; j < 64; j++) {
119edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            int avg = (2*i + j)/3;
120edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            avg23tab[(i << 6) | j] = avg;
121edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
122edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
123edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
124edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    asm volatile ("" : : : "memory");
125edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    tables_initialized = 1;
126edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
127edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
128edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project/*
129edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Utility to scan a DXT1 compressed texture to determine whether it
130edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * contains a transparent pixel (color0 < color1, code == 3).  This
131edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * may be useful if the application lacks information as to whether
132edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * the true format is GL_COMPRESSED_RGB_S3TC_DXT1_EXT or
133edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * GL_COMPRESSED_RGBA_S3TC_DXT1_EXT.
134edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */
135edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectbool
136edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectDXT1HasAlpha(const GLvoid *data, int width, int height) {
137edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#if TIMING
138edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    struct timeval start_t, end_t;
139edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    struct timezone tz;
140edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
141edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    gettimeofday(&start_t, &tz);
142edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#endif
143edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
144edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    bool hasAlpha = false;
145edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
146edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int xblocks = (width + 3)/4;
147edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int yblocks = (height + 3)/4;
148edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int numblocks = xblocks*yblocks;
149edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
150edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t const *d32 = (uint32_t *)data;
151edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (int b = 0; b < numblocks; b++) {
152edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        uint32_t colors = *d32++;
153edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
154edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#if __BYTE_ORDER == __BIG_ENDIAN
155edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        colors = swap(colors);
156edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#endif
157edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
158edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        uint16_t color0 = colors & 0xffff;
159edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        uint16_t color1 = colors >> 16;
160edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
161edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        if (color0 < color1) {
162edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // There's no need to endian-swap within 'bits'
163edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // since we don't care which pixel is the transparent one
164edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint32_t bits = *d32++;
165edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
166edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // Detect if any (odd, even) pair of bits are '11'
167edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            //      bits: b31 b30 b29 ... b3 b2 b1 b0
168edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // bits >> 1: b31 b31 b30 ... b4 b3 b2 b1
169edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            //         &: b31 (b31 & b30) (b29 & b28) ... (b2 & b1) (b1 & b0)
170edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            //  & 0x55..:   0 (b31 & b30)       0     ...     0     (b1 & b0)
171edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (((bits & (bits >> 1)) & 0x55555555) != 0) {
172edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                hasAlpha = true;
173edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                goto done;
174edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
175edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        } else {
176edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // Skip 4 bytes
177edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            ++d32;
178edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
179edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
180edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
181edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project done:
182edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#if TIMING
183edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    gettimeofday(&end_t, &tz);
184edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    long usec = (end_t.tv_sec - start_t.tv_sec)*1000000 +
185edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        (end_t.tv_usec - start_t.tv_usec);
186edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
187edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    printf("Scanned w=%d h=%d in %ld usec\n", width, height, usec);
188edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#endif
189edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
190edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    return hasAlpha;
191edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
192edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
193edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic void
194edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectdecodeDXT1(const GLvoid *data, int width, int height,
195edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project           void *surface, int stride,
196edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project           bool hasAlpha)
197edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
198edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
199edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    init_tables();
200edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
201edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t const *d32 = (uint32_t *)data;
202edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
203edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // Color table for the current block
204edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint16_t c[4];
205edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    c[0] = c[1] = c[2] = c[3] = 0;
206edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
207edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // Specified colors from the previous block
208edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint16_t prev_color0 = 0x0000;
209edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint16_t prev_color1 = 0x0000;
210edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
211edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint16_t* rowPtr = (uint16_t*)surface;
212edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (int base_y = 0; base_y < height; base_y += 4, rowPtr += 4*stride) {
213edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        uint16_t *blockPtr = rowPtr;
214edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        for (int base_x = 0; base_x < width; base_x += 4, blockPtr += 4) {
215edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint32_t colors = *d32++;
216edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint32_t bits = *d32++;
217edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
218edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#if __BYTE_ORDER == __BIG_ENDIAN
219edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            colors = swap(colors);
220edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            bits = swap(bits);
221edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#endif
222edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
223edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // Raw colors
224edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint16_t color0 = colors & 0xffff;
225edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint16_t color1 = colors >> 16;
226edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
227edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // If the new block has the same base colors as the
228edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // previous one, we don't need to recompute the color
229edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // table c[]
230edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (color0 != prev_color0 || color1 != prev_color1) {
231edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                // Store raw colors for comparison with next block
232edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                prev_color0 = color0;
233edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                prev_color1 = color1;
234edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
235edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                int r0 =   red(color0);
236edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                int g0 = green(color0);
237edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                int b0 =  blue(color0);
238edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
239edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                int r1 =   red(color1);
240edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                int g1 = green(color1);
241edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                int b1 =  blue(color1);
242edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
243edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                if (hasAlpha) {
244edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    c[0] = (r0 << 11) | ((g0 >> 1) << 6) | (b0 << 1) | 0x1;
245edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    c[1] = (r1 << 11) | ((g1 >> 1) << 6) | (b1 << 1) | 0x1;
246edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                } else {
247edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    c[0] = color0;
248edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    c[1] = color1;
249edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                }
250edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
251edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                int r2, g2, b2, r3, g3, b3, a3;
252edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
253edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                int bbits = bits >> 1;
254edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                bool has2 = ((bbits & ~bits) & 0x55555555) != 0;
255edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                bool has3 = ((bbits &  bits) & 0x55555555) != 0;
256edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
257edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                if (has2 || has3) {
258edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    if (color0 > color1) {
259edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        r2 = avg23(r0, r1);
260edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        g2 = avg23(g0, g1);
261edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        b2 = avg23(b0, b1);
262edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
263edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        r3 = avg23(r1, r0);
264edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        g3 = avg23(g1, g0);
265edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        b3 = avg23(b1, b0);
266edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        a3 = 1;
267edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    } else {
268edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        r2 = (r0 + r1) >> 1;
269edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        g2 = (g0 + g1) >> 1;
270edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        b2 = (b0 + b1) >> 1;
271edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
272edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        r3 = g3 = b3 = a3 = 0;
273edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    }
274edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    if (hasAlpha) {
275edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        c[2] = (r2 << 11) | ((g2 >> 1) << 6) |
276edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                            (b2 << 1) | 0x1;
277edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        c[3] = (r3 << 11) | ((g3 >> 1) << 6) |
278edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                            (b3 << 1) | a3;
279edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    } else {
280edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        c[2] = (r2 << 11) | (g2 << 5) | b2;
281edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                        c[3] = (r3 << 11) | (g3 << 5) | b3;
282edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    }
283edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                }
284edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
285edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
286edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint16_t* blockRowPtr = blockPtr;
287edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            for (int y = 0; y < 4; y++, blockRowPtr += stride) {
288edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                // Don't process rows past the botom
289edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                if (base_y + y >= height) {
290edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    break;
291edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                }
292edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
293edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                int w = min(width - base_x, 4);
294edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                for (int x = 0; x < w; x++) {
295edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    int code = bits & 0x3;
296edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    bits >>= 2;
297edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
298edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    blockRowPtr[x] = c[code];
299edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                }
300edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
301edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
302edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
303edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
304edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
305edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// Output data as internalformat=GL_RGBA, type=GL_UNSIGNED_BYTE
306edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic void
307edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectdecodeDXT3(const GLvoid *data, int width, int height,
308edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project           void *surface, int stride)
309edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
310edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
311edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    init_tables();
312edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
313edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t const *d32 = (uint32_t *)data;
314edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
315edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // Specified colors from the previous block
316edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint16_t prev_color0 = 0x0000;
317edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint16_t prev_color1 = 0x0000;
318edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
319edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // Color table for the current block
320edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t c[4];
321edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    c[0] = c[1] = c[2] = c[3] = 0;
322edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
323edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t* rowPtr = (uint32_t*)surface;
324edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (int base_y = 0; base_y < height; base_y += 4, rowPtr += 4*stride) {
325edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        uint32_t *blockPtr = rowPtr;
326edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        for (int base_x = 0; base_x < width; base_x += 4, blockPtr += 4) {
327edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
328edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#if __BYTE_ORDER == __BIG_ENDIAN
329edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint32_t alphahi = *d32++;
330edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint32_t alphalo = *d32++;
331edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            alphahi = swap(alphahi);
332edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            alphalo = swap(alphalo);
333edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#else
334edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint32_t alphalo = *d32++;
335edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint32_t alphahi = *d32++;
336edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#endif
337edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
338edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint32_t colors = *d32++;
339edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint32_t bits = *d32++;
340edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
341edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#if __BYTE_ORDER == __BIG_ENDIAN
342edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            colors = swap(colors);
343edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            bits = swap(bits);
344edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#endif
345edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
346edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint64_t alpha = ((uint64_t)alphahi << 32) | alphalo;
347edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
348edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // Raw colors
349edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint16_t color0 = colors & 0xffff;
350edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint16_t color1 = colors >> 16;
351edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
352edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // If the new block has the same base colors as the
353edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // previous one, we don't need to recompute the color
354edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // table c[]
355edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (color0 != prev_color0 || color1 != prev_color1) {
356edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                // Store raw colors for comparison with next block
357edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                prev_color0 = color0;
358edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                prev_color1 = color1;
359edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
360edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                int bbits = bits >> 1;
361edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                bool has2 = ((bbits & ~bits) & 0x55555555) != 0;
362edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                bool has3 = ((bbits &  bits) & 0x55555555) != 0;
363edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
364edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                if (has2 || has3) {
365edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    int r0 =   red(color0);
366edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    int g0 = green(color0);
367edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    int b0 =  blue(color0);
368edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
369edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    int r1 =   red(color1);
370edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    int g1 = green(color1);
371edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    int b1 =  blue(color1);
372edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
373edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    int r2 = avg23(r0, r1);
374edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    int g2 = avg23(g0, g1);
375edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    int b2 = avg23(b0, b1);
376edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
377edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    int r3 = avg23(r1, r0);
378edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    int g3 = avg23(g1, g0);
379edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    int b3 = avg23(b1, b0);
380edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
381edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    c[0] = rgb565SepTo888(r0, g0, b0);
382edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    c[1] = rgb565SepTo888(r1, g1, b1);
383edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    c[2] = rgb565SepTo888(r2, g2, b2);
384edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    c[3] = rgb565SepTo888(r3, g3, b3);
385edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                } else {
386edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    // Convert to 8 bits
387edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    c[0] = rgb565To888(color0);
388edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    c[1] = rgb565To888(color1);
389edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                }
390edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
391edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
392edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint32_t* blockRowPtr = blockPtr;
393edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            for (int y = 0; y < 4; y++, blockRowPtr += stride) {
394edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                // Don't process rows past the botom
395edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                if (base_y + y >= height) {
396edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    break;
397edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                }
398edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
399edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                int w = min(width - base_x, 4);
400edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                for (int x = 0; x < w; x++) {
401edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    int a = alpha & 0xf;
402edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    alpha >>= 4;
403edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
404edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    int code = bits & 0x3;
405edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    bits >>= 2;
406edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
407edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    blockRowPtr[x] = c[code] | (a << 28) | (a << 24);
408edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                }
409edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
410edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
411edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
412edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
413edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
414edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project// Output data as internalformat=GL_RGBA, type=GL_UNSIGNED_BYTE
415edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectstatic void
416edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectdecodeDXT5(const GLvoid *data, int width, int height,
417edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project           void *surface, int stride)
418edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
419edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
420edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    init_tables();
421edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
422edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t const *d32 = (uint32_t *)data;
423edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
424edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // Specified alphas from the previous block
425edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint8_t prev_alpha0 = 0x00;
426edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint8_t prev_alpha1 = 0x00;
427edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
428edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // Specified colors from the previous block
429edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint16_t prev_color0 = 0x0000;
430edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project     uint16_t prev_color1 = 0x0000;
431edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
432edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // Alpha table for the current block
433edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint8_t a[8];
434edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    a[0] = a[1] = a[2] = a[3] = a[4] = a[5] = a[6] = a[7] = 0;
435edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
436edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // Color table for the current block
437edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t c[4];
438edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    c[0] = c[1] = c[2] = c[3] = 0;
439edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
440edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int good_a5 = 0;
441edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int bad_a5 = 0;
442edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int good_a6 = 0;
443edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int bad_a6 = 0;
444edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int good_a7 = 0;
445edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    int bad_a7 = 0;
446edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
447edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    uint32_t* rowPtr = (uint32_t*)surface;
448edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    for (int base_y = 0; base_y < height; base_y += 4, rowPtr += 4*stride) {
449edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        uint32_t *blockPtr = rowPtr;
450edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        for (int base_x = 0; base_x < width; base_x += 4, blockPtr += 4) {
451edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
452edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#if __BYTE_ORDER == __BIG_ENDIAN
453edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint32_t alphahi = *d32++;
454edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint32_t alphalo = *d32++;
455edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            alphahi = swap(alphahi);
456edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            alphalo = swap(alphalo);
457edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#else
458edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project             uint32_t alphalo = *d32++;
459edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project             uint32_t alphahi = *d32++;
460edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#endif
461edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
462edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint32_t colors = *d32++;
463edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint32_t bits = *d32++;
464edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
465edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#if __BYTE_ORDER == __BIG_ENDIANx
466edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            colors = swap(colors);
467edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            bits = swap(bits);
468edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#endif
469edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
470edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint64_t alpha = ((uint64_t)alphahi << 32) | alphalo;
471edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint64_t alpha0 = alpha & 0xff;
472edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            alpha >>= 8;
473edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint64_t alpha1 = alpha & 0xff;
474edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            alpha >>= 8;
475edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
476edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (alpha0 != prev_alpha0 || alpha1 != prev_alpha1) {
477edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                prev_alpha0 = alpha0;
478edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                prev_alpha1 = alpha1;
479edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
480edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                a[0] = alpha0;
481edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                a[1] = alpha1;
482edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                int a01 = alpha0 + alpha1 - 1;
483edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                if (alpha0 > alpha1) {
484edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    a[2] = div7(6*alpha0 +   alpha1);
485edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    a[4] = div7(4*alpha0 + 3*alpha1);
486edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    a[6] = div7(2*alpha0 + 5*alpha1);
487edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
488edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    // Use symmetry to derive half of the values
489edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    // A few values will be off by 1 (~.5%)
490edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    // Alternate which values are computed directly
491edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    // and which are derived to try to reduce bias
492edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    a[3] = a01 - a[6];
493edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    a[5] = a01 - a[4];
494edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    a[7] = a01 - a[2];
495edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                } else {
496edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    a[2] = div5(4*alpha0 +   alpha1);
497edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    a[4] = div5(2*alpha0 + 3*alpha1);
498edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    a[3] = a01 - a[4];
499edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    a[5] = a01 - a[2];
500edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    a[6] = 0x00;
501edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    a[7] = 0xff;
502edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                }
503edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
504edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
505edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // Raw colors
506edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint16_t color0 = colors & 0xffff;
507edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint16_t color1 = colors >> 16;
508edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
509edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // If the new block has the same base colors as the
510edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // previous one, we don't need to recompute the color
511edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            // table c[]
512edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            if (color0 != prev_color0 || color1 != prev_color1) {
513edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                // Store raw colors for comparison with next block
514edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                prev_color0 = color0;
515edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                prev_color1 = color1;
516edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
517edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                int bbits = bits >> 1;
518edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                bool has2 = ((bbits & ~bits) & 0x55555555) != 0;
519edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                bool has3 = ((bbits &  bits) & 0x55555555) != 0;
520edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
521edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                if (has2 || has3) {
522edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    int r0 =   red(color0);
523edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    int g0 = green(color0);
524edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    int b0 =  blue(color0);
525edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
526edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    int r1 =   red(color1);
527edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    int g1 = green(color1);
528edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    int b1 =  blue(color1);
529edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
530edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    int r2 = avg23(r0, r1);
531edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    int g2 = avg23(g0, g1);
532edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    int b2 = avg23(b0, b1);
533edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
534edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    int r3 = avg23(r1, r0);
535edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    int g3 = avg23(g1, g0);
536edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    int b3 = avg23(b1, b0);
537edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
538edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    c[0] = rgb565SepTo888(r0, g0, b0);
539edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    c[1] = rgb565SepTo888(r1, g1, b1);
540edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    c[2] = rgb565SepTo888(r2, g2, b2);
541edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    c[3] = rgb565SepTo888(r3, g3, b3);
542edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                } else {
543edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    // Convert to 8 bits
544edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    c[0] = rgb565To888(color0);
545edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    c[1] = rgb565To888(color1);
546edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                }
547edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
548edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
549edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            uint32_t* blockRowPtr = blockPtr;
550edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            for (int y = 0; y < 4; y++, blockRowPtr += stride) {
551edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                // Don't process rows past the botom
552edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                if (base_y + y >= height) {
553edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    break;
554edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                }
555edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
556edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                int w = min(width - base_x, 4);
557edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                for (int x = 0; x < w; x++) {
558edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    int acode = alpha & 0x7;
559edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    alpha >>= 3;
560edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
561edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    int code = bits & 0x3;
562edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    bits >>= 2;
563edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
564edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                    blockRowPtr[x] = c[code] | (a[acode] << 24);
565edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                }
566edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
567edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        }
568edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
569edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
570edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
571edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project/*
572edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Decode a DXT-compressed texture into memory.  DXT textures consist of
573edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * a series of 4x4 pixel blocks in left-to-right, top-down order.
574edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * The number of blocks is given by ceil(width/4)*ceil(height/4).
575edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
576edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * 'data' points to the texture data. 'width' and 'height' indicate the
577edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * dimensions of the texture.  We assume width and height are >= 0 but
578edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * do not require them to be powers of 2 or divisible by any factor.
579edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
580edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * The output is written to 'surface' with each scanline separated by
581edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * 'stride' 2- or 4-byte words.
582edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
583edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * 'format' indicates the type of compression and must be one of the following:
584edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
585edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *   GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
586edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *      The output is written as 5/6/5 opaque RGB (16 bit words).
587edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *      8 bytes are read from 'data' for each block.
588edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
589edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *   GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
590edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *      The output is written as 5/5/5/1 RGBA (16 bit words)
591edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *      8 bytes are read from 'data' for each block.
592edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
593edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *   GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
594edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *   GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
595edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *      The output is written as 8/8/8/8 ARGB (32 bit words)
596edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *      16 bytes are read from 'data' for each block.
597edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */
598edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectvoid
599edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source ProjectdecodeDXT(const GLvoid *data, int width, int height,
600edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project          void *surface, int stride, int format)
601edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project{
602edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#if TIMING
603edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    struct timeval start_t, end_t;
604edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    struct timezone tz;
605edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
606edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    gettimeofday(&start_t, &tz);
607edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#endif
608edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
609edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    switch (format) {
610edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
611edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        decodeDXT1(data, width, height, surface, stride, false);
612edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
613edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
614edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
615edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        decodeDXT1(data, width, height, surface, stride, true);
616edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
617edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
618edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
619edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        decodeDXT3(data, width, height, surface, stride);
620edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
621edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
622edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
623edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        decodeDXT5(data, width, height, surface, stride);
624edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        break;
625edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    }
626edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
627edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#if TIMING
628edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    gettimeofday(&end_t, &tz);
629edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    long usec = (end_t.tv_sec - start_t.tv_sec)*1000000 +
630edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project        (end_t.tv_usec - start_t.tv_usec);
631edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
632edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    printf("Loaded w=%d h=%d in %ld usec\n", width, height, usec);
633edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project#endif
634edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project}
635edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
636edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project} // namespace android
637