openperf/src/common/ldecod_src/img_process.c
2024-10-14 12:14:49 +08:00

281 lines
10 KiB
C

/*!
*************************************************************************************
* \file img_process.c
*
* \brief
* Input data Image Processing functions
*
* \author
* Main contributors (see contributors.h for copyright, address and
*affiliation details)
* - Alexis Michael Tourapis <alexis.tourapis@dolby.com>
*
*************************************************************************************
*/
#include "img_process.h"
#include "contributors.h"
#include "fast_memory.h"
#include "global.h"
#include "io_image.h"
#include "memalloc.h"
static inline void ResetImage(ImageData *imgOut) {
fast_memset(imgOut->frm_data[0][0], 0,
imgOut->format.height[0] * imgOut->format.width[0] *
sizeof(imgpel));
if (imgOut->format.yuv_format != YUV400) {
if (sizeof(imgpel) == sizeof(signed char)) {
fast_memset(imgOut->frm_data[1][0], 128,
imgOut->format.height[1] * imgOut->format.width[1] *
sizeof(imgpel));
fast_memset(imgOut->frm_data[2][0], 128,
imgOut->format.height[1] * imgOut->format.width[1] *
sizeof(imgpel));
} else {
int i, j, k;
imgpel med_value;
for (k = 1; k <= 2; k++) {
med_value = (imgpel)(imgOut->format.max_value[k] + 1) >> 1;
for (j = 0; j < imgOut->format.height[1]; j++) {
for (i = 0; i < imgOut->format.width[1]; i++) {
imgOut->frm_data[k][j][i] = med_value;
}
}
}
}
}
}
static inline void CPImage(ImageData *imgOut, ImageData *imgIn) {
memcpy(imgOut->frm_data[0][0], imgIn->frm_data[0][0],
imgIn->format.height[0] * imgIn->format.width[0] * sizeof(imgpel));
if (imgIn->format.yuv_format != YUV400) {
memcpy(imgOut->frm_data[1][0], imgIn->frm_data[1][0],
imgIn->format.height[1] * imgIn->format.width[1] * sizeof(imgpel));
memcpy(imgOut->frm_data[2][0], imgIn->frm_data[2][0],
imgIn->format.height[1] * imgIn->format.width[1] * sizeof(imgpel));
}
}
// to be modified
static inline void FilterImage(ImageData *imgOut, ImageData *imgIn) {
memcpy(imgOut->frm_data[0][0], imgIn->frm_data[0][0],
imgIn->format.height[0] * imgIn->format.width[0] * sizeof(imgpel));
if (imgIn->format.yuv_format != YUV400) {
memcpy(imgOut->frm_data[1][0], imgIn->frm_data[1][0],
imgIn->format.height[1] * imgIn->format.width[1] * sizeof(imgpel));
memcpy(imgOut->frm_data[2][0], imgIn->frm_data[2][0],
imgIn->format.height[1] * imgIn->format.width[1] * sizeof(imgpel));
}
}
// Line interleaving for 3:2 pulldown
static inline void BlendImageLines(ImageData *imgIn0, ImageData *imgIn1) {
int j;
for (j = 1; j < imgIn1->format.height[0]; j += 2)
memcpy(imgIn0->frm_data[0][j], imgIn1->frm_data[0][j],
imgIn1->format.width[0] * sizeof(imgpel));
if (imgIn1->format.yuv_format != YUV400) {
for (j = 1; j < imgIn1->format.height[1]; j += 2) {
memcpy(imgIn0->frm_data[1][j], imgIn1->frm_data[1][j],
imgIn1->format.width[1] * sizeof(imgpel));
}
for (j = 1; j < imgIn1->format.height[2]; j += 2) {
memcpy(imgIn0->frm_data[2][j], imgIn1->frm_data[2][j],
imgIn1->format.width[2] * sizeof(imgpel));
}
}
}
// to be modified
static inline void FilterImageSep(ImageData *imgOut, ImageData *imgIn) {
int i, j;
static const int SepFilter[6] = {1, -5, 20, 20, -5, 1};
int max_width = imgOut->format.width[0] - 1;
int max_height = imgOut->format.height[0] - 1;
int **temp_data = new_mem2Dint(
imgIn->format.height[0],
imgIn->format.width[0]); // temp memory for filtering. Could be allocated
// once to speed up code
// implementation was not optimized. only just implemented as proof of concept
// horizontal filtering
for (j = 0; j < imgOut->format.height[0]; j++) {
for (i = 0; i < imgOut->format.width[0]; i++) {
temp_data[j][i] =
SepFilter[0] * imgIn->frm_data[0][j][iClip3(0, max_width, i - 2)] +
SepFilter[1] * imgIn->frm_data[0][j][iClip3(0, max_width, i - 1)] +
SepFilter[2] * imgIn->frm_data[0][j][iClip3(0, max_width, i)] +
SepFilter[3] * imgIn->frm_data[0][j][iClip3(0, max_width, i + 1)] +
SepFilter[4] * imgIn->frm_data[0][j][iClip3(0, max_width, i + 2)] +
SepFilter[5] * imgIn->frm_data[0][j][iClip3(0, max_width, i + 3)];
}
}
for (j = 0; j < imgOut->format.height[0]; j++) {
for (i = 0; i < imgOut->format.width[0]; i++) {
imgOut->frm_data[0][j][i] = (imgpel)iClip3(
0, imgOut->format.max_value[0],
rshift_rnd_sign(
SepFilter[0] * temp_data[iClip3(0, max_height, j - 2)][i] +
SepFilter[1] * temp_data[iClip3(0, max_height, j - 1)][i] +
SepFilter[2] * temp_data[iClip3(0, max_height, j)][i] +
SepFilter[3] * temp_data[iClip3(0, max_height, j + 1)][i] +
SepFilter[4] * temp_data[iClip3(0, max_height, j + 2)][i] +
SepFilter[5] * temp_data[iClip3(0, max_height, j + 3)][i],
10));
}
}
if (imgOut->format.yuv_format != YUV400) {
int k;
max_width = imgOut->format.width[1] - 1;
max_height = imgOut->format.height[1] - 1;
for (k = 1; k <= 2; k++) {
// horizontal filtering
for (j = 0; j < imgOut->format.height[1]; j++) {
for (i = 0; i < imgOut->format.width[1]; i++) {
temp_data[j][i] =
SepFilter[0] *
imgIn->frm_data[k][j][iClip3(0, max_width, i - 2)] +
SepFilter[1] *
imgIn->frm_data[k][j][iClip3(0, max_width, i - 1)] +
SepFilter[2] * imgIn->frm_data[k][j][iClip3(0, max_width, i)] +
SepFilter[3] *
imgIn->frm_data[k][j][iClip3(0, max_width, i + 1)] +
SepFilter[4] *
imgIn->frm_data[k][j][iClip3(0, max_width, i + 2)] +
SepFilter[5] * imgIn->frm_data[k][j][iClip3(0, max_width, i + 3)];
}
}
for (j = 0; j < imgOut->format.height[1]; j++) {
for (i = 0; i < imgOut->format.width[1]; i++) {
imgOut->frm_data[k][j][i] = (imgpel)iClip3(
0, imgOut->format.max_value[k],
rshift_rnd_sign(
SepFilter[0] * temp_data[iClip3(0, max_height, j - 2)][i] +
SepFilter[1] *
temp_data[iClip3(0, max_height, j - 1)][i] +
SepFilter[2] * temp_data[iClip3(0, max_height, j)][i] +
SepFilter[3] *
temp_data[iClip3(0, max_height, j + 1)][i] +
SepFilter[4] *
temp_data[iClip3(0, max_height, j + 2)][i] +
SepFilter[5] * temp_data[iClip3(0, max_height, j + 3)][i],
10));
}
}
}
}
free_mem2Dint(temp_data);
}
// to be modified
static inline void MuxImages(ImageData *imgOut, ImageData *imgIn0,
ImageData *imgIn1, ImageData *Map) {
int i, j;
for (j = 0; j < imgOut->format.height[0]; j++) {
for (i = 0; i < imgOut->format.width[0]; i++) {
imgOut->frm_data[0][j][i] = (imgpel)rshift_rnd_sf(
imgIn0->frm_data[0][j][i] *
(Map->format.max_value[0] - Map->frm_data[0][j][i]) +
imgIn1->frm_data[0][j][i] * Map->frm_data[0][j][i],
Map->format.bit_depth[0]);
}
}
if (imgOut->format.yuv_format != YUV400) {
int k;
for (k = 1; k <= 2; k++) {
for (j = 0; j < imgOut->format.height[1]; j++) {
for (i = 0; i < imgOut->format.width[1]; i++) {
imgOut->frm_data[k][j][i] = (imgpel)rshift_rnd_sf(
imgIn0->frm_data[k][j][i] *
(Map->format.max_value[k] - Map->frm_data[k][j][i]) +
imgIn1->frm_data[k][j][i] * Map->frm_data[k][j][i],
Map->format.bit_depth[k]);
}
}
}
}
}
static inline void YV12toYUV(ImageData *imgOut, ImageData *imgIn) {
memcpy(imgOut->frm_data[0][0], imgIn->frm_data[0][0],
imgIn->format.height[0] * imgIn->format.width[0] * sizeof(imgpel));
if (imgIn->format.yuv_format != YUV400) {
memcpy(imgOut->frm_data[1][0], imgIn->frm_data[2][0],
imgIn->format.height[1] * imgIn->format.width[1] * sizeof(imgpel));
memcpy(imgOut->frm_data[2][0], imgIn->frm_data[1][0],
imgIn->format.height[1] * imgIn->format.width[1] * sizeof(imgpel));
}
}
int init_process_image(VideoParameters *p_Vid, InputParameters *p_Inp) {
int memory_size = 0;
switch (p_Inp->ProcessInput) {
default:
break;
}
return memory_size;
}
void clear_process_image(VideoParameters *p_Vid, InputParameters *p_Inp) {
switch (p_Inp->ProcessInput) {
default:
break;
}
}
void process_image(VideoParameters *p_Vid, InputParameters *p_Inp) {
switch (p_Inp->ProcessInput) {
default:
case 0:
CPImage(&p_Vid->imgData, &p_Vid->imgData0);
if (p_Inp->enable_32_pulldown)
BlendImageLines(&p_Vid->imgData, &p_Vid->imgData4);
break;
case 1:
FilterImage(&p_Vid->imgData, &p_Vid->imgData0);
if (p_Inp->enable_32_pulldown) {
FilterImage(&p_Vid->imgData32, &p_Vid->imgData4);
BlendImageLines(&p_Vid->imgData, &p_Vid->imgData32);
}
break;
case 2:
YV12toYUV(&p_Vid->imgData, &p_Vid->imgData0);
if (p_Inp->enable_32_pulldown) {
YV12toYUV(&p_Vid->imgData32, &p_Vid->imgData4);
BlendImageLines(&p_Vid->imgData, &p_Vid->imgData32);
}
break;
case 3:
MuxImages(&p_Vid->imgData, &p_Vid->imgData0, &p_Vid->imgData1,
&p_Vid->imgData2);
if (p_Inp->enable_32_pulldown) {
MuxImages(&p_Vid->imgData32, &p_Vid->imgData4, &p_Vid->imgData5,
&p_Vid->imgData6);
BlendImageLines(&p_Vid->imgData, &p_Vid->imgData32);
}
break;
case 4:
FilterImageSep(&p_Vid->imgData, &p_Vid->imgData0);
if (p_Inp->enable_32_pulldown) {
FilterImageSep(&p_Vid->imgData, &p_Vid->imgData4);
BlendImageLines(&p_Vid->imgData, &p_Vid->imgData32);
}
break;
}
}