aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/media/atomisp/pci/atomisp2/css2400/sh_css_param_shading.c
diff options
context:
space:
mode:
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.c417
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 e6ebd1b08f0d..000000000000
--- 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("");
-}
-