将C ++函数转换为Java [英] Convert C++ function to 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屋!