// SPDX-License-Identifier: GPL-2.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);
	assert(out_table);

	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,
    unsigned int table_width,
    unsigned int table_height)
{
	/* initialize table with ones, shift becomes zero */
	unsigned int i, j;
	struct ia_css_shading_table *result;

	assert(target_table);

	result = ia_css_shading_table_alloc(table_width, table_height);
	if (!result) {
		*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, i;
	unsigned int left_padding, top_padding, left_cropping;
	unsigned int bds_numerator, bds_denominator;
	int right_padding;

	struct ia_css_shading_table *result;

	assert(target_table);
	assert(binary);

	if (!in_table) {
		sh_css_params_shading_id_table_generate(target_table,
							binary->sctbl_width_per_color,
							binary->sctbl_height);
		return;
	}

	/*
	 * We use the ISP input resolution for the shading table because
	 * shading correction is performed in the bayer domain (before bayer
	 * down scaling).
	 */
	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;

	/*
	 * 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;

	/*
	 * 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);

	/* 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_width_per_color;
	table_height = binary->sctbl_height;

	result = ia_css_shading_table_alloc(table_width, table_height);
	if (!result) {
		*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] =
		    kvmalloc(width * height * sizeof(*me->data[0]),
			     GFP_KERNEL);
		if (!me->data[i]) {
			unsigned int j;

			for (j = 0; j < i; j++) {
				kvfree(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)
		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]) {
			kvfree(table->data[i]);
			table->data[i] = NULL;
		}
	}
	kfree(table);

	IA_CSS_LEAVE("");
}
