Linux设备驱动之LCD显示摄像图像之三进行转换

来源:互联网 发布:linux防火墙策略 编辑:程序博客网 时间:2024/05/22 13:47

因为LCD为RGB模式,所以我们所要做的工作就是将我们其他像素模式转换为RGB模式
大部分函数参照/* luvcview */这个应用函数

Convert_manager.c:

#include <config.h>#include <convert_manager.h>#include <string.h>static PT_VideoConvert g_ptVideoConvertHead = NULL;int RegisterVideoConvert(PT_VideoConvert ptVideoConvert){    PT_VideoConvert ptTmp;    if (!g_ptVideoConvertHead)    {        g_ptVideoConvertHead   = ptVideoConvert;        ptVideoConvert->ptNext = NULL;    }    else    {        ptTmp = g_ptVideoConvertHead;        while (ptTmp->ptNext)        {            ptTmp = ptTmp->ptNext;        }        ptTmp->ptNext     = ptVideoConvert;        ptVideoConvert->ptNext = NULL;    }    return 0;}void ShowVideoConvert(void){    int i = 0;    PT_VideoConvert ptTmp = g_ptVideoConvertHead;    while (ptTmp)    {        printf("%02d %s\n", i++, ptTmp->name);        ptTmp = ptTmp->ptNext;    }}PT_VideoConvert GetVideoConvert(char *pcName){    PT_VideoConvert ptTmp = g_ptVideoConvertHead;    while (ptTmp)    {        if (strcmp(ptTmp->name, pcName) == 0)        {            return ptTmp;        }        ptTmp = ptTmp->ptNext;    }    return NULL;}PT_VideoConvert GetVideoConvertForFormats(int iPixelFormatIn, int iPixelFormatOut){    PT_VideoConvert ptTmp = g_ptVideoConvertHead;    while (ptTmp)    {        if (ptTmp->isSupport(iPixelFormatIn, iPixelFormatOut))        {            return ptTmp;        }        ptTmp = ptTmp->ptNext;    }    return NULL;}int VideoConvertInit(void){    int iError;    iError = Yuv2RgbInit();    iError |= Mjpeg2RgbInit();    iError |= Rgb2RgbInit();    return iError;}

mjpeg2rgb:

