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