• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 #include "GLcommon/PaletteTexture.h"
17 #include <stdio.h>
18 
19 
20 
21 struct Color
22 {
ColorColor23   Color(unsigned char r, unsigned char g,unsigned char b, unsigned char a):red(r),green(g),blue(b),alpha(a){};
24   unsigned char red;
25   unsigned char green;
26   unsigned char blue;
27   unsigned char alpha;
28 };
29 
getPaletteInfo(GLenum internalFormat,unsigned int & indexSizeBits,unsigned int & colorSizeBytes,GLenum & colorFrmt)30 void getPaletteInfo(GLenum internalFormat,unsigned int& indexSizeBits,unsigned int& colorSizeBytes,GLenum& colorFrmt) {
31 
32         colorFrmt = GL_RGB;
33         switch(internalFormat)
34     {
35     case GL_PALETTE4_RGB8_OES:
36         indexSizeBits = 4;
37         colorSizeBytes = 3;
38         break;
39 
40     case GL_PALETTE4_RGBA8_OES:
41         indexSizeBits = 4;
42         colorSizeBytes = 4;
43         colorFrmt = GL_RGBA;
44         break;
45 
46     case GL_PALETTE4_RGBA4_OES:
47     case GL_PALETTE4_RGB5_A1_OES:
48         colorFrmt = GL_RGBA;
49         /* fall-through */
50     case GL_PALETTE4_R5_G6_B5_OES:
51         indexSizeBits = 4;
52         colorSizeBytes = 2;
53         break;
54 
55     case GL_PALETTE8_RGB8_OES:
56         indexSizeBits = 8;
57         colorSizeBytes = 3;
58         break;
59 
60     case GL_PALETTE8_RGBA8_OES:
61         indexSizeBits = 8;
62         colorSizeBytes = 4;
63         colorFrmt = GL_RGBA;
64         break;
65 
66     case GL_PALETTE8_RGBA4_OES:
67     case GL_PALETTE8_RGB5_A1_OES:
68         colorFrmt = GL_RGBA;
69         /* fall-through */
70     case GL_PALETTE8_R5_G6_B5_OES:
71         indexSizeBits = 8;
72         colorSizeBytes = 2;
73         break;
74     }
75 }
76 
77 
paletteColor(const unsigned char * pallete,unsigned int index,GLenum format)78 Color paletteColor(const unsigned char* pallete,unsigned int index,GLenum format)
79 {
80         short s;
81         switch(format) {
82         //RGB
83     case GL_PALETTE4_RGB8_OES:
84     case GL_PALETTE8_RGB8_OES:
85             return Color(pallete[index],pallete[index+1],pallete[index+2],0);
86     case GL_PALETTE8_R5_G6_B5_OES:
87     case GL_PALETTE4_R5_G6_B5_OES:
88             s = *((short *)(pallete+index));
89             return Color((s >> 11)*255/31,((s >> 5) & 0x3f)*255/63 ,(s & 0x1f)*255/31,0);
90 
91         //RGBA
92     case GL_PALETTE4_RGBA8_OES:
93     case GL_PALETTE8_RGBA8_OES:
94             return Color(pallete[index],pallete[index+1],pallete[index+2],pallete[index+3]);
95     case GL_PALETTE4_RGBA4_OES:
96     case GL_PALETTE8_RGBA4_OES:
97             s = *((short *)(pallete+index));
98             return Color(((s >> 12) & 0xf)*255/15,((s >> 8) & 0xf)*255/15,((s >> 4) & 0xf)*255/15 ,(s & 0xf)*255/15);
99     case GL_PALETTE4_RGB5_A1_OES:
100     case GL_PALETTE8_RGB5_A1_OES:
101             s = *((short *)(pallete+index));
102             return Color(((s >> 11) & 0x1f)*255/31,((s >> 6) & 0x1f)*255/31,((s >> 1) & 0x1f)*255/31 ,(s & 0x1) * 255);
103         default:
104             return Color(255,255,255,255);
105     }
106 }
107 
uncompressTexture(GLenum internalformat,GLenum & formatOut,GLsizei width,GLsizei height,GLsizei imageSize,const GLvoid * data,GLint level)108 unsigned char* uncompressTexture(GLenum internalformat,GLenum& formatOut,GLsizei width,GLsizei height,GLsizei imageSize, const GLvoid* data,GLint level) {
109 
110     unsigned int indexSizeBits;  //the size of the color index in the pallete
111     unsigned int colorSizeBytes; //the size of each color cell in the pallete
112 
113     getPaletteInfo(internalformat,indexSizeBits,colorSizeBytes,formatOut);
114     if(!data)
115     {
116         return NULL;
117     }
118 
119     const unsigned char* palette = static_cast<const unsigned char *>(data);
120 
121     //the pallete positioned in the begininng of the data
122     // so we jump over it to get to the colos indices in the palette
123 
124     int nColors = 2 << (indexSizeBits -1); //2^indexSizeBits
125     int paletteSizeBytes = nColors*colorSizeBytes;
126     const unsigned char* imageIndices =  palette + paletteSizeBytes;
127 
128     //jumping to the the correct mipmap level
129     for(int i=0;i<level;i++) {
130         imageIndices+= (width*height*indexSizeBits)/8;
131         width  = width  >> 1;
132         height = height >> 1;
133     }
134 
135     int colorSizeOut = (formatOut == GL_RGB? 3:4);
136     int nPixels = width*height;
137     unsigned char* pixelsOut = new unsigned char[nPixels*colorSizeOut];
138     if(!pixelsOut) return NULL;
139 
140     int leftBytes = ((palette + imageSize) /* the end of data pointer*/
141                       - imageIndices);
142     int leftPixels = (leftBytes * 8 )/indexSizeBits;
143 
144     int maxIndices = (leftPixels < nPixels) ? leftPixels:nPixels;
145 
146     //filling the pixels array
147     for(int i =0 ; i < maxIndices ; i++) {
148         int paletteIndex = 0;
149         int indexOut = i*colorSizeOut;
150         if(indexSizeBits == 4) {
151             paletteIndex = (i%2) == 0 ?
152                            imageIndices[i/2] >> 4:  //upper bits
153                            imageIndices[i/2] & 0xf; //lower bits
154         } else {
155             paletteIndex = imageIndices[i];
156         }
157 
158         paletteIndex*=colorSizeBytes;
159         Color c = paletteColor(palette,paletteIndex,internalformat);
160 
161         pixelsOut[indexOut] = c.red;
162         pixelsOut[indexOut+1] = c.green;
163         pixelsOut[indexOut+2] = c.blue;
164         if(formatOut == GL_RGBA) {
165             pixelsOut[indexOut+3] = c.alpha;
166         }
167     }
168     return pixelsOut;
169 }
170 
171