blob: 7a289ad091557ff9f8896ad654b7dbb2d91e328a [file] [log] [blame]
Alexis Hetu1b900872020-02-24 12:09:16 -05001// 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"
Nicolas Capensa4347a92020-03-01 08:29:25 -050016
Alexis Hetu1b900872020-02-24 12:09:16 -050017#include "System/Math.hpp"
18
Nicolas Capensa4347a92020-03-01 08:29:25 -050019#ifdef SWIFTSHADER_ENABLE_ASTC
Antonio Maioranob02a7082020-03-30 21:55:20 -040020# include "astc_codec_internals.h"
Nicolas Capensa4347a92020-03-01 08:29:25 -050021#endif
22
Alexis Hetu1b900872020-02-24 12:09:16 -050023#include <memory>
24#include <unordered_map>
25
26namespace {
27
Nicolas Capensa4347a92020-03-01 08:29:25 -050028#ifdef SWIFTSHADER_ENABLE_ASTC
Alexis Hetu1b900872020-02-24 12:09:16 -050029void 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}
Nicolas Capensa4347a92020-03-01 08:29:25 -050099#endif
Alexis Hetu1b900872020-02-24 12:09:16 -0500100
101} // namespace
102
103void 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{
Nicolas Capensa4347a92020-03-01 08:29:25 -0500109#ifdef SWIFTSHADER_ENABLE_ASTC
Alexis Hetu1b900872020-02-24 12:09:16 -0500110 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());
Nicolas Capensa4347a92020-03-01 08:29:25 -0500134#endif
Alexis Hetu1b900872020-02-24 12:09:16 -0500135}