RGB图像数据字符叠加,图像压缩(ijl库),YUV转RGB

RGB图像数据字符叠加,图像压缩(ijl库),YUV转RGB

http://blog.sina.com.cn/s/blog_51396f890100nv2t.html
时间:2010-01-01 12:02 来源:CSDN.NET  作者:秩名  点击:912次
一些非常有用的图像格式转换及使用的源代码,包括RGB图像数据字符叠加,图像压缩(ijl库),YUV转RGB等等。
收藏到:  MSN - Live Favorites  添加到QQ书签  百度收藏  CSDN技术网摘  添加到google  365Key网摘  新浪ViVi  yahoo  收藏到收客网  Digbuzz我挖网  RGB图像数据字符叠加,图像压缩(ijl库),YUV转RGB
TAG:  YUV   YUV转RGB   RGB   文字叠加   BMP转JPG  

 

#ifndef YUVRGB24_H
#define YUVRGB24_H

//初始化YUV图像转化为RGB图像使用的表格
void init_dither_tab();

//YUV图像转化为RGB图像时宽度高度都不变
#ifdef OLD
 void ConvertYUVtoRGB(
  unsigned char *src0,
  unsigned char *src1,
  unsigned char *src2,
  unsigned char *dst_ori,
  int width,
  int height);
#else
 void ConvertYUVtoRGB(
  unsigned char *src,
  unsigned char *dst_ori,
  int width,
  int height);
#endif

//YUV图像转化为RGB图像时宽度折半高度不变
void ConvertYUVtoRGBSample(
 unsigned char *src,
 unsigned char *dst_ori,
 int width,
 int height);

//YUV图像转化为RGB图像时宽度折半高度不变 进行图像翻转
void ConvertYUVtoRGBSampleReverse(
 unsigned char *src,
 unsigned char *dst_ori,
 int width,
 int height);

//YUV图像转化为RGB图像时宽度直接由720扩为768
//隔16个点插入一列(最后一列忽略 共插44列) 两边各插2列
void ConvertYUV720toRGB768(
 unsigned char *src,
 unsigned char *dst_ori,
 int width,
 int height);

//YUV图像转化为RGB图像时宽度直接由720扩为768,高度扩展1倍
//隔16个点插入一列(最后一列忽略 共插44列) 两边各插2列
void ConvertYUV720toRGB768TwoHeight(
 unsigned char *src,
 unsigned char *dst_ori,
 int width,
 int height);

//YUV图像转化为RGB图像时宽度直接由720扩为768 高度扩展1倍 进行图像翻转
//隔16个点插入一列(最后一列忽略 共插44列) 两边各插2列
void ConvertYUV720toRGB768TwoHeightReverse(
 unsigned char *src,
 unsigned char *dst_ori,
 int width,
 int height);
#endif

 

//#include "config.h"
//#include "tmndec.h"
//#include "global.h"
#include "stdafx.h"


static long int crv_tab[256];
static long int cbu_tab[256];
static long int cgu_tab[256];

static long int cgv_tab[256];
static long int tab_76309[256];

static unsigned char *clp;
static unsigned char *pclp;

void init_dither_tab()
{
 long int crv,cbu,cgu,cgv;
 int i;  

 crv = 104597; cbu = 132201; 
 cgu = 25675;  cgv = 53279;

 for (i = 0; i < 256; i++)
 {
  crv_tab[i] = (i-128) * crv;
  cbu_tab[i] = (i-128) * cbu;
  cgu_tab[i] = (i-128) * cgu;
  cgv_tab[i] = (i-128) * cgv;
  tab_76309[i] = 76309*(i-16);
 }

}

void free_clp()
{
 //free( pclp );
}

inline unsigned char CharClip( int value )
{
 if( value < 0 )
 {
  return 0;
 }
 else if( value > 255 )
 {
  return 255;
 }
 else
 {
  return (unsigned char)value;
 }
}

#ifdef OLD
 void ConvertYUVtoRGB(
  unsigned char *src0,
  unsigned char *src1,
  unsigned char *src2,
  unsigned char *dst_ori,
  int width,
  int height)
#else
 void ConvertYUVtoRGB(
  unsigned char *src,
  unsigned char *dst_ori,
  int width,
  int height)
