/*
 * 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,
		 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);
	assert(binary);

	if (!in_table) {
		sh_css_params_shading_id_table_generate(target_table,
							binary->sctbl_legacy_width_per_color,
							binary->sctbl_legacy_height);
		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);

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

	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] =
		    sh_css_malloc(width * height * sizeof(*me->data[0]));
		if (!me->data[i]) {
			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)
		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("");
}
