All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.rcsb.cif.binary.encoding.RunLengthEncoding Maven / Gradle / Ivy

package org.rcsb.cif.binary.encoding;

import org.rcsb.cif.binary.data.Int32Array;
import org.rcsb.cif.binary.data.IntArray;

import java.util.ArrayDeque;
import java.util.Deque;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * 

Represents each integer value in the input as a pair of (value, number of repeats) and stores the result * sequentially as {@link Int32Array}. Additionally, stores the size of the original array to make decoding * easier.

* *
 * RunLength {
 *     kind = "RunLength"
 *     srcType: int[]
 *     srcSize: number
 * }
 * Example
 * [1, 1, 1, 2, 3, 3]
 * ---RunLength--->
 * { srcSize = 6 } [1, 3, 2, 1, 3, 2]
 * 
*/ public class RunLengthEncoding implements Encoding { private int srcType; private int srcSize; public RunLengthEncoding() { } public RunLengthEncoding(int srcType, int srcSize) { this.srcType = srcType; this.srcSize = srcSize; } @Override public Map getMapRepresentation() { Map map = new LinkedHashMap<>(); map.put("kind", "RunLength"); map.put("srcType", srcType); map.put("srcSize", srcSize); return map; } @Override public IntArray decode(Int32Array data) { int[] input = data.getData(); if (input.length == 0) { return data; } int dataOffset = 0; IntArray output = IntArray.create(srcType, srcSize); output.setEncoding(data.getEncoding()); int[] outputArray = output.getData(); for (int i = 0; i < data.length(); i += 2) { int value = input[i]; // value to be repeated int length = input[i + 1]; // number of repeats for (int j = 0; j < length; ++j) { outputArray[dataOffset++] = value; } } return output; } @Override public Int32Array encode(IntArray data) { int[] input = data.getData(); if (input.length == 0) { Deque> enc = new ArrayDeque<>(data.getEncoding()); this.srcType = 3; this.srcSize = 0; enc.add(this); return new Int32Array(new int[0], enc); } // calculate output size int fullLength = 2; for (int i = 1; i < input.length; i++) { if (input[i - 1] != input[i]) { fullLength += 2; } } int[] output = new int[fullLength]; int offset = 0; int runLength = 1; for (int i = 1; i < input.length; i++) { if (input[i - 1] != input[i]) { output[offset] = input[i - 1]; output[offset + 1] = runLength; runLength = 1; offset += 2; } else { ++runLength; } } output[offset] = input[input.length - 1]; output[offset + 1] = runLength; Deque> enc = new ArrayDeque<>(data.getEncoding()); this.srcType = 3; this.srcSize = input.length; enc.add(this); return new Int32Array(output, enc); } @Override public String toString() { return "RunLengthEncoding{" + "srcType=" + srcType + ", srcSize=" + srcSize + '}'; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy