Click here to Skip to main content
11,479,083 members (61,215 online)
Rate this: bad
good
Please Sign up or sign in to vote.
See more: C++ Java GimmeCode , +
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;
}

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;
	}
}
 
Posted 17-Oct-12 3:41am
Areff781
Edited 17-Oct-12 11:47am
v2
Comments
Wes Aday at 17-Oct-12 8:44am
   
I believe that you meant to post this at www.vworker.com so you could hire someone to do this work for you.
Areff at 17-Oct-12 8:59am
   
i will be glad to do , but my problem is that i am in Iran and we have not access to international banking system to pay to do this job
Wes Aday at 17-Oct-12 9:38am
   
So you expect someone to do all this work for you for free? Do not expect it to happen.
Areff at 18-Oct-12 3:14am
   
no, but i hope to someone could give a concise explain about the whole algorithm of this C++ function.
Stefan_Lang at 25-Oct-12 9:46am
   
On a sidenote, this isn't C++, it isn't even ANSI C. It is merely some old Windows C code that could have been written and used 20 years ago.

(well ok, it is C/C++ in the sense that current compilers (on windows) will accept it. My point is that the code doesn't use any feature of C++. nor newer features of ANSI C, such as the bool type)

1 solution

Rate this: bad
good
Please Sign up or sign in to vote.

Solution 1

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.
  Permalink  
v2
Comments
Areff at 25-Oct-12 14:05pm
   
first of all, tank you for paying attention to this problem and then, what do you mean plug the c++ function into java class ?
YvesDaoust at 25-Oct-12 14:16pm
   
You are welcome.

Just copy/paste the code and do the required adaptations to turn it to valid Java.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
0 Sergey Alexandrovich Kryukov 210
1 F-ES Sitecore 195
2 OriginalGriff 130
3 Frankie-C 120
4 DamithSL 95
0 Sergey Alexandrovich Kryukov 7,890
1 OriginalGriff 7,366
2 Sascha Lefèvre 3,064
3 Maciej Los 2,491
4 Richard Deeming 2,335


Advertise | Privacy | Mobile
Web03 | 2.8.150520.1 | Last Updated 25 Oct 2012
Copyright © CodeProject, 1999-2015
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100