⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 kmphoto.c

📁 vc环境下的pgp源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*____________________________________________________________________________
	Copyright (C) 1998 Network Associates, Inc.
	All rights reserved.
	
	KMPhoto.c - photoID routines
	

	$Id: KMPhoto.c,v 1.16 1998/08/11 14:43:35 pbj Exp $
____________________________________________________________________________*/
#include "pgpPFLConfig.h"

// project header files
#include "pgpkmx.h"

// pgp header files
#include "pgpJPEG.h"
#include "pgpClientShared.h"
#include "pgpEndianConversion.h"

// external global variables
extern HINSTANCE g_hInst;

// constant definitions
#define DISPLAY_WIDTH		120
#define MAX_FILE_WIDTH		1000
#define MAX_FILE_HEIGHT		1200
#define MAX_PHOTO_WIDTH		120
#define MAX_PHOTO_HEIGHT	144

// error handler struct for JPEG library
struct my_error_mgr {
	struct jpeg_error_mgr pub;	
	jmp_buf setjmp_buffer;
};

typedef struct my_error_mgr * my_error_ptr;

//	___________________________________________________
//
//	extract size information from DIB

INT
KMGetDIBSize (LPBITMAPINFO lpbi, INT* piWidth, INT* piHeight)
{
	INT	iRowSize;
	INT	iDIBSize;

	// return image dimensions
	if (piWidth)
		*piWidth = lpbi->bmiHeader.biWidth;
	if (piHeight)
		*piHeight = lpbi->bmiHeader.biHeight;

	// rows length must be a multiple of sizeof(LONG)
	iRowSize = (lpbi->bmiHeader.biWidth * lpbi->bmiHeader.biBitCount) >>3;
	iRowSize = ((iRowSize+3)>>2)<<2;

	// calculate image size by multiplying row length by number of rows
	// and adding in header and color table sizes
	iDIBSize = lpbi->bmiHeader.biSize;
	iDIBSize += lpbi->bmiHeader.biClrUsed * sizeof(RGBQUAD);
	iDIBSize += iRowSize * lpbi->bmiHeader.biHeight;

	return iDIBSize;
}
 
//	___________________________________________________
//
//	create logical palette from bitmap color table

static HPALETTE 
sPaletteFromDIB (
		  LPBITMAPINFO	lpbmi, 
		  INT*			piNumColors) 
{
	HPALETTE			hPal	= NULL;
	LPBITMAPINFOHEADER	lpbi;
	LPLOGPALETTE		lpPal;
	HANDLE				hLogPal;
	INT					i;
 
	lpbi = (LPBITMAPINFOHEADER)lpbmi;

	// palettes are only used on images with 8 bits/pixel or less
	switch (lpbi->biBitCount) {
	case 1 :
		*piNumColors = 2;
		break;

	case 4 :
		*piNumColors = 16;
		break;

	case 8 :
		if (lpbi->biClrUsed) 
			*piNumColors = lpbi->biClrUsed;
		else 
			*piNumColors = 256;
		break;

	default :
		*piNumColors = 0;
		break;
	}
 
	// if a palette is indicated, extract it from bitmap color table
	if (*piNumColors) {
		hLogPal = GlobalAlloc (GHND, sizeof (LOGPALETTE) +
                             sizeof (PALETTEENTRY) * (*piNumColors));
		lpPal = (LPLOGPALETTE) GlobalLock (hLogPal);
		lpPal->palVersion = 0x300;
		lpPal->palNumEntries = *piNumColors;
 
		for (i=0; i<*piNumColors; i++) {
			lpPal->palPalEntry[i].peRed   = lpbmi->bmiColors[i].rgbRed;
			lpPal->palPalEntry[i].peGreen = lpbmi->bmiColors[i].rgbGreen;
			lpPal->palPalEntry[i].peBlue  = lpbmi->bmiColors[i].rgbBlue;
			lpPal->palPalEntry[i].peFlags = 0;
		}
		hPal = CreatePalette (lpPal);
		GlobalUnlock (hLogPal);
		GlobalFree (hLogPal);
	}

	return hPal;
}
 
//	___________________________________________________
//
//	derive DDB and palette from DIB 

HBITMAP
KMDDBfromDIB (
		LPBITMAPINFO	lpbi, 
		HPALETTE*		lphPalette)
{
	HBITMAP		hBitmapFinal = NULL;
	HDC			hdc;
    INT			iNumColors;
	LPVOID		lpPixels;
 
	hdc = GetDC (NULL);

	*lphPalette = NULL;
	iNumColors = 0;

	if (GetDeviceCaps (hdc, RASTERCAPS) & RC_PALETTE) 
		*lphPalette = sPaletteFromDIB ((LPBITMAPINFO)lpbi, &iNumColors);

	if (*lphPalette) {
		SelectPalette (hdc, *lphPalette, FALSE);
		RealizePalette (hdc);
	}
 
	lpPixels = (LPBYTE)lpbi + 
				lpbi->bmiHeader.biSize +
				(iNumColors * sizeof(RGBQUAD));

	hBitmapFinal = CreateDIBitmap (hdc,
                   &(lpbi->bmiHeader),
                   CBM_INIT,
                   lpPixels,
                   lpbi,
                   DIB_RGB_COLORS);
 
	ReleaseDC (NULL, hdc);

	return (hBitmapFinal);
}

