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