diff options
Diffstat (limited to 'drivers/staging/media/atomisp/pci/atomisp2/css2400/sh_css_param_shading.c')
-rw-r--r-- | drivers/staging/media/atomisp/pci/atomisp2/css2400/sh_css_param_shading.c | 417 |
1 files changed, 0 insertions, 417 deletions
diff --git a/drivers/staging/media/atomisp/pci/atomisp2/css2400/sh_css_param_shading.c b/drivers/staging/media/atomisp/pci/atomisp2/css2400/sh_css_param_shading.c deleted file mode 100644 index e6ebd1b..0000000 --- a/drivers/staging/media/atomisp/pci/atomisp2/css2400/sh_css_param_shading.c +++ /dev/null @@ -1,417 +0,0 @@ -/* - * Support for Intel Camera Imaging ISP subsystem. - * Copyright (c) 2015, Intel Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - */ - -#include <linux/slab.h> - -#include <math_support.h> -#include "sh_css_param_shading.h" -#include "ia_css_shading.h" -#include "assert_support.h" -#include "sh_css_defs.h" -#include "sh_css_internal.h" -#include "ia_css_debug.h" -#include "ia_css_pipe_binarydesc.h" - -#include "sh_css_hrt.h" - -#include "platform_support.h" - -/* Bilinear interpolation on shading tables: - * For each target point T, we calculate the 4 surrounding source points: - * ul (upper left), ur (upper right), ll (lower left) and lr (lower right). - * We then calculate the distances from the T to the source points: x0, x1, - * y0 and y1. - * We then calculate the value of T: - * dx0*dy0*Slr + dx0*dy1*Sur + dx1*dy0*Sll + dx1*dy1*Sul. - * We choose a grid size of 1x1 which means: - * dx1 = 1-dx0 - * dy1 = 1-dy0 - * - * Sul dx0 dx1 Sur - * .<----->|<------------->. - * ^ - * dy0| - * v T - * - . - * ^ - * | - * dy1| - * v - * . . - * Sll Slr - * - * Padding: - * The area that the ISP operates on can include padding both on the left - * and the right. We need to padd the shading table such that the shading - * values end up on the correct pixel values. This means we must padd the - * shading table to match the ISP padding. - * We can have 5 cases: - * 1. All 4 points fall in the left padding. - * 2. The left 2 points fall in the left padding. - * 3. All 4 points fall in the cropped (target) region. - * 4. The right 2 points fall in the right padding. - * 5. All 4 points fall in the right padding. - * Cases 1 and 5 are easy to handle: we simply use the - * value 1 in the shading table. - * Cases 2 and 4 require interpolation that takes into - * account how far into the padding area the pixels - * fall. We extrapolate the shading table into the - * padded area and then interpolate. - */ -static void -crop_and_interpolate(unsigned int cropped_width, - unsigned int cropped_height, - unsigned int left_padding, - int right_padding, - int top_padding, - const struct ia_css_shading_table *in_table, - struct ia_css_shading_table *out_table, - enum ia_css_sc_color color) -{ - unsigned int i, j, - sensor_width, - sensor_height, - table_width, - table_height, - table_cell_h, - out_cell_size, - in_cell_size, - out_start_row, - padded_width; - int out_start_col, /* can be negative to indicate padded space */ - table_cell_w; - unsigned short *in_ptr, - *out_ptr; - - assert(in_table != NULL); - assert(out_table != NULL); - - sensor_width = in_table->sensor_width; - sensor_height = in_table->sensor_height; - table_width = in_table->width; - table_height = in_table->height; - in_ptr = in_table->data[color]; - out_ptr = out_table->data[color]; - - padded_width = cropped_width + left_padding + right_padding; - out_cell_size = CEIL_DIV(padded_width, out_table->width - 1); - in_cell_size = CEIL_DIV(sensor_width, table_width - 1); - - out_start_col = ((int)sensor_width - (int)cropped_width)/2 - left_padding; - out_start_row = ((int)sensor_height - (int)cropped_height)/2 - top_padding; - table_cell_w = (int)((table_width-1) * in_cell_size); - table_cell_h = (table_height-1) * in_cell_size; - - for (i = 0; i < out_table->height; i++) { - int ty, src_y0, src_y1; - unsigned int sy0, sy1, dy0, dy1, divy; - - /* calculate target point and make sure it falls within - the table */ - ty = out_start_row + i * out_cell_size; - - /* calculate closest source points in shading table and - make sure they fall within the table */ - src_y0 = ty / (int)in_cell_size; - if (in_cell_size < out_cell_size) - src_y1 = (ty + out_cell_size) / in_cell_size; - else - src_y1 = src_y0 + 1; - src_y0 = clamp(src_y0, 0, (int)table_height-1); - src_y1 = clamp(src_y1, 0, (int)table_height-1); - ty = min(clamp(ty, 0, (int)sensor_height-1), - (int)table_cell_h); - - /* calculate closest source points for distance computation */ - sy0 = min(src_y0 * in_cell_size, sensor_height-1); - sy1 = min(src_y1 * in_cell_size, sensor_height-1); - /* calculate distance between source and target pixels */ - dy0 = ty - sy0; - dy1 = sy1 - ty; - divy = sy1 - sy0; - if (divy == 0) { - dy0 = 1; - divy = 1; - } - - for (j = 0; j < out_table->width; j++, out_ptr++) { - int tx, src_x0, src_x1; - unsigned int sx0, sx1, dx0, dx1, divx; - unsigned short s_ul, s_ur, s_ll, s_lr; - - /* calculate target point */ - tx = out_start_col + j * out_cell_size; - /* calculate closest source points. */ - src_x0 = tx / (int)in_cell_size; - if (in_cell_size < out_cell_size) { - src_x1 = (tx + out_cell_size) / - (int)in_cell_size; - } else { - src_x1 = src_x0 + 1; - } - /* if src points fall in padding, select closest ones.*/ - src_x0 = clamp(src_x0, 0, (int)table_width-1); - src_x1 = clamp(src_x1, 0, (int)table_width-1); - tx = min(clamp(tx, 0, (int)sensor_width-1), - (int)table_cell_w); - /* calculate closest source points for distance - computation */ - sx0 = min(src_x0 * in_cell_size, sensor_width-1); - sx1 = min(src_x1 * in_cell_size, sensor_width-1); - /* calculate distances between source and target - pixels */ - dx0 = tx - sx0; - dx1 = sx1 - tx; - divx = sx1 - sx0; - /* if we're at the edge, we just use the closest - point still in the grid. We make up for the divider - in this case by setting the distance to - out_cell_size, since it's actually 0. */ - if (divx == 0) { - dx0 = 1; - divx = 1; - } - - /* get source pixel values */ - s_ul = in_ptr[(table_width*src_y0)+src_x0]; - s_ur = in_ptr[(table_width*src_y0)+src_x1]; - s_ll = in_ptr[(table_width*src_y1)+src_x0]; - s_lr = in_ptr[(table_width*src_y1)+src_x1]; - - *out_ptr = (unsigned short) ((dx0*dy0*s_lr + dx0*dy1*s_ur + dx1*dy0*s_ll + dx1*dy1*s_ul) / - (divx*divy)); - } - } -} - -void -sh_css_params_shading_id_table_generate( - struct ia_css_shading_table **target_table, -#ifndef ISP2401 - const struct ia_css_binary *binary) -#else - unsigned int table_width, - unsigned int table_height) -#endif -{ - /* initialize table with ones, shift becomes zero */ -#ifndef ISP2401 - unsigned int i, j, table_width, table_height; -#else - unsigned int i, j; -#endif - struct ia_css_shading_table *result; - - assert(target_table != NULL); -#ifndef ISP2401 - assert(binary != NULL); -#endif - -#ifndef ISP2401 - table_width = binary->sctbl_width_per_color; - table_height = binary->sctbl_height; -#endif - result = ia_css_shading_table_alloc(table_width, table_height); - if (result == NULL) { - *target_table = NULL; - return; - } - - for (i = 0; i < IA_CSS_SC_NUM_COLORS; i++) { - for (j = 0; j < table_height * table_width; j++) - result->data[i][j] = 1; - } - result->fraction_bits = 0; - *target_table = result; -} - -void -prepare_shading_table(const struct ia_css_shading_table *in_table, - unsigned int sensor_binning, - struct ia_css_shading_table **target_table, - const struct ia_css_binary *binary, - unsigned int bds_factor) -{ - unsigned int input_width, - input_height, - table_width, - table_height, - left_padding, - top_padding, - padded_width, - left_cropping, - i; - unsigned int bds_numerator, bds_denominator; - int right_padding; - - struct ia_css_shading_table *result; - - assert(target_table != NULL); - assert(binary != NULL); - - if (!in_table) { -#ifndef ISP2401 - sh_css_params_shading_id_table_generate(target_table, binary); -#else - sh_css_params_shading_id_table_generate(target_table, - binary->sctbl_legacy_width_per_color, binary->sctbl_legacy_height); -#endif - return; - } - - padded_width = binary->in_frame_info.padded_width; - /* We use the ISP input resolution for the shading table because - shading correction is performed in the bayer domain (before bayer - down scaling). */ -#if defined(USE_INPUT_SYSTEM_VERSION_2401) - padded_width = CEIL_MUL(binary->effective_in_frame_res.width + 2*ISP_VEC_NELEMS, - 2*ISP_VEC_NELEMS); -#endif - input_height = binary->in_frame_info.res.height; - input_width = binary->in_frame_info.res.width; - left_padding = binary->left_padding; - left_cropping = (binary->info->sp.pipeline.left_cropping == 0) ? - binary->dvs_envelope.width : 2*ISP_VEC_NELEMS; - - sh_css_bds_factor_get_numerator_denominator - (bds_factor, &bds_numerator, &bds_denominator); - - left_padding = (left_padding + binary->info->sp.pipeline.left_cropping) * bds_numerator / bds_denominator - binary->info->sp.pipeline.left_cropping; - right_padding = (binary->internal_frame_info.res.width - binary->effective_in_frame_res.width * bds_denominator / bds_numerator - left_cropping) * bds_numerator / bds_denominator; - top_padding = binary->info->sp.pipeline.top_cropping * bds_numerator / bds_denominator - binary->info->sp.pipeline.top_cropping; - -#if !defined(USE_WINDOWS_BINNING_FACTOR) - /* @deprecated{This part of the code will be replaced by the code - * in the #else section below to make the calculation same across - * all platforms. - * Android and Windows platforms interpret the binning_factor parameter - * differently. In Android, the binning factor is expressed in the form - * 2^N * 2^N, whereas in Windows platform, the binning factor is N*N} - */ - - /* We take into account the binning done by the sensor. We do this - by cropping the non-binned part of the shading table and then - increasing the size of a grid cell with this same binning factor. */ - input_width <<= sensor_binning; - input_height <<= sensor_binning; - /* We also scale the padding by the same binning factor. This will - make it much easier later on to calculate the padding of the - shading table. */ - left_padding <<= sensor_binning; - right_padding <<= sensor_binning; - top_padding <<= sensor_binning; -#else - input_width *= sensor_binning; - input_height *= sensor_binning; - left_padding *= sensor_binning; - right_padding *= sensor_binning; - top_padding *= sensor_binning; -#endif /*USE_WINDOWS_BINNING_FACTOR*/ - - /* during simulation, the used resolution can exceed the sensor - resolution, so we clip it. */ - input_width = min(input_width, in_table->sensor_width); - input_height = min(input_height, in_table->sensor_height); - -#ifndef ISP2401 - table_width = binary->sctbl_width_per_color; - table_height = binary->sctbl_height; -#else - /* This prepare_shading_table() function is called only in legacy API (not in new API). - Then, the legacy shading table width and height should be used. */ - table_width = binary->sctbl_legacy_width_per_color; - table_height = binary->sctbl_legacy_height; -#endif - - result = ia_css_shading_table_alloc(table_width, table_height); - if (result == NULL) { - *target_table = NULL; - return; - } - result->sensor_width = in_table->sensor_width; - result->sensor_height = in_table->sensor_height; - result->fraction_bits = in_table->fraction_bits; - - /* now we crop the original shading table and then interpolate to the - requested resolution and decimation factor. */ - for (i = 0; i < IA_CSS_SC_NUM_COLORS; i++) { - crop_and_interpolate(input_width, input_height, - left_padding, right_padding, top_padding, - in_table, - result, i); - } - *target_table = result; -} - -struct ia_css_shading_table * -ia_css_shading_table_alloc( - unsigned int width, - unsigned int height) -{ - unsigned int i; - struct ia_css_shading_table *me; - - IA_CSS_ENTER(""); - - me = kmalloc(sizeof(*me), GFP_KERNEL); - if (!me) - return me; - - me->width = width; - me->height = height; - me->sensor_width = 0; - me->sensor_height = 0; - me->fraction_bits = 0; - for (i = 0; i < IA_CSS_SC_NUM_COLORS; i++) { - me->data[i] = - sh_css_malloc(width * height * sizeof(*me->data[0])); - if (me->data[i] == NULL) { - unsigned int j; - for (j = 0; j < i; j++) { - sh_css_free(me->data[j]); - me->data[j] = NULL; - } - kfree(me); - return NULL; - } - } - - IA_CSS_LEAVE(""); - return me; -} - -void -ia_css_shading_table_free(struct ia_css_shading_table *table) -{ - unsigned int i; - - if (table == NULL) - return; - - /* We only output logging when the table is not NULL, otherwise - * logs will give the impression that a table was freed. - * */ - IA_CSS_ENTER(""); - - for (i = 0; i < IA_CSS_SC_NUM_COLORS; i++) { - if (table->data[i]) { - sh_css_free(table->data[i]); - table->data[i] = NULL; - } - } - kfree(table); - - IA_CSS_LEAVE(""); -} - |