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)
{
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 ) {
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; pDst = (BYTE *)pImageData;
pDst += di; 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; pDst += di; }
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 + 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; dfile << "STEP 1" << endl;
i = 0;
pPrintData[i++] = 0x1B;
pPrintData[i++] = 'Z'; pTemp = pDst2; pTemp += src_line; for ( y = 0; y < height && y < src_hgt; y++ )
{
dfile << "f";
z = 0;
zh = 0; 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; }
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) )
{
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]) {
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;
} 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);
for (int i = 0; i < img.length - 1;) {
byte ctr = 1;
if (first == second) {
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 {
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));
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;
}
}