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