📄 imgcmc.c
字号:
//////////////////////////////////////////////////////////////////////////
// Copyright (C) 2004, Eyoka @ Microunit
// All Rights Reserved
//________________________________________________________________________
//
// FILENAME: imgcmc.c
// PROJECT: High-Resolution Video System On OMAP
// MODULE: Image Color Mode Converter
// DESCRIPTION: Converting images between different color-modes.
// TARGET CPU: DSP-C55xx of OMAP5910
// VERSION: 1.1
//________________________________________________________________________
//
// REVISE HISTORY
// DATE VERSION AUTHOR DESCRIPTION
// 2004-10-22 1.1 Eyoka Data order changed due to DSPMMU ENDIANISM
// Convertion cancelled.
// 2004-10-13 1.0 Eyoka First release.
//////////////////////////////////////////////////////////////////////////
#include "imgcmc.h"
#include "dspdma.h"
/////////////////////////////////////////////////////////////////////
// GLOBAL VARIABLES
/////////////////////////////////////////////////////////////////////
// double buffering for Camera YUYV in
WORD In_buf_1[320];
WORD In_buf_2[320];
// double buffering for Out
WORD Out_buf_1[320];
WORD Out_buf_2[320];
/////////////////////////////////////////////////////////////////////
// FUNCTIONS
/////////////////////////////////////////////////////////////////////
//___________________________________________________________________
// Function: IMG_ConvertColorMode
// Usage: Convert color-mode of a whole image.
// Parameters:
// hIn - handle of the input image
// hOut - handle of the result image
// Return Values:
// N/A
//___________________________________________________________________
// Do NOT support windowing
// Support YUYV->RGB565 only now
// if size_out > size_in, crop input.
// if size_out < size_in, output is filled with black.(NOT tested)
void IMG_ConvertColorMode(IMG_HANDLE hIn, IMG_HANDLE hOut)
{
short i;
WORD nRows = hOut->height; // rows to process
WORD sizeRead = hOut->width; // pixels to read each row
WORD empty_height = 0; // rows to fill black
// data BYTE address in SDRAM
DWORD addrRAW = hIn->addr;
DWORD addrOut = hOut->addr;
// background transfer buffers
WORD *pIn_Tran = In_buf_1;
WORD *pOut_Tran = Out_buf_1;
// foreground process buffers
WORD *pIn_Proc = In_buf_2;
WORD *pOut_Proc = Out_buf_2;
// temp pointer for swapping
WORD *ptr;
// check size
if(hOut->height > hIn->height)
{
empty_height = hOut->height - hIn->height;
nRows = hIn->height;
}
if(hOut->width > hIn->width)
{
sizeRead = hIn->width;
}
// read first line to input buffer
DMA_SD2DA(pIn_Tran, addrRAW, sizeRead);
addrRAW += hIn->width * 2;
// start double buffering loop
for(i=0; i<nRows; i++)
{
// swap input buffer
ptr = pIn_Tran;
pIn_Tran = pIn_Proc;
pIn_Proc = ptr;
// start input background transfer
DMA_SD2DA(pIn_Tran, addrRAW, sizeRead);
addrRAW += hIn->width * 2;
// convert color-mode
IMGCMC_YUYV_RGB565(pIn_Proc, pOut_Proc, sizeRead);
// swap Out buffer
ptr = pOut_Tran;
pOut_Tran = pOut_Proc;
pOut_Proc = ptr;
// start Out background transfer
DMA_DA2SD(addrOut, pOut_Tran, hOut->width);
addrOut += hOut->width * 2;
}
DMA_DA2SD(addrOut, pOut_Tran, hOut->width);
addrOut += hOut->width * 2;
// fill black rows
for(i=0; i<empty_height; i++)
{
memset((void*)(addrOut/2), 0, hOut->width);
}
}
//___________________________________________________________________
// Function: IMGCMC_YUYV_RGB565
// Usage: Convert color-mode of image data.
// Parameters:
// pIn - pointer to input
// pOut - pointer to output
// size - number of pixels to be converted
// Return Values:
// N/A
//___________________________________________________________________
// Y,U,V: [0,255]
// R = Y + 1.402 *(V-128)
// G = Y - 0.34414*(U-128) - 0.71414*(V-128)
// B = Y + 1.772 *(U-128)
//
// Y <<= 8
// U,V -= 128
// chrom_r = 359 * V;
// chrom_g = -88 * U - 183 * V;
// chrom_b = 454 * U;
// (R<<8) = Y + chrom_r
// (G<<8) = Y + chrom_g
// (B<<8) = Y + chrom_b
void IMGCMC_YUYV_RGB565(WORD *pIn, WORD *pOut, WORD size)
{
WORD i;
WORD Y1, Y2;
short U, V;
long chrom_r, chrom_g, chrom_b;
long temp;
WORD R, G, B;
// for each 2 pixels
for (i=0; i<size; i+=2)
{
// read YUV(Y<<=8)
// U,V is swapped due to Camera Difference.
V = (short)(pIn[0]>>8) - 128;
Y1 = pIn[0] << 8;
U = (short)(pIn[1]>>8) - 128;
Y2 = pIn[1] << 8;
// chrominance modifier
chrom_r = 359 * V;
chrom_g = -88 * U - 183 * V;
chrom_b = 454 * U;
// R1
temp = (long)Y1 + chrom_r;
temp >>= 8;
temp = (temp > 0xF0)? 0xF0 : temp;
temp = (temp < 0x10)? 0x10 : temp;
R = (WORD)temp;
// G1
temp = (long)Y1 + chrom_g;
temp >>= 8;
temp = (temp > 0xF0)? 0xF0 : temp;
temp = (temp < 0x10)? 0x10 : temp;
G = (WORD)temp;
// B1
temp = (long)Y1 + chrom_b;
temp >>= 8;
temp = (temp > 0xF0)? 0xF0 : temp;
temp = (temp < 0x10)? 0x10 : temp;
B = (WORD)temp;
// pixel1
pOut[1] = ((R&0x00F8)<<8) | ((G&0x00FC)<<3) | ((B&0x00F8)>>3);
// R2
temp = (long)Y2 + chrom_r;
temp >>= 8;
temp = (temp > 0xF0)? 0xF0 : temp;
temp = (temp < 0x10)? 0x10 : temp;
R = (WORD)temp;
// G2
temp = (long)Y2 + chrom_g;
temp >>= 8;
temp = (temp > 0xF0)? 0xF0 : temp;
temp = (temp < 0x10)? 0x10 : temp;
G = (WORD)temp;
// B2
temp = (long)Y2 + chrom_b;
temp >>= 8;
temp = (temp > 0xF0)? 0xF0 : temp;
temp = (temp < 0x10)? 0x10 : temp;
B = (WORD)temp;
// pixel2
pOut[0] = ((R&0x00F8)<<8) | ((G&0x00FC)<<3) | ((B&0x00F8)>>3);
pOut += 2;
pIn += 2;
}
}
// the end
//////////////////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -