306 lines
11 KiB
C++

//===============================================================================
// Copyright (c) 2007-2016 Advanced Micro Devices, Inc. All rights reserved.
// Copyright (c) 2004-2006 ATI Technologies Inc.
//===============================================================================
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files(the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions :
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
// ASTC_Decode.cpp : A reference decoder for ASTC
//
#include "common.h"
#include "astc/astc_decode.h"
#include "astc_host.h"
// //using namespace ASTC_Encoder;
// void decompress_symbolic_block2(
// astc_decode_mode decode_mode,
// int xdim, int ydim, int zdim, // dimensions of block
// int xpos, int ypos, int zpos, // position of block
// const symbolic_compressed_block * scb, imageblock_cpu * blk)
// {
// blk->xpos = xpos;
// blk->ypos = ypos;
// blk->zpos = zpos;
//
// int i;
//
// // if we detected an error-block, blow up immediately.
// if (scb->error_block)
// {
// if (decode_mode == DECODE_LDR_SRGB)
// {
// for (i = 0; i < xdim * ydim * zdim; i++)
// {
// blk->orig_data[4 * i] = 1.0f;
// blk->orig_data[4 * i + 1] = 0.0f;
// blk->orig_data[4 * i + 2] = 1.0f;
// blk->orig_data[4 * i + 3] = 1.0f;
// blk->rgb_lns[i] = 0;
// blk->alpha_lns[i] = 0;
// blk->nan_texel[i] = 0;
// }
// }
// else
// {
// for (i = 0; i < xdim * ydim * zdim; i++)
// {
// blk->orig_data[4 * i] = 0.0f;
// blk->orig_data[4 * i + 1] = 0.0f;
// blk->orig_data[4 * i + 2] = 0.0f;
// blk->orig_data[4 * i + 3] = 0.0f;
// blk->rgb_lns[i] = 0;
// blk->alpha_lns[i] = 0;
// blk->nan_texel[i] = 1;
// }
// }
//
// imageblock_initialize_work_from_orig_cpu(blk, xdim * ydim * zdim);
// update_imageblock_flags_cpu(blk, xdim, ydim, zdim);
// return;
// }
//
//
//
//
// if (scb->block_mode < 0)
// {
// float red = 0, green = 0, blue = 0, alpha = 0;
// int use_lns = 0;
// int use_nan = 0;
//
// if (scb->block_mode == -2)
// {
// // For sRGB decoding, we should return only the top 8 bits.
// int mask = (decode_mode == DECODE_LDR_SRGB) ? 0xFF00 : 0xFFFF;
//
// red = sf16_to_float(unorm16_to_sf16((uint16_t)scb->constant_color[0] & mask));
// green = sf16_to_float(unorm16_to_sf16((uint16_t)scb->constant_color[1] & mask));
// blue = sf16_to_float(unorm16_to_sf16((uint16_t)scb->constant_color[2] & mask));
// alpha = sf16_to_float(unorm16_to_sf16((uint16_t)scb->constant_color[3] & mask));
// use_lns = 0;
// use_nan = 0;
// }
// else
// {
// switch (decode_mode)
// {
// case DECODE_LDR_SRGB:
// red = 1.0f;
// green = 0.0f;
// blue = 1.0f;
// alpha = 1.0f;
// use_lns = 0;
// use_nan = 0;
// break;
// case DECODE_LDR:
// red = 0.0f;
// green = 0.0f;
// blue = 0.0f;
// alpha = 0.0f;
// use_lns = 0;
// use_nan = 1;
// break;
// case DECODE_HDR:
// // constant-color block; unpack from FP16 to FP32.
// red = sf16_to_float((sf16)scb->constant_color[0]);
// green = sf16_to_float((sf16)scb->constant_color[1]);
// blue = sf16_to_float((sf16)scb->constant_color[2]);
// alpha = sf16_to_float((sf16)scb->constant_color[3]);
// use_lns = 1;
// use_nan = 0;
// break;
// }
// }
//
// for (i = 0; i < xdim * ydim * zdim; i++)
// {
// blk->orig_data[4 * i] = red;
// blk->orig_data[4 * i + 1] = green;
// blk->orig_data[4 * i + 2] = blue;
// blk->orig_data[4 * i + 3] = alpha;
// blk->rgb_lns[i] = (uint8_t)use_lns;
// blk->alpha_lns[i] = (uint8_t)use_lns;
// blk->nan_texel[i] = (uint8_t)use_nan;
// }
//
//
// imageblock_initialize_work_from_orig_cpu(blk, xdim * ydim * zdim);
// update_imageblock_flags_cpu(blk, xdim, ydim, zdim);
// return;
// }
//
//
// // get the appropriate partition-table entry
// int partition_count = scb->partition_count;
// const partition_info_cpu *pt = get_partition_table(xdim, ydim, zdim, partition_count);
// pt += scb->partition_index;
//
// // get the appropriate block descriptor
// const block_size_descriptor *bsd = get_block_size_descriptor(xdim, ydim, zdim);
// const decimation_table *const *ixtab2 = bsd->decimation_tables;
//
//
// const decimation_table *it = ixtab2[bsd->block_modes[scb->block_mode].decimation_mode];
//
// int is_dual_plane = bsd->block_modes[scb->block_mode].is_dual_plane;
//
// int weight_quantization_level = bsd->block_modes[scb->block_mode].quantization_mode;
//
//
// // decode the color endpoints
// ushort4 color_endpoint0[4];
// ushort4 color_endpoint1[4];
//
// int rgb_hdr_endpoint[4];
// int alpha_hdr_endpoint[4];
// int nan_endpoint[4];
//
// for (i = 0; i < partition_count; i++)
// unpack_color_endpoints(decode_mode,
// scb->color_formats[i],
// scb->color_quantization_level, scb->color_values[i], &(rgb_hdr_endpoint[i]), &(alpha_hdr_endpoint[i]), &(nan_endpoint[i]), &(color_endpoint0[i]), &(color_endpoint1[i]));
//
// // first unquantize the weights
// int uq_plane1_weights[MAX_WEIGHTS_PER_BLOCK];
// int uq_plane2_weights[MAX_WEIGHTS_PER_BLOCK];
// int weight_count = it->num_weights;
//
//
// const quantization_and_transfer_table *qat = &(quant_and_xfer_tables[weight_quantization_level]);
//
// for (i = 0; i < weight_count; i++)
// {
// uq_plane1_weights[i] = qat->unquantized_value[scb->plane1_weights[i]];
// }
// if (is_dual_plane)
// {
// for (i = 0; i < weight_count; i++)
// uq_plane2_weights[i] = qat->unquantized_value[scb->plane2_weights[i]];
// }
//
//
// // then un-decimate them.
// int weights[MAX_TEXELS_PER_BLOCK];
// int plane2_weights[MAX_TEXELS_PER_BLOCK];
//
//
// int texels_per_block = xdim * ydim * zdim;
// for (i = 0; i < texels_per_block; i++)
// weights[i] = compute_value_of_texel_int(i, it, uq_plane1_weights);
//
// if (is_dual_plane)
// for (i = 0; i < texels_per_block; i++)
// plane2_weights[i] = compute_value_of_texel_int(i, it, uq_plane2_weights);
//
//
// int plane2_color_component = scb->plane2_color_component;
//
//
// // now that we have endpoint colors and weights, we can unpack actual colors for
// // each texel.
// for (i = 0; i < texels_per_block; i++)
// {
// int partition = pt->partition_of_texel[i];
//
// ushort4 color = lerp_color_int(decode_mode,
// color_endpoint0[partition],
// color_endpoint1[partition],
// weights[i],
// plane2_weights[i],
// is_dual_plane ? plane2_color_component : -1);
//
// blk->rgb_lns[i] = (uint8_t)rgb_hdr_endpoint[partition];
// blk->alpha_lns[i] = (uint8_t)alpha_hdr_endpoint[partition];
// blk->nan_texel[i] = (uint8_t)nan_endpoint[partition];
//
// blk->work_data[4 * i] = color.x;
// blk->work_data[4 * i + 1] = color.y;
// blk->work_data[4 * i + 2] = color.z;
// blk->work_data[4 * i + 3] = color.w;
// }
//
// imageblock_initialize_orig_from_work_cpu(blk, xdim * ydim * zdim);
//
// update_imageblock_flags_cpu(blk, xdim, ydim, zdim);
// }
void ASTCBlockDecoder::DecompressBlock( BYTE BlockWidth,
BYTE BlockHeight,
BYTE bitness,
float out[][4],
BYTE in[ASTC_COMPRESSED_BLOCK_SIZE]) {
// Results Buffer
astc_codec_image_cpu *img = allocate_image_cpu(bitness, BlockWidth, BlockHeight, 1, 0);
initialize_image_cpu(img);
ASTC_Encoder::uint8_t *bp = in;
physical_compressed_block_cpu pcb = *(physical_compressed_block_cpu *) bp;
symbolic_compressed_block_cpu scb;
physical_to_symbolic_cpu(BlockWidth, BlockHeight, 1, pcb, &scb);
swizzlepattern_cpu swz_decode = { 0, 1, 2, 3 };
imageblock_cpu pb;
// astc_decode_mode decode_mode1 = DECODE_HDR;
// decompress_symbolic_block((astc_decode_mode)decode_mode1, BlockWidth, BlockHeight, 1, 0, 0, 0, (symbolic_compressed_block*)&scb, (imageblock_cpu *)&pb);
ASTC_Encoder::astc_decode_mode decode_mode = ASTC_Encoder::DECODE_HDR;
decompress_symbolic_block_cpu(decode_mode, BlockWidth, BlockHeight, 1, 0, 0, 0, &scb, &pb);
write_imageblock_cpu(img, &pb, BlockWidth, BlockHeight, 1, 0, 0, 0, swz_decode);
// copy results to our output buffer
int x, y, z;
int index=0;
int exsize = img->xsize + 2 * img->padding;
int eysize = img->ysize + 2 * img->padding;
int ezsize = (img->zsize == 1) ? 1 : img->zsize + 2 * img->padding;
if (img->imagedata8) {
for (z = 0; z < ezsize; z++)
for (y = 0; y < eysize; y++) {
for (x = 0; x < exsize; x++) {
out[index][0] = img->imagedata8[z][y][4 * x];
out[index][1] = img->imagedata8[z][y][4 * x + 1];
out[index][2] = img->imagedata8[z][y][4 * x + 2];
out[index][3] = img->imagedata8[z][y][4 * x + 3];
index++;
}
}
} else if (img->imagedata16) {
for (z = 0; z < ezsize; z++)
for (y = 0; y < eysize; y++)
for (x = 0; x < exsize; x++) {
out[index][0] = img->imagedata16[z][y][4 * x];
out[index][1] = img->imagedata16[z][y][4 * x + 1];
out[index][2] = img->imagedata16[z][y][4 * x + 2];
out[index][3] = img->imagedata16[z][y][4 * x + 3];
}
}
destroy_image_cpu(img);
}