#endif
{      
 int y11;
 int y12;
 int y13;
 int y14;
 int u, v;
 int i, j;
 int c11, c21, c31, c41;
 int c12, c22, c32, c42;
 unsigned long DW; // 4 bytes
 unsigned long *id1; // 4 bytes
 unsigned char *py, *pu,*pv;
 unsigned char *d1;
 
 d1 = dst_ori;
 
 py = src;
 pu = src+1;
 pv = src+3;

 id1 = (unsigned long *)d1;

 for (j = 0; j < height; j ++ )
 {
  for (i = 0; i < width; i += 4 )
  {
   u = *pu;
   v = *pv;
     
   c11 = crv_tab[v];  
   c21 = cgu_tab[u];
   c31 = cgv_tab[v];
   c41 = cbu_tab[u];
   pu += 4;
   pv += 4;

   u = *pu;
   v = *pv;
   c12 = crv_tab[v];
   c22 = cgu_tab[u];
   c32 = cgv_tab[v];
   c42 = cbu_tab[u];

   pu += 4;
   pv += 4;

   y11 = tab_76309[*py];
   py += 2;
   y12 = tab_76309[*py];
   py += 2;

   y13 = tab_76309[*py];
   py += 2;
   y14 = tab_76309[*py];
   py += 2;

  
   //DW = ((clp[(y11 + c41)>>16])) |
   //     ((clp[(y11 - c21 - c31)>>16])<<8) |
   //     ((clp[(y11 + c11)>>16])<<16) | 
   //     ((clp[(y12 + c41)>>16])<<24);
   DW = (( CharClip( (y11 + c41)>>16 ) )) |
    (( CharClip( (y11 - c21 - c31)>>16 ) <<8 )) |
    (( CharClip( (y11 + c11)>>16 ) <<16 )) | 
    (( CharClip( (y12 + c41)>>16 ) << 24 ));
   *id1++ = DW;

  
   //DW = ((clp[(y12 - c21 - c31)>>16])) |
   //     ((clp[(y12 + c11)>>16])<<8) | 
   //     ((clp[(y13 + c42)>>16])<<16) |
   //     ((clp[(y13 - c22 - c32)>>16])<<24);
   DW = (( CharClip( (y12 - c21 - c31)>>16 ) )) |
    (( CharClip( (y12 + c11)>>16 ) <<8 )) | 
    (( CharClip( (y13 + c42)>>16 ) <<16 )) |
    (( CharClip( (y13 - c22 - c32) >>16 ) <<24 ));
   *id1++ = DW;

  
  
   DW = (( CharClip( (y13 + c12)>>16 ) )) | 
    (( CharClip( (y14 + c42)>>16 )<<8 )) |
    (( CharClip( (y14 - c22 - c32 )>>16 )<<16)) |
    (( CharClip( (y14 + c12)>>16 )<<24)); 
   *id1++ = DW;
  }

  //id1 -= (9 * width)>>2;
  //id2 -= (9 * width)>>2;
  //py += width;
  //py2 += width;
 }          


void ConvertYUVtoRGBSample(
 unsigned char *src,
 unsigned char *dst_ori,
 int width,
 int height)
{    
 int y11;
 int y12;
 int y13;
 int y14;
 int u,v;
 int i,j;
 int c11, c21, c31, c41;
 int c12, c22, c32, c42;
 unsigned long DW;   // 4 bytes
 unsigned long *id1; // 4 bytes
 unsigned char *py, *pu,*pv;
 unsigned char *d1;

 d1 = dst_ori;

 py = src;
 pu = src+1;
 pv = src+3;

 id1 = (unsigned long *)d1;

 for (j = 0; j < height; j ++ )
 {
  for (i = 0; i < width; i += 8 )
  {
   u = *pu;
   v = *pv;
     
   c11 = crv_tab[v];  
   c21 = cgu_tab[u];
  
   pu += 4;
   pv += 4;
   u = *pu;
   v = *pv;

   c31 = cgv_tab[v];
   c41 = cbu_tab[u];
  
   pu += 4;
   pv += 4;
   u = *pu;
   v = *pv;
   c12 = crv_tab[v];
   c22 = cgu_tab[u];
   pu += 4;
   pv += 4;
   u = *pu;
   v = *pv;
   c32 = cgv_tab[v];
   c42 = cbu_tab[u];

   pu += 4;
   pv += 4;

   y11 = tab_76309[*py];
   py += 4;
   y12 = tab_76309[*py];
   py += 4;

   y13 = tab_76309[*py];
   py += 4;
   y14 = tab_76309[*py];
   py += 4;

  
   //DW = ((clp[(y11 + c41)>>16])) |
   //     ((clp[(y11 - c21 - c31)>>16])<<8) |
   //     ((clp[(y11 + c11)>>16])<<16) | 
   //     ((clp[(y12 + c41)>>16])<<24);
   DW = (( CharClip( (y11 + c41)>>16 ) )) |
    (( CharClip( (y11 - c21 - c31)>>16 ) <<8 )) |
    (( CharClip( (y11 + c11)>>16 ) <<16 )) | 
    (( CharClip( (y12 + c41)>>16 ) << 24 ));
   *id1++ = DW;

  
   //DW = ((clp[(y12 - c21 - c31)>>16])) |
   //     ((clp[(y12 + c11)>>16])<<8) | 
   //     ((clp[(y13 + c42)>>16])<<16) |
   //     ((clp[(y13 - c22 - c32)>>16])<<24);
   DW = (( CharClip( (y12 - c21 - c31)>>16 ) )) |
    (( CharClip( (y12 + c11)>>16 ) <<8 )) | 
      (( CharClip( (y13 + c42)>>16 ) <<16 )) |
      (( CharClip( (y13 - c22 - c32) >>16 ) <<24 ));
   *id1++ = DW;

  
  
   DW = (( CharClip( (y13 + c12)>>16 ) )) | 
      (( CharClip( (y14 + c42)>>16 )<<8 )) |
      (( CharClip( (y14 - c22 - c32 )>>16 )<<16)) |
      (( CharClip( (y14 + c12)>>16 )<<24)); 
   *id1++ = DW;
  }
  //id1 -= (9 * width)>>2;
  //id2 -= (9 * width)>>2;
  //py += width;
  //py2 += width;
 }          

void ConvertYUVtoRGBSampleReverse(
 unsigned char *src,
 unsigned char *dst_ori,
 int width,
 int height)
{    
 int y11;
 int y12;
 int y13;
 int y14;
 int u,v;
 int i,j;
 int c11, c21, c31, c41;
 int c12, c22, c32, c42;
 unsigned long DW;   // 4 bytes
 unsigned long *id1; // 4 bytes
 unsigned char *py, *pu,*pv;
 unsigned char *d1;
 
 const int DST_LINEIMAGE_SIZE = 360 * 3; // 目标图像(RGB)1行的数据长度(BYTE)
 const int DST_END_ADDRESS = DST_LINEIMAGE_SIZE * 288; // 目标图像(RGB)末尾地址

 d1 = dst_ori + DST_END_ADDRESS;

 py = src;
 pu = src+1;
 pv = src+3;

 //id1 = (unsigned long *)d1;

 for (j = 0; j < height; j ++ )
 {
  d1  -= DST_LINEIMAGE_SIZE;
  id1 = (unsigned long*)d1;

  for (i = 0; i < width; i += 8 )
  {
   u = *pu;
   v = *pv;
     
   c11 = crv_tab[v];  
   c21 = cgu_tab[u];
  
   pu += 4;
   pv += 4;
   u = *pu;
   v = *pv;

   c31 = cgv_tab[v];
   c41 = cbu_tab[u];
  
   pu += 4;
   pv += 4;
   u = *pu;
   v = *pv;
   c12 = crv_tab[v];
   c22 = cgu_tab[u];
   pu += 4;
   pv += 4;
   u = *pu;
   v = *pv;
   c32 = cgv_tab[v];
   c42 = cbu_tab[u];

   pu += 4;
   pv += 4;

   y11 = tab_76309[*py];
   py += 4;
   y12 = tab_76309[*py];
   py += 4;

   y13 = tab_76309[*py];
   py += 4;
   y14 = tab_76309[*py];
   py += 4;

  
   //DW = ((clp[(y11 + c41)>>16])) |
   //     ((clp[(y11 - c21 - c31)>>16])<<8) |
   //     ((clp[(y11 + c11)>>16])<<16) | 
   //     ((clp[(y12 + c41)>>16])<<24);
   DW = (( CharClip( (y11 + c41)>>16 ) )) |
    (( CharClip( (y11 - c21 - c31)>>16 ) <<8 )) |
    (( CharClip( (y11 + c11)>>16 ) <<16 )) | 
    (( CharClip( (y12 + c41)>>16 ) << 24 ));
   *id1++ = DW;

  
   //DW = ((clp[(y12 - c21 - c31)>>16])) |
   //     ((clp[(y12 + c11)>>16])<<8) | 
   //     ((clp[(y13 + c42)>>16])<<16) |
   //     ((clp[(y13 - c22 - c32)>>16])<<24);
   DW = (( CharClip( (y12 - c21 - c31)>>16 ) )) |
    (( CharClip( (y12 + c11)>>16 ) <<8 )) | 
      (( CharClip( (y13 + c42)>>16 ) <<16 )) |
      (( CharClip( (y13 - c22 - c32) >>16 ) <<24 ));
   *id1++ = DW;

  
  
   DW = (( CharClip( (y13 + c12)>>16 ) )) | 
      (( CharClip( (y14 + c42)>>16 )<<8 )) |
      (( CharClip( (y14 - c22 - c32 )>>16 )<<16)) |
      (( CharClip( (y14 + c12)>>16 )<<24)); 
   *id1++ = DW;
  } // for width

  //d1 -= DST_TWOLINEIMAGE_SIZE;
  //id1 = (unsigned long*)d1;

  //id1 -= (9 * width)>>2;
  //id2 -= (9 * width)>>2;
  //py += width;
  //py2 += width;
 } // for height         

void ConvertYUV720toRGB768(
 unsigned char *src,
 unsigned char *dst_ori,
 int width,
 int height)
{      
 int y11;
 int y12;
 int y13;
 int y14;
 int u, v;
 int i, j;
 int c11, c21, c31, c41;
 int c12, c22, c32, c42;
 unsigned long DW; // 4 bytes
 unsigned long *id1; // 4 bytes
 unsigned char *py, *pu,*pv;
 unsigned char *d1;
 
 d1 = dst_ori+6;
 
 py = src;
 pu = src+1;
 pv = src+3;

 id1 = (unsigned long *)d1;

 for (j = 0; j < height; j ++ )
 {
  for (i = 0; i < width; i += 4 )
  {
   u = *pu;
   v = *pv;
     
   c11 = crv_tab[v];  
   c21 = cgu_tab[u];
   c31 = cgv_tab[v];
   c41 = cbu_tab[u];
   pu += 4;
   pv += 4;

   u = *pu;
   v = *pv;
   c12 = crv_tab[v];
   c22 = cgu_tab[u];
   c32 = cgv_tab[v];
   c42 = cbu_tab[u];

   pu += 4;
   pv += 4;

   y11 = tab_76309[*py];
   py += 2;
   y12 = tab_76309[*py];
   py += 2;

   y13 = tab_76309[*py];
   py += 2;
   y14 = tab_76309[*py];
   py += 2;

  
   //DW = ((clp[(y11 + c41)>>16])) |
   //     ((clp[(y11 - c21 - c31)>>16])<<8) |
   //     ((clp[(y11 + c11)>>16])<<16) | 
   //     ((clp[(y12 + c41)>>16])<<24);
   DW = (( CharClip( (y11 + c41)>>16 ) )) |
    (( CharClip( (y11 - c21 - c31)>>16 ) <<8 )) |
    (( CharClip( (y11 + c11)>>16 ) <<16 )) | 
    (( CharClip( (y12 + c41)>>16 ) << 24 ));
   *id1++ = DW;

  
   //DW = ((clp[(y12 - c21 - c31)>>16])) |
   //     ((clp[(y12 + c11)>>16])<<8) | 
   //     ((clp[(y13 + c42)>>16])<<16) |
   //     ((clp[(y13 - c22 - c32)>>16])<<24);
   DW = (( CharClip( (y12 - c21 - c31)>>16 ) )) |
    (( CharClip( (y12 + c11)>>16 ) <<8 )) | 
    (( CharClip( (y13 + c42)>>16 ) <<16 )) |
    (( CharClip( (y13 - c22 - c32) >>16 ) <<24 ));
   *id1++ = DW;

  
  
   DW = (( CharClip( (y13 + c12)>>16 ) )) | 
    (( CharClip( (y14 + c42)>>16 )<<8 )) |
    (( CharClip( (y14 - c22 - c32 )>>16 )<<16)) |
    (( CharClip( (y14 + c12)>>16 )<<24)); 
   *id1++ = DW;

   if ((i) == 0 &&
    i>0 &&
    i<width-1)
   {
    *d1 = *(d1-3);
    *(d1+1) = *(d1-2);
    *(d1+2) = *(d1-1);
    d1 += 3;
    id1 = (unsigned long*)d1;
   }
   else if (i == 0)
   {
    *(d1-6) = *d1;
    *(d1-5) = *(d1+1);
    *(d1-4) = *(d1+2);
    *(d1-3) = *(d1+3);
    *(d1-2) = *(d1+4);
    *(d1-1) = *(d1+5);
   }
   else if (i == (width-1)/16*16)
   {
    *(d1+5) = *(d1-1);
    *(d1+4) = *(d1-2);
    *(d1+3) = *(d1-3);
    *(d1+2) = *(d1-4);
    *(d1+1) = *(d1-5);
    *d1 = *(d1-6);
   }

   d1 += 12;
  }
  if (j < height-1)
  {
   d1 += 12;
   id1 = (unsigned long*)d1;
  }
  //id1 -= (9 * width)>>2;
  //id2 -= (9 * width)>>2;
  //py += width;
  //py2 += width;
 }          

void ConvertYUV720toRGB768TwoHeight(
 unsigned char *src,
 unsigned char *dst_ori,
 int width,
 int height)
{      
 int y11;
 int y12;
 int y13;
 int y14;
 int u, v;
 int i, j;
 int c11, c21, c31, c41;
 int c12, c22, c32, c42;
 unsigned long DW; // 4 bytes
 unsigned long *id1; // 4 bytes
 unsigned char *py, *pu,*pv;
 unsigned char *d1; // 目标图像存储区域 
 const int DST_LINEIMAGE_SIZE = 768 * 3; // 目标图像(RGB)一行的数据长度(BYTE)

 d1 = dst_ori+6;
 
 py = src;
 pu = src+1;
 pv = src+3;

 id1 = (unsigned long *)d1;

 for (j = 0; j < height; j ++ )
 {
  for (i = 0; i < width; i += 4)
  {
   u = *pu;
   v = *pv;
     
   c11 = crv_tab[v];  
   c21 = cgu_tab[u];
   c31 = cgv_tab[v];
   c41 = cbu_tab[u];
   pu += 4;
   pv += 4;

   u = *pu;
   v = *pv;
   c12 = crv_tab[v];
   c22 = cgu_tab[u];
   c32 = cgv_tab[v];
   c42 = cbu_tab[u];

   pu += 4;
   pv += 4;

   y11 = tab_76309[*py];
   py += 2;
   y12 = tab_76309[*py];
   py += 2;

   y13 = tab_76309[*py];
   py += 2;
   y14 = tab_76309[*py];
   py += 2;

  
   //DW = ((clp[(y11 + c41)>>16])) |
   //     ((clp[(y11 - c21 - c31)>>16])<<8) |
   //     ((clp[(y11 + c11)>>16])<<16) | 
   //     ((clp[(y12 + c41)>>16])<<24);
   DW = (( CharClip( (y11 + c41)>>16 ) )) |
    (( CharClip( (y11 - c21 - c31)>>16 ) <<8 )) |
    (( CharClip( (y11 + c11)>>16 ) <<16 )) | 
    (( CharClip( (y12 + c41)>>16 ) << 24 ));
   *id1++ = DW;

  
   //DW = ((clp[(y12 - c21 - c31)>>16])) |
   //     ((clp[(y12 + c11)>>16])<<8) | 
   //     ((clp[(y13 + c42)>>16])<<16) |
   //     ((clp[(y13 - c22 - c32)>>16])<<24);
   DW = (( CharClip( (y12 - c21 - c31)>>16 ) )) |
    (( CharClip( (y12 + c11)>>16 ) <<8 )) | 
    (( CharClip( (y13 + c42)>>16 ) <<16 )) |
    (( CharClip( (y13 - c22 - c32) >>16 ) <<24 ));
   *id1++ = DW;

  
  
   DW = (( CharClip( (y13 + c12)>>16 ) )) | 
    (( CharClip( (y14 + c42)>>16 )<<8 )) |
    (( CharClip( (y14 - c22 - c32 )>>16 )<<16)) |
    (( CharClip( (y14 + c12)>>16 )<<24)); 
   *id1++ = DW;
  
   if ((i) == 0 &&
    i>0 &&
    i<width-1)
   {
    d1 += 12;

    *d1 = *(d1-3);
    *(d1+1) = *(d1-2);
    *(d1+2) = *(d1-1);
    d1 += 3;
    id1 = (unsigned long*)d1;
   }
   else if (i == 0)
   {
    *(d1-6) = *d1;
    *(d1-5) = *(d1+1);
    *(d1-4) = *(d1+2);
    *(d1-3) = *d1;
    *(d1-2) = *(d1+1);
    *(d1-1) = *(d1+2);

    d1 += 12;
   }
   else if (i == (width-1)/4*4)
   {
    d1 += 12;
   
    *d1 = *(d1-3);
    *(d1+1) = *(d1-2);
    *(d1+2) = *(d1-1);
    *(d1+3) = *(d1-3);
    *(d1+4) = *(d1-2);
    *(d1+5) = *(d1-1);
   }
   else
   {
    d1 += 12;
   }
  }
  if (j < height-1)
  {
   d1 += 12;
   id1 = (unsigned long*)d1;

   memcpy(d1,(d1-DST_LINEIMAGE_SIZE),DST_LINEIMAGE_SIZE);
   d1 += DST_LINEIMAGE_SIZE;
   id1 = (unsigned long*)d1;
  }
  //id1 -= (9 * width)>>2;
  //id2 -= (9 * width)>>2;
  //py += width;
  //py2 += width;
 }          

void ConvertYUV720toRGB768TwoHeightReverse(
 unsigned char *src,
 unsigned char *dst_ori,
 int width,
 int height)
{      
 int y11;
 int y12;
 int y13;
 int y14;
 int u, v;
 int i, j;
 int c11, c21, c31, c41;
 int c12, c22, c32, c42;
 unsigned long DW; // 4 bytes
 unsigned long *id1; // 4 bytes
 unsigned char *py, *pu,*pv;
 unsigned char *d1; // 目标图像存储区域 用来运算
 unsigned char *d2; // 目标图像存储区域 用来定位

 const int DST_LINEIMAGE_SIZE = 768 * 3; // 目标图像(RGB)1行的数据长度(BYTE)
 const int DST_TWOLINEIMAGE_SIZE = 768 * 3 * 2; // 目标图像(RGB)2行的数据长度(BYTE)
 const int DST_END_ADDRESS = DST_LINEIMAGE_SIZE * 576; // 目标图像(RGB)目标图像(RGB)末尾地址

 d2 = dst_ori + DST_END_ADDRESS;
 
 py = src;
 pu = src+1;
 pv = src+3;

 // id1 = (unsigned long *)d1;

 for (j = 0; j < height; j ++ )
 {
 
  d2  -= DST_TWOLINEIMAGE_SIZE;
  d1  = d2 + 6;
  id1 = (unsigned long*)d1;

  for (i = 0; i < width; i += 4 )
  {
   u = *pu;
   v = *pv;
     
   c11 = crv_tab[v];  
   c21 = cgu_tab[u];
   c31 = cgv_tab[v];
   c41 = cbu_tab[u];
   pu += 4;
   pv += 4;

   u = *pu;
   v = *pv;
   c12 = crv_tab[v];
   c22 = cgu_tab[u];
   c32 = cgv_tab[v];
   c42 = cbu_tab[u];

   pu += 4;
   pv += 4;

   y11 = tab_76309[*py];
   py += 2;
   y12 = tab_76309[*py];
   py += 2;

   y13 = tab_76309[*py];
   py += 2;
   y14 = tab_76309[*py];
   py += 2;

  
   //DW = ((clp[(y11 + c41)>>16])) |
   //     ((clp[(y11 - c21 - c31)>>16])<<8) |
   //     ((clp[(y11 + c11)>>16])<<16) | 
   //     ((clp[(y12 + c41)>>16])<<24);
   DW = (( CharClip( (y11 + c41)>>16 ) )) |
    (( CharClip( (y11 - c21 - c31)>>16 ) <<8 )) |
    (( CharClip( (y11 + c11)>>16 ) <<16 )) | 
    (( CharClip( (y12 + c41)>>16 ) << 24 ));
   *id1++ = DW;

  
   //DW = ((clp[(y12 - c21 - c31)>>16])) |
   //     ((clp[(y12 + c11)>>16])<<8) | 
   //     ((clp[(y13 + c42)>>16])<<16) |
   //     ((clp[(y13 - c22 - c32)>>16])<<24);
   DW = (( CharClip( (y12 - c21 - c31)>>16 ) )) |
    (( CharClip( (y12 + c11)>>16 ) <<8 )) | 
    (( CharClip( (y13 + c42)>>16 ) <<16 )) |
    (( CharClip( (y13 - c22 - c32) >>16 ) <<24 ));
   *id1++ = DW;

  
  
   DW = (( CharClip( (y13 + c12)>>16 ) )) | 
    (( CharClip( (y14 + c42)>>16 )<<8 )) |
    (( CharClip( (y14 - c22 - c32 )>>16 )<<16)) |
    (( CharClip( (y14 + c12)>>16 )<<24)); 
   *id1++ = DW;

   if ((i) == 0 &&
    i>0 &&
    i<width-1)
   {
    d1 += 12;

    *d1 = *(d1-3);
    *(d1+1) = *(d1-2);
    *(d1+2) = *(d1-1);
    d1 += 3;
    id1 = (unsigned long*)d1;
   }
   else if (i == 0)
   {
    *(d1-6) = *d1;
    *(d1-5) = *(d1+1);
    *(d1-4) = *(d1+2);
    *(d1-3) = *d1;
    *(d1-2) = *(d1+1);
    *(d1-1) = *(d1+2);

    d1 += 12;
   }
   else if (i == (width-1)/4*4)
   {
    d1 += 12;
   
    *d1 = *(d1-3);
    *(d1+1) = *(d1-2);
    *(d1+2) = *(d1-1);
    *(d1+3) = *(d1-3);
    *(d1+4) = *(d1-2);
    *(d1+5) = *(d1-1);
   }
   else
   {
    d1 += 12;
   }
  }
 
  d1 += 6;
  memcpy(d1,(d1-DST_LINEIMAGE_SIZE),DST_LINEIMAGE_SIZE);
 
  //id1 -= (9 * width)>>2;
  //id2 -= (9 * width)>>2;
  //py += width;
  //py2 += width; 
 }          

/
// End of this file.
/


 #include "stdafx.h"
#include "PSA.h"
#include "Imageaddchar.h"
#include "ijl.h"
#include "yuvrgb24.h"
LPBITMAPINFOHEADER   m_lpVehicleBitmapHeader = NULL;
HDC                  m_hMemDC;
HBITMAP              m_hBmp;
HBITMAP              m_hBmpOld;
HFONT                m_hFont;
HFONT                m_hFontOld;
LPBYTE               m_lpMemImage = NULL;

int                  m_piBrandRatio[32];     
static bool          m_bPermitAddCharToImage;

const int            PLATE_IMAGE_SIZE = 128 * 20 * 2;
const int            BRAND_IMAGE_SIZE = 64 * 20 * 2; 


BEGIN_MESSAGE_MAP(CPSAApp, CWinApp)
 //{{AFX_MSG_MAP(CPSAApp)
  // NOTE - the ClassWizard will add and remove mapping macros here.
  //    DO NOT EDIT what you see in these blocks of generated code!
 //}}AFX_MSG_MAP
END_MESSAGE_MAP()

/
// CPSAApp construction

CPSAApp::CPSAApp()
{
 // TODO: add construction code here,
 // Place all significant initialization in InitInstance
}

/
// The one and only CPSAApp object

CPSAApp theApp;


int WriteToLog(int iErrorNumber,TCHAR *szMsg)
{
 int    i = 0;
 int    iLastSperate = 0;
 TCHAR  szCurPath[272]; 
 HANDLE hWndFile;
 WIN32_FIND_DATA fileFind;
 FILE   *fp;
 SYSTEMTIME lpSystemTime;
 
 GetModuleFileName(GetModuleHandle(NULL),szCurPath,256); 

 for (i=0; i<256; i++)
 {
  if (szCurPath[i] == '//')
  {
   iLastSperate = i;
  }
  else if(szCurPath[i] == '/0')
  {
   break;
  }
 }
 
 if (iLastSperate > 0 && i < 256)
 {
  szCurPath[iLastSperate] = '/0';
 }
 else
 {
  return (-1);
 }
 
 strcat(szCurPath,"//psaImage.evt");

 //printf("current path: %s /n",szCurPath);
 
 GetLocalTime(&lpSystemTime);
 
 printf("current time: d-d-d d:d:d:d/n",
                    lpSystemTime.wYear,lpSystemTime.wMonth,lpSystemTime.wDay,
        lpSystemTime.wHour,lpSystemTime.wMinute,lpSystemTime.wSecond,
        lpSystemTime.wMilliseconds);

 hWndFile = FindFirstFile(szCurPath,&fileFind);
 FindClose(hWndFile);


 if (INVALID_HANDLE_VALUE == hWndFile)
 {
  if ((fp = fopen(szCurPath,"w")) == NULL)
  {
   return (-2);
  }
  fprintf(fp,"d-d-d d:d:d:d  Event:d  %s/n",
          lpSystemTime.wYear,lpSystemTime.wMonth,lpSystemTime.wDay,
       lpSystemTime.wHour,lpSystemTime.wMinute,lpSystemTime.wSecond,lpSystemTime.wMilliseconds,
       iErrorNumber,szMsg);
  fclose(fp);
 }
 else
 {
  if (fileFind.nFileSizeLow > 61440)  // if event file size > 60K, delete, create new
  {
   if (DeleteFile(szCurPath))
   {
    if ((fp = fopen(szCurPath,"w")) == NULL)
    {
     return (-2);
    }
    fprintf(fp,"d-d-d d:d:d:d  Event:d  %s/n",
         lpSystemTime.wYear,lpSystemTime.wMonth,lpSystemTime.wDay,
         lpSystemTime.wHour,lpSystemTime.wMinute,lpSystemTime.wSecond,lpSystemTime.wMilliseconds,
         iErrorNumber,szMsg);
    fclose(fp);
   }
  }
  else
  {
   if ((fp = fopen(szCurPath,"a+")) == NULL)
   {
    return (-3);
   }
   else
   {
    fprintf(fp,"d-d-d d:d:d:d  Event:d  %s/n",
         lpSystemTime.wYear,lpSystemTime.wMonth,lpSystemTime.wDay,
         lpSystemTime.wHour,lpSystemTime.wMinute,lpSystemTime.wSecond,lpSystemTime.wMilliseconds,
         iErrorNumber,szMsg);
    fclose(fp);
   }
  }
 }

 
 
 return (0);
}


int CompressRGBToJPEG(BYTE *lpImageRGB, 
       int originalWidth,
       int originalHeight,
       int   jpegQuality,
       char* jpegFileName,
       int   isNeedReversal,
       int   isResizeImage)
{
 int res = 0;
 int jpegImageWidth;
 int jpegImageHeight;
 IJLERR jerr;
 JPEG_CORE_PROPERTIES jcprops;
 
 jerr = ijlInit(&jcprops);
 if (jerr != IJL_OK)
    {
  res = 1;
  goto Exit;
    }
 
 if (isResizeImage == 0) //保持原始比例
 {
  jpegImageWidth = originalWidth;
  jpegImageHeight = originalHeight;
 }
// else if (isResizeImage == 112) //宽度变为1/2,高度不变
// {
//  jpegImageWidth = originalWidth/2;
//  jpegImageHeight = originalHeight;
// }
 else //保持原始比例
 {
  jpegImageWidth = originalWidth;
  jpegImageHeight = originalHeight;
 }

    // Setup DIB
   jcprops.DIBWidth         = originalWidth;
 if (isNeedReversal == 0) //如果不需要翻转图片
 {
  jcprops.DIBHeight        = originalHeight;
 }
 else                     //如果需要翻转图片
 {
  jcprops.DIBHeight        = -originalHeight;
 }
    jcprops.DIBBytes         = lpImageRGB;
 jcprops.DIBColor         = IJL_BGR;
 jcprops.DIBChannels      = 3;
 jcprops.DIBPadBytes      = IJL_DIB_PAD_BYTES(jcprops.DIBWidth,3);

    // Setup JPEG
    jcprops.JPGFile          = jpegFileName;
    jcprops.JPGWidth         = jpegImageWidth;
    jcprops.JPGHeight        = jpegImageHeight;
 jcprops.jquality         = jpegQuality;
 jcprops.JPGColor         = IJL_YCBCR;
 jcprops.JPGChannels      = 3;
 jcprops.JPGSubsampling   = IJL_411;

    jerr = ijlWrite(&jcprops,IJL_JFILE_WRITEWHOLEIMAGE);
 if(IJL_OK != jerr)
 {
  //printf("ijlInit() failed - %s/n",ijlErrorStr(jerr));
  res = 2;
  goto Exit;
 }

Exit:
 jerr = ijlFree(&jcprops);
 if(IJL_OK != jerr)
 {
  //printf("ijlFree() failed - %s/n",ijlErrorStr(jerr));
  res = 3;
 }

 return res;
}


extern "C" int PASCAL EXPORT PSAInit()
{
 AFX_MANAGE_STATE(AfxGetStaticModuleState());
 
 m_bPermitAddCharToImage = false;

 init_dither_tab();

 srand(unsigned int(time(NULL)));

 return 0;
}


extern "C" int PASCAL EXPORT PSAFree()
{
 AFX_MANAGE_STATE(AfxGetStaticModuleState());
 
 m_bPermitAddCharToImage = false;

 int res = 0;

 return (res);
}


extern "C" int PASCAL EXPORT PSAAddCharToImage(LPBYTE lpImage,
              CHAR *chLicense,
              CHAR *chDateTime,
              CHAR *chSpeed,
              CHAR *chLocation,
              CHAR *chLimitSpeed,
              CHAR *chDirection,
              WORD wImageWidth,
              WORD wImageHeight,
              BYTE btColorB,
              BYTE btColorG,
              BYTE btColorR)
{
 AFX_MANAGE_STATE(AfxGetStaticModuleState());
 
 int iRetval;

 CImageaddchar cImage;

 iRetval = cImage.Imageaddchar(lpImage,
                            chLicense,
          chDateTime,
          chSpeed,
          chLocation,
          chLimitSpeed,
                                  chDirection,
          wImageWidth,
          wImageHeight,
          btColorB,
          btColorG,
          btColorR);

 return (iRetval);
}


extern "C" int PASCAL EXPORT PSAFreeCharToImageInit(DWORD   hDC,
                                                    DWORD   dwImageWidth,
             DWORD   dwImageHeight,
             LPCTSTR lpszFontName,
             int     iFontSize,
             DWORD   dwFontBold,
             DWORD   dwFontItalic,
             DWORD   dwFontUnderline,
             DWORD   dwFontStrikeOut,
             BYTE    btForeColorB,
             BYTE    btForeColorG,
             BYTE    btForeColorR)
             
{
 AFX_MANAGE_STATE(AfxGetStaticModuleState());

 DWORD        dwImageByte = 0;
 int          iRetval     = 0xFF; 
   
 dwImageByte = dwImageWidth * dwImageHeight * (DWORD)3; //计算BMP图像数据总大小
 
 m_lpMemImage = (LPBYTE) new unsigned char[dwImageByte];
 
 m_lpVehicleBitmapHeader = (LPBITMAPINFOHEADER) new char[40];

 //BITMAPINFOHEADER 结构变量初始化
    m_lpVehicleBitmapHeader->biBitCount = 24;
    m_lpVehicleBitmapHeader->biClrImportant = 0;
    m_lpVehicleBitmapHeader->biClrUsed = 0;
    m_lpVehicleBitmapHeader->biCompression = 0;
    m_lpVehicleBitmapHeader->biHeight = dwImageHeight;
    m_lpVehicleBitmapHeader->biPlanes = 1;
    m_lpVehicleBitmapHeader->biSize = 40;
    m_lpVehicleBitmapHeader->biSizeImage = dwImageByte;
    m_lpVehicleBitmapHeader->biWidth = dwImageWidth;
    m_lpVehicleBitmapHeader->biXPelsPerMeter = 0;
    m_lpVehicleBitmapHeader->biYPelsPerMeter = 0;
 
 // CreateCompatibleDC 创建一个与特定设备场景一致的内存设备场景
 // 返回值:执行成功返回新设备场景句柄,若出错则为零
 // 注意点:不再需要时,该设备场景可用DeleteDC函数删除。
    m_hMemDC = CreateCompatibleDC((HDC)hDC);           //用DeleteDC删除句柄
 if (m_hMemDC == 0)
 {
  iRetval = iRetval & 0xFE; // 1111 1110
 }

 //hMemDC = CreateDC("DISPLAY",NULL,NULL, NULL);  //用DeleteDC删除句柄
 //HDC hMemDC = GetDC(0);                         //用ReleaseDC释放句柄

 
 // CreateDIBSection 创建一个DIBSection,这是一个GDI对象,可象一幅与设备有关位图那样使用。但是,它在内部作为一幅与设备无关位图保存。
 // 返回值:执行成功返回DIBSection位图的句柄,零表示失败。
 // 注意点:一旦不再需要,记住用DeleteObject函数删除DIBSection位图。
 
 m_hBmp = CreateDIBSection(m_hMemDC,
                      (BITMAPINFO*)m_lpVehicleBitmapHeader,
       DIB_RGB_COLORS,
       (LPVOID*)&m_lpMemImage,
       NULL,
                         0);
 
 //hBmp = CreateCompatibleBitmap(hMemDC,lpVehicleBitmapHeader->biWidth,lpVehicleBitmapHeader->biHeight);
 if (m_hBmp == 0)
 {
  iRetval = iRetval & 0xFD; // 1111 1101
 }
 
 //SelectObject 每个设备场景都可能有选入其中的图形对象。其中包括位图、刷子、字体、画笔以及区域等等。
 //             一次选入设备场景的只能有一个对象。选定的对象会在设备场景的绘图操作中使用。
 //             例如,当前选定的画笔决定了在设备场景中描绘的线段颜色及样式
    //返回值:与以前选入设备场景的相同hObject类型的一个对象的句柄,零表示出错。
 m_hBmpOld = (HBITMAP)SelectObject(m_hMemDC, m_hBmp);
 
 //CreateFont 用指定的属性创建一种逻辑字体
    //返回值:执行成功则返回逻辑字体的句柄,零表示失败。
 if (dwFontBold > 0) //创建粗体的字符
 {
  m_hFont = CreateFont(iFontSize,0,0,0,FW_BOLD,dwFontItalic,dwFontUnderline,dwFontStrikeOut,DEFAULT_CHARSET,0,0,0,0,lpszFontName);
 }
 else
 {
  m_hFont = CreateFont(iFontSize,0,0,0,FW_THIN,dwFontItalic,dwFontUnderline,dwFontStrikeOut,DEFAULT_CHARSET,0,0,0,0,lpszFontName);
 }
 if (m_hFont == 0)
 {
  iRetval = iRetval & 0xFB; // 1111 1011
 }

 m_hFontOld = (HFONT)SelectObject(m_hMemDC, m_hFont);
 
 //SetBkMode 指定阴影刷子、虚线画笔以及字符中的空隙的填充方式
    //返回值:文本色的前一个RGB颜色设定。CLR_INVALID表示失败。
    SetBkMode(m_hMemDC, TRANSPARENT); //TRANSPARENT 表示透明处理,即不作上述填充
                                 //OPAQUE 表示用当前的背景色填充虚线画笔、阴影刷子以及字符的空隙 

 //SetTextColor 设置当前文本颜色。这种颜色也称为“前景色”
    //返回值:文本色的前一个RGB颜色设定。CLR_INVALID表示失败。
 SetTextColor(m_hMemDC, RGB(btForeColorR, btForeColorG, btForeColorB));
   
 //如果初始化成功,那么返回值0
 if (iRetval == 0xFF)
 {
  iRetval = 0;
  m_bPermitAddCharToImage = true;
 }
 
 return (iRetval);
}


extern "C" int PASCAL EXPORT PSAFreeCharToImageEnd()
{
 AFX_MANAGE_STATE(AfxGetStaticModuleState());
 
 int          iRetval     = 0xFF; 

 SelectObject(m_hMemDC,m_hFontOld);
 
 SelectObject(m_hMemDC, m_hBmpOld);
 
 //DeleteObject 用这个函数删除GDI对象,比如画笔、刷子、字体、位图、区域以及调色板等等。
 //对象使用的所有系统资源都会被释放
    //返回值:非零表示成功,零表示失败。
 DeleteObject(m_hBmp);
 
 DeleteObject(m_hBmpOld);

 DeleteObject(m_hFont);

 DeleteObject(m_hFontOld);

 //DeleteObject(hMemBmp);

 DeleteDC(m_hMemDC);
 
 if (m_lpMemImage != NULL)
 {
  delete[] m_lpMemImage;
  m_lpMemImage = NULL;
 }

 if (m_lpVehicleBitmapHeader != NULL)
 {
  delete[] m_lpVehicleBitmapHeader;
  m_lpVehicleBitmapHeader = NULL;
 }
 
 //如果终止成功,那么返回值置0
 if (iRetval == 0xFF)
 {
  iRetval = 0;
 }
 
 m_bPermitAddCharToImage = false;

 return (iRetval);
}


extern "C" int PASCAL EXPORT PSAFreeCharToImage(LPBYTE  lpImage,
                                                LPBYTE  lpImageDst,
               LPCTSTR lpszLineFirstString,
               LPCTSTR lpszLineSecondString,
               LPCTSTR lpszLineThirdString,
            DWORD   dwLineFirstStartPosX,
            DWORD   dwLineFirstStartPosY,
            DWORD   dwLineSecondStartPosX,
            DWORD   dwLineSecondStartPosY,
            DWORD   dwLineThirdStartPosX,
            DWORD   dwLineThirdStartPosY)
{
 AFX_MANAGE_STATE(AfxGetStaticModuleState());
 
 if (!m_bPermitAddCharToImage)
 {
  return -1;
 }

 int          iTmp        = 0;
 int          iStringLen  = 0;
 int          iRetval     = 0xFF; 
 
 //SetDIBits 函数将来自与设备无关位图的二进制位复制到一幅与设备有关的位图里
    //返回值:非零表示成功,零表示失败。
 iTmp = SetDIBits(m_hMemDC,
               m_hBmp,
            0,
            m_lpVehicleBitmapHeader->biHeight,
            (LPVOID)lpImage,
            (BITMAPINFO*)m_lpVehicleBitmapHeader,
            DIB_RGB_COLORS);
 if (iTmp == 0)
 {
  iRetval = iRetval & 0xFE; // 1111 1110
 }

 //TextOut 文本绘图函数。
    //返回值:非零表示成功,零表示失败。
 iStringLen = lstrlen(lpszLineFirstString);
 if (iStringLen > 0)
 {
  TextOut(m_hMemDC, dwLineFirstStartPosX, dwLineFirstStartPosY, lpszLineFirstString, iStringLen);
 }
 
 iStringLen = lstrlen(lpszLineSecondString);
 if (iStringLen > 0)
 {
  TextOut(m_hMemDC, dwLineSecondStartPosX, dwLineSecondStartPosY, lpszLineSecondString, iStringLen);
 }

 iStringLen = lstrlen(lpszLineThirdString);
 if (iStringLen > 0)
 {
  TextOut(m_hMemDC, dwLineThirdStartPosX, dwLineThirdStartPosY, lpszLineThirdString, iStringLen);
 }
 
 //BYTE *pTemp = new BYTE[dwImageByte];
 //ZeroMemory(pTemp, dwImageByte);

 //GetDIBits 函数将来自一幅位图的二进制位复制到一幅与设备无关的位图里
    //返回值:非零表示成功,零表示失败。
 iTmp = GetDIBits(m_hMemDC,
               m_hBmp,
        0,
      m_lpVehicleBitmapHeader->biHeight,
               (LPVOID)lpImageDst,
      (BITMAPINFO*)m_lpVehicleBitmapHeader,
      DIB_RGB_COLORS);
 //iTmp = GetBitmapBits(hBmp, dwImageByte,(LPVOID)lpImageDst);
 if (iTmp == 0)
 {
  iRetval = iRetval & 0xFD; // 1111 1101
 }
   
 //如果字符叠加成功,那么返回值置0
 if (iRetval == 0xFF)
 {
  iRetval = 0;
 }

 return (iRetval);
}


extern "C" int PASCAL EXPORT PSACompressRawBufferToJpeg422File(
        BYTE* lpRawImageBuffer,
        int   originalWidth,
        int   originalHeight,
        int   jpegQuality,
        char* jpegFileName,
        int   isNeedReversal,
        int   isResizeImage)
{
 AFX_MANAGE_STATE(AfxGetStaticModuleState());

 int res = 0;
 int jpegImageWidth;
 int jpegImageHeight;
 IJLERR jerr;
 JPEG_CORE_PROPERTIES jcprops;
 
 jerr = ijlInit(&jcprops);
 if (jerr != IJL_OK)
    {
  res = 1;
  goto Exit;
    }
 
 if (isResizeImage == 0) //保持原始比例
 {
  jpegImageWidth = originalWidth;
  jpegImageHeight = originalHeight;
 }
// else if (isResizeImage == 112) //宽度变为1/2,高度不变
// {
//  jpegImageWidth = originalWidth/2;
//  jpegImageHeight = originalHeight;
// }
 else //保持原始比例
 {
  jpegImageWidth = originalWidth;
  jpegImageHeight = originalHeight;
 }

 jcprops.DIBWidth         = originalWidth;
 if (isNeedReversal == 0) //如果不需要翻转图片
 {
  jcprops.DIBHeight        = originalHeight;
 }
 else                     //如果需要翻转图片
 {
  jcprops.DIBHeight        = -originalHeight;
 }
 jcprops.DIBChannels      = 3;
 jcprops.DIBBytes         = lpRawImageBuffer;
 jcprops.DIBPadBytes      = 0;
 jcprops.DIBColor         = IJL_YCBCR;
 jcprops.DIBSubsampling   = IJL_422;

 jcprops.JPGFile          = jpegFileName;
 jcprops.JPGWidth         = jpegImageWidth;
 jcprops.JPGHeight        = jpegImageHeight;
 jcprops.JPGChannels      = 3;
 jcprops.JPGColor         = IJL_YCBCR;
 jcprops.JPGSubsampling   = IJL_422;
 jcprops.jquality         = jpegQuality;

 jerr = ijlWrite(&jcprops,IJL_JFILE_WRITEWHOLEIMAGE);
 if(IJL_OK != jerr)
 {
  //printf("ijlInit() failed - %s/n",ijlErrorStr(jerr));
  res = 2;
  goto Exit;
 }

Exit:
 jerr = ijlFree(&jcprops);
 if(IJL_OK != jerr)
 {
  //printf("ijlFree() failed - %s/n",ijlErrorStr(jerr));
  res = 3;
 }

 return res;
} // PSACompressRawBufferToJpeg422File


extern "C" int PASCAL EXPORT PSARawToJpeg411Sample(
        BYTE* lpRawImageBuffer,
        int   originalWidth,
        int   originalHeight,
        int   jpegQuality,
        char* jpegFileName,
        int   isNeedReversal,
        int   isResizeImage)
{
 AFX_MANAGE_STATE(AfxGetStaticModuleState());
 
 int res = 0;
 BYTE* lpRGBImageBuffer;
 int rgbWidth;
 int rgbHeight;

 // 行长折半压缩为Jpeg文件
 rgbWidth = originalWidth / 2;
 rgbHeight = originalHeight;
 lpRGBImageBuffer = new BYTE[rgbWidth * rgbHeight * 3];

 ConvertYUVtoRGBSample(lpRawImageBuffer,lpRGBImageBuffer,originalWidth,originalHeight);
 
 //比例不变压缩为Jpeg文件

 res = CompressRGBToJPEG(lpRGBImageBuffer,
                      rgbWidth,
       rgbHeight,
       jpegQuality,
       jpegFileName,
       isNeedReversal,
       isResizeImage);

 if (lpRGBImageBuffer != NULL)
 {
  delete[] lpRGBImageBuffer;
  lpRGBImageBuffer = NULL;
 }

 return (res);
}


extern "C" int PASCAL EXPORT PSARawToJpeg411SampleAddChar(
        BYTE* lpRawImageBuffer,
        int   originalWidth,
        int   originalHeight,
        int   jpegQuality,
        char* jpegFileName,
        int   isNeedReversal,
        int   isResizeImage,
        LPCTSTR lpszLineFirstString,
        LPCTSTR lpszLineSecondString,
        LPCTSTR lpszLineThirdString,
        DWORD   dwLineFirstStartPosX,
        DWORD   dwLineFirstStartPosY,
        DWORD   dwLineSecondStartPosX,
        DWORD   dwLineSecondStartPosY,
        DWORD   dwLineThirdStartPosX,
        DWORD   dwLineThirdStartPosY)
{
 AFX_MANAGE_STATE(AfxGetStaticModuleState());

 int res = 0;
 BYTE* lpRGBImageBuffer;
 int rgbWidth;
 int rgbHeight;
 BYTE* lpRGBImageBufferAddChar;
 DWORD dwRGBImageSize = 0;

 // 行长折半压缩为Jpeg文件
 rgbWidth = originalWidth / 2;
 rgbHeight = originalHeight;

 dwRGBImageSize = rgbWidth * rgbHeight * 3;
 lpRGBImageBufferAddChar = new BYTE[dwRGBImageSize];
 lpRGBImageBuffer = new BYTE[dwRGBImageSize];
 
 // 图像数据格式从YUV转化为RGB,并且进行列抽样压缩(1/2)
 // ConvertYUVtoRGBSample(lpRawImageBuffer,lpRGBImageBuffer,originalWidth,originalHeight);

 ConvertYUVtoRGBSampleReverse(
  lpRawImageBuffer,
  lpRGBImageBuffer,
  originalWidth,
  originalHeight);
 
 res = PSAFreeCharToImage(lpRGBImageBuffer,
                       lpRGBImageBufferAddChar,
        lpszLineFirstString,
        lpszLineSecondString,
        lpszLineThirdString,
        dwLineFirstStartPosX,
        dwLineFirstStartPosY,
        dwLineSecondStartPosX,
        dwLineSecondStartPosY,
        dwLineThirdStartPosX,
        dwLineThirdStartPosY);

 if (res == 0) // 如果字符叠加成功
 {
  res = CompressRGBToJPEG(lpRGBImageBufferAddChar,
        rgbWidth,
        rgbHeight,
        jpegQuality,
        jpegFileName,
        isNeedReversal,
        isResizeImage);
 }
 else
 {
  res = CompressRGBToJPEG(lpRGBImageBuffer,
        rgbWidth,
        rgbHeight,
        jpegQuality,
        jpegFileName,
        isNeedReversal,
        isResizeImage);
 }

 if (lpRGBImageBuffer != NULL) // 释放内存:无字符叠加RGB数据
 {
  delete[] lpRGBImageBuffer;
  lpRGBImageBuffer = NULL;
 }
 
 if (lpRGBImageBufferAddChar != NULL) // 释放内存:有字符叠加RGB数据
 {
  delete[] lpRGBImageBufferAddChar;
  lpRGBImageBufferAddChar = NULL;
 }

 return (res);
}


extern "C" int PASCAL EXPORT PSARawToJpeg411Special(
        BYTE* lpRawImageBuffer,
        int   originalWidth,
        int   originalHeight,
        int   jpegQuality,
        char* jpegFileName,
        int   isNeedReversal,
        int   isResizeImage)
{
 AFX_MANAGE_STATE(AfxGetStaticModuleState());
 
 int res = 0;
 BYTE* lpRGBImageBuffer;
 int rgbWidth;
 int rgbHeight;
 
 //宽度由720转化为768 高度不变
 rgbWidth = 768;
 rgbHeight = originalHeight * 2;
 lpRGBImageBuffer = new BYTE[rgbWidth * rgbHeight * 3];

 // ConvertYUV720toRGB768(lpRawImageBuffer,lpRGBImageBuffer,originalWidth,originalHeight);

 ConvertYUV720toRGB768TwoHeight(
  lpRawImageBuffer,
  lpRGBImageBuffer,
  originalWidth,
  originalHeight);

 res = CompressRGBToJPEG(lpRGBImageBuffer,
                      rgbWidth,
       rgbHeight,
       jpegQuality,
       jpegFileName,
       isNeedReversal,
       isResizeImage);

 if (lpRGBImageBuffer != NULL)
 {
  delete[] lpRGBImageBuffer;
  lpRGBImageBuffer = NULL;
 }

 return (res);
}


extern "C" int PASCAL EXPORT PSARawToJpeg411SpecialAddChar(
        BYTE* lpRawImageBuffer,
        int   originalWidth,
        int   originalHeight,
        int   jpegQuality,
        char* jpegFileName,
        int   isNeedReversal,
        int   isResizeImage,
        LPCTSTR lpszLineFirstString,
        LPCTSTR lpszLineSecondString,
        LPCTSTR lpszLineThirdString,
        DWORD   dwLineFirstStartPosX,
        DWORD   dwLineFirstStartPosY,
        DWORD   dwLineSecondStartPosX,
        DWORD   dwLineSecondStartPosY,
        DWORD   dwLineThirdStartPosX,
        DWORD   dwLineThirdStartPosY)
{
 AFX_MANAGE_STATE(AfxGetStaticModuleState());
 
 int res = 0;
 BYTE* lpRGBImageBuffer;
 int rgbWidth;
 int rgbHeight;
 BYTE* lpRGBImageBufferAddChar;
 DWORD dwRGBImageSize = 0;
 
 //宽度由720转化为768 高度不变
 rgbWidth  = 768;
 rgbHeight = originalHeight * 2;

 dwRGBImageSize = rgbWidth * rgbHeight * 3;
 lpRGBImageBufferAddChar = new BYTE[dwRGBImageSize];
 lpRGBImageBuffer = new BYTE[dwRGBImageSize];
 
 // 图像数据格式从YUV转化为RGB,并且进行列抽样压缩(1/2)
 // ConvertYUV720toRGB768(lpRawImageBuffer,lpRGBImageBuffer,originalWidth,originalHeight);
 
 // 无翻转图像保存为 768 * 576
 
 
 // 翻转图像保存为 768 * 576
 ConvertYUV720toRGB768TwoHeightReverse(
  lpRawImageBuffer,
  lpRGBImageBuffer,
  originalWidth,
  originalHeight);

 // 叠加字符
 res = PSAFreeCharToImage(lpRGBImageBuffer,
                       lpRGBImageBufferAddChar,
        lpszLineFirstString,
        lpszLineSecondString,
        lpszLineThirdString,
        dwLineFirstStartPosX,
        dwLineFirstStartPosY,
        dwLineSecondStartPosX,
        dwLineSecondStartPosY,
        dwLineThirdStartPosX,
        dwLineThirdStartPosY);

 if (res == 0) // 如果字符叠加成功 保存叠加字符后图片数据
 {
  res = CompressRGBToJPEG(lpRGBImageBufferAddChar,
        rgbWidth,
        rgbHeight,
        jpegQuality,
        jpegFileName,
        isNeedReversal,
        isResizeImage);
 }
 else // 如果字符叠加失败 保存叠加字符前图片数据
 {
  res = CompressRGBToJPEG(lpRGBImageBuffer,
        rgbWidth,
        rgbHeight,
        jpegQuality,
        jpegFileName,
        isNeedReversal,
        isResizeImage);
 }

 if (lpRGBImageBuffer != NULL) // 释放内存:无字符叠加RGB数据
 {
  delete[] lpRGBImageBuffer;
  lpRGBImageBuffer = NULL;
 }
 
 if (lpRGBImageBufferAddChar != NULL) // 释放内存:有字符叠加RGB数据
 {
  delete[] lpRGBImageBufferAddChar;
  lpRGBImageBufferAddChar = NULL;
 }

 return (res);
}


extern "C" int PASCAL EXPORT PSAReadRawFileToBuffer(
        char* lpszRawFile,
        int   &imageWidth,
        int   &imageHeight,
        BYTE *lpRawImageBuffer
        )
{
 AFX_MANAGE_STATE(AfxGetStaticModuleState());

 int res = 0;

 CFile   rawFile;
 CString strRawFile;
 CFileException e;

 short int width;
 short int height;
 int       rawImageSize;
 BYTE*     imageBuffer;
 int       fileLength;
 
 strRawFile.Format("%s",lpszRawFile);
 strRawFile.MakeLower();

 int iFind = strRawFile.ReverseFind( '.' );
 if (iFind == -1)
 {
  res = 1;
  return res;
 }
 
 iFind = strRawFile.Find("raw");
 if (iFind == -1)
 {
  res = 2;
  return res;
 }

 if (rawFile.Open(strRawFile, CFile::modeRead, &e) == NULL)
 {
  res = 3;
  return res;
 }

 rawFile.SeekToBegin();
 rawFile.Read(&width, 2);
 rawFile.Read(&height, 2);

 rawImageSize = width * height * 2 + 4;

 fileLength = rawFile.GetLength();

 if (rawImageSize != fileLength)
 {
  rawFile.Close();
  res = 4;
  return res;
 }

 imageBuffer  = new unsigned char[rawImageSize];
 imageWidth   = width;
 imageHeight  = height;
 
 rawFile.SeekToBegin();
 if (rawFile.Read(imageBuffer, rawImageSize) != (unsigned int)rawImageSize)
 {
  if (imageBuffer != NULL)
  {
   delete[] imageBuffer;
   imageBuffer = NULL;
  }
  rawFile.Close();
  res = 5;
  return res;
 }
 
 memcpy(lpRawImageBuffer, imageBuffer+4, rawImageSize-4);
 if (imageBuffer != NULL)
 {
  delete[] imageBuffer;
  imageBuffer = NULL;
 }
 rawFile.Close();

 return res;
}


extern "C" int PASCAL EXPORT PSAReadRaw768To720(
        char* lpszRawFile,
        int   &imageWidth,
        int   &imageHeight,
        BYTE *lpRawImageBuffer
        )
{
 AFX_MANAGE_STATE(AfxGetStaticModuleState());

 int res = 0;

 CFile   rawFile;
 CString strRawFile;
 CFileException e;

 short int width;
 short int height;
 int       rawImageSize;
 BYTE*     imageBuffer;
 BYTE*     imageTmp;
 BYTE*     imageDst;
 int       fileLength;
 int       nRowLength;
 
 strRawFile.Format("%s",lpszRawFile);
 strRawFile.MakeLower();

 int iFind = strRawFile.ReverseFind( '.' );
 if (iFind == -1)
 {
  res = 1;
  return res;
 }
 
 iFind = strRawFile.Find("raw");
 if (iFind == -1)
 {
  res = 2;
  return res;
 }

 if (rawFile.Open(strRawFile, CFile::modeRead, &e) == NULL)
 {
  res = 3;
  return res;
 }

 rawFile.SeekToBegin();
 rawFile.Read(&width, 2);
 rawFile.Read(&height, 2);

 rawImageSize = width * height * 2 + 4;

 fileLength = rawFile.GetLength();

 if (rawImageSize != fileLength)
 {
  rawFile.Close();
  res = 4;
  return res;
 }

 imageBuffer  = new unsigned char[rawImageSize];
 imageWidth   = width;
 imageHeight  = height;
 
 rawFile.SeekToBegin();
 if (rawFile.Read(imageBuffer, rawImageSize) != (unsigned int)rawImageSize)
 {
  if (imageBuffer != NULL)
  {
   delete[] imageBuffer;
   imageBuffer = NULL;
  }
  rawFile.Close();
  res = 5;
  return res;
 }
 
 //memcpy(lpRawImageBuffer, imageBuffer+4, rawImageSize-4);
 imageTmp = imageBuffer + 4;
 imageDst = lpRawImageBuffer;

 if (width == 768)
 {
  imageWidth = 720;
 
  nRowLength = 0;
  for (int i=0; i< height; i++)
  {
   memcpy(imageDst, imageTmp, 1440);
   imageDst += 1440;
   imageTmp += 1536;
  }
 }
 else
 {
  memcpy(imageDst, imageTmp, rawImageSize-4);
 }

 if (imageBuffer != NULL)
 {
  delete[] imageBuffer;
  imageBuffer = NULL;
 }
 rawFile.Close();

 return res;
}


extern "C" int PASCAL EXPORT PSAReadRaw768To720HalfHeight(
        char* lpszRawFile,
        int   &imageWidth,
        int   &imageHeight,
        BYTE *lpRawImageBuffer
        )
{
 AFX_MANAGE_STATE(AfxGetStaticModuleState());

 int res = 0;

 CFile   rawFile;
 CString strRawFile;
 CFileException e;

 short int width;
 short int height;
 int       rawImageSize;
 BYTE*     imageBuffer;
 BYTE*     imageTmp;
 BYTE*     imageDst;
 int       fileLength;
 int       nRowLength;
 
 strRawFile.Format("%s",lpszRawFile);
 strRawFile.MakeLower();

 int iFind = strRawFile.ReverseFind( '.' );
 if (iFind == -1)
 {
  res = 1;
  return res;
 }
 
 iFind = strRawFile.Find("raw");
 if (iFind == -1)
 {
  res = 2;
  return res;
 }

 if (rawFile.Open(strRawFile, CFile::modeRead, &e) == NULL)
 {
  res = 3;
  return res;
 }

 rawFile.SeekToBegin();
 rawFile.Read(&width, 2);
 rawFile.Read(&height, 2);

 rawImageSize = width * height * 2 + 4;

 fileLength = rawFile.GetLength();

 if (rawImageSize != fileLength)
 {
  rawFile.Close();
  res = 4;
  return res;
 }

 imageBuffer  = new unsigned char[rawImageSize];
 imageWidth   = width;
 imageHeight  = height;
 
 rawFile.SeekToBegin();
 if (rawFile.Read(imageBuffer, rawImageSize) != (unsigned int)rawImageSize)
 {
  if (imageBuffer != NULL)
  {
   delete[] imageBuffer;
   imageBuffer = NULL;
  }
  rawFile.Close();
  res = 5;
  return res;
 }
 
 //memcpy(lpRawImageBuffer, imageBuffer+4, rawImageSize-4);
 imageTmp = imageBuffer + 4;
 imageDst = lpRawImageBuffer;

 if (width == 768)
 {
  imageWidth   = 720;
  imageHeight  = height / 2;

  nRowLength = 0;

  imageTmp += 768 * 2 * (height / 2); // 复制下半幅图,如果复制上半幅图则注释掉此句

  for (int i=0; i< (height / 2); i++)
  {
   memcpy(imageDst, imageTmp, 1440);
   imageDst += 1440;
   imageTmp += 1536;
  }
 }
 else
 {
  memcpy(imageDst, imageTmp, ((rawImageSize - 4) / 2));
 }

 if (imageBuffer != NULL)
 {
  delete[] imageBuffer;
  imageBuffer = NULL;
 }
 rawFile.Close();

 return res;
}


extern "C" int PASCAL EXPORT PSAWriteRawFile(
        const char* lpszRawFile,
        int   imageWidth,
        int   imageHeight,
        BYTE *lpRawImageBuffer
        )
{
 AFX_MANAGE_STATE(AfxGetStaticModuleState());

 int res = 0;
 unsigned long ulRawImageSize;
 BYTE btHeader[4];
 WORD* lpWordHeader;
 FILE* fileWrite;

 fileWrite = fopen(lpszRawFile,"wb");
 if (fileWrite == NULL)
 {
  res = 1;
  goto Exit;
 }
 
 lpWordHeader = (WORD *)btHeader;
 lpWordHeader[0] = (WORD)imageWidth;
 lpWordHeader[1] = (WORD)imageHeight;
 
 if (fwrite(btHeader,1,4,fileWrite) != 4)
 {
  fclose(fileWrite);
  res = 2;
  goto Exit;
 }

 ulRawImageSize = imageWidth * imageHeight * 2;

 if (fwrite(lpRawImageBuffer, 1, ulRawImageSize, fileWrite) != ulRawImageSize)
 {
  fclose(fileWrite);
  res = 3;
  goto Exit;
 }
 fclose(fileWrite);
 
Exit:
 return res;
}


extern "C" int PASCAL EXPORT PSAWriteBMPFile(
        LPCSTR lpszBMPFile,
        int  imageWidth,
        int  imageHeight,
        BYTE *lpRawImageBuffer
        )
{
 AFX_MANAGE_STATE(AfxGetStaticModuleState());

 int   res = 0;
 FILE* fileWrite;
 
 BYTE*            lpRGBImageBuffer;
 BITMAPFILEHEADER bmFileHeader;
 BITMAPINFO       bmInfo;
 DWORD            dwRGBImageSize = imageWidth * imageHeight * 3;
 BYTE             lpFileHeader[128];
 int              ibmFileHeaderSize;             
 
 bmFileHeader.bfType = 0x4D42;
 bmFileHeader.bfSize = 54 + dwRGBImageSize;
 bmFileHeader.bfOffBits = 54;
 bmFileHeader.bfReserved1 = 0;
 bmFileHeader.bfReserved2 = 0;
 
 bmInfo.bmiHeader.biBitCount      = 24;
    bmInfo.bmiHeader.biClrImportant  = 0;
    bmInfo.bmiHeader.biClrUsed       = 0;
    bmInfo.bmiHeader.biCompression   = 0;
    bmInfo.bmiHeader.biHeight        = imageHeight;
    bmInfo.bmiHeader.biPlanes        = 1;
    bmInfo.bmiHeader.biSize          = 40;
    bmInfo.bmiHeader.biSizeImage     = dwRGBImageSize;
    bmInfo.bmiHeader.biWidth         = imageWidth;
 bmInfo.bmiHeader.biXPelsPerMeter = 0;
    bmInfo.bmiHeader.biYPelsPerMeter = 0;
 
 lpRGBImageBuffer = new BYTE[dwRGBImageSize];

 ConvertYUVtoRGB(lpRawImageBuffer,lpRGBImageBuffer,imageWidth,imageHeight);

 fileWrite = fopen(lpszBMPFile,"wb");
 if (fileWrite == NULL)
 {
  res = 1;
  goto Exit;
 }
 
 ibmFileHeaderSize = sizeof(BITMAPFILEHEADER);
 memcpy(lpFileHeader,&bmFileHeader,ibmFileHeaderSize);
 memcpy(&lpFileHeader[ibmFileHeaderSize],&bmInfo.bmiHeader,sizeof(BITMAPINFOHEADER));
 
 if (fwrite(lpFileHeader,sizeof(BYTE),54,fileWrite) != 54)
 {
  fclose(fileWrite);
  res = 5;
  goto Exit;
 }

 

 if (fwrite(lpRGBImageBuffer, sizeof(BYTE), dwRGBImageSize, fileWrite) != dwRGBImageSize)
 {
  fclose(fileWrite);
  res = 4;
  goto Exit;
 }

Exit:
 if (res != 1)
 {
  fclose(fileWrite);
 }
 if (lpRGBImageBuffer != NULL)
 {
  delete[] lpRGBImageBuffer;
  lpRGBImageBuffer = NULL;
 }

 return res;
}


extern "C" int PASCAL EXPORT PSATryGetFileVersion(
        LPTSTR lpszFileName,
        DWORD* iMajor,
        DWORD* iMinor,
        DWORD* iRelease,
        DWORD* iBuild
        )
{
 AFX_MANAGE_STATE(AfxGetStaticModuleState());
 
 int               iVersionInfoSize = 0;
 BYTE*             lpVersionDataBuffer;
 int               retval = 0;
 int               res    = -999;
 BYTE*             lplpVersion;
 VS_FIXEDFILEINFO* version;
    DWORD             dwVersionSize;
  
 if (lpszFileName == NULL)
 {
  return(res);
 }

 iVersionInfoSize = GetFileVersionInfoSize(lpszFileName,0);
 if (iVersionInfoSize > 0)
 {
  lpVersionDataBuffer = new BYTE[iVersionInfoSize];
  retval = GetFileVersionInfo(lpszFileName,0,iVersionInfoSize,lpVersionDataBuffer);
  if (retval != 0)
  {
   retval = VerQueryValue(lpVersionDataBuffer,"/",(void**)&lplpVersion,(unsignedint*)&dwVersionSize);
   if (retval != 0)
   {
    version = (VS_FIXEDFILEINFO*)lplpVersion;
    *iMajor = version->dwFileVersionMS >> 16;
    *iMinor = version->dwFileVersionMS & 0xFFFF;
    *iRelease = version->dwFileVersionLS >> 16;
    *iBuild   = version->dwFileVersionLS & 0xFFFF;
    res = 0;
   }
   else
   {
    res = -3;
   }
  }
  else
  {
   res = -2;
  }
  if (lpVersionDataBuffer != NULL)
  {
   delete[] lpVersionDataBuffer;
   lpVersionDataBuffer = NULL;
  }
 }
 else
 {
  res = -1;
 }

 return(res);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值