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

📄 kmphoto.c

📁 vc环境下的pgp源码
💻 C
📖 第 1 页 / 共 2 页
字号:
		INT*			piLength)
{
	PGPError				err;
	LPBYTE					pJPEGbuf;
	INT						iJPEGlen;
	PGPPhotoUserIDHeader*	pheader;
	LPBYTE					pdata;
	PGPUInt16				usHeaderLength;
	
	// currently we only support JPEG photoids
	err = sJPEGFromDIB (lpbmi, kPGPDefaultJPEQQuality, 
		iMaxWidth, iMaxHeight, bShrink, &pJPEGbuf, &iJPEGlen);

	if (IsntPGPError (err)) {
		*piLength = iJPEGlen + sizeof(PGPPhotoUserIDHeader);
		*pbuf = KMAlloc (*piLength);

		if (*pbuf) {
			pheader = (PGPPhotoUserIDHeader*)*pbuf;
			usHeaderLength = sizeof(PGPPhotoUserIDHeader);
			PGPUInt16ToStorage (usHeaderLength, 
								(PGPByte*)&(pheader->headerLength));
			pheader->headerVersion 	= kPGPPhotoIDHeaderVersion;
			pheader->photoIDFormat	= kPGPPhotoIDFormat_JPEG;

			pdata = *pbuf + usHeaderLength;

			memcpy (pdata, pJPEGbuf, iJPEGlen);
		}
		else {
			*piLength = 0;
			err = kPGPError_OutOfMemory;
		}

	}

	return err;
}

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

static LPBITMAPINFO
sDIBfromJPEGFile (
		FILE*	infile, 
		BOOL	bForDisplay)
{
	LPBITMAPINFO	lpbmi	= NULL;

	INT				i, iNumBits, iDIBsize;
	INT				iRowDataLen, iRowDIBLen;
	struct			my_error_mgr jerr;
	struct			jpeg_decompress_struct cinfo;
	HDC				hdc;
	JSAMPARRAY		buffer;
	JSAMPROW		pSamp;
	LPBYTE			pDIB;
	BOOL			bQuantize;


	// get pixel depth supported by the current display device
	hdc = GetDC (NULL);
	iNumBits = GetDeviceCaps (hdc, BITSPIXEL) * GetDeviceCaps (hdc, PLANES);
	ReleaseDC (NULL, hdc);

	// quantize colors only if a 256 color display
	//	if more than 256, display is RGB and quantization is not needed
	//	if less than 256, quantization does no good as system palette will
	//		be used regardless
	if (bForDisplay && (iNumBits == 8)) bQuantize = TRUE;
	else bQuantize = FALSE;

	// prepare error handling structure for JPEG library
	cinfo.err = jpeg_std_error (&jerr.pub);
	jerr.pub.error_exit = my_error_exit;
	if (setjmp(jerr.setjmp_buffer)) {
		// here only when JPEG library encounters an error
		jpeg_destroy_decompress (&cinfo);
		return NULL;
	}

	// initialize decompression structure
	jpeg_create_decompress (&cinfo);

	// identify source of JPEG data as input file
	jpeg_stdio_src (&cinfo, infile);

	// load header data from file
	(void) jpeg_read_header (&cinfo, TRUE);

	// set scaling factor for decompression
	if (bForDisplay) {
		cinfo.scale_num = 1;
		if (cinfo.image_width > 4*DISPLAY_WIDTH) 
			cinfo.scale_denom = 8;
		else if (cinfo.image_width > 2*DISPLAY_WIDTH) 
			cinfo.scale_denom = 4;
		else if (cinfo.image_width > 1*DISPLAY_WIDTH) 
			cinfo.scale_denom = 2;
		else 
			cinfo.scale_denom = 1;
	}
	else {
		cinfo.scale_num = 1;
		cinfo.scale_denom = 1;
	}

	// set decompression parameters
	if (bQuantize) {
		cinfo.quantize_colors = TRUE;
		cinfo.two_pass_quantize = TRUE;
		cinfo.dither_mode = JDITHER_FS;
		cinfo.desired_number_of_colors = 128;
	}
	else {
		cinfo.quantize_colors = FALSE;
	}

	// start decompression
	(void) jpeg_start_decompress (&cinfo);

	// calculate bitmap size parameters and set DIB header info
	if (bQuantize) {
		iRowDataLen = cinfo.output_width * 1;
		iRowDIBLen = ((iRowDataLen+3)>>2)<<2;
		iDIBsize = sizeof(BITMAPINFOHEADER);
		iDIBsize += (cinfo.actual_number_of_colors * sizeof (RGBQUAD));
		iDIBsize += (iRowDIBLen * cinfo.output_height);

		lpbmi = KMAlloc (iDIBsize);
		lpbmi->bmiHeader.biSize = sizeof (BITMAPINFOHEADER);
		lpbmi->bmiHeader.biWidth = cinfo.output_width;
		lpbmi->bmiHeader.biHeight = cinfo.output_height;
		lpbmi->bmiHeader.biPlanes = 1;
		lpbmi->bmiHeader.biBitCount = 8;
		lpbmi->bmiHeader.biCompression = BI_RGB;
		lpbmi->bmiHeader.biSizeImage = iRowDIBLen * cinfo.output_height;
		lpbmi->bmiHeader.biClrUsed = cinfo.actual_number_of_colors;
		lpbmi->bmiHeader.biClrImportant = cinfo.actual_number_of_colors;
	}
	else {
		iRowDataLen = cinfo.output_width * 3;
		iRowDIBLen = ((iRowDataLen+3)>>2)<<2;
		iDIBsize = sizeof(BITMAPINFOHEADER);
		iDIBsize += (iRowDIBLen * cinfo.output_height);

		lpbmi = KMAlloc (iDIBsize);
		lpbmi->bmiHeader.biSize = sizeof (BITMAPINFOHEADER);
		lpbmi->bmiHeader.biWidth = cinfo.output_width;
		lpbmi->bmiHeader.biHeight = cinfo.output_height;
		lpbmi->bmiHeader.biPlanes = 1;
		lpbmi->bmiHeader.biBitCount = 24;
		lpbmi->bmiHeader.biCompression = BI_RGB;
		lpbmi->bmiHeader.biSizeImage = iRowDIBLen * cinfo.output_height;
		lpbmi->bmiHeader.biClrUsed = 0;
		lpbmi->bmiHeader.biClrImportant = 0;
	}

	// have JPEG library allocate buffer for data output
	buffer = (*cinfo.mem->alloc_sarray)
			((j_common_ptr) &cinfo, JPOOL_IMAGE, iRowDataLen, 1);

	// put color table into DIB
	if (bQuantize) {
		pSamp = cinfo.colormap[0];
		for (i = 0;  i < cinfo.actual_number_of_colors;  i++) 
			lpbmi->bmiColors[i].rgbRed = pSamp[i];

		pSamp = cinfo.colormap[1];
		for (i = 0;  i < cinfo.actual_number_of_colors;  i++) 
			lpbmi->bmiColors[i].rgbGreen = pSamp[i];

		pSamp = cinfo.colormap[2];
		for (i = 0;  i < cinfo.actual_number_of_colors;  i++) 
			lpbmi->bmiColors[i].rgbBlue = pSamp[i];
	}

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

	// decompress the image, one line at a time
	while (cinfo.output_scanline < cinfo.output_height) {
		(void) jpeg_read_scanlines (&cinfo, buffer, 1);

		// if quantized, just store the colormap index in the DIB
		if (bQuantize) {
			pSamp = buffer[0];
			for (i=0; i<iRowDataLen; i++) {
				pDIB[i] = pSamp[i];
			}
		}
		// otherwise data is RGB, but DIB are in BGR order, so invert
		else {
			pSamp = buffer[0];
			for (i=0; i<iRowDataLen; i+=3) {
				pDIB[i+2] = pSamp[i+0];
				pDIB[i+1] = pSamp[i+1];
				pDIB[i+0] = pSamp[i+2];
			}
		}

		// step to previous row
		pDIB -= iRowDIBLen;
	}

	// finished decompressing
	jpeg_finish_decompress (&cinfo);
	jpeg_destroy_decompress (&cinfo);

	return lpbmi;
}

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

static LPBITMAPINFO
sDIBfromJPEGBuffer (
		LPBYTE	buf, 
		INT		isize, 
		BOOL	bForDisplay)
{
	LPBITMAPINFO	lpbmi	= NULL;

	FILE*			infile;

	// write JPEG data to temp file for library to read from
	infile = tmpfile ();
	fwrite (buf, 1, isize, infile);
	rewind (infile);

	// convert the file
	lpbmi = sDIBfromJPEGFile (infile, bForDisplay);

	// close and delete temporary file
	fclose (infile);
	_rmtmp ();

	return lpbmi;
}

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

PGPError
KMDIBfromPhoto (
		LPBYTE			buf, 
		INT				isize, 
		BOOL			bForDisplay,
		LPBITMAPINFO*	plpbmi)
{
	PGPError				err				= kPGPError_NoErr;
	PGPPhotoUserIDHeader*	pheader;
	LPBYTE					pdata;
	PGPUInt16				usHeaderLength;

	if (!plpbmi) return kPGPError_BadParams;

	*plpbmi = NULL;
	pheader = (PGPPhotoUserIDHeader*)buf;

	if (pheader->headerVersion != kPGPPhotoIDHeaderVersion)
		err = kPGPError_BadParams;
	else {
		switch (pheader->photoIDFormat) {
		case kPGPPhotoIDFormat_JPEG :
			usHeaderLength = 
				PGPStorageToUInt16 ((PGPByte*)&pheader->headerLength);
			pdata = buf + usHeaderLength;
			*plpbmi = sDIBfromJPEGBuffer (pdata, 
						isize - usHeaderLength, bForDisplay);
			break;

		default :
			err = kPGPError_BadParams;
		}
	}

	return err;
}

//	___________________________________________________
//
//	copy PhotoID buffer to clipboard in DIB format