/* MJPEG : 实质上每一帧数据都是一个完整的JPEG文件 */#include <convert_manager.h>#include <stdlib.h>#include <string.h>#include <setjmp.h>#include <jpeglib.h>typedef struct MyErrorMgr{    struct jpeg_error_mgr pub;    jmp_buf setjmp_buffer;}T_MyErrorMgr, *PT_MyErrorMgr;extern void jpeg_mem_src_tj(j_decompress_ptr, unsigned char *, unsigned long);static int isSupportMjpeg2Rgb(int iPixelFormatIn, int iPixelFormatOut){    if (iPixelFormatIn != V4L2_PIX_FMT_MJPEG)        return 0;    if ((iPixelFormatOut != V4L2_PIX_FMT_RGB565) && (iPixelFormatOut != V4L2_PIX_FMT_RGB32))    {        return 0;    }    return 1;}static void MyErrorExit(j_common_ptr ptCInfo){    static char errStr[JMSG_LENGTH_MAX];    PT_MyErrorMgr ptMyErr = (PT_MyErrorMgr)ptCInfo->err;    /* Create the message */    (*ptCInfo->err->format_message) (ptCInfo, errStr);    DBG_PRINTF("%s\n", errStr);    longjmp(ptMyErr->setjmp_buffer, 1);}//Garmen:转换一行static int CovertOneLine(int iWidth, int iSrcBpp, int iDstBpp, unsigned char *pudSrcDatas, unsigned char *pudDstDatas){    unsigned int dwRed;    unsigned int dwGreen;    unsigned int dwBlue;    unsigned int dwColor;    unsigned short *pwDstDatas16bpp = (unsigned short *)pudDstDatas;    unsigned int   *pwDstDatas32bpp = (unsigned int *)pudDstDatas;    int i;    int pos = 0;    if (iSrcBpp != 24)    {        return -1;    }    if (iDstBpp == 24)    {        memcpy(pudDstDatas, pudSrcDatas, iWidth*3);    }    else    {        for (i = 0; i < iWidth; i++)        {            dwRed   = pudSrcDatas[pos++];            dwGreen = pudSrcDatas[pos++];            dwBlue  = pudSrcDatas[pos++];            if (iDstBpp == 32)            {                dwColor = (dwRed << 16) | (dwGreen << 8) | dwBlue;                *pwDstDatas32bpp = dwColor;                pwDstDatas32bpp++;            }            else if (iDstBpp == 16)            {                /* 565 */                dwRed   = dwRed >> 3;                dwGreen = dwGreen >> 2;                dwBlue  = dwBlue >> 3;                dwColor = (dwRed << 11) | (dwGreen << 5) | (dwBlue);                *pwDstDatas16bpp = dwColor;                pwDstDatas16bpp++;            }        }    }    return 0;}//static int GetPixelDatasFrmJPG(PT_FileMap ptFileMap, PT_PixelDatas ptPixelDatas)/* 把内存里的JPEG图像转换为RGB图像 */static int Mjpeg2RgbConvert(PT_VideoBuf ptVideoBufIn, PT_VideoBuf ptVideoBufOut){    struct jpeg_decompress_struct tDInfo;    //struct jpeg_error_mgr tJErr;    int iRet;    int iRowStride;    unsigned char *aucLineBuffer = NULL;    unsigned char *pucDest;    T_MyErrorMgr tJerr;    //Garmen:定义一个PT_PixelDatas类型结构体,等于&ptVideoBufOut->tPixelDatas    PT_PixelDatas ptPixelDatas = &ptVideoBufOut->tPixelDatas;    // 分配和初始化一个decompression结构体    //tDInfo.err = jpeg_std_error(&tJErr);    tDInfo.err               = jpeg_std_error(&tJerr.pub);    tJerr.pub.error_exit     = MyErrorExit;    if(setjmp(tJerr.setjmp_buffer))    {        /* 如果程序能运行到这里, 表示JPEG解码出错 */        jpeg_destroy_decompress(&tDInfo);        if (aucLineBuffer)        {            free(aucLineBuffer);        }        if (ptPixelDatas->aucPixelDatas)        {            free(ptPixelDatas->aucPixelDatas);        }        return -1;    }    jpeg_create_decompress(&tDInfo);    // 用jpeg_read_header获得jpg信息    //jpeg_stdio_src(&tDInfo, ptFileMap->tFp);    /* 把数据设为内存中的数据 */    jpeg_mem_src_tj (&tDInfo, ptVideoBufIn->tPixelDatas.aucPixelDatas, ptVideoBufIn->tPixelDatas.iTotalBytes);    iRet = jpeg_read_header(&tDInfo, TRUE);    // 设置解压参数,比如放大、缩小    tDInfo.scale_num = tDInfo.scale_denom = 1;    // 启动解压:jpeg_start_decompress       jpeg_start_decompress(&tDInfo);    // 一行的数据长度    iRowStride = tDInfo.output_width * tDInfo.output_components;    aucLineBuffer = malloc(iRowStride);    if (NULL == aucLineBuffer)    {        return -1;    }    ptPixelDatas->iWidth  = tDInfo.output_width;    ptPixelDatas->iHeight = tDInfo.output_height;    //ptPixelDatas->iBpp    = iBpp;    ptPixelDatas->iLineBytes    = ptPixelDatas->iWidth * ptPixelDatas->iBpp / 8;    ptPixelDatas->iTotalBytes   = ptPixelDatas->iHeight * ptPixelDatas->iLineBytes;    if (NULL == ptPixelDatas->aucPixelDatas)    {        ptPixelDatas->aucPixelDatas = malloc(ptPixelDatas->iTotalBytes);    }    pucDest = ptPixelDatas->aucPixelDatas;    // 循环调用jpeg_read_scanlines来一行一行地获得解压的数据    while (tDInfo.output_scanline < tDInfo.output_height)    {        /* 得到一行数据,里面的颜色格式为0xRR, 0xGG, 0xBB */        (void) jpeg_read_scanlines(&tDInfo, &aucLineBuffer, 1);        // 转到ptPixelDatas去        CovertOneLine(ptPixelDatas->iWidth, 24, ptPixelDatas->iBpp, aucLineBuffer, pucDest);        pucDest += ptPixelDatas->iLineBytes;    }    free(aucLineBuffer);    jpeg_finish_decompress(&tDInfo);    jpeg_destroy_decompress(&tDInfo);    return 0;}static int Mjpeg2RgbConvertExit(PT_VideoBuf ptVideoBufOut){    if (ptVideoBufOut->tPixelDatas.aucPixelDatas)    {        free(ptVideoBufOut->tPixelDatas.aucPixelDatas);        ptVideoBufOut->tPixelDatas.aucPixelDatas = NULL;    }    return 0;}/* 构造 */static T_VideoConvert g_tMjpeg2RgbConvert = {    .name        = "mjpeg2rgb",    .isSupport   = isSupportMjpeg2Rgb,    .Convert     = Mjpeg2RgbConvert,    .ConvertExit = Mjpeg2RgbConvertExit,};/* 注册 */int Mjpeg2RgbInit(void){    return RegisterVideoConvert(&g_tMjpeg2RgbConvert);}

