xref: /aosp_15_r20/external/mesa3d/src/mesa/main/texcompress_rgtc.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker  * Copyright (C) 2011 Red Hat Inc.
3*61046927SAndroid Build Coastguard Worker  *
4*61046927SAndroid Build Coastguard Worker  * block compression parts are:
5*61046927SAndroid Build Coastguard Worker  * Copyright (C) 2004  Roland Scheidegger   All Rights Reserved.
6*61046927SAndroid Build Coastguard Worker  *
7*61046927SAndroid Build Coastguard Worker  * Permission is hereby granted, free of charge, to any person obtaining a
8*61046927SAndroid Build Coastguard Worker  * copy of this software and associated documentation files (the "Software"),
9*61046927SAndroid Build Coastguard Worker  * to deal in the Software without restriction, including without limitation
10*61046927SAndroid Build Coastguard Worker  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11*61046927SAndroid Build Coastguard Worker  * and/or sell copies of the Software, and to permit persons to whom the
12*61046927SAndroid Build Coastguard Worker  * Software is furnished to do so, subject to the following conditions:
13*61046927SAndroid Build Coastguard Worker  *
14*61046927SAndroid Build Coastguard Worker  * The above copyright notice and this permission notice (including the next
15*61046927SAndroid Build Coastguard Worker  * paragraph) shall be included in all copies or substantial portions of the
16*61046927SAndroid Build Coastguard Worker  * Software.
17*61046927SAndroid Build Coastguard Worker  *
18*61046927SAndroid Build Coastguard Worker  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19*61046927SAndroid Build Coastguard Worker  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20*61046927SAndroid Build Coastguard Worker  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
21*61046927SAndroid Build Coastguard Worker  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22*61046927SAndroid Build Coastguard Worker  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23*61046927SAndroid Build Coastguard Worker  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24*61046927SAndroid Build Coastguard Worker  * DEALINGS IN THE SOFTWARE.
25*61046927SAndroid Build Coastguard Worker  *
26*61046927SAndroid Build Coastguard Worker  * Author:
27*61046927SAndroid Build Coastguard Worker  *    Dave Airlie
28*61046927SAndroid Build Coastguard Worker  */
29*61046927SAndroid Build Coastguard Worker 
30*61046927SAndroid Build Coastguard Worker /**
31*61046927SAndroid Build Coastguard Worker  * \file texcompress_rgtc.c
32*61046927SAndroid Build Coastguard Worker  * GL_EXT_texture_compression_rgtc support.
33*61046927SAndroid Build Coastguard Worker  */
34*61046927SAndroid Build Coastguard Worker 
35*61046927SAndroid Build Coastguard Worker #include <stdlib.h>
36*61046927SAndroid Build Coastguard Worker 
37*61046927SAndroid Build Coastguard Worker #include "config.h"
38*61046927SAndroid Build Coastguard Worker #include "util/glheader.h"
39*61046927SAndroid Build Coastguard Worker 
40*61046927SAndroid Build Coastguard Worker #include "image.h"
41*61046927SAndroid Build Coastguard Worker #include "macros.h"
42*61046927SAndroid Build Coastguard Worker #include "mipmap.h"
43*61046927SAndroid Build Coastguard Worker #include "texcompress.h"
44*61046927SAndroid Build Coastguard Worker #include "util/rgtc.h"
45*61046927SAndroid Build Coastguard Worker #include "util/format/u_format_rgtc.h"
46*61046927SAndroid Build Coastguard Worker #include "texcompress_rgtc.h"
47*61046927SAndroid Build Coastguard Worker #include "texstore.h"
48*61046927SAndroid Build Coastguard Worker 
extractsrc_u(GLubyte srcpixels[4][4],const GLubyte * srcaddr,GLint srcRowStride,GLint numxpixels,GLint numypixels,GLint comps)49*61046927SAndroid Build Coastguard Worker static void extractsrc_u( GLubyte srcpixels[4][4], const GLubyte *srcaddr,
50*61046927SAndroid Build Coastguard Worker 			  GLint srcRowStride, GLint numxpixels, GLint numypixels, GLint comps)
51*61046927SAndroid Build Coastguard Worker {
52*61046927SAndroid Build Coastguard Worker    GLubyte i, j;
53*61046927SAndroid Build Coastguard Worker    const GLubyte *curaddr;
54*61046927SAndroid Build Coastguard Worker    for (j = 0; j < numypixels; j++) {
55*61046927SAndroid Build Coastguard Worker       curaddr = srcaddr + j * srcRowStride * comps;
56*61046927SAndroid Build Coastguard Worker       for (i = 0; i < numxpixels; i++) {
57*61046927SAndroid Build Coastguard Worker          srcpixels[j][i] = *curaddr;
58*61046927SAndroid Build Coastguard Worker          curaddr += comps;
59*61046927SAndroid Build Coastguard Worker       }
60*61046927SAndroid Build Coastguard Worker    }
61*61046927SAndroid Build Coastguard Worker }
62*61046927SAndroid Build Coastguard Worker 
extractsrc_s(GLbyte srcpixels[4][4],const GLbyte * srcaddr,GLint srcRowStride,GLint numxpixels,GLint numypixels,GLint comps)63*61046927SAndroid Build Coastguard Worker static void extractsrc_s( GLbyte srcpixels[4][4], const GLbyte *srcaddr,
64*61046927SAndroid Build Coastguard Worker 			  GLint srcRowStride, GLint numxpixels, GLint numypixels, GLint comps)
65*61046927SAndroid Build Coastguard Worker {
66*61046927SAndroid Build Coastguard Worker    GLubyte i, j;
67*61046927SAndroid Build Coastguard Worker    const GLbyte *curaddr;
68*61046927SAndroid Build Coastguard Worker    for (j = 0; j < numypixels; j++) {
69*61046927SAndroid Build Coastguard Worker       curaddr = srcaddr + j * srcRowStride * comps;
70*61046927SAndroid Build Coastguard Worker       for (i = 0; i < numxpixels; i++) {
71*61046927SAndroid Build Coastguard Worker          srcpixels[j][i] = *curaddr;
72*61046927SAndroid Build Coastguard Worker          curaddr += comps;
73*61046927SAndroid Build Coastguard Worker       }
74*61046927SAndroid Build Coastguard Worker    }
75*61046927SAndroid Build Coastguard Worker }
76*61046927SAndroid Build Coastguard Worker 
77*61046927SAndroid Build Coastguard Worker 
78*61046927SAndroid Build Coastguard Worker GLboolean
_mesa_texstore_red_rgtc1(TEXSTORE_PARAMS)79*61046927SAndroid Build Coastguard Worker _mesa_texstore_red_rgtc1(TEXSTORE_PARAMS)
80*61046927SAndroid Build Coastguard Worker {
81*61046927SAndroid Build Coastguard Worker    GLubyte *dst;
82*61046927SAndroid Build Coastguard Worker    const GLubyte *tempImage = NULL;
83*61046927SAndroid Build Coastguard Worker    int i, j;
84*61046927SAndroid Build Coastguard Worker    int numxpixels, numypixels;
85*61046927SAndroid Build Coastguard Worker    const GLubyte *srcaddr;
86*61046927SAndroid Build Coastguard Worker    GLubyte srcpixels[4][4];
87*61046927SAndroid Build Coastguard Worker    GLubyte *blkaddr;
88*61046927SAndroid Build Coastguard Worker    GLint dstRowDiff, redRowStride;
89*61046927SAndroid Build Coastguard Worker    GLubyte *tempImageSlices[1];
90*61046927SAndroid Build Coastguard Worker 
91*61046927SAndroid Build Coastguard Worker    assert(dstFormat == MESA_FORMAT_R_RGTC1_UNORM ||
92*61046927SAndroid Build Coastguard Worker           dstFormat == MESA_FORMAT_L_LATC1_UNORM);
93*61046927SAndroid Build Coastguard Worker 
94*61046927SAndroid Build Coastguard Worker    tempImage = malloc(srcWidth * srcHeight * 1 * sizeof(GLubyte));
95*61046927SAndroid Build Coastguard Worker    if (!tempImage)
96*61046927SAndroid Build Coastguard Worker       return GL_FALSE; /* out of memory */
97*61046927SAndroid Build Coastguard Worker    redRowStride = 1 * srcWidth * sizeof(GLubyte);
98*61046927SAndroid Build Coastguard Worker    tempImageSlices[0] = (GLubyte *) tempImage;
99*61046927SAndroid Build Coastguard Worker    _mesa_texstore(ctx, dims,
100*61046927SAndroid Build Coastguard Worker                   baseInternalFormat,
101*61046927SAndroid Build Coastguard Worker                   MESA_FORMAT_R_UNORM8,
102*61046927SAndroid Build Coastguard Worker                   redRowStride, tempImageSlices,
103*61046927SAndroid Build Coastguard Worker                   srcWidth, srcHeight, srcDepth,
104*61046927SAndroid Build Coastguard Worker                   srcFormat, srcType, srcAddr,
105*61046927SAndroid Build Coastguard Worker                   srcPacking);
106*61046927SAndroid Build Coastguard Worker 
107*61046927SAndroid Build Coastguard Worker    dst = dstSlices[0];
108*61046927SAndroid Build Coastguard Worker 
109*61046927SAndroid Build Coastguard Worker    blkaddr = dst;
110*61046927SAndroid Build Coastguard Worker    dstRowDiff = dstRowStride >= (srcWidth * 2) ? dstRowStride - (((srcWidth + 3) & ~3) * 2) : 0;
111*61046927SAndroid Build Coastguard Worker    for (j = 0; j < srcHeight; j+=4) {
112*61046927SAndroid Build Coastguard Worker       if (srcHeight > j + 3) numypixels = 4;
113*61046927SAndroid Build Coastguard Worker       else numypixels = srcHeight - j;
114*61046927SAndroid Build Coastguard Worker       srcaddr = tempImage + j * srcWidth;
115*61046927SAndroid Build Coastguard Worker       for (i = 0; i < srcWidth; i += 4) {
116*61046927SAndroid Build Coastguard Worker          if (srcWidth > i + 3) numxpixels = 4;
117*61046927SAndroid Build Coastguard Worker          else numxpixels = srcWidth - i;
118*61046927SAndroid Build Coastguard Worker          extractsrc_u(srcpixels, srcaddr, srcWidth, numxpixels, numypixels, 1);
119*61046927SAndroid Build Coastguard Worker          util_format_unsigned_encode_rgtc_ubyte(blkaddr, srcpixels, numxpixels, numypixels);
120*61046927SAndroid Build Coastguard Worker          srcaddr += numxpixels;
121*61046927SAndroid Build Coastguard Worker          blkaddr += 8;
122*61046927SAndroid Build Coastguard Worker       }
123*61046927SAndroid Build Coastguard Worker       blkaddr += dstRowDiff;
124*61046927SAndroid Build Coastguard Worker    }
125*61046927SAndroid Build Coastguard Worker 
126*61046927SAndroid Build Coastguard Worker    free((void *) tempImage);
127*61046927SAndroid Build Coastguard Worker 
128*61046927SAndroid Build Coastguard Worker    return GL_TRUE;
129*61046927SAndroid Build Coastguard Worker }
130*61046927SAndroid Build Coastguard Worker 
131*61046927SAndroid Build Coastguard Worker GLboolean
_mesa_texstore_signed_red_rgtc1(TEXSTORE_PARAMS)132*61046927SAndroid Build Coastguard Worker _mesa_texstore_signed_red_rgtc1(TEXSTORE_PARAMS)
133*61046927SAndroid Build Coastguard Worker {
134*61046927SAndroid Build Coastguard Worker    GLbyte *dst;
135*61046927SAndroid Build Coastguard Worker    const GLbyte *tempImage = NULL;
136*61046927SAndroid Build Coastguard Worker    int i, j;
137*61046927SAndroid Build Coastguard Worker    int numxpixels, numypixels;
138*61046927SAndroid Build Coastguard Worker    const GLbyte *srcaddr;
139*61046927SAndroid Build Coastguard Worker    GLbyte srcpixels[4][4];
140*61046927SAndroid Build Coastguard Worker    GLbyte *blkaddr;
141*61046927SAndroid Build Coastguard Worker    GLint dstRowDiff, redRowStride;
142*61046927SAndroid Build Coastguard Worker    GLbyte *tempImageSlices[1];
143*61046927SAndroid Build Coastguard Worker 
144*61046927SAndroid Build Coastguard Worker    assert(dstFormat == MESA_FORMAT_R_RGTC1_SNORM ||
145*61046927SAndroid Build Coastguard Worker           dstFormat == MESA_FORMAT_L_LATC1_SNORM);
146*61046927SAndroid Build Coastguard Worker 
147*61046927SAndroid Build Coastguard Worker    redRowStride = 1 * srcWidth * sizeof(GLbyte);
148*61046927SAndroid Build Coastguard Worker    tempImage = malloc(srcWidth * srcHeight * 1 * sizeof(GLbyte));
149*61046927SAndroid Build Coastguard Worker    if (!tempImage)
150*61046927SAndroid Build Coastguard Worker       return GL_FALSE; /* out of memory */
151*61046927SAndroid Build Coastguard Worker    tempImageSlices[0] = (GLbyte *) tempImage;
152*61046927SAndroid Build Coastguard Worker    _mesa_texstore(ctx, dims,
153*61046927SAndroid Build Coastguard Worker                   baseInternalFormat,
154*61046927SAndroid Build Coastguard Worker                   MESA_FORMAT_R_SNORM8,
155*61046927SAndroid Build Coastguard Worker                   redRowStride, (GLubyte **)tempImageSlices,
156*61046927SAndroid Build Coastguard Worker                   srcWidth, srcHeight, srcDepth,
157*61046927SAndroid Build Coastguard Worker                   srcFormat, srcType, srcAddr,
158*61046927SAndroid Build Coastguard Worker                   srcPacking);
159*61046927SAndroid Build Coastguard Worker 
160*61046927SAndroid Build Coastguard Worker    dst = (GLbyte *) dstSlices[0];
161*61046927SAndroid Build Coastguard Worker 
162*61046927SAndroid Build Coastguard Worker    blkaddr = dst;
163*61046927SAndroid Build Coastguard Worker    dstRowDiff = dstRowStride >= (srcWidth * 2) ? dstRowStride - (((srcWidth + 3) & ~3) * 2) : 0;
164*61046927SAndroid Build Coastguard Worker    for (j = 0; j < srcHeight; j+=4) {
165*61046927SAndroid Build Coastguard Worker       if (srcHeight > j + 3) numypixels = 4;
166*61046927SAndroid Build Coastguard Worker       else numypixels = srcHeight - j;
167*61046927SAndroid Build Coastguard Worker       srcaddr = tempImage + j * srcWidth;
168*61046927SAndroid Build Coastguard Worker       for (i = 0; i < srcWidth; i += 4) {
169*61046927SAndroid Build Coastguard Worker          if (srcWidth > i + 3) numxpixels = 4;
170*61046927SAndroid Build Coastguard Worker          else numxpixels = srcWidth - i;
171*61046927SAndroid Build Coastguard Worker          extractsrc_s(srcpixels, srcaddr, srcWidth, numxpixels, numypixels, 1);
172*61046927SAndroid Build Coastguard Worker          util_format_signed_encode_rgtc_ubyte(blkaddr, srcpixels, numxpixels, numypixels);
173*61046927SAndroid Build Coastguard Worker          srcaddr += numxpixels;
174*61046927SAndroid Build Coastguard Worker          blkaddr += 8;
175*61046927SAndroid Build Coastguard Worker       }
176*61046927SAndroid Build Coastguard Worker       blkaddr += dstRowDiff;
177*61046927SAndroid Build Coastguard Worker    }
178*61046927SAndroid Build Coastguard Worker 
179*61046927SAndroid Build Coastguard Worker    free((void *) tempImage);
180*61046927SAndroid Build Coastguard Worker 
181*61046927SAndroid Build Coastguard Worker    return GL_TRUE;
182*61046927SAndroid Build Coastguard Worker }
183*61046927SAndroid Build Coastguard Worker 
184*61046927SAndroid Build Coastguard Worker GLboolean
_mesa_texstore_rg_rgtc2(TEXSTORE_PARAMS)185*61046927SAndroid Build Coastguard Worker _mesa_texstore_rg_rgtc2(TEXSTORE_PARAMS)
186*61046927SAndroid Build Coastguard Worker {
187*61046927SAndroid Build Coastguard Worker    GLubyte *dst;
188*61046927SAndroid Build Coastguard Worker    const GLubyte *tempImage = NULL;
189*61046927SAndroid Build Coastguard Worker    int i, j;
190*61046927SAndroid Build Coastguard Worker    int numxpixels, numypixels;
191*61046927SAndroid Build Coastguard Worker    const GLubyte *srcaddr;
192*61046927SAndroid Build Coastguard Worker    GLubyte srcpixels[4][4];
193*61046927SAndroid Build Coastguard Worker    GLubyte *blkaddr;
194*61046927SAndroid Build Coastguard Worker    GLint dstRowDiff, rgRowStride;
195*61046927SAndroid Build Coastguard Worker    mesa_format tempFormat;
196*61046927SAndroid Build Coastguard Worker    GLubyte *tempImageSlices[1];
197*61046927SAndroid Build Coastguard Worker 
198*61046927SAndroid Build Coastguard Worker    assert(dstFormat == MESA_FORMAT_RG_RGTC2_UNORM ||
199*61046927SAndroid Build Coastguard Worker           dstFormat == MESA_FORMAT_LA_LATC2_UNORM);
200*61046927SAndroid Build Coastguard Worker 
201*61046927SAndroid Build Coastguard Worker    if (baseInternalFormat == GL_RG)
202*61046927SAndroid Build Coastguard Worker       tempFormat = MESA_FORMAT_RG_UNORM8;
203*61046927SAndroid Build Coastguard Worker    else
204*61046927SAndroid Build Coastguard Worker       tempFormat = MESA_FORMAT_LA_UNORM8;
205*61046927SAndroid Build Coastguard Worker 
206*61046927SAndroid Build Coastguard Worker    rgRowStride = 2 * srcWidth * sizeof(GLubyte);
207*61046927SAndroid Build Coastguard Worker    tempImage = malloc(srcWidth * srcHeight * 2 * sizeof(GLubyte));
208*61046927SAndroid Build Coastguard Worker    if (!tempImage)
209*61046927SAndroid Build Coastguard Worker       return GL_FALSE; /* out of memory */
210*61046927SAndroid Build Coastguard Worker    tempImageSlices[0] = (GLubyte *) tempImage;
211*61046927SAndroid Build Coastguard Worker    _mesa_texstore(ctx, dims,
212*61046927SAndroid Build Coastguard Worker                   baseInternalFormat,
213*61046927SAndroid Build Coastguard Worker                   tempFormat,
214*61046927SAndroid Build Coastguard Worker                   rgRowStride, tempImageSlices,
215*61046927SAndroid Build Coastguard Worker                   srcWidth, srcHeight, srcDepth,
216*61046927SAndroid Build Coastguard Worker                   srcFormat, srcType, srcAddr,
217*61046927SAndroid Build Coastguard Worker                   srcPacking);
218*61046927SAndroid Build Coastguard Worker 
219*61046927SAndroid Build Coastguard Worker    dst = dstSlices[0];
220*61046927SAndroid Build Coastguard Worker 
221*61046927SAndroid Build Coastguard Worker    blkaddr = dst;
222*61046927SAndroid Build Coastguard Worker    dstRowDiff = dstRowStride >= (srcWidth * 4) ? dstRowStride - (((srcWidth + 3) & ~3) * 4) : 0;
223*61046927SAndroid Build Coastguard Worker    for (j = 0; j < srcHeight; j+=4) {
224*61046927SAndroid Build Coastguard Worker       if (srcHeight > j + 3) numypixels = 4;
225*61046927SAndroid Build Coastguard Worker       else numypixels = srcHeight - j;
226*61046927SAndroid Build Coastguard Worker       srcaddr = tempImage + j * srcWidth * 2;
227*61046927SAndroid Build Coastguard Worker       for (i = 0; i < srcWidth; i += 4) {
228*61046927SAndroid Build Coastguard Worker          if (srcWidth > i + 3) numxpixels = 4;
229*61046927SAndroid Build Coastguard Worker          else numxpixels = srcWidth - i;
230*61046927SAndroid Build Coastguard Worker          extractsrc_u(srcpixels, srcaddr, srcWidth, numxpixels, numypixels, 2);
231*61046927SAndroid Build Coastguard Worker          util_format_unsigned_encode_rgtc_ubyte(blkaddr, srcpixels, numxpixels, numypixels);
232*61046927SAndroid Build Coastguard Worker 
233*61046927SAndroid Build Coastguard Worker          blkaddr += 8;
234*61046927SAndroid Build Coastguard Worker          extractsrc_u(srcpixels, (GLubyte *)srcaddr + 1, srcWidth, numxpixels, numypixels, 2);
235*61046927SAndroid Build Coastguard Worker          util_format_unsigned_encode_rgtc_ubyte(blkaddr, srcpixels, numxpixels, numypixels);
236*61046927SAndroid Build Coastguard Worker 
237*61046927SAndroid Build Coastguard Worker          blkaddr += 8;
238*61046927SAndroid Build Coastguard Worker 
239*61046927SAndroid Build Coastguard Worker          srcaddr += numxpixels * 2;
240*61046927SAndroid Build Coastguard Worker       }
241*61046927SAndroid Build Coastguard Worker       blkaddr += dstRowDiff;
242*61046927SAndroid Build Coastguard Worker    }
243*61046927SAndroid Build Coastguard Worker 
244*61046927SAndroid Build Coastguard Worker    free((void *) tempImage);
245*61046927SAndroid Build Coastguard Worker 
246*61046927SAndroid Build Coastguard Worker    return GL_TRUE;
247*61046927SAndroid Build Coastguard Worker }
248*61046927SAndroid Build Coastguard Worker 
249*61046927SAndroid Build Coastguard Worker GLboolean
_mesa_texstore_signed_rg_rgtc2(TEXSTORE_PARAMS)250*61046927SAndroid Build Coastguard Worker _mesa_texstore_signed_rg_rgtc2(TEXSTORE_PARAMS)
251*61046927SAndroid Build Coastguard Worker {
252*61046927SAndroid Build Coastguard Worker    GLbyte *dst;
253*61046927SAndroid Build Coastguard Worker    const GLbyte *tempImage = NULL;
254*61046927SAndroid Build Coastguard Worker    int i, j;
255*61046927SAndroid Build Coastguard Worker    int numxpixels, numypixels;
256*61046927SAndroid Build Coastguard Worker    const GLbyte *srcaddr;
257*61046927SAndroid Build Coastguard Worker    GLbyte srcpixels[4][4];
258*61046927SAndroid Build Coastguard Worker    GLbyte *blkaddr;
259*61046927SAndroid Build Coastguard Worker    GLint dstRowDiff, rgRowStride;
260*61046927SAndroid Build Coastguard Worker    mesa_format tempFormat;
261*61046927SAndroid Build Coastguard Worker    GLbyte *tempImageSlices[1];
262*61046927SAndroid Build Coastguard Worker 
263*61046927SAndroid Build Coastguard Worker    assert(dstFormat == MESA_FORMAT_RG_RGTC2_SNORM ||
264*61046927SAndroid Build Coastguard Worker           dstFormat == MESA_FORMAT_LA_LATC2_SNORM);
265*61046927SAndroid Build Coastguard Worker 
266*61046927SAndroid Build Coastguard Worker    if (baseInternalFormat == GL_RG)
267*61046927SAndroid Build Coastguard Worker       tempFormat = MESA_FORMAT_RG_SNORM8;
268*61046927SAndroid Build Coastguard Worker    else
269*61046927SAndroid Build Coastguard Worker       tempFormat = MESA_FORMAT_LA_SNORM8;
270*61046927SAndroid Build Coastguard Worker 
271*61046927SAndroid Build Coastguard Worker    rgRowStride = 2 * srcWidth * sizeof(GLbyte);
272*61046927SAndroid Build Coastguard Worker    tempImage = malloc(srcWidth * srcHeight * 2 * sizeof(GLbyte));
273*61046927SAndroid Build Coastguard Worker    if (!tempImage)
274*61046927SAndroid Build Coastguard Worker       return GL_FALSE; /* out of memory */
275*61046927SAndroid Build Coastguard Worker    tempImageSlices[0] = (GLbyte *) tempImage;
276*61046927SAndroid Build Coastguard Worker    _mesa_texstore(ctx, dims,
277*61046927SAndroid Build Coastguard Worker                   baseInternalFormat,
278*61046927SAndroid Build Coastguard Worker                   tempFormat,
279*61046927SAndroid Build Coastguard Worker                   rgRowStride, (GLubyte **)tempImageSlices,
280*61046927SAndroid Build Coastguard Worker                   srcWidth, srcHeight, srcDepth,
281*61046927SAndroid Build Coastguard Worker                   srcFormat, srcType, srcAddr,
282*61046927SAndroid Build Coastguard Worker                   srcPacking);
283*61046927SAndroid Build Coastguard Worker 
284*61046927SAndroid Build Coastguard Worker    dst = (GLbyte *) dstSlices[0];
285*61046927SAndroid Build Coastguard Worker 
286*61046927SAndroid Build Coastguard Worker    blkaddr = dst;
287*61046927SAndroid Build Coastguard Worker    dstRowDiff = dstRowStride >= (srcWidth * 4) ? dstRowStride - (((srcWidth + 3) & ~3) * 4) : 0;
288*61046927SAndroid Build Coastguard Worker    for (j = 0; j < srcHeight; j += 4) {
289*61046927SAndroid Build Coastguard Worker       if (srcHeight > j + 3) numypixels = 4;
290*61046927SAndroid Build Coastguard Worker       else numypixels = srcHeight - j;
291*61046927SAndroid Build Coastguard Worker       srcaddr = tempImage + j * srcWidth * 2;
292*61046927SAndroid Build Coastguard Worker       for (i = 0; i < srcWidth; i += 4) {
293*61046927SAndroid Build Coastguard Worker          if (srcWidth > i + 3) numxpixels = 4;
294*61046927SAndroid Build Coastguard Worker          else numxpixels = srcWidth - i;
295*61046927SAndroid Build Coastguard Worker 
296*61046927SAndroid Build Coastguard Worker          extractsrc_s(srcpixels, srcaddr, srcWidth, numxpixels, numypixels, 2);
297*61046927SAndroid Build Coastguard Worker          util_format_signed_encode_rgtc_ubyte(blkaddr, srcpixels, numxpixels, numypixels);
298*61046927SAndroid Build Coastguard Worker          blkaddr += 8;
299*61046927SAndroid Build Coastguard Worker 
300*61046927SAndroid Build Coastguard Worker          extractsrc_s(srcpixels, srcaddr + 1, srcWidth, numxpixels, numypixels, 2);
301*61046927SAndroid Build Coastguard Worker          util_format_signed_encode_rgtc_ubyte(blkaddr, srcpixels, numxpixels, numypixels);
302*61046927SAndroid Build Coastguard Worker          blkaddr += 8;
303*61046927SAndroid Build Coastguard Worker 
304*61046927SAndroid Build Coastguard Worker          srcaddr += numxpixels * 2;
305*61046927SAndroid Build Coastguard Worker       }
306*61046927SAndroid Build Coastguard Worker       blkaddr += dstRowDiff;
307*61046927SAndroid Build Coastguard Worker    }
308*61046927SAndroid Build Coastguard Worker 
309*61046927SAndroid Build Coastguard Worker    free((void *) tempImage);
310*61046927SAndroid Build Coastguard Worker 
311*61046927SAndroid Build Coastguard Worker    return GL_TRUE;
312*61046927SAndroid Build Coastguard Worker }
313*61046927SAndroid Build Coastguard Worker 
314*61046927SAndroid Build Coastguard Worker static void
fetch_red_rgtc1(const GLubyte * map,GLint rowStride,GLint i,GLint j,GLfloat * texel)315*61046927SAndroid Build Coastguard Worker fetch_red_rgtc1(const GLubyte *map,
316*61046927SAndroid Build Coastguard Worker                 GLint rowStride, GLint i, GLint j, GLfloat *texel)
317*61046927SAndroid Build Coastguard Worker {
318*61046927SAndroid Build Coastguard Worker    GLubyte red;
319*61046927SAndroid Build Coastguard Worker    util_format_unsigned_fetch_texel_rgtc(rowStride, map, i, j, &red, 1);
320*61046927SAndroid Build Coastguard Worker    texel[RCOMP] = UBYTE_TO_FLOAT(red);
321*61046927SAndroid Build Coastguard Worker    texel[GCOMP] = 0.0;
322*61046927SAndroid Build Coastguard Worker    texel[BCOMP] = 0.0;
323*61046927SAndroid Build Coastguard Worker    texel[ACOMP] = 1.0;
324*61046927SAndroid Build Coastguard Worker }
325*61046927SAndroid Build Coastguard Worker 
326*61046927SAndroid Build Coastguard Worker static void
fetch_l_latc1(const GLubyte * map,GLint rowStride,GLint i,GLint j,GLfloat * texel)327*61046927SAndroid Build Coastguard Worker fetch_l_latc1(const GLubyte *map,
328*61046927SAndroid Build Coastguard Worker               GLint rowStride, GLint i, GLint j, GLfloat *texel)
329*61046927SAndroid Build Coastguard Worker {
330*61046927SAndroid Build Coastguard Worker    GLubyte red;
331*61046927SAndroid Build Coastguard Worker    util_format_unsigned_fetch_texel_rgtc(rowStride, map, i, j, &red, 1);
332*61046927SAndroid Build Coastguard Worker    texel[RCOMP] =
333*61046927SAndroid Build Coastguard Worker    texel[GCOMP] =
334*61046927SAndroid Build Coastguard Worker    texel[BCOMP] = UBYTE_TO_FLOAT(red);
335*61046927SAndroid Build Coastguard Worker    texel[ACOMP] = 1.0;
336*61046927SAndroid Build Coastguard Worker }
337*61046927SAndroid Build Coastguard Worker 
338*61046927SAndroid Build Coastguard Worker static void
fetch_signed_red_rgtc1(const GLubyte * map,GLint rowStride,GLint i,GLint j,GLfloat * texel)339*61046927SAndroid Build Coastguard Worker fetch_signed_red_rgtc1(const GLubyte *map,
340*61046927SAndroid Build Coastguard Worker                        GLint rowStride, GLint i, GLint j, GLfloat *texel)
341*61046927SAndroid Build Coastguard Worker {
342*61046927SAndroid Build Coastguard Worker    GLbyte red;
343*61046927SAndroid Build Coastguard Worker    util_format_signed_fetch_texel_rgtc(rowStride, (const GLbyte *) map,
344*61046927SAndroid Build Coastguard Worker                            i, j, &red, 1);
345*61046927SAndroid Build Coastguard Worker    texel[RCOMP] = BYTE_TO_FLOAT_TEX(red);
346*61046927SAndroid Build Coastguard Worker    texel[GCOMP] = 0.0;
347*61046927SAndroid Build Coastguard Worker    texel[BCOMP] = 0.0;
348*61046927SAndroid Build Coastguard Worker    texel[ACOMP] = 1.0;
349*61046927SAndroid Build Coastguard Worker }
350*61046927SAndroid Build Coastguard Worker 
351*61046927SAndroid Build Coastguard Worker static void
fetch_signed_l_latc1(const GLubyte * map,GLint rowStride,GLint i,GLint j,GLfloat * texel)352*61046927SAndroid Build Coastguard Worker fetch_signed_l_latc1(const GLubyte *map,
353*61046927SAndroid Build Coastguard Worker                      GLint rowStride, GLint i, GLint j, GLfloat *texel)
354*61046927SAndroid Build Coastguard Worker {
355*61046927SAndroid Build Coastguard Worker    GLbyte red;
356*61046927SAndroid Build Coastguard Worker    util_format_signed_fetch_texel_rgtc(rowStride, (GLbyte *) map,
357*61046927SAndroid Build Coastguard Worker                            i, j, &red, 1);
358*61046927SAndroid Build Coastguard Worker    texel[RCOMP] =
359*61046927SAndroid Build Coastguard Worker    texel[GCOMP] =
360*61046927SAndroid Build Coastguard Worker    texel[BCOMP] = BYTE_TO_FLOAT(red);
361*61046927SAndroid Build Coastguard Worker    texel[ACOMP] = 1.0;
362*61046927SAndroid Build Coastguard Worker }
363*61046927SAndroid Build Coastguard Worker 
364*61046927SAndroid Build Coastguard Worker static void
fetch_rg_rgtc2(const GLubyte * map,GLint rowStride,GLint i,GLint j,GLfloat * texel)365*61046927SAndroid Build Coastguard Worker fetch_rg_rgtc2(const GLubyte *map,
366*61046927SAndroid Build Coastguard Worker                GLint rowStride, GLint i, GLint j, GLfloat *texel)
367*61046927SAndroid Build Coastguard Worker {
368*61046927SAndroid Build Coastguard Worker    GLubyte red, green;
369*61046927SAndroid Build Coastguard Worker    util_format_unsigned_fetch_texel_rgtc(rowStride,
370*61046927SAndroid Build Coastguard Worker                              map,
371*61046927SAndroid Build Coastguard Worker                              i, j, &red, 2);
372*61046927SAndroid Build Coastguard Worker    util_format_unsigned_fetch_texel_rgtc(rowStride,
373*61046927SAndroid Build Coastguard Worker                              map + 8,
374*61046927SAndroid Build Coastguard Worker                              i, j, &green, 2);
375*61046927SAndroid Build Coastguard Worker    texel[RCOMP] = UBYTE_TO_FLOAT(red);
376*61046927SAndroid Build Coastguard Worker    texel[GCOMP] = UBYTE_TO_FLOAT(green);
377*61046927SAndroid Build Coastguard Worker    texel[BCOMP] = 0.0;
378*61046927SAndroid Build Coastguard Worker    texel[ACOMP] = 1.0;
379*61046927SAndroid Build Coastguard Worker }
380*61046927SAndroid Build Coastguard Worker 
381*61046927SAndroid Build Coastguard Worker static void
fetch_la_latc2(const GLubyte * map,GLint rowStride,GLint i,GLint j,GLfloat * texel)382*61046927SAndroid Build Coastguard Worker fetch_la_latc2(const GLubyte *map,
383*61046927SAndroid Build Coastguard Worker                GLint rowStride, GLint i, GLint j, GLfloat *texel)
384*61046927SAndroid Build Coastguard Worker {
385*61046927SAndroid Build Coastguard Worker    GLubyte red, green;
386*61046927SAndroid Build Coastguard Worker    util_format_unsigned_fetch_texel_rgtc(rowStride,
387*61046927SAndroid Build Coastguard Worker                              map,
388*61046927SAndroid Build Coastguard Worker                              i, j, &red, 2);
389*61046927SAndroid Build Coastguard Worker    util_format_unsigned_fetch_texel_rgtc(rowStride,
390*61046927SAndroid Build Coastguard Worker                              map + 8,
391*61046927SAndroid Build Coastguard Worker                              i, j, &green, 2);
392*61046927SAndroid Build Coastguard Worker    texel[RCOMP] =
393*61046927SAndroid Build Coastguard Worker    texel[GCOMP] =
394*61046927SAndroid Build Coastguard Worker    texel[BCOMP] = UBYTE_TO_FLOAT(red);
395*61046927SAndroid Build Coastguard Worker    texel[ACOMP] = UBYTE_TO_FLOAT(green);
396*61046927SAndroid Build Coastguard Worker }
397*61046927SAndroid Build Coastguard Worker 
398*61046927SAndroid Build Coastguard Worker 
399*61046927SAndroid Build Coastguard Worker static void
fetch_signed_rg_rgtc2(const GLubyte * map,GLint rowStride,GLint i,GLint j,GLfloat * texel)400*61046927SAndroid Build Coastguard Worker fetch_signed_rg_rgtc2(const GLubyte *map,
401*61046927SAndroid Build Coastguard Worker                       GLint rowStride, GLint i, GLint j, GLfloat *texel)
402*61046927SAndroid Build Coastguard Worker {
403*61046927SAndroid Build Coastguard Worker    GLbyte red, green;
404*61046927SAndroid Build Coastguard Worker    util_format_signed_fetch_texel_rgtc(rowStride,
405*61046927SAndroid Build Coastguard Worker                            (GLbyte *) map,
406*61046927SAndroid Build Coastguard Worker                            i, j, &red, 2);
407*61046927SAndroid Build Coastguard Worker    util_format_signed_fetch_texel_rgtc(rowStride,
408*61046927SAndroid Build Coastguard Worker                            (GLbyte *) map + 8,
409*61046927SAndroid Build Coastguard Worker                            i, j, &green, 2);
410*61046927SAndroid Build Coastguard Worker    texel[RCOMP] = BYTE_TO_FLOAT_TEX(red);
411*61046927SAndroid Build Coastguard Worker    texel[GCOMP] = BYTE_TO_FLOAT_TEX(green);
412*61046927SAndroid Build Coastguard Worker    texel[BCOMP] = 0.0;
413*61046927SAndroid Build Coastguard Worker    texel[ACOMP] = 1.0;
414*61046927SAndroid Build Coastguard Worker }
415*61046927SAndroid Build Coastguard Worker 
416*61046927SAndroid Build Coastguard Worker 
417*61046927SAndroid Build Coastguard Worker static void
fetch_signed_la_latc2(const GLubyte * map,GLint rowStride,GLint i,GLint j,GLfloat * texel)418*61046927SAndroid Build Coastguard Worker fetch_signed_la_latc2(const GLubyte *map,
419*61046927SAndroid Build Coastguard Worker                       GLint rowStride, GLint i, GLint j, GLfloat *texel)
420*61046927SAndroid Build Coastguard Worker {
421*61046927SAndroid Build Coastguard Worker    GLbyte red, green;
422*61046927SAndroid Build Coastguard Worker    util_format_signed_fetch_texel_rgtc(rowStride,
423*61046927SAndroid Build Coastguard Worker                            (GLbyte *) map,
424*61046927SAndroid Build Coastguard Worker                            i, j, &red, 2);
425*61046927SAndroid Build Coastguard Worker    util_format_signed_fetch_texel_rgtc(rowStride,
426*61046927SAndroid Build Coastguard Worker                            (GLbyte *) map + 8,
427*61046927SAndroid Build Coastguard Worker                            i, j, &green, 2);
428*61046927SAndroid Build Coastguard Worker    texel[RCOMP] =
429*61046927SAndroid Build Coastguard Worker    texel[GCOMP] =
430*61046927SAndroid Build Coastguard Worker    texel[BCOMP] = BYTE_TO_FLOAT_TEX(red);
431*61046927SAndroid Build Coastguard Worker    texel[ACOMP] = BYTE_TO_FLOAT_TEX(green);
432*61046927SAndroid Build Coastguard Worker }
433*61046927SAndroid Build Coastguard Worker 
434*61046927SAndroid Build Coastguard Worker 
435*61046927SAndroid Build Coastguard Worker compressed_fetch_func
_mesa_get_compressed_rgtc_func(mesa_format format)436*61046927SAndroid Build Coastguard Worker _mesa_get_compressed_rgtc_func(mesa_format format)
437*61046927SAndroid Build Coastguard Worker {
438*61046927SAndroid Build Coastguard Worker    switch (format) {
439*61046927SAndroid Build Coastguard Worker    case MESA_FORMAT_R_RGTC1_UNORM:
440*61046927SAndroid Build Coastguard Worker       return fetch_red_rgtc1;
441*61046927SAndroid Build Coastguard Worker    case MESA_FORMAT_L_LATC1_UNORM:
442*61046927SAndroid Build Coastguard Worker       return fetch_l_latc1;
443*61046927SAndroid Build Coastguard Worker    case MESA_FORMAT_R_RGTC1_SNORM:
444*61046927SAndroid Build Coastguard Worker       return fetch_signed_red_rgtc1;
445*61046927SAndroid Build Coastguard Worker    case MESA_FORMAT_L_LATC1_SNORM:
446*61046927SAndroid Build Coastguard Worker       return fetch_signed_l_latc1;
447*61046927SAndroid Build Coastguard Worker    case MESA_FORMAT_RG_RGTC2_UNORM:
448*61046927SAndroid Build Coastguard Worker       return fetch_rg_rgtc2;
449*61046927SAndroid Build Coastguard Worker    case MESA_FORMAT_LA_LATC2_UNORM:
450*61046927SAndroid Build Coastguard Worker       return fetch_la_latc2;
451*61046927SAndroid Build Coastguard Worker    case MESA_FORMAT_RG_RGTC2_SNORM:
452*61046927SAndroid Build Coastguard Worker       return fetch_signed_rg_rgtc2;
453*61046927SAndroid Build Coastguard Worker    case MESA_FORMAT_LA_LATC2_SNORM:
454*61046927SAndroid Build Coastguard Worker       return fetch_signed_la_latc2;
455*61046927SAndroid Build Coastguard Worker    default:
456*61046927SAndroid Build Coastguard Worker       return NULL;
457*61046927SAndroid Build Coastguard Worker    }
458*61046927SAndroid Build Coastguard Worker }
459*61046927SAndroid Build Coastguard Worker 
460*61046927SAndroid Build Coastguard Worker void
_mesa_unpack_rgtc(uint8_t * dst_row,unsigned dst_stride,const uint8_t * src_row,unsigned src_stride,unsigned src_width,unsigned src_height,mesa_format format)461*61046927SAndroid Build Coastguard Worker _mesa_unpack_rgtc(uint8_t *dst_row,
462*61046927SAndroid Build Coastguard Worker                   unsigned dst_stride,
463*61046927SAndroid Build Coastguard Worker                   const uint8_t *src_row,
464*61046927SAndroid Build Coastguard Worker                   unsigned src_stride,
465*61046927SAndroid Build Coastguard Worker                   unsigned src_width,
466*61046927SAndroid Build Coastguard Worker                   unsigned src_height,
467*61046927SAndroid Build Coastguard Worker                   mesa_format format)
468*61046927SAndroid Build Coastguard Worker {
469*61046927SAndroid Build Coastguard Worker    switch (format) {
470*61046927SAndroid Build Coastguard Worker    case MESA_FORMAT_R_RGTC1_UNORM:
471*61046927SAndroid Build Coastguard Worker    case MESA_FORMAT_L_LATC1_UNORM:
472*61046927SAndroid Build Coastguard Worker       util_format_rgtc1_unorm_unpack_r_8unorm(dst_row, dst_stride,
473*61046927SAndroid Build Coastguard Worker                                               src_row, src_stride,
474*61046927SAndroid Build Coastguard Worker                                               src_width, src_height);
475*61046927SAndroid Build Coastguard Worker       break;
476*61046927SAndroid Build Coastguard Worker 
477*61046927SAndroid Build Coastguard Worker    case MESA_FORMAT_R_RGTC1_SNORM:
478*61046927SAndroid Build Coastguard Worker    case MESA_FORMAT_L_LATC1_SNORM:
479*61046927SAndroid Build Coastguard Worker       util_format_rgtc1_snorm_unpack_r_8snorm((int8_t *)dst_row, dst_stride,
480*61046927SAndroid Build Coastguard Worker                                               src_row, src_stride,
481*61046927SAndroid Build Coastguard Worker                                               src_width, src_height);
482*61046927SAndroid Build Coastguard Worker       break;
483*61046927SAndroid Build Coastguard Worker 
484*61046927SAndroid Build Coastguard Worker    case MESA_FORMAT_RG_RGTC2_UNORM:
485*61046927SAndroid Build Coastguard Worker    case MESA_FORMAT_LA_LATC2_UNORM:
486*61046927SAndroid Build Coastguard Worker       util_format_rgtc2_unorm_unpack_rg_8unorm(dst_row, dst_stride,
487*61046927SAndroid Build Coastguard Worker                                                src_row, src_stride,
488*61046927SAndroid Build Coastguard Worker                                                src_width, src_height);
489*61046927SAndroid Build Coastguard Worker       break;
490*61046927SAndroid Build Coastguard Worker 
491*61046927SAndroid Build Coastguard Worker    case MESA_FORMAT_RG_RGTC2_SNORM:
492*61046927SAndroid Build Coastguard Worker    case MESA_FORMAT_LA_LATC2_SNORM:
493*61046927SAndroid Build Coastguard Worker       util_format_rgtc2_snorm_unpack_rg_8snorm((int8_t *)dst_row, dst_stride,
494*61046927SAndroid Build Coastguard Worker                                                src_row, src_stride,
495*61046927SAndroid Build Coastguard Worker                                                src_width, src_height);
496*61046927SAndroid Build Coastguard Worker       break;
497*61046927SAndroid Build Coastguard Worker 
498*61046927SAndroid Build Coastguard Worker    default:
499*61046927SAndroid Build Coastguard Worker       unreachable("unexpected format");
500*61046927SAndroid Build Coastguard Worker    }
501*61046927SAndroid Build Coastguard Worker }
502