<iframe id="aswift_1" height="15" marginHeight="0" frameBorder="0" width="468" name="aswift_1" marginWidth="0" scrolling="no"></iframe> /************************************** 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 =http://www.mamicode.com/= 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); } (秩名) |