rgb2rgb:

#include <convert_manager.h>#include <stdlib.h>#include <string.h>static int isSupportRgb2Rgb(int iPixelFormatIn, int iPixelFormatOut){    if (iPixelFormatIn != V4L2_PIX_FMT_RGB565)        return 0;    if ((iPixelFormatOut != V4L2_PIX_FMT_RGB565) && (iPixelFormatOut != V4L2_PIX_FMT_RGB32))    {        return 0;    }    return 1;}static int Rgb2RgbConvert(PT_VideoBuf ptVideoBufIn, PT_VideoBuf ptVideoBufOut){       PT_PixelDatas ptPixelDatasIn  = &ptVideoBufIn->tPixelDatas;    PT_PixelDatas ptPixelDatasOut = &ptVideoBufOut->tPixelDatas;    int x, y;    int r, g, b;    int color;    unsigned short *pwSrc = (unsigned short *)ptPixelDatasIn->aucPixelDatas;    unsigned int *pdwDest;    if (ptVideoBufIn->iPixelFormat != V4L2_PIX_FMT_RGB565)    {        return -1;    }    if (ptVideoBufOut->iPixelFormat == V4L2_PIX_FMT_RGB565)    {        ptPixelDatasOut->iWidth  = ptPixelDatasIn->iWidth;        ptPixelDatasOut->iHeight = ptPixelDatasIn->iHeight;        ptPixelDatasOut->iBpp    = 16;        ptPixelDatasOut->iLineBytes  = ptPixelDatasOut->iWidth * ptPixelDatasOut->iBpp / 8;        ptPixelDatasOut->iTotalBytes = ptPixelDatasOut->iLineBytes * ptPixelDatasOut->iHeight;        if (!ptPixelDatasOut->aucPixelDatas)        {            ptPixelDatasOut->aucPixelDatas = malloc(ptPixelDatasOut->iTotalBytes);        }        memcpy(ptPixelDatasOut->aucPixelDatas, ptPixelDatasIn->aucPixelDatas, ptPixelDatasOut->iTotalBytes);        return 0;    }    else if (ptVideoBufOut->iPixelFormat == V4L2_PIX_FMT_RGB32)    {        ptPixelDatasOut->iWidth  = ptPixelDatasIn->iWidth;        ptPixelDatasOut->iHeight = ptPixelDatasIn->iHeight;        ptPixelDatasOut->iBpp    = 32;        ptPixelDatasOut->iLineBytes  = ptPixelDatasOut->iWidth * ptPixelDatasOut->iBpp / 8;        ptPixelDatasOut->iTotalBytes = ptPixelDatasOut->iLineBytes * ptPixelDatasOut->iHeight;        if (!ptPixelDatasOut->aucPixelDatas)        {            ptPixelDatasOut->aucPixelDatas = malloc(ptPixelDatasOut->iTotalBytes);        }        pdwDest = (unsigned int *)ptPixelDatasOut->aucPixelDatas;        for (y = 0; y < ptPixelDatasOut->iHeight; y++)        {            for (x = 0; x < ptPixelDatasOut->iWidth; x++)            {                color = *pwSrc++;                /* 从RGB565格式的数据中提取出R,G,B */                r = color >> 11;                g = (color >> 5) & (0x3f);                b = color & 0x1f;                /* 把r,g,b转为0x00RRGGBB的32位数据 */                color = ((r << 3) << 16) | ((g << 2) << 8) | (b << 3);                *pdwDest = color;                pdwDest++;            }        }        return 0;    }    return -1;}static int Rgb2RgbConvertExit(PT_VideoBuf ptVideoBufOut){    if (ptVideoBufOut->tPixelDatas.aucPixelDatas)    {        free(ptVideoBufOut->tPixelDatas.aucPixelDatas);        ptVideoBufOut->tPixelDatas.aucPixelDatas = NULL;    }    return 0;}/* 构造 */static T_VideoConvert g_tRgb2RgbConvert = {    .name        = "rgb2rgb",    .isSupport   = isSupportRgb2Rgb,    .Convert     = Rgb2RgbConvert,    .ConvertExit = Rgb2RgbConvertExit,};/* 注册 */int Rgb2RgbInit(void){    return RegisterVideoConvert(&g_tRgb2RgbConvert);}

