xref: /aosp_15_r20/external/swiftshader/src/Device/ASTC_Decoder.cpp (revision 03ce13f70fcc45d86ee91b7ee4cab1936a95046e)
1*03ce13f7SAndroid Build Coastguard Worker // Copyright 2020 The SwiftShader Authors. All Rights Reserved.
2*03ce13f7SAndroid Build Coastguard Worker //
3*03ce13f7SAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
4*03ce13f7SAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
5*03ce13f7SAndroid Build Coastguard Worker // You may obtain a copy of the License at
6*03ce13f7SAndroid Build Coastguard Worker //
7*03ce13f7SAndroid Build Coastguard Worker //    http://www.apache.org/licenses/LICENSE-2.0
8*03ce13f7SAndroid Build Coastguard Worker //
9*03ce13f7SAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
10*03ce13f7SAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
11*03ce13f7SAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*03ce13f7SAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
13*03ce13f7SAndroid Build Coastguard Worker // limitations under the License.
14*03ce13f7SAndroid Build Coastguard Worker 
15*03ce13f7SAndroid Build Coastguard Worker #include "ASTC_Decoder.hpp"
16*03ce13f7SAndroid Build Coastguard Worker 
17*03ce13f7SAndroid Build Coastguard Worker #include "System/Math.hpp"
18*03ce13f7SAndroid Build Coastguard Worker 
19*03ce13f7SAndroid Build Coastguard Worker #ifdef SWIFTSHADER_ENABLE_ASTC
20*03ce13f7SAndroid Build Coastguard Worker #	include "astc_codec_internals.h"
21*03ce13f7SAndroid Build Coastguard Worker #endif
22*03ce13f7SAndroid Build Coastguard Worker 
23*03ce13f7SAndroid Build Coastguard Worker #include <memory>
24*03ce13f7SAndroid Build Coastguard Worker #include <unordered_map>
25*03ce13f7SAndroid Build Coastguard Worker 
26*03ce13f7SAndroid Build Coastguard Worker namespace {
27*03ce13f7SAndroid Build Coastguard Worker 
28*03ce13f7SAndroid Build Coastguard Worker #ifdef SWIFTSHADER_ENABLE_ASTC
write_imageblock(unsigned char * img,const imageblock * pb,int xsize,int ysize,int zsize,int bytes,int destPitchB,int destSliceB,bool isUnsignedByte,int xdim,int ydim,int zdim,int xpos,int ypos,int zpos)29*03ce13f7SAndroid Build Coastguard Worker void write_imageblock(unsigned char *img,
30*03ce13f7SAndroid Build Coastguard Worker                       // picture-block to initialize with image data. We assume that orig_data is valid
31*03ce13f7SAndroid Build Coastguard Worker                       const imageblock *pb,
32*03ce13f7SAndroid Build Coastguard Worker                       // output dimensions
33*03ce13f7SAndroid Build Coastguard Worker                       int xsize, int ysize, int zsize,
34*03ce13f7SAndroid Build Coastguard Worker                       // output format
35*03ce13f7SAndroid Build Coastguard Worker                       int bytes, int destPitchB, int destSliceB, bool isUnsignedByte,
36*03ce13f7SAndroid Build Coastguard Worker                       // block dimensions
37*03ce13f7SAndroid Build Coastguard Worker                       int xdim, int ydim, int zdim,
38*03ce13f7SAndroid Build Coastguard Worker                       // position to write the block to
39*03ce13f7SAndroid Build Coastguard Worker                       int xpos, int ypos, int zpos)
40*03ce13f7SAndroid Build Coastguard Worker {
41*03ce13f7SAndroid Build Coastguard Worker 	const float *fptr = pb->orig_data;
42*03ce13f7SAndroid Build Coastguard Worker 	const uint8_t *nptr = pb->nan_texel;
43*03ce13f7SAndroid Build Coastguard Worker 
44*03ce13f7SAndroid Build Coastguard Worker 	for(int z = 0; z < zdim; z++)
45*03ce13f7SAndroid Build Coastguard Worker 	{
46*03ce13f7SAndroid Build Coastguard Worker 		for(int y = 0; y < ydim; y++)
47*03ce13f7SAndroid Build Coastguard Worker 		{
48*03ce13f7SAndroid Build Coastguard Worker 			for(int x = 0; x < xdim; x++)
49*03ce13f7SAndroid Build Coastguard Worker 			{
50*03ce13f7SAndroid Build Coastguard Worker 				int xi = xpos + x;
51*03ce13f7SAndroid Build Coastguard Worker 				int yi = ypos + y;
52*03ce13f7SAndroid Build Coastguard Worker 				int zi = zpos + z;
53*03ce13f7SAndroid Build Coastguard Worker 
54*03ce13f7SAndroid Build Coastguard Worker 				if(xi >= 0 && yi >= 0 && zi >= 0 && xi < xsize && yi < ysize && zi < zsize)
55*03ce13f7SAndroid Build Coastguard Worker 				{
56*03ce13f7SAndroid Build Coastguard Worker 					unsigned char *pix = &img[zi * destSliceB + yi * destPitchB + xi * bytes];
57*03ce13f7SAndroid Build Coastguard Worker 
58*03ce13f7SAndroid Build Coastguard Worker 					if(isUnsignedByte)
59*03ce13f7SAndroid Build Coastguard Worker 					{
60*03ce13f7SAndroid Build Coastguard Worker 						if(*nptr)
61*03ce13f7SAndroid Build Coastguard Worker 						{
62*03ce13f7SAndroid Build Coastguard Worker 							// NaN-pixel, but we can't display it. Display purple instead.
63*03ce13f7SAndroid Build Coastguard Worker 							pix[0] = 0xFF;
64*03ce13f7SAndroid Build Coastguard Worker 							pix[1] = 0x00;
65*03ce13f7SAndroid Build Coastguard Worker 							pix[2] = 0xFF;
66*03ce13f7SAndroid Build Coastguard Worker 							pix[3] = 0xFF;
67*03ce13f7SAndroid Build Coastguard Worker 						}
68*03ce13f7SAndroid Build Coastguard Worker 						else
69*03ce13f7SAndroid Build Coastguard Worker 						{
70*03ce13f7SAndroid Build Coastguard Worker 							pix[0] = static_cast<unsigned char>(sw::clamp(fptr[0], 0.0f, 1.0f) * 255.0f + 0.5f);
71*03ce13f7SAndroid Build Coastguard Worker 							pix[1] = static_cast<unsigned char>(sw::clamp(fptr[1], 0.0f, 1.0f) * 255.0f + 0.5f);
72*03ce13f7SAndroid Build Coastguard Worker 							pix[2] = static_cast<unsigned char>(sw::clamp(fptr[2], 0.0f, 1.0f) * 255.0f + 0.5f);
73*03ce13f7SAndroid Build Coastguard Worker 							pix[3] = static_cast<unsigned char>(sw::clamp(fptr[3], 0.0f, 1.0f) * 255.0f + 0.5f);
74*03ce13f7SAndroid Build Coastguard Worker 						}
75*03ce13f7SAndroid Build Coastguard Worker 					}
76*03ce13f7SAndroid Build Coastguard Worker 					else
77*03ce13f7SAndroid Build Coastguard Worker 					{
78*03ce13f7SAndroid Build Coastguard Worker 						if(*nptr)
79*03ce13f7SAndroid Build Coastguard Worker 						{
80*03ce13f7SAndroid Build Coastguard Worker 							unsigned int *pixu = reinterpret_cast<unsigned int *>(pix);
81*03ce13f7SAndroid Build Coastguard Worker 							pixu[0] = pixu[1] = pixu[2] = pixu[3] = 0x7FFFFFFF;  // QNaN
82*03ce13f7SAndroid Build Coastguard Worker 						}
83*03ce13f7SAndroid Build Coastguard Worker 						else
84*03ce13f7SAndroid Build Coastguard Worker 						{
85*03ce13f7SAndroid Build Coastguard Worker 							float *pixf = reinterpret_cast<float *>(pix);
86*03ce13f7SAndroid Build Coastguard Worker 							pixf[0] = fptr[0];
87*03ce13f7SAndroid Build Coastguard Worker 							pixf[1] = fptr[1];
88*03ce13f7SAndroid Build Coastguard Worker 							pixf[2] = fptr[2];
89*03ce13f7SAndroid Build Coastguard Worker 							pixf[3] = fptr[3];
90*03ce13f7SAndroid Build Coastguard Worker 						}
91*03ce13f7SAndroid Build Coastguard Worker 					}
92*03ce13f7SAndroid Build Coastguard Worker 				}
93*03ce13f7SAndroid Build Coastguard Worker 				fptr += 4;
94*03ce13f7SAndroid Build Coastguard Worker 				nptr++;
95*03ce13f7SAndroid Build Coastguard Worker 			}
96*03ce13f7SAndroid Build Coastguard Worker 		}
97*03ce13f7SAndroid Build Coastguard Worker 	}
98*03ce13f7SAndroid Build Coastguard Worker }
99*03ce13f7SAndroid Build Coastguard Worker #endif
100*03ce13f7SAndroid Build Coastguard Worker 
101*03ce13f7SAndroid Build Coastguard Worker }  // namespace
102*03ce13f7SAndroid Build Coastguard Worker 
Decode(const unsigned char * source,unsigned char * dest,int destWidth,int destHeight,int destDepth,int bytes,int destPitchB,int destSliceB,int xBlockSize,int yBlockSize,int zBlockSize,int xblocks,int yblocks,int zblocks,bool isUnsignedByte)103*03ce13f7SAndroid Build Coastguard Worker void ASTC_Decoder::Decode(const unsigned char *source, unsigned char *dest,
104*03ce13f7SAndroid Build Coastguard Worker                           int destWidth, int destHeight, int destDepth,
105*03ce13f7SAndroid Build Coastguard Worker                           int bytes, int destPitchB, int destSliceB,
106*03ce13f7SAndroid Build Coastguard Worker                           int xBlockSize, int yBlockSize, int zBlockSize,
107*03ce13f7SAndroid Build Coastguard Worker                           int xblocks, int yblocks, int zblocks, bool isUnsignedByte)
108*03ce13f7SAndroid Build Coastguard Worker {
109*03ce13f7SAndroid Build Coastguard Worker #ifdef SWIFTSHADER_ENABLE_ASTC
110*03ce13f7SAndroid Build Coastguard Worker 	build_quantization_mode_table();
111*03ce13f7SAndroid Build Coastguard Worker 
112*03ce13f7SAndroid Build Coastguard Worker 	astc_decode_mode decode_mode = isUnsignedByte ? DECODE_LDR : DECODE_HDR;
113*03ce13f7SAndroid Build Coastguard Worker 
114*03ce13f7SAndroid Build Coastguard Worker 	std::unique_ptr<block_size_descriptor> bsd(new block_size_descriptor);
115*03ce13f7SAndroid Build Coastguard Worker 	init_block_size_descriptor(xBlockSize, yBlockSize, zBlockSize, bsd.get());
116*03ce13f7SAndroid Build Coastguard Worker 
117*03ce13f7SAndroid Build Coastguard Worker 	std::unique_ptr<imageblock> ib(new imageblock);
118*03ce13f7SAndroid Build Coastguard Worker 	std::unique_ptr<symbolic_compressed_block> scb(new symbolic_compressed_block);
119*03ce13f7SAndroid Build Coastguard Worker 	for(int z = 0; z < zblocks; z++)
120*03ce13f7SAndroid Build Coastguard Worker 	{
121*03ce13f7SAndroid Build Coastguard Worker 		for(int y = 0; y < yblocks; y++)
122*03ce13f7SAndroid Build Coastguard Worker 		{
123*03ce13f7SAndroid Build Coastguard Worker 			for(int x = 0; x < xblocks; x++, source += 16)
124*03ce13f7SAndroid Build Coastguard Worker 			{
125*03ce13f7SAndroid Build Coastguard Worker 				physical_to_symbolic(bsd.get(), *(physical_compressed_block *)source, scb.get());
126*03ce13f7SAndroid Build Coastguard Worker 				decompress_symbolic_block(decode_mode, bsd.get(), x * xBlockSize, y * yBlockSize, z * zBlockSize, scb.get(), ib.get());
127*03ce13f7SAndroid Build Coastguard Worker 				write_imageblock(dest, ib.get(), destWidth, destHeight, destDepth, bytes, destPitchB, destSliceB, isUnsignedByte,
128*03ce13f7SAndroid Build Coastguard Worker 				                 xBlockSize, yBlockSize, zBlockSize, x * xBlockSize, y * yBlockSize, z * zBlockSize);
129*03ce13f7SAndroid Build Coastguard Worker 			}
130*03ce13f7SAndroid Build Coastguard Worker 		}
131*03ce13f7SAndroid Build Coastguard Worker 	}
132*03ce13f7SAndroid Build Coastguard Worker 
133*03ce13f7SAndroid Build Coastguard Worker 	term_block_size_descriptor(bsd.get());
134*03ce13f7SAndroid Build Coastguard Worker #endif
135*03ce13f7SAndroid Build Coastguard Worker }
136