PGPError
KMCopyPhotoToClipboard (HWND hWnd, LPBYTE buf, INT isize)
{
	PGPError		err;
	LPBITMAPINFO	lpbmi;
	HANDLE			hMem;
	LPBYTE			pMem;
	INT				iDIBsize;

	err = KMDIBfromPhoto (buf, isize, FALSE, &lpbmi);

	if (IsntPGPError (err)) {
		iDIBsize = KMGetDIBSize (lpbmi, NULL, NULL);
		hMem = GlobalAlloc (GMEM_MOVEABLE|GMEM_DDESHARE, iDIBsize);
		pMem = GlobalLock (hMem);
		CopyMemory (pMem, lpbmi, iDIBsize);
		GlobalUnlock (hMem);

		OpenClipboard (hWnd);
		SetClipboardData (CF_DIB, hMem);
		CloseClipboard ();

		KMFree (lpbmi);
	}

	return err;
}

//	___________________________________________________
//
//	paste data in clipboard (DIB format) into JPEG buffer

PGPError
KMPastePhotoFromClipboard (HWND hWnd, LPBYTE* pbuf, INT* pisize)
{
	HANDLE			hMem;
	LPBITMAPINFO	lpbmi;
	PGPError		err;

	if (OpenClipboard (hWnd)) { 
		hMem = GetClipboardData (CF_DIB); 
		lpbmi = (LPBITMAPINFO)GlobalLock (hMem);

		err = sPhotoFromDIB (lpbmi, MAX_PHOTO_WIDTH,
							 MAX_PHOTO_HEIGHT, TRUE, pbuf, pisize);

		GlobalUnlock (hMem);
		CloseClipboard(); 
	}
	return err;
}

//	___________________________________________________
//
//	read BMP file into PhotoID buffer

static PGPError
sReadPhotoFromBMPFile (
		FILE*		pfile, 
		LPBYTE*		pbuf, 
		INT*		pisize)
{
	PGPError			err		= kPGPError_Win32_InvalidImage;
	LPBYTE				pfilebuf;
	BITMAPFILEHEADER	bmfh;
	LPBITMAPINFO		lpbmi;
	ULONG				ulMaxFileSize;

	// read file header to get size of file
	rewind (pfile);
	if (fread (&bmfh, 1, sizeof(bmfh), pfile) != sizeof(bmfh))
		return err;

	// check for internal magic number and valid size
	if ((bmfh.bfType != 0x4d42) ||		// 'BM'
		(bmfh.bfSize < (sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFO)))) {
		return err;
	}

	// check for giant files
	ulMaxFileSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFO);
	ulMaxFileSize += 256*sizeof(RGBQUAD);
	ulMaxFileSize += MAX_FILE_WIDTH*MAX_FILE_HEIGHT*4;
	if (bmfh.bfSize > ulMaxFileSize) {
		return kPGPError_Win32_ImageTooBig;
	}

	// allocate buffer to hold entire file
	pfilebuf = KMAlloc (bmfh.bfSize);
	if (!pfilebuf) {
		return kPGPError_OutOfMemory;
	}

	// read the entire file into the buffer
	rewind (pfile);
	if (fread (pfilebuf, 1, bmfh.bfSize, pfile) != bmfh.bfSize)
		return err;

	// set the pointer to byte following file header
	lpbmi = (LPBITMAPINFO)(pfilebuf + sizeof(bmfh));

	// check for compressed images (not supported)
	if (lpbmi->bmiHeader.biCompression != BI_RGB) {
		KMFree (pfilebuf);
		return err;
	}

	// convert
	err = sPhotoFromDIB (lpbmi, MAX_PHOTO_WIDTH,
						 MAX_PHOTO_HEIGHT, TRUE, pbuf, pisize);

	KMFree (pfilebuf);

	return err;
}

//	___________________________________________________
//
//	read JPEG file into PhotoID buffer

static PGPError
sReadPhotoFromJPEGFile (
		FILE*		pfile, 
		LPBYTE*		pbuf, 
		INT*		pisize)
{
	PGPError			err		= kPGPError_Win32_InvalidImage;
	LPBITMAPINFO		lpbmi;

	// convert the JPEG file to a BMP buffer
	rewind (pfile);
	lpbmi = sDIBfromJPEGFile (pfile, FALSE);

	// convert to photoid format
	if (lpbmi) {
		err = sPhotoFromDIB (lpbmi, MAX_PHOTO_WIDTH,
						 MAX_PHOTO_HEIGHT, TRUE, pbuf, pisize);
	}

	return err;
}

//	___________________________________________________
//
//	read image file into PhotoID buffer

PGPError
KMReadPhotoFromFile (
		LPSTR		pszFile, 
		LPBYTE*		pbuf, 
		INT*		pisize)
{
	PGPError			err		= kPGPError_Win32_InvalidImage;
	FILE*				pfile;

	pfile = fopen (pszFile, "rb");

	if (pfile) {
		// attempt to read file as a JPEG file
		err = sReadPhotoFromJPEGFile (pfile, pbuf, pisize);

		// if that didn't work, try it as a BMP file
		if (IsPGPError (err)) {
			err = sReadPhotoFromBMPFile (pfile, pbuf, pisize);
		}

		fclose (pfile); 
	}

	return err;
}

⌨️ 快捷键说明

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