Rev 331 |
Blame |
Compare with Previous |
Last modification |
View Log
| RSS feed
/*
* Copyright (C) 2014 Steve Ratcliffe
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 or
* version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
package test.files;
import uk.me.parabola.imgfmt.app.ImgFileReader;
/**
* Read a direction from NOD 1.
*
* This is moderately complex. You can have a single direction in a byte or two 4 bit directions.
* If the first haveNet bit is 1 then you have the 2 4 bit directions, otherwise a single 8 bit.
*
* When you read a direction and you have packed 4 bit directions then every other read just uses
* the other half of the byte that was read and saved before.
*
* When the haveNet bit is zero, then the sign bit is used to indicate if the current direction value
* should be used or a new one. When there are a sequence of haveNet==false arcs, then the first
* one that also has sign==true will read the next direction.
*
* So there may be several haveNet==false,sign==false followed by one or more haveNet==false,sign=true arcs.
* The first set will all have the same direction and the second set will have the next direction.
*
* @author Steve Ratcliffe
*/
public class DirectionReader {
private final ImgFileReader reader;
private boolean haveDir;
private boolean largeDir;
private byte savedDir;
private boolean lastSign;
public DirectionReader(ImgFileReader reader) {
this.reader = reader;
}
public int fetchDirection(boolean first, boolean hasNet, boolean sign) {
if (first) {
haveDir = false;
largeDir = !hasNet;
}
int direction;
if (first || hasNet || (sign != lastSign)) {
direction = fetchDirection();
} else {
direction = currentDirection(largeDir);
}
lastSign = sign;
return direction;
}
private int fetchDirection() {
if (largeDir) {
savedDir = reader.get();
return savedDir;
}
if (haveDir) {
haveDir = false;
int dir = (savedDir & 0xf0);
return dir;
} else {
savedDir = reader.get();
haveDir = true;
int dir = (savedDir & 0xf) << 4;
return dir;
}
}
private int currentDirection(boolean largeDir) {
if (largeDir)
return savedDir;
return haveDir ? ((savedDir & 0xf) << 4) : (savedDir & 0xf0);
}
}