yuv2rgb:

#include <convert_manager.h>#include <stdlib.h>#include "color.h"static int isSupportYuv2Rgb(int iPixelFormatIn, int iPixelFormatOut){    if (iPixelFormatIn != V4L2_PIX_FMT_YUYV)        return 0;    if ((iPixelFormatOut != V4L2_PIX_FMT_RGB565) && (iPixelFormatOut != V4L2_PIX_FMT_RGB32))    {        return 0;    }    return 1;}/* translate YUV422Packed to rgb24 */static unsigned intPyuv422torgb565(unsigned char * input_ptr, unsigned char * output_ptr, unsigned int image_width, unsigned int image_height){    unsigned int i, size;    unsigned char Y, Y1, U, V;    unsigned char *buff = input_ptr;    unsigned char *output_pt = output_ptr;    unsigned int r, g, b;    unsigned int color;    size = image_width * image_height /2;    for (i = size; i > 0; i--) {        /* bgr instead rgb ?? */        Y = buff[0] ;        U = buff[1] ;        Y1 = buff[2];        V = buff[3];        buff += 4;        r = R_FROMYV(Y,V);        g = G_FROMYUV(Y,U,V); //b        b = B_FROMYU(Y,U); //v        /* 把r,g,b三色构造为rgb565的16位值 */        r = r >> 3;        g = g >> 2;        b = b >> 3;        color = (r << 11) | (g << 5) | b;        *output_pt++ = color & 0xff;        *output_pt++ = (color >> 8) & 0xff;        r = R_FROMYV(Y1,V);        g = G_FROMYUV(Y1,U,V); //b        b = B_FROMYU(Y1,U); //v        /* 把r,g,b三色构造为rgb565的16位值 */        r = r >> 3;        g = g >> 2;        b = b >> 3;        color = (r << 11) | (g << 5) | b;        *output_pt++ = color & 0xff;        *output_pt++ = (color >> 8) & 0xff;    }    return 0;}/* translate YUV422Packed to rgb24 */static unsigned intPyuv422torgb32(unsigned char * input_ptr, unsigned char * output_ptr, unsigned int image_width, unsigned int image_height){    unsigned int i, size;    unsigned char Y, Y1, U, V;    unsigned char *buff = input_ptr;    unsigned int *output_pt = (unsigned int *)output_ptr;    unsigned int r, g, b;    unsigned int color;    size = image_width * image_height /2;    for (i = size; i > 0; i--) {        /* bgr instead rgb ?? */        Y = buff[0] ;        U = buff[1] ;        Y1 = buff[2];        V = buff[3];        buff += 4;        r = R_FROMYV(Y,V);        g = G_FROMYUV(Y,U,V); //b        b = B_FROMYU(Y,U); //v        /* rgb888 */        color = (r << 16) | (g << 8) | b;        *output_pt++ = color;        r = R_FROMYV(Y1,V);        g = G_FROMYUV(Y1,U,V); //b        b = B_FROMYU(Y1,U); //v        color = (r << 16) | (g << 8) | b;        *output_pt++ = color;    }    return 0;}/* 参考luvcview */static int Yuv2RgbConvert(PT_VideoBuf ptVideoBufIn, PT_VideoBuf ptVideoBufOut){    PT_PixelDatas ptPixelDatasIn  = &ptVideoBufIn->tPixelDatas;    PT_PixelDatas ptPixelDatasOut = &ptVideoBufOut->tPixelDatas;    ptPixelDatasOut->iWidth  = ptPixelDatasIn->iWidth;    ptPixelDatasOut->iHeight = ptPixelDatasIn->iHeight;    if (ptVideoBufOut->iPixelFormat == V4L2_PIX_FMT_RGB565)    {        ptPixelDatasOut->iBpp = 16;        ptPixelDatasOut->iLineBytes  = ptPixelDatasOut->iWidth * ptPixelDatasOut->iBpp / 8;        ptPixelDatasOut->iTotalBytes = ptPixelDatasOut->iLineBytes * ptPixelDatasOut->iHeight;        if (!ptPixelDatasOut->aucPixelDatas)        {            ptPixelDatasOut->aucPixelDatas = malloc(ptPixelDatasOut->iTotalBytes);        }        Pyuv422torgb565(ptPixelDatasIn->aucPixelDatas, ptPixelDatasOut->aucPixelDatas, ptPixelDatasOut->iWidth, ptPixelDatasOut->iHeight);        return 0;    }    else if (ptVideoBufOut->iPixelFormat == V4L2_PIX_FMT_RGB32)    {        ptPixelDatasOut->iBpp = 32;        ptPixelDatasOut->iLineBytes  = ptPixelDatasOut->iWidth * ptPixelDatasOut->iBpp / 8;        ptPixelDatasOut->iTotalBytes = ptPixelDatasOut->iLineBytes * ptPixelDatasOut->iHeight;        if (!ptPixelDatasOut->aucPixelDatas)        {            ptPixelDatasOut->aucPixelDatas = malloc(ptPixelDatasOut->iTotalBytes);        }        Pyuv422torgb32(ptPixelDatasIn->aucPixelDatas, ptPixelDatasOut->aucPixelDatas, ptPixelDatasOut->iWidth, ptPixelDatasOut->iHeight);        return 0;    }    return -1;}static int Yuv2RgbConvertExit(PT_VideoBuf ptVideoBufOut){    if (ptVideoBufOut->tPixelDatas.aucPixelDatas)    {        free(ptVideoBufOut->tPixelDatas.aucPixelDatas);        ptVideoBufOut->tPixelDatas.aucPixelDatas = NULL;    }    return 0;}/* 构造 */static T_VideoConvert g_tYuv2RgbConvert = {    .name        = "yuv2rgb",    .isSupport   = isSupportYuv2Rgb,    .Convert     = Yuv2RgbConvert,    .ConvertExit = Yuv2RgbConvertExit,};extern void initLut(void);/* 注册 */int Yuv2RgbInit(void){    initLut();    return RegisterVideoConvert(&g_tYuv2RgbConvert);}