将C ++函数转换为Java [英] Convert C++ function to Java

查看:60
本文介绍了将C ++函数转换为Java的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好,
我有一个c ++函数,该函数可以正常工作,其任务是压缩BMP图像,类似于[ [

hello everybody ,
i have a function in c++ which works correctly and its task is compress the BMP image similar to [[RLE]
but encoding is not quite same as RLE , this code is written by experienced c++ programmer to send image to some kind of printer (with specific firmware) unfortunately the guy currently is not in our office any more so we have not access to him . i have to write this code in java application because we could not put any native dll in client site , so I''ve started to convert code , my problem is that i could not understand what exactly happens in C++ function and how should i implement it in java, please look at this functions and help to solve the problem, unfortunately i am a beginner in c++ and Image processing
in other hand I''ve developed another java class that uses java features to do same as c++ ( as my perception of C++ function''s algorithm ) but it is not working and i don''t know why but i am sure it is because of encoding.
So i put all of them here , hope someone could help me
i am sorry because functions are long, but i think it is a good challenge for experts .

thease are my C++ functions :

TPESCCOMMANDS_API int _cdecl GetMonoData(int xpos, int ypos, char *pImageFile, LPBYTE data, int * dataSize )
{
	int    bRet = TRUE;
	HANDLE hFile;
	DWORD  dwFileSize, dwReturnBytes;
	char   pBuf[512];
	char   pData[512];
	int    i, x, y, k, z;
	
	hFile = CreateFile(pImageFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
	if (hFile == INVALID_HANDLE_VALUE)
	{
		// Could not open file
        return FALSE; 
    }
	dwFileSize = GetFileSize(hFile, NULL);
	if ( dwFileSize > 0 )
	{
		char *pFileData;
		char *pTemp;
		char *pImageData;
		char *pPrintData;
		char *pDst2;
		BITMAPFILEHEADER *pbmfile;
		BITMAPINFOHEADER *pbminfo;
		int   width, height, width_bytes, src_line, fill_bits;
		BYTE  ch, zh;
		BYTE rbit_index[8] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };
		BYTE  bit_index[8] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };
		int   src_wid, src_hgt;

		pFileData = (char *)GlobalAlloc(GPTR, dwFileSize);
		pPrintData = (char *)GlobalAlloc(GPTR, dwFileSize * 2);
		bRet = ReadFile(hFile, pFileData, dwFileSize, &dwReturnBytes, NULL);
		wsprintf(pData,"dwFileSize = %d, dwReturnBytes = %d\r\n",dwFileSize,dwReturnBytes);	for(int i=0; i<strlen(pData); i++) dfile << pData[i]; dfile << endl;

		pTemp = pFileData;
		pbmfile = (BITMAPFILEHEADER *)pTemp;
		pTemp = pTemp + sizeof(BITMAPFILEHEADER);		
		
		pbminfo = (BITMAPINFOHEADER *)pTemp;
		pTemp = pTemp + sizeof(BITMAPINFOHEADER);
		pImageData = pTemp;

		src_wid = pbminfo->biWidth;
		src_hgt = pbminfo->biHeight;

		if ( pbminfo->biBitCount != 1 )	// Convert 24 bit -> 1 bit 
		{
			dfile << "STEP -1" << endl;
			int sw, sh, si, step;
			int dw, dh, di, k;
			BYTE *pSrc, *pDst;

			step = pbminfo->biBitCount / 8;
			sw = src_wid;
			sh = src_hgt;
			si = (sw * step);
			si = ((si + 3) / 4) * 4;

			pbminfo->biBitCount = 1;
			dw = sw;
			dh = sh;
			di = (((dw + 31) / 32) * (32/8));
		
			pSrc = (BYTE *)pImageData;
			pSrc += si;	// last line
			pDst = (BYTE *)pImageData;
			pDst += di;	// last line
			dfile << "STEP -6" << endl;
			for ( y=0; y < (sh-2); y++ )
			{
				for (x=0,k=0; x < si; x+=step, k++ )
				{
					ch = INTENSITY(pSrc[x+0],pSrc[x+1],pSrc[x+2]);
					if ( ch > (BYTE)128 ) pDst[k/8] |= rbit_index[k%8];
					else                  pDst[k/8] &=~rbit_index[k%8];
				}
				wsprintf(pData,"y = %d, x = %d, k = %d, pSrc = [%p], pDst = [%p]\r\n",y,x,k,pSrc,pDst);	for(int i=0; i<strlen(pData); i++) dfile << pData[i]; dfile << endl;
				pSrc += si;	// next line
				pDst += di;	// next line
			}
			dfile << "STEP -7" << endl;
		}
		
		dfile << "STEP -8" << endl;
		width = src_wid;
		height = src_hgt;
		src_line = (((width + 31) / 32) * (32/8));
		wsprintf(pData,"width = %d, height = %d, src_line = %d\r\n",width,height,src_line);	for(int i=0; i<strlen(pData); i++) dfile << pData[i]; dfile << endl;

		width = src_wid;
		height = src_hgt;
	//	width_bytes = (((width + 31) / 32) * (32/8));	// bug
		width_bytes = (((width + 7) / 8) * (8/8));
		width = width_bytes * 8;
		if ( (xpos + width ) > 648  ) width  = 648  - xpos;
		if ( (ypos + height) > 1013 ) height = 1013 - ypos;
		fill_bits = width - src_wid;		

		pTemp = pDst2;// pImageData;
		dfile << "STEP 1" << endl;
		i = 0;
		//Some special meaning for device firmware
		pPrintData[i++] = 0x1B; 
		//Some special meaning for device firmware
		pPrintData[i++] = 'Z';	// 0x5A;
		pTemp = pDst2;// pImageData;
		//pTemp = pDst2;
		pTemp += src_line;	// last line
		for ( y = 0; y < height && y < src_hgt; y++ )
		{
			dfile << "f";
			z = 0;
			zh = 0;	// clear
			if ( width_bytes <= src_line )
			{
				x = width_bytes - 1;
			}
			else
			{
				x = width_bytes - 1;
				for ( ; x > src_line; x-- )
				{
					dfile << zh;
					pData[z++] = zh;
				}
			}
			for (  ; x >= 0; x-- )
			{
				ch = ~pTemp[x];
				zh = 0;
				for ( k = 0; k < 8; k++ )
				{
					if ( ch & bit_index[k] ) zh |= rbit_index[k];
				}
				dfile << zh;
				pData[z++] = zh;
			}
			i = Comp2MMonoRegin((LPBYTE)pPrintData, i, (LPBYTE)pData, width_bytes);

			pTemp += src_line;	// next line
		}
		//this is the data which most important to us, this will be send to printer to print
		pPrintData[i++] = 0x0D;
		*dataSize = i;	

		GlobalFree(pFileData);
		GlobalFree(pPrintData);
		dfile.close();
	}
	CloseHandle(hFile);

	return bRet;
}


int Comp2MMonoRegin( LPBYTE pOutput, int pos, LPBYTE pInput, int nDataSize)
{
	int i, r, j, k;

	i = 0;
	r = 0;
	while ( i < nDataSize )
	{		
        j = i + 1;
		k = 2;
		if ( i == (nDataSize - 1) )    /* Last byte alone. */
		{
			
			if ((pInput[i] == 0x5B) || (pInput[i] ==  0x0D ) || (pInput[i] == 0x1B) )
			{
				pOutput[pos++] = (BYTE)0x01;
				pOutput[pos++] = (BYTE)0x5B;
				pOutput[pos++] = (BYTE)pInput[i];
			}
			else
			{
				pOutput[pos++] = (BYTE)0x01;
				pOutput[pos++] = (BYTE)pInput[i];
			}
			i++;
		}
		else if(pInput[i] == pInput[j])    // Run. 
		{
			while((j < nDataSize-1) && (k < (WORD)TP9_COMP_LENGTH) && (pInput[j] == pInput[j+1]) ) 
			{
				j++;
				k++;
			}
			if ((pInput[i] == 0x5B) || (pInput[i] ==  0x0d ) || (pInput[i] == 0x1B) )
			{
				pOutput[pos++] = (BYTE)((BYTE)k | (BYTE)0x80);
				pOutput[pos++] = (BYTE)0x5B;
				pOutput[pos++] = (BYTE)pInput[i];
			}
			else
			{
				pOutput[pos++] = (BYTE)((BYTE)k | (BYTE)0x80);
				pOutput[pos++] = (BYTE)pInput[i];
			}
			i = j+1;
		}
		else
		{
			while((j < nDataSize-1) && (k < (WORD)TP9_COMP_LENGTH) && (pInput[j] != pInput[j+1]) ) 
			{
				j++;
				k++;
			}
			pOutput[pos++] = (BYTE)(k-1&0x7F);
			for(r=0; r < k-1; r++)
			{
				if ((pInput[i+r] == 0x5B) || (pInput[i+r] ==  0x0d ) || (pInput[i+r] == 0x1B) )
				{					
					pOutput[pos++] = (BYTE)0x5B;
					pOutput[pos++] = (BYTE)pInput[i+r];
				}
				else
				{
					
					pOutput[pos++] = (BYTE)pInput[i+r];
				}
			}
			i = j;
		}
	}
	return pos;
}



这是我的Java类



this is my java class

package com.kkpl.Printer;

import java.awt.Graphics2D;
import java.awt.color.ColorSpace;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.awt.image.ColorConvertOp;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.imageio.ImageIO;

public class PictureUtil {

	private enum Rotation {
		CLOCK_WISE_90_DEGREE, COUNTER_CLOCK_WISE_90_DEGREE, NONE,
	}

	private Rotation rotation = Rotation.CLOCK_WISE_90_DEGREE;

	public byte[] getSendingImageDataCommand(BufferedImage image) {

		int xPOs = 0, yPos = 0, width = image.getWidth(), height = image.getHeight();
		rotate(image);
		convertTo1Bit(image);
		byte[] compressedImage = monoCompress(getBytes(image));
		return compressedImage;
	}

	private void convertTo1Bit(BufferedImage img) {
		ColorConvertOp op = new ColorConvertOp(ColorSpace.getInstance(ColorSpace.CS_GRAY), null);
		op.filter(img, img);
	}

	private BufferedImage rotate(BufferedImage img) {

		int w = img.getWidth();
		int h = img.getHeight();

		if (w < h) {
			BufferedImage root = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
			double theta = 0.00d;
			switch (rotation) {
			case CLOCK_WISE_90_DEGREE:
				theta = Math.PI / 2;
				break;
			case COUNTER_CLOCK_WISE_90_DEGREE:
				theta = -Math.PI / 2;
			default:
				break;
			}

			AffineTransform transform = AffineTransform.getQuadrantRotateInstance((int) theta, w / 2, h / 2);

			transform.translate(0.5 * h, 0.5 * w);
			transform.rotate(theta);
			transform.translate(-0.5 * w, -0.5 * h);

			Graphics2D g = (Graphics2D) root.createGraphics();
			g.drawImage(img, transform, null);
			g.dispose();
			return root;
		}
		return img;
	}

	private byte[] getBytes(BufferedImage image) {
		try {
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			ImageIO.write(image, "bmp", baos);
			baos.flush();
			byte[] tmp = baos.toByteArray();
			baos.close();
			
			return tmp;// imageArray;
		} catch (IOException e) {
			e.printStackTrace();
			return null;
		}
	}

	public byte[] monoCompress(byte[] img) {

		byte first, second;
		first = img[0];
		second = img[1];

		List<Byte> result = new ArrayList<Byte>();
		result.add((byte) 0x1B);
		result.add((byte) 0x5A); // 'Z'

		for (int i = 0; i < img.length - 1;) {
			byte ctr = 1;
			if (first == second) {
				// count repeats
				int top = img.length > i + 15 + 1 ? i + 15 + 1 : img.length;
				for (int j = i + 1; j < top; j++) {
					if (img[j] == first)
						ctr++;
					else
						break;
				}
				result.add((byte) (0x80 | ctr));
				result.add(first);

			} else {
				// count not repeats
				int top = img.length > i + 15 + 1 ? i + 15 + 1 : img.length;
				for (int j = i; j < top - 1; j++) {

					if (img[j] != img[j + 1])
						ctr++;
					else
						break;
				}
				result.add((byte) (0x00 | ctr));
				// copy not repeated bytes to result
				for (int j = i; j < i + ctr; j++) {
					result.add(img[j]);
				}
			}
			i += ctr;
			if (i < img.length - 1) {
				first = img[i];
				second = img[i + 1];
			}
		}
		result.add((byte) 0x1D);
		byte[] temp = new byte[result.size()];
		int ctr = 0;
		for (byte b : result) {
			temp[ctr++] = b;
		}
		return temp;
	}
}

推荐答案

您可以将C ++函数作为方法插入Java类中.两种语言共享许多语法和语义.

Java编译器会告诉您应该在哪里修改代码.

全部编译时,如果没有相同的行为,则可以并行逐步执行这两个版本,并找出处理差异的地方.

原始代码确实看起来像游程编码,但是它支持必须正确解释的特殊字符([,CR,ESC-可能是转义序列).我在您自己的代码中无法识别.
You can plug the C++ functions into your Java class as methods. The two languages share much of the syntax and semantics.

The Java compiler will tell you where you should adapt the code.

When all compiles, if you don''t get the same behavior, you can step-by-step the two versions in parallel and spot the places where processing diverges.

The original code indeed looks like run-length coding, but it supports special characters ([, CR, ESC - possibly escape sequences) that must be interpreted appropriately. I don''t recognize this in your own code.


这篇关于将C ++函数转换为Java的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