org.opentripplanner.common.geometry.DlugoszVarLenIntPacker Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of otp Show documentation
Show all versions of otp Show documentation
The OpenTripPlanner multimodal journey planning system
package org.opentripplanner.common.geometry;
import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
import java.util.List;
/**
* Variable-length integer encoding. This optimize integer storage when most of the values are
* small, but few of them can be quite large (as in a geometry). Adapted Dlugosz scheme to support
* signed int whose average are around 0.
*
* See Dlugosz' variable-length integer encoding (http://www.dlugosz.com/ZIP2/VLI.html).
*
* @author laurent
*
*/
public class DlugoszVarLenIntPacker {
public static byte[] pack(int[] arr) {
if (arr == null)
return null;
ByteArrayOutputStream baos = new ByteArrayOutputStream(arr.length);
for (int i : arr) {
if (i >= -64 && i <= 63) {
// 0xxx xxxx -> 7 bits value
// i+64 between 0 and 127, 7 bits
int ui = i + 64;
baos.write(ui);
} else if (i >= -8192 && i <= 8191) {
// 10xx xxxx + 8 -> 14 bits value
// i+8192 between 0 and 16383
int ui = i + 8192;
baos.write(0x80 | (ui >> 8)); // 6b MSB
baos.write(ui & 0xFF); // 8b LSB
} else if (i >= -1048576 && i <= 1048575) {
// 110 xxxx + 2x8 -> 21 bits value
// i + 1048576 between 0 and 2097151
int ui = i + 1048576;
baos.write(0xC0 | (ui >> 16)); // 5b MSB
baos.write((ui >> 8) & 0xFF); // 8b
baos.write(ui & 0xFF); // 8b
} else if (i >= -67108864 && i <= 67108863) {
// 1110 0xxx + 3x8 -> 27 bits value
// i + 67108864 between 0 and 134217727
int ui = i + 67108864;
baos.write(0xE0 | (ui >> 24)); // 3b MSB
baos.write((ui >> 16) & 0xFF); // 8b
baos.write((ui >> 8) & 0xFF); // 8b
baos.write(ui & 0xFF); // 8b
} else { // int can't have more than 32 bits
// 1110 1xxx + 4x8 -> 35 bits value
// i + 0x80000000 fits in 35 bits for sure
long ui = (long) i + 2147483648L;
baos.write((int) (0xE8 | (ui >> 32))); // 3b MSB
baos.write((int) ((ui >> 24) & 0xFF)); // 8b
baos.write((int) ((ui >> 16) & 0xFF)); // 8b
baos.write((int) ((ui >> 8) & 0xFF)); // 8b
baos.write((int) (ui & 0xFF)); // 8b
}
}
return baos.toByteArray();
}
public static int[] unpack(byte[] arr) {
if (arr == null)
return null;
List retval = new ArrayList(arr.length);
int i = 0;
while (i < arr.length) {
int v1 = arr[i] & 0xFF;
i++;
if ((v1 & 0x80) == 0x00) {
// 0xxx xxxx -> 7 bits value
int sv = (v1 & 0x7F) - 64;
retval.add(sv);
} else if ((v1 & 0xC0) == 0x80) {
// 10xx xxxx + 8 -> 14 bits value
int sv = ((v1 & 0x3F) << 8) + (arr[i] & 0xFF) - 8192;
i++;
retval.add(sv);
} else if ((v1 & 0xE0) == 0xC0) {
// 110 xxxx + 2x8 -> 21 bits value
int sv = ((v1 & 0x1F) << 16) + ((arr[i] & 0xFF) << 8) + (arr[i + 1] & 0xFF)
- 1048576;
i += 2;
retval.add(sv);
} else if ((v1 & 0xF8) == 0xE0) {
// 1110 0xxx + 3x8 -> 27 bits value
int sv = ((v1 & 0x1F) << 24) + ((arr[i] & 0xFF) << 16) + ((arr[i + 1] & 0xFF) << 8)
+ (arr[i + 2] & 0xFF) - 67108864;
i += 3;
retval.add(sv);
} else {
// 1110 1xxx + 4x8 -> 35 bits value
long sv = (((long) v1 & 0x1F) << 32) + ((arr[i] & 0xFF) << 24)
+ ((arr[i + 1] & 0xFF) << 16) + ((arr[i + 2] & 0xFF) << 8)
+ (arr[i + 3] & 0xFF) - 2147483648L;
i += 4;
retval.add((int) sv);
}
}
int[] bufret = new int[retval.size()];
i = 0;
for (int v : retval) {
bufret[i++] = v;
}
return bufret;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy