// deinterlace.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include "deinterlace.h"
/*
 *  ======== deinterlace_420psemi.c ========
 *  Video encoder algorithm.
 *
 *  This file contains an implementation of the IVIDENC1 interface
 *  defined by XDM.
 */

#include <string.h>
typedef unsigned char uint8_t;

enum YUVFormat{
	FMT_YUV411P,
	FMT_YUV420P,
	FMT_YUV420PSEMI,
	FMT_YUV422P,
	FMT_YUV444P};


#define MAX_NEG_CROP 0

static uint8_t ff_cropTbl[256 + 2 * MAX_NEG_CROP];


void Deinterlace_init(void)
{
	int i;

	for(i=0;i<256;i++) ff_cropTbl[i + MAX_NEG_CROP] = i;
	for(i=0;i<MAX_NEG_CROP;i++) {
		ff_cropTbl[i] = 0;
		ff_cropTbl[i + MAX_NEG_CROP + 256] = 255;
	}
}

void deinterlace_line(uint8_t *dst,
							   const uint8_t *lum_m4, const uint8_t *lum_m3,
							   const uint8_t *lum_m2, const uint8_t *lum_m1,
							   const uint8_t *lum,
							   int size)
{
	const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP;
	int sum;

	for(;size > 0;size--) {
		sum = -lum_m4[0];
		sum += lum_m3[0] << 2;
		sum += lum_m2[0] << 1;
		sum += lum_m1[0] << 2;
		sum += -lum[0];
		dst[0] = cm[(sum + 4) >> 3];

		if(sum >= 2040) dst[0] = 0xff;
		
		lum_m4++;
		lum_m3++;
		lum_m2++;
		lum_m1++;
		lum++;
		dst++;
	}
}

void deinterlace_bottom_field(uint8_t *dst, int dst_wrap,
									 const uint8_t *src1, int src_wrap,
									 int width, int height)
{
	const uint8_t *src_m2, *src_m1, *src_0, *src_p1, *src_p2;
	int y;

	src_m2 = src1;
	src_m1 = src1;
	src_0=&src_m1[src_wrap];
	src_p1=&src_0[src_wrap];
	src_p2=&src_p1[src_wrap];
	for(y=0;y<(height-2);y+=2) {
		memcpy(dst,src_m1,width);
		dst += dst_wrap;
		deinterlace_line(dst,src_m2,src_m1,src_0,src_p1,src_p2,width);
		src_m2 = src_0;
		src_m1 = src_p1;
		src_0 = src_p2;
		src_p1 += 2*src_wrap;
		src_p2 += 2*src_wrap;
		dst += dst_wrap;
	}
	memcpy(dst,src_m1,width);
	dst += dst_wrap;
	/* do last line */
	deinterlace_line(dst,src_m2,src_m1,src_0,src_0,src_0,width);
}

int Deinterlace_process(unsigned char *dst, unsigned char *src, int width, int height)
{
	int i;
	unsigned char *srcData[3]={NULL},*dstData[3]={NULL};
	int iplane = 1;

	if ((width & 3) != 0 || (height & 3) != 0)
		return -1;


	srcData[0] = src;
	srcData[1] = src + width *height;
	srcData[2] = src + ((width*height*5)>>2);
	dstData[0] = dst;
	dstData[1] = dst + width *height;
	dstData[2] = dst + ((width*height*5)>>2);

	for(i=0;i<iplane;i++) {
		if (i == 1) {
			width >>= 1;
			height >>= 1;
		}
		deinterlace_bottom_field(dstData[i], width, srcData[i], width, width, height);
	}

	memset(dstData[1], 128, (width * height)>>1);
	return 0;
}