/***************************************************************************** * This file is part of uvg266 VVC encoder. * * Copyright (c) 2021, Tampere University, ITU/ISO/IEC, project contributors * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright notice, this * list of conditions and the following disclaimer in the documentation and/or * other materials provided with the distribution. * * * Neither the name of the Tampere University or ITU/ISO/IEC nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION HOWEVER CAUSED AND ON * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * INCLUDING NEGLIGENCE OR OTHERWISE ARISING IN ANY WAY OUT OF THE USE OF THIS ****************************************************************************/ //Compile with gcc -o generate_tables generate_tables.c //Run ./generate_tables > ../src/tables.c #include #include #include #include "../src/global.h" #include "../src/tables.h" const uint32_t* _sig_last_scan[3][5]; int8_t _convert_to_bit[LCU_WIDTH + 1]; /** * Initialize g_sig_last_scan with scan positions for a transform block of * size width x height. */ static void init_sig_last_scan(uint32_t *buff_d, uint32_t *buff_h, uint32_t *buff_v, int32_t width, int32_t height) { uint32_t num_scan_pos = width * height; uint32_t next_scan_pos = 0; int32_t xx, yy, x, y; uint32_t scan_line; uint32_t blk_y, blk_x; uint32_t blk; uint32_t cnt = 0; assert(width == height && width <= 32); if (width <= 4) { uint32_t *buff_tmp = buff_d; for (scan_line = 0; next_scan_pos < num_scan_pos; scan_line++) { int primary_dim = scan_line; int second_dim = 0; while (primary_dim >= width) { second_dim++; primary_dim--; } while (primary_dim >= 0 && second_dim < width) { buff_tmp[next_scan_pos] = primary_dim * width + second_dim ; next_scan_pos++; second_dim++; primary_dim--; } } } if (width > 4 && width <= 32) { uint32_t num_blk_side = width >> 2; uint32_t num_blks = num_blk_side * num_blk_side; uint32_t log2_width = g_to_bits[width]; for (blk = 0; blk < num_blks; blk++) { uint32_t init_blk_pos = g_sig_last_scan_cg[log2_width][SCAN_DIAG][blk]; next_scan_pos = 0; { uint32_t offset_y = init_blk_pos / num_blk_side; uint32_t offset_x = init_blk_pos - offset_y * num_blk_side; uint32_t offset_d = 4 * (offset_x + offset_y * width); uint32_t offset_scan = 16 * blk; for (scan_line = 0; next_scan_pos < 16; scan_line++) { int primary_dim = scan_line; int second_dim = 0; //TODO: optimize while (primary_dim >= 4) { second_dim++; primary_dim--; } while (primary_dim >= 0 && second_dim < 4) { buff_d[next_scan_pos + offset_scan] = primary_dim * width + second_dim + offset_d; next_scan_pos++; second_dim++; primary_dim--; } } } } } if (width > 2) { uint32_t num_blk_side = width >> 2; for (blk_y = 0; blk_y < num_blk_side; blk_y++) { for (blk_x = 0; blk_x < num_blk_side; blk_x++) { uint32_t offset = blk_y * 4 * width + blk_x * 4; for (y = 0; y < 4; y++) { for (x = 0; x < 4; x++) { buff_h[cnt] = y * width + x + offset; cnt ++; } } } } cnt = 0; for (blk_x = 0; blk_x < num_blk_side; blk_x++) { for (blk_y = 0; blk_y < num_blk_side; blk_y++) { uint32_t offset = blk_y * 4 * width + blk_x * 4; for (x = 0; x < 4; x++) { for (y = 0; y < 4; y++) { buff_v[cnt] = y * width + x + offset; cnt ++; } } } } } else { for (yy = 0; yy < height; yy++) { for (xx = 0; xx < width; xx++) { buff_h[cnt] = yy * width + xx; cnt ++; } } cnt = 0; for (xx = 0; xx < width; xx++) { for (yy = 0; yy < height; yy++) { buff_v[cnt] = yy * width + xx; cnt ++; } } } } void init_tables(void) { int i; int c = 0; memset( _convert_to_bit,-1, sizeof( _convert_to_bit ) ); for (i = 4; i < LCU_WIDTH; i *= 2) { _convert_to_bit[i] = (int8_t)c; c++; } _convert_to_bit[i] = (int8_t)c; c = 2; for (i = 0; i < 5; i++) { uint32_t *sls0, *sls1, *sls2; sls0 = (uint32_t*)malloc(c*c*sizeof(uint32_t)); sls1 = (uint32_t*)malloc(c*c*sizeof(uint32_t)); sls2 = (uint32_t*)malloc(c*c*sizeof(uint32_t)); init_sig_last_scan(sls0, sls1, sls2, c, c); _sig_last_scan[0][i] = sls0; _sig_last_scan[1][i] = sls1; _sig_last_scan[2][i] = sls2; c <<= 1; } } void free_tables(void) { int i; for (i = 0; i < 5; i++) { FREE_POINTER(_sig_last_scan[0][i]); FREE_POINTER(_sig_last_scan[1][i]); FREE_POINTER(_sig_last_scan[2][i]); } } int main() { int i, c, j, h; printf("//The file tables.c is automatically generated by generate_tables, do not edit.\n\n"); printf("#include \"tables.h\"\n\n"); printf("#if LCU_WIDTH!=%d\n", LCU_WIDTH); printf("#error \"LCU_WIDTH!=%d\"\n", LCU_WIDTH); printf("#endif\n\n"); init_tables(); printf("const int8_t g_convert_to_bit[LCU_WIDTH + 1] = {"); for (i=0; i < LCU_WIDTH + 1; ++i) { if (i!=LCU_WIDTH) { printf("%d, ", _convert_to_bit[i]); } else { printf("%d", _convert_to_bit[i]); } } printf("};\n\n"); c = 2; for (i = 0; i < 5; i++) { for (h = 0; h < 3; h++) { printf("static const uint32_t g_sig_last_scan_%d_%d[%d] = {",h,i,c*c); for (j = 0; j < c*c; ++j) { if (j!=c*c-1) { printf("%u, ", _sig_last_scan[h][i][j]); } else { printf("%u", _sig_last_scan[h][i][j]); } if (j % 100 == 99) printf("\n "); } printf("};\n"); } printf("\n"); c <<= 1; } printf("const uint32_t* const g_sig_last_scan[3][5] = {\n"); for (h = 0; h < 3; h++) { printf(" {"); for (i = 0; i < 5; i++) { if (i!=4) { printf("g_sig_last_scan_%d_%d, ", h, i); } else { printf("g_sig_last_scan_%d_%d", h, i); } } if (h<2) { printf("},\n"); } else { printf("}\n"); } } printf("};\n"); return 0; }