//	___________________________________________________
//
//	error handler routine for JPEG library
//
//	converts error code to string and displays it in MessageBox

METHODDEF(void)
my_error_exit (j_common_ptr cinfo)
{
//	CHAR szError [JMSG_LENGTH_MAX];

	my_error_ptr myerr = (my_error_ptr) cinfo->err;

//	(*cinfo->err->format_message) (cinfo, szError);
//	MessageBox (NULL, szError, "JPEG Library Error", MB_OK);
//
	longjmp(myerr->setjmp_buffer, 1);
}

//	___________________________________________________
//
//	convert DIB to JPEG buffer

static PGPError
sJPEGFromDIB (
		LPBITMAPINFO	lpbmi, 
		INT				iQuality,
		INT				iMaxWidth,
		INT				iMaxHeight,
		BOOL			bShrink,
		LPBYTE*			pbuf, 
		INT*			piLength)
{
	PGPError	err				= kPGPError_NoErr;

	INT			iColorTableLength;
	INT			iRowOrigLen, iRowJPEGLen, iRowDIBLen, iDIBsize;
	INT			i, j, index;
	INT			iWidth, iHeight, iZoom;
	INT			idxX, idxY;
	struct		my_error_mgr jerr;
	struct		jpeg_compress_struct cinfo;
	FILE*		outfile;
	LPBYTE		pDIB;
	LPBYTE		pRGBorig;
	LPBYTE		pRGBjpeg;
	JSAMPROW	pSampRow[1];	
	double		fZoom, fImageRatio, fMaxRatio, fTemp;

	// do we really need to shrink image ?
	fZoom = 1.0;
	iZoom = 1000;
	iWidth = lpbmi->bmiHeader.biWidth;
	iHeight = lpbmi->bmiHeader.biHeight;

	if (bShrink) {
		if ((lpbmi->bmiHeader.biWidth > iMaxWidth) ||
			(lpbmi->bmiHeader.biHeight > iMaxHeight)) {

			fImageRatio = (double)lpbmi->bmiHeader.biWidth /
						  (double)lpbmi->bmiHeader.biHeight;
			fMaxRatio   = (double)iMaxWidth / (double)iMaxHeight;

			if (fImageRatio >= fMaxRatio) {
				fZoom = (double)iMaxWidth / 
						(double)lpbmi->bmiHeader.biWidth;
				fTemp = (1000.0 / fZoom);

				iWidth = iMaxWidth;
				iHeight = (INT)(lpbmi->bmiHeader.biHeight * fZoom);

				iZoom = (INT)fTemp;
			}
			else {
				fZoom = (double)iMaxHeight / 
						(double)lpbmi->bmiHeader.biHeight;
				fTemp = (1000.0 / fZoom);

				iHeight = iMaxHeight;
				iWidth = (INT)(lpbmi->bmiHeader.biWidth * fZoom);

				iZoom = (INT)fTemp;
			}
		}
	}

	// calculate length of row of image in bytes (3 color channels)
	iRowOrigLen = lpbmi->bmiHeader.biWidth * 3;
	iRowJPEGLen = (iWidth+1) * 3;	

	// calculate length of row of image in DIB structure
	iRowDIBLen = (lpbmi->bmiHeader.biWidth * lpbmi->bmiHeader.biBitCount) >>3;
	iRowDIBLen = ((iRowDIBLen+3)>>2)<<2;

	// allocate buffer used for passing rows of RGB data into library
	pRGBorig = KMAlloc (iRowOrigLen);
	if (pRGBorig == NULL) 
		return kPGPError_OutOfMemory;

	pRGBjpeg = KMAlloc (iRowJPEGLen);
	if (pRGBjpeg == NULL) 
		return kPGPError_OutOfMemory;

	// calculate size of DIB structure
	iColorTableLength = lpbmi->bmiHeader.biClrUsed;
	if (iColorTableLength == 0) {
		switch (lpbmi->bmiHeader.biBitCount) {
		case 1 :
			iColorTableLength = 2;
			break;
		case 4 :
			iColorTableLength = 16;
			break;
		case 8 :
			iColorTableLength = 256;
			break;
		default :
			iColorTableLength = 0;
			break;
		}
	}
	iDIBsize = sizeof(BITMAPINFOHEADER);
	iDIBsize += (iColorTableLength * sizeof (RGBQUAD));
	iDIBsize += (iRowDIBLen * lpbmi->bmiHeader.biHeight);

	// initialize pointer to last row of DIB (DIB is stored bottom-up)
	pDIB = (LPBYTE)lpbmi;
	pDIB += iDIBsize;
	pDIB -= iRowDIBLen;

	// JPEG library will write to temporary file
	outfile = tmpfile ();

	// setup error handler for JPEG library
	cinfo.err = jpeg_std_error (&jerr.pub);
	jerr.pub.error_exit = my_error_exit;
	if (setjmp(jerr.setjmp_buffer)) {
		// will be here only on error in library
		jpeg_destroy_compress (&cinfo);
		fclose (outfile);
		_rmtmp ();
		return kPGPError_Win32_InvalidImage;
	}

	// initialize compression structure
	jpeg_create_compress (&cinfo);

	// specify destination of JPEG stream
	jpeg_stdio_dest (&cinfo, outfile);

	// specify image characteristics
	cinfo.image_width = iWidth;
	cinfo.image_height = iHeight;
	cinfo.input_components = 3;	
	cinfo.in_color_space = JCS_RGB;
	jpeg_set_defaults (&cinfo);

	// specify quality of compressed image
	jpeg_set_quality (&cinfo, iQuality, TRUE);

	// startup compression
	jpeg_start_compress (&cinfo, TRUE);

	pSampRow[0] = pRGBjpeg;
	idxY = 0;
	while (cinfo.next_scanline < cinfo.image_height) {

		// fill buffer of data on basis of number of bits/pixel
		switch (lpbmi->bmiHeader.biBitCount) {
		case 1 :
			// B/W image
			for (j=i=0; i<iRowOrigLen; i+=3) {
				index = pDIB [j>>3];
				index = (index >> (7 - (j&0x07))) & 0x01;
				j++;

				pRGBorig[i+0] = lpbmi->bmiColors[index].rgbRed;
				pRGBorig[i+1] = lpbmi->bmiColors[index].rgbGreen;
				pRGBorig[i+2] = lpbmi->bmiColors[index].rgbBlue;
			}
			break;

		case 4 :
			// 16 color image, derive RGB values from color table
			for (j=i=0; i<iRowOrigLen; i+=3) {
				if (j & 0x1) 
					index = pDIB [j>>1] & 0x0F;
				else 
					index = pDIB [j>>1] >> 4;
				j++;

				pRGBorig[i+0] = lpbmi->bmiColors[index].rgbRed;
				pRGBorig[i+1] = lpbmi->bmiColors[index].rgbGreen;
				pRGBorig[i+2] = lpbmi->bmiColors[index].rgbBlue;
			}
			break;

		case 8 :
			// 256 color image, derive RGB values from color table
			for (j=i=0; i<iRowOrigLen; i+=3) {
				index = pDIB[j++];
				pRGBorig[i+0] = lpbmi->bmiColors[index].rgbRed;
				pRGBorig[i+1] = lpbmi->bmiColors[index].rgbGreen;
				pRGBorig[i+2] = lpbmi->bmiColors[index].rgbBlue;
			}
			break;

		case 24 :
			// RGB image, but DIB stores it as BGR, so invert
			for (i=0; i<iRowOrigLen; i+=3) {
				pRGBorig[i+0] = pDIB[i+2];
				pRGBorig[i+1] = pDIB[i+1];
				pRGBorig[i+2] = pDIB[i+0];
			}
			break;

		case 32 :
			// RGB image, but in DIB it's 0BGR, so invert and discard byte
			for (i=j=0; i<iRowOrigLen; i+=3) {
				pRGBorig[i+0] = pDIB[j+3];
				pRGBorig[i+1] = pDIB[j+2];
				pRGBorig[i+2] = pDIB[j+1];
				j += 4;
			}
			break;
		}

		// subsample the row of data
		idxX = 0;
		for (i=j=0; j<iRowOrigLen; j+=3) {
			idxX -= 1000;
			while (idxX < 0) {
				pRGBjpeg[i+0] = pRGBorig[j+0];
				pRGBjpeg[i+1] = pRGBorig[j+1];
				pRGBjpeg[i+2] = pRGBorig[j+2];

				i += 3;
				idxX += iZoom;
			}
		}

		// pass the RGB data into the library
		(void) jpeg_write_scanlines (&cinfo, pSampRow, 1);

		// step to previous DIB scan line
		idxY += iZoom;
		while (idxY > 0) {
			pDIB -= iRowDIBLen;
			idxY -= 1000;
		}
	}

	// done with image
	jpeg_finish_compress (&cinfo);
	jpeg_destroy_compress (&cinfo);
	KMFree (pRGBorig);
	KMFree (pRGBjpeg);

	// now extract JPEG data from file -- first calculate buffer length
	fseek (outfile, 0, SEEK_END);
	*piLength = ftell (outfile);

	// allocate buffer
	*pbuf = KMAlloc (*piLength);

	// read data from file into buffer
	if (*pbuf != NULL) {
		rewind (outfile);
		fread (*pbuf, 1, *piLength, outfile); 
	}

	// memory allocation error
	else 
		err = kPGPError_OutOfMemory;

	fclose (outfile);
	_rmtmp ();

	return err;
}


//	___________________________________________________
//
//	convert DIB to PhotoID buffer

static PGPError
sPhotoFromDIB (
		LPBITMAPINFO	lpbmi, 
		INT				iMaxWidth,
		INT				iMaxHeight,
		BOOL			bShrink,
		LPBYTE*			pbuf, 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -