Skip to content

Instantly share code, notes, and snippets.

@Barala
Last active March 18, 2020 15:12
Show Gist options
  • Save Barala/8c0b2ec1e2b01ce915975aa1a7ec6bff to your computer and use it in GitHub Desktop.
Save Barala/8c0b2ec1e2b01ce915975aa1a7ec6bff to your computer and use it in GitHub Desktop.
Convert 4BA points into 3BA byte array
package my.app;
import java.util.Objects;
/**
*
* Converts 4ba point data into 3ba byte buffer
*
* @author barala
*
*/
public class FourBAPointsToThreeBAByteArray {
private static final Point[]TEST = {getPoint(271,90),getPoint(623, 59), getPoint(623, 57), getPoint(-1, -1), getPoint(267, 55),
getPoint(255, 55), getPoint(590, 56), getPoint(246, 58), getPoint(573, 59), getPoint(234, 91), getPoint(213, 61),
getPoint(207, 63), getPoint(495, 65), getPoint(495, 65), getPoint(-1, -1)};
private static final byte[] EXPECTED_BYTES = {0x60 , 0x41 , 0x2B , 0x5A , 0x4C , 0x5C , 0x21 , 0x20 , 0x5F ,
0x26 , 0x70 , 0x60 , 0x41 , 0x26 , 0x3F , 0x5E , 0x20 , 0x40 , 0x49 , 0x20 , 0x59 , 0x55 , 0x20 ,
0x22 , 0x48 , 0x20 , 0x59 , 0x55 , 0x24 , 0x48 , 0x5D , 0x5C , 0x3A , 0x5F , 0x20 , 0x32 , 0x44 ,
0x20 , 0x22 , 0x20 , 0x20 , 0x20 , 0x70};
private static Point getPoint(int x, int y){
return new Point(x, y);
}
public static void main(String[] args) {
byte[] bytes = convertFourBAtoThree(TEST);
StringBuilder sb = new StringBuilder();
for (int i=0;i<bytes.length;i++) {
assert bytes[i]==EXPECTED_BYTES[i];
sb.append(String.format("%02X ", bytes[i]));
}
System.out.println(sb.toString());
}
public static byte[] convertFourBAtoThree(Point[] points){
Signature signature = new Signature(-1, null, null);
sigAddDataPoints(signature, points, points.length);
byte[] bytes = signature.getBuffer();
//return till mark
byte[] output = new byte[signature.currentMarker];
for(int i=0;i<signature.currentMarker;i++){
output[i]=bytes[i];
}
return output;
}
private static void sigAddDataPoints(Signature signature, Point[] points, int size){
signature.setPrevPoint(new Point(-1, -1));
for(int i=0;i<size;i++) {
sigAddDataPoint(signature, points[i].getX(), points[i].getY());
}
}
private static void sigAddDataPoint(Signature signature, int x, int y){
Point prevPoint = signature.getPrevPoint();
if(prevPoint.getX() == -1 && prevPoint.getY() == -1){
if(!(x==-1 && y==-1)){
sigAddDataPoint3BA(signature, x, y, SignatureTouchType.TOUCH_TYPE_DOWN);
}
} else {
if(x==-1 && y==-1){
sigAddDataPoint3BA(signature, x, y, SignatureTouchType.TOUCH_TYPE_UP);
}else{
sigAddDataPoint3BA(signature, x, y, SignatureTouchType.TOUCH_TYPE_MOVED);
}
}
}
private static void sigAddDataPoint3BA(Signature signature, int x, int y, SignatureTouchType signatureTouchType) {
byte[] coord3BABuf = new byte[4];
int index=0;
Point point = null;
switch (signatureTouchType) {
case TOUCH_TYPE_DOWN:
point = new Point(normalize3BACoordinate(x, true),
normalize3BACoordinate(y, true));
coord3BABuf[index++] = (byte) calcControl(normalize3BACoordinate(x, false),
normalize3BACoordinate(y, false));
coord3BABuf[index++] = (byte) calcCharacter(point.getX());
coord3BABuf[index++] = (byte) calcCharacter(point.getY());
coord3BABuf[index++] = (byte) calcLastCharacter(point.getX(), point.getY());
appendToBuffer(signature, coord3BABuf, index);
break;
case TOUCH_TYPE_MOVED:
point = new Point(normalize3BACoordinate(x-signature.getPrevPoint().getX(), true),
normalize3BACoordinate(y-signature.getPrevPoint().getY(), true));
coord3BABuf[index++] = (byte) calcCharacter(point.getX());
coord3BABuf[index++] = (byte) calcCharacter(point.getY());
coord3BABuf[index++] = (byte) calcLastCharacter(point.getX(), point.getY());
appendToBuffer(signature, coord3BABuf, index);
break;
case TOUCH_TYPE_UP:
coord3BABuf[index++]=0x70;
appendToBuffer(signature, coord3BABuf, index);
default:
break;
}
signature.setPrevPoint(new Point(x, y));
}
private static void appendToBuffer(Signature signature, byte[] data, int size){
if(signature.getBuffer()==null || signature.getCurrentMarker()+size >= signature.capacity){
int capacity = signature.getCapacity()+16;
signature.setCapacity(capacity);
}
signature.addBuffer(data, size);
}
private static int normalize3BACoordinate(int coord, boolean isNineBits) {
boolean isNegative = coord<0;
int sign = (isNegative)?(isNineBits?1<<8:1<<11):0;
int value = (isNineBits)?(coord&0x1ff):(coord&0xfff);
return sign | value;
}
private static int calcControl(int x, int y) {
return ((((x)>>7)&0xc)|(((y)>>9)&0x3)|0x60);
}
private static int calcCharacter(int n) {
return ((((n)>>3)&0x3f)+0x20);
}
private static int calcLastCharacter(int x, int y){
return (((((x)&0x7)<<3)|((y)&0x7))+0x20);
}
enum SignatureTouchType{
TOUCH_TYPE_DOWN, TOUCH_TYPE_UP, TOUCH_TYPE_ENTERED, TOUCH_TYPE_EXITED, TOUCH_TYPE_MOVED, TOUCH_TYPE_UNKNOWN;
}
}
class Signature{
byte[] buffer;
int currentMarker;
int capacity;
Point prevPoint;
public byte[] getBuffer() {
return buffer;
}
public void setPrevPoint(Point point) {
this.prevPoint = point;
}
public void setCapacity(int size){
this.capacity=size;
if(this.buffer==null){
this.buffer = new byte[this.capacity];
} else{
byte[] temp = new byte[this.capacity];
System.arraycopy(buffer, 0, temp, 0, this.currentMarker);
this.buffer = temp;
}
}
public int getCurrentMarker() {
return currentMarker;
}
public int getCapacity() {
return capacity;
}
public Point getPrevPoint() {
return prevPoint;
}
public Signature(int capacity, Point prevPoint, byte[] add) {
if(capacity<0) return;
this.buffer = new byte[capacity];
addBuffer(add, add.length);
this.prevPoint=prevPoint;
}
public void addBuffer(byte[] addBuffer, int size) {
if(addBuffer == null) return;
if(this.currentMarker + size >= this.capacity) {
throw new IllegalArgumentException("Capacity is lesser than requested buffer size");
}
for(int i=0;i<size;i++) {
this.buffer[i+this.currentMarker]=addBuffer[i];
}
this.currentMarker+=size;
}
}
class Point {
static final Point MAX_VALUE = new Point(Integer.MAX_VALUE, Integer.MAX_VALUE);
static final Point MIN_VALUE = new Point(Integer.MIN_VALUE, Integer.MIN_VALUE);
static final Point ORIGIN = new Point(0, 0);
private final int x, y;
public Point(final int x, final int y) {
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public Point add(final Point other) {
return valueOf(x + other.x, y + other.y);
}
public Point negate() {
return valueOf(-x, -y);
}
@Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof Point)) {
return false;
}
final Point other = (Point) obj;
return x == other.x && y == other.y;
}
@Override
public int hashCode() {
return Objects.hash(x, y);
}
@Override
public String toString() {
return "(" + x + ',' + y + ')';
}
static Point valueOf(final int x, final int y) {
if (x == ORIGIN.x && y == ORIGIN.y) {
return ORIGIN;
} else {
return new Point(x, y);
}
}
}
@Barala
Copy link
Author

Barala commented Sep 9, 2018

Signature class can be removed. If you use java ByteBuffer directly!!

@milindkarpe
Copy link

Can we convert the 3 Byte array points to 4 Byte array points?

@Barala
Copy link
Author

Barala commented Mar 18, 2020

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment