<menu id="w8yyk"><menu id="w8yyk"></menu></menu>
  • <dd id="w8yyk"><nav id="w8yyk"></nav></dd>
    <menu id="w8yyk"></menu>
    <menu id="w8yyk"><code id="w8yyk"></code></menu>
    <menu id="w8yyk"></menu>
    <xmp id="w8yyk">
    <xmp id="w8yyk"><nav id="w8yyk"></nav>
  • 網站首頁 > 物聯資訊 > 技術分享

    RGB圖像數據字符疊加,圖像壓縮(ijl庫),YUV轉RGB

    2016-09-28 00:00:00 廣州睿豐德信息科技有限公司 閱讀
    睿豐德科技 專注RFID識別技術和條碼識別技術與管理軟件的集成項目。質量追溯系統、MES系統、金蝶與條碼系統對接、用友與條碼系統對接 jackyhwei 發布于 2010-01-01 12:02 點擊:3218次  RFID設備管理軟件 來自:CSDN.NET 一些非常有用的圖像格式轉換及使用的源代碼,包括RGB圖像數據字符疊加,圖像壓縮(ijl庫),YUV轉RGB等等。 TAG: YUV  YUV轉RGB  RGB  BMP轉JPG  文字疊加    

    /**************************************
    File: yuvrgb24.h
    Description: header file for yuvrgb24.c
    Date: Nov. 4, 2002
    *****************************************/

    #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

    /************************************************************************
     *
     *  yuvrgb24.c, colour space conversion for tmndecode (H.263 decoder)
     *  Copyright (C) 1996  Telenor R&D, Norway
     *        Karl Olav Lillevold <Karl.Lillevold@nta.no>
     ************************************************************************/

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

    /* Data for ConvertYUVtoRGB*/
    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;  /* fra matrise i global.h */
     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 );
    }
                
    /**********************************************************************
     *
     * Name:          ConvertYUVtoRGB 
     * Description:     Converts YUV image to RGB (packed mode)
     * 
     * Input:          pointer to source luma, Cr, Cb, destination,
     *                       image width and height
     * Returns:       
     * Side effects:
     *
     * Date: 951208 Author: Karl.Lillevold@nta.no
     *
     ***********************************************************************/

    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]; /* (255/219)*65536 */
       py += 2;
       y12 = tab_76309[*py];
       py += 2;

       y13 = tab_76309[*py]; /* (255/219)*65536 */
       py += 2;
       y14 = tab_76309[*py];
       py += 2;

       /* RGBR*/
       //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;

       /* GBRG*/
       //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;

       /* BRGB*/
       /*DW = ((clp[(y13 + c12)>>16])) |  
        ((clp[(y14 + c42)>>16])<<8) |
        ((clp[(y14 - c22 - c32)>>16])<<16) |
        ((clp[(y14 + c12)>>16])<<24);  
          */
       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]; /* (255/219)*65536 */
       py += 4;
       y12 = tab_76309[*py];
       py += 4;

       y13 = tab_76309[*py]; /* (255/219)*65536 */
       py += 4;
       y14 = tab_76309[*py];
       py += 4;

       /* RGBR*/
       //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;

       /* GBRG*/
       //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;

       /* BRGB*/
       /*DW = ((clp[(y13 + c12)>>16])) |  
          ((clp[(y14 + c42)>>16])<<8) |
          ((clp[(y14 - c22 - c32)>>16])<<16) |
          ((clp[(y14 + c12)>>16])<<24);  
          */
       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]; /* (255/219)*65536 */
       py += 4;
       y12 = tab_76309[*py];
       py += 4;

       y13 = tab_76309[*py]; /* (255/219)*65536 */
       py += 4;
       y14 = tab_76309[*py];
       py += 4;

       /* RGBR*/
       //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;

       /* GBRG*/
       //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;

       /* BRGB*/
       /*DW = ((clp[(y13 + c12)>>16])) |  
          ((clp[(y14 + c42)>>16])<<8) |
          ((clp[(y14 - c22 - c32)>>16])<<16) |
          ((clp[(y14 + c12)>>16])<<24);  
          */
       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]; /* (255/219)*65536 */
       py += 2;
       y12 = tab_76309[*py];
       py += 2;

       y13 = tab_76309[*py]; /* (255/219)*65536 */
       py += 2;
       y14 = tab_76309[*py];
       py += 2;

       /* RGBR*/
       //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;

       /* GBRG*/
       //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;

       /* BRGB*/
       /*DW = ((clp[(y13 + c12)>>16])) |  
        ((clp[(y14 + c42)>>16])<<8) |
        ((clp[(y14 - c22 - c32)>>16])<<16) |
        ((clp[(y14 + c12)>>16])<<24);  
          */
       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%16) == 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]; /* (255/219)*65536 */
       py += 2;
       y12 = tab_76309[*py];
       py += 2;

       y13 = tab_76309[*py]; /* (255/219)*65536 */
       py += 2;
       y14 = tab_76309[*py];
       py += 2;

       /* RGBR*/
       //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;

       /* GBRG*/
       //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;

       /* BRGB*/
       /*DW = ((clp[(y13 + c12)>>16])) |  
        ((clp[(y14 + c42)>>16])<<8) |
        ((clp[(y14 - c22 - c32)>>16])<<16) |
        ((clp[(y14 + c12)>>16])<<24);  
          */
       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%16) == 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]; /* (255/219)*65536 */
       py += 2;
       y12 = tab_76309[*py];
       py += 2;

       y13 = tab_76309[*py]; /* (255/219)*65536 */
       py += 2;
       y14 = tab_76309[*py];
       py += 2;

       /* RGBR*/
       //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;

       /* GBRG*/
       //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;

       /* BRGB*/
       /*DW = ((clp[(y13 + c12)>>16])) |  
        ((clp[(y14 + c42)>>16])<<8) |
        ((clp[(y14 - c22 - c32)>>16])<<16) |
        ((clp[(y14 + c12)>>16])<<24);  
          */
       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%16) == 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;

    /************************************************************************
    Function WriteToLog:
            往當前目錄下日志文件寫入信息
    Input:
            int iErrorNumber   錯誤號
      TCHAR *szMsg       寫入的具體信息
    return:
            成功返回0值,異常返回其它整數;
    Update:
      Author         Date              Ver      Remark  
      Shimingjie     2005/01/06        1.0      Create         
    ************************************************************************/
    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: %04d-%02d-%02d %02d:%02d:%02d:%03d\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,"%04d-%02d-%02d %02d:%02d:%02d:%03d  Event:%06d  %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,"%04d-%02d-%02d %02d:%02d:%02d:%03d  Event:%06d  %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,"%04d-%02d-%02d %02d:%02d:%02d:%03d  Event:%06d  %s\n",
             lpSystemTime.wYear,lpSystemTime.wMonth,lpSystemTime.wDay,
             lpSystemTime.wHour,lpSystemTime.wMinute,lpSystemTime.wSecond,lpSystemTime.wMilliseconds,
             iErrorNumber,szMsg);
        fclose(fp);
       }
      }
     }

     /***********************************************
     if (SetCurrentDirectory(szCurPath) != 0)
     {
      printf("set current path ok...\n");
     }
     else
     {
      printf("set current path failure!\n");
     }
     ***********************************************/
     
     return (0);
    }

    /************************************************************************
    Function CompressRGBToJPEG:
            RGB圖像數據壓縮為JPEG文件保存
    Input:
            BYTE *lpImageRGB        RGB圖像數據區
         int   originalWidth     原始圖像寬度
      int   originalHeight    原始圖像高度
      int   jpegQuality       JPEG壓縮質量[1-100]
      char* jpegFileName      JPEG文件保存的名稱 
      int   isNeedReversal    是否需要翻轉
      int   isResizeImage     是否需要縮放圖像的尺寸
    return:
            成功返回0值,異常返回其它整數;
    Update:
      Author         Date              Ver      Remark  
      Shimingjie     2005/01/06        1.0      Create         
    ************************************************************************/
    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" EXPORTS Function PSAInit:
           動態庫顯式初始化預留函數
    Input:
           無
    return:
           成功返回0值;
    Update:
      Author         Date              Ver      Remark  
      Shimingjie     2005/01/06        1.0      Create    
      Shimingjie     2006/01/13        1.1      Edit
    ************************************************************************/
    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" EXPORTS Function PSAFree:
           動態庫顯式釋放資源預留函數
    Input:
           無
    return:
           成功返回0值;
    Update:
      Author         Date              Ver      Remark  
      Shimingjie     2005/01/06        1.0      Create         
    ************************************************************************/
    extern "C" int PASCAL EXPORT PSAFree()
    {
     AFX_MANAGE_STATE(AfxGetStaticModuleState());
     
     m_bPermitAddCharToImage = false;

     int res = 0;

     return (res);
    }

    /************************************************************************
    extern "C" EXPORTS Function PSAAddCharToImage:
            字符疊加在BMP圖象數據上,通過字庫點陣方式    
    Input:
            LPBYTE lpCharImage       需要進行字符疊加的圖象BMP數據指針頭
      CString strLicense       需要疊加牌照號
      CString strDateTime      需要疊加的時間日期
      CString strSpeed         需要疊加的車速
      CString strLocation      需要疊加的卡口點名稱描述
      CString strLimitSpeed    需要疊加的限速
      String strDirection      需要疊加的卡口點方向描述
      DWORD dwImgWidth         圖象寬
      DWORD dwImgHeight        圖象高
      BYTE btColorB            疊加文字的顏色RGB值中的B
      BYTE btColorG            疊加文字的顏色RGB值中的G
      BYTE btColorR            疊加文字的顏色RGB值中的R
    return:
            字符疊加無錯誤返回>=0整數,異常返回<0整數;
    Update:
      Author         Date              Ver      Remark  
      Shimingjie     2005/01/06        1.0      Create         
    ************************************************************************/
    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" EXPORTS Function PSAFreeCharToImageInit:
            初始化在內存設備場景中進行字符疊加   
    Input:
            DWORD   hDC                    設備場景(根據此設備場景建立內存設備場景)
      DWORD   dwImgWidth             圖象寬
      DWORD   dwImgHeight            圖象高
      LPCTSTR lpszFontName           疊加字符名稱
      int     iFontSize              疊加字符的大小
       DWORD   dwFontBold             是否粗體
      DWORD   dwFontItalic           是否斜體 
      DWORD   dwFontUnderline        是否加下劃線
      DWORD   dwFontStrikeOut        是否加刪除線 
      BYTE    btColorB               疊加文字的顏色RGB值中的B
      BYTE    btColorG               疊加文字的顏色RGB值中的G
      BYTE    btColorR               疊加文字的顏色RGB值中的R
    return:
            正常返回0值,非0值表示失敗;
    Update:
      Author         Date              Ver      Remark  
      Shimingjie     2005/05/17        1.0      Create  
    ************************************************************************/
    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" EXPORTS Function PSAFreeCharToImageEnd:
            釋放在內存設備場景中進行字符疊加所申請的資源   
    Input:
            
    Output:
            正常返回非0值,0值表示失敗;
    Update:
      Author         Date              Ver      Remark  
      Shimingjie     2005/05/17        1.0      Create  
    ************************************************************************/
    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" EXPORTS Function PSAFreeCharToImage:
            字符疊加在BMP圖象數據上,通過創建MemDC方式寫入   
    Input:
      LPBYTE  lpImage                需要進行字符疊加的BMP圖像數據指針
            LPCTSTR lpszLineFirstString    疊加的第一行字符
      LPCTSTR lpszLineSecondString   疊加的第二行字符
      LPCTSTR lpszLineThirdString    疊加的第三行字符
      DWORD   dwLineFirstStartPosX   第一行字符的起始X坐標
      DWORD   dwLineFirstStartPosY   第一行字符的起始Y坐標
      DWORD   dwLineSecondStartPosX  第二行字符的起始X坐標
      DWORD   dwLineSecondStartPosY  第二行字符的起始Y坐標
      DWORD   dwLineThirdStartPosX   第三行字符的起始X坐標
      DWORD   dwLineThirdStartPosY   第三行字符的起始Y坐標
    Output:
      LPBYTE  lpImageDst             疊加字符后的BMP圖像數據指針 
    return::
            正常返回0值,非0值表示失敗;
    Update:
      Author         Date              Ver      Remark  
      Shimingjie     2005/04/06        1.0      Create  
      Shimingjie     2005/04/26        1.1      Add remark/Interface Complete
      Shimingjie     2005/05/17        1.2      Change Function Mode && Parameter 
    ************************************************************************/
    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" EXPORTS Function PSACompressRawBufferToJpeg422File:
            源圖 Ycrcb格式[422] 直接壓縮為JPEG文件保存[深圳發現晚間圖像壓縮存在塊狀]
    Input:
      BYTE* lpRawImageBuffer 源圖數據區
      int   originalWidth    源圖寬度
      int   originalHeight   源圖高度
      int   jpegQuality      JPEG壓縮質量
      char* jpegFileName     JPEG保存文件名  
      int   isNeedReversal   壓縮為JPEG時是否需要翻轉
      int   isResizeImage    是否需要更改圖像大小 
    return:
            正常返回0值,非0值表示失敗;
    Update:
      Author         Date              Ver      Remark  
      Shimingjie     2005/08/18        1.0      Create  
    ************************************************************************/
    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" EXPORTS Function PSARawToJpeg411Sample:
            源圖 Ycrcb格式[422] 通過查表轉化為RGB 轉化時行長度折半
      壓縮為JPEG文件保存
    Input:
      BYTE* lpRawImageBuffer 源圖數據區
      int   originalWidth    源圖寬度
      int   originalHeight   源圖高度
      int   jpegQuality      JPEG壓縮質量
      char* jpegFileName     JPEG保存文件名  
      int   isNeedReversal   壓縮為JPEG時是否需要翻轉
      int   isResizeImage    是否需要更改圖像大小 
    return:
            正常返回0值,非0值表示失敗;
    Update:
      Author         Date              Ver      Remark  
      Shimingjie     2005/08/18        1.0      Create  
    ************************************************************************/
    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文件 
     /*
     rgbWidth = originalWidth;
     rgbHeight = originalHeight;
     lpRGBImageBuffer = new BYTE[rgbWidth * rgbHeight * 3];
     ConvertYUVtoRGB(lpRawImageBuffer,lpRGBImageBuffer,originalWidth,originalHeight);
     */

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

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

     return (res);
    }

    /************************************************************************
    extern "C" EXPORTS Function PSARawToJpeg411SampleAddChar:
            源圖 Ycrcb格式[422] 通過查表轉化為RGB 轉化時行長度折半 
      疊加字符 壓縮為JPEG文件保存
    Input:
      BYTE* lpRawImageBuffer 源圖數據區
      int   originalWidth    源圖寬度
      int   originalHeight   源圖高度
      int   jpegQuality      JPEG壓縮質量
      char* jpegFileName     JPEG保存文件名  
      int   isNeedReversal   壓縮為JPEG時是否需要翻轉
      int   isResizeImage    是否需要更改圖像大小 
      LPCTSTR lpszLineFirstString    疊加的第一行字符
      LPCTSTR lpszLineSecondString   疊加的第二行字符
      LPCTSTR lpszLineThirdString    疊加的第三行字符
      DWORD   dwLineFirstStartPosX   第一行字符的起始X坐標
      DWORD   dwLineFirstStartPosY   第一行字符的起始Y坐標
      DWORD   dwLineSecondStartPosX  第二行字符的起始X坐標
      DWORD   dwLineSecondStartPosY  第二行字符的起始Y坐標
      DWORD   dwLineThirdStartPosX   第三行字符的起始X坐標
      DWORD   dwLineThirdStartPosY   第三行字符的起始Y坐標
    return:
            正常返回0值,非0值表示失敗;
    Update:
      Author         Date              Ver      Remark  
      Shimingjie     2006/01/14        1.0      Create  
    ************************************************************************/
    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" EXPORTS Function PSARawToJpeg411Special:
            源圖 Ycrcb格式[422] 通過查表轉化為RGB 轉化時行由720->768 高度擴1倍
      壓縮為JPEG文件保存
    Input:
      BYTE* lpRawImageBuffer 源圖數據區
      int   originalWidth    源圖寬度
      int   originalHeight   源圖高度
      int   jpegQuality      JPEG壓縮質量
      char* jpegFileName     JPEG保存文件名  
      int   isNeedReversal   壓縮為JPEG時是否需要翻轉
      int   isResizeImage    是否需要更改圖像大小 
    return:
            正常返回0值,非0值表示失敗;
    Update:
      Author         Date              Ver      Remark  
      Shimingjie     2006/01/14        1.0      Create  
    ************************************************************************/
    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" EXPORTS Function PSARawToJpeg411SpecialAddChar:
      源圖 Ycrcb格式[422] 通過查表轉化為RGB 轉化時行由720->768 高度擴1倍
      疊加字符 壓縮為JPEG文件保存
    Input:
      BYTE* lpRawImageBuffer 源圖數據區
      int   originalWidth    源圖寬度
      int   originalHeight   源圖高度
      int   jpegQuality      JPEG壓縮質量
      char* jpegFileName     JPEG保存文件名  
      int   isNeedReversal   壓縮為JPEG時是否需要翻轉
      int   isResizeImage    是否需要更改圖像大小 
      LPCTSTR lpszLineFirstString    疊加的第一行字符
      LPCTSTR lpszLineSecondString   疊加的第二行字符
      LPCTSTR lpszLineThirdString    疊加的第三行字符
      DWORD   dwLineFirstStartPosX   第一行字符的起始X坐標
      DWORD   dwLineFirstStartPosY   第一行字符的起始Y坐標
      DWORD   dwLineSecondStartPosX  第二行字符的起始X坐標
      DWORD   dwLineSecondStartPosY  第二行字符的起始Y坐標
      DWORD   dwLineThirdStartPosX   第三行字符的起始X坐標
      DWORD   dwLineThirdStartPosY   第三行字符的起始Y坐標
    return:
            正常返回0值,非0值表示失敗;
    Update:
      Author         Date              Ver      Remark  
      Shimingjie     2006/01/14        1.0      Create  
    ************************************************************************/
    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
     /*******************************************
     ConvertYUV720toRGB768TwoHeight(
      lpRawImageBuffer,
      lpRGBImageBuffer,
      originalWidth,
      originalHeight);
     *******************************************/
     
     // 翻轉圖像保存為 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" EXPORTS Function PSAReadRawFileToBuffer:
            讀取源圖 Ycrcb格式[422]
    Input:
      char* lpszRawFile          需要讀取的文件名稱(全路徑完整名稱)  
    Output:
         int  &imageWidth           圖像寬度
      int  &imageHeight          圖像高度
      BYTE *lpRawImageBuffer     圖像數據緩存
    return::
            正常返回0值,非0值表示失敗;
    Update:
      Author         Date              Ver      Remark  
      Shimingjie     2005/08/18        1.0      Create  
    ************************************************************************/
    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" EXPORTS Function PSAReadRawFileToBuffer:
            讀取源圖 Ycrcb格式[422] 寬度由768更更改為720 高度不變
    Input:
      char* lpszRawFile          需要讀取的文件名稱(全路徑完整名稱)  
    Output:
         int  &imageWidth           圖像寬度
      int  &imageHeight          圖像高度
      BYTE *lpRawImageBuffer     圖像數據緩存
    return::
            正常返回0值,非0值表示失敗;
    Update:
      Author         Date              Ver      Remark  
      Shimingjie     2005/08/18        1.0      Create  
    ************************************************************************/
    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" EXPORTS Function PSAReadRawFileToBuffer:
            讀取源圖 Ycrcb格式[422] 寬度由768更更改為720  高度取1/2
      取源圖像數據 Height / 2 至 Height 行
    Input:
      char* lpszRawFile          需要讀取的文件名稱(全路徑完整名稱)  
    Output:
         int  &imageWidth           圖像寬度
      int  &imageHeight          圖像高度
      BYTE *lpRawImageBuffer     圖像數據緩存
    return::
            正常返回0值,非0值表示失敗;
    Update:
      Author         Date              Ver      Remark  
      Shimingjie     2006/01/14        1.0      Create  
    ************************************************************************/
    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" EXPORTS Function PSAWriteRawFile:
            保存源圖 Ycrcb格式[422]
    Input:
      const char* lpszRawFile    需要保存的文件名稱(全路徑完整名稱)  
         int   imageWidth           圖像寬度
      int   imageHeight          圖像高度
      BYTE *lpRawImageBuffer     圖像緩存
    return::
            正常返回0值,非0值表示失敗;
    Update:
      Author         Date              Ver      Remark  
      Shimingjie     2005/08/18        1.0      Create  
    ************************************************************************/
    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" EXPORTS Function PSAWriteBMPFile:
            保存為BMP格式的圖像
    Input:
      LPCSTR lpszBMPFile          需要保存的文件名稱(全路徑完整名稱)  
         int    imageWidth           圖像寬度
      int    imageHeight          圖像高度
      BYTE  *lpRawImageBuffer     圖像緩存
    return::
            正常返回0值,非0值表示失敗;
    Update:
      Author         Date              Ver      Remark  
      Shimingjie     2005/08/31        1.0      Create  
    ************************************************************************/
    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(&bmFileHeader,sizeof(BITMAPFILEHEADER),1,fileWrite) != sizeof(BITMAPFILEHEADER))
     {
      fclose(fileWrite);
      res = 2;
      goto Exit;
     }
     
     if (fwrite(&bmInfo.bmiHeader,sizeof(BITMAPINFOHEADER ),1,fileWrite) != sizeof(BITMAPINFOHEADER ))
     {
      fclose(fileWrite);
      res = 3;
      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" EXPORTS Function PSATryGetFileVersion:
            嘗試獲取外部文件的版本信息
      對有版本信息的文件有效[例如Exe文件/DLL文件]   
    Input:
      LPCTSTR lpszFileName     需要獲取的文件名稱(全路徑完整名稱)  
         DWORD* iMajor            主版本號
      DWORD* iMinor            次版本號
      DWORD* iRelease          內部版本號
      DWORD* iBuild            修訂號 
    return::
            正常返回0值,非0值表示失敗;
    Update:
      Author         Date              Ver      Remark  
      Shimingjie     2005/08/18        1.0      Create  
    ************************************************************************/
    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,(unsigned int*)&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);
    }

     

    (秩名)   本站文章除注明轉載外,均為本站原創或編譯歡迎任何形式的轉載,但請務必注明出處,尊重他人勞動,同學習共成長。轉載請注明:文章轉載自:羅索實驗室 [http://www.rosoo.net/a/201001/8204.html]    RFID管理系統集成商 RFID中間件 條碼系統中間層 物聯網軟件集成
    最近免费观看高清韩国日本大全