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

com.badlogic.gdx.utils.compression.rangecoder.Encoder Maven / Gradle / Ivy

The newest version!
/*******************************************************************************
 * Copyright 2011 See AUTHORS file.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 ******************************************************************************/

package com.badlogic.gdx.utils.compression.rangecoder;

import java.io.IOException;

public class Encoder {
	static final int kTopMask = ~((1 << 24) - 1);

	static final int kNumBitModelTotalBits = 11;
	static final int kBitModelTotal = (1 << kNumBitModelTotalBits);
	static final int kNumMoveBits = 5;

	java.io.OutputStream Stream;

	long Low;
	int Range;
	int _cacheSize;
	int _cache;

	long _position;

	public void SetStream (java.io.OutputStream stream) {
		Stream = stream;
	}

	public void ReleaseStream () {
		Stream = null;
	}

	public void Init () {
		_position = 0;
		Low = 0;
		Range = -1;
		_cacheSize = 1;
		_cache = 0;
	}

	public void FlushData () throws IOException {
		for (int i = 0; i < 5; i++)
			ShiftLow();
	}

	public void FlushStream () throws IOException {
		Stream.flush();
	}

	public void ShiftLow () throws IOException {
		int LowHi = (int)(Low >>> 32);
		if (LowHi != 0 || Low < 0xFF000000L) {
			_position += _cacheSize;
			int temp = _cache;
			do {
				Stream.write(temp + LowHi);
				temp = 0xFF;
			} while (--_cacheSize != 0);
			_cache = (((int)Low) >>> 24);
		}
		_cacheSize++;
		Low = (Low & 0xFFFFFF) << 8;
	}

	public void EncodeDirectBits (int v, int numTotalBits) throws IOException {
		for (int i = numTotalBits - 1; i >= 0; i--) {
			Range >>>= 1;
			if (((v >>> i) & 1) == 1) Low += Range;
			if ((Range & Encoder.kTopMask) == 0) {
				Range <<= 8;
				ShiftLow();
			}
		}
	}

	public long GetProcessedSizeAdd () {
		return _cacheSize + _position + 4;
	}

	static final int kNumMoveReducingBits = 2;
	public static final int kNumBitPriceShiftBits = 6;

	public static void InitBitModels (short[] probs) {
		for (int i = 0; i < probs.length; i++)
			probs[i] = (kBitModelTotal >>> 1);
	}

	public void Encode (short[] probs, int index, int symbol) throws IOException {
		int prob = probs[index];
		int newBound = (Range >>> kNumBitModelTotalBits) * prob;
		if (symbol == 0) {
			Range = newBound;
			probs[index] = (short)(prob + ((kBitModelTotal - prob) >>> kNumMoveBits));
		} else {
			Low += (newBound & 0xFFFFFFFFL);
			Range -= newBound;
			probs[index] = (short)(prob - ((prob) >>> kNumMoveBits));
		}
		if ((Range & kTopMask) == 0) {
			Range <<= 8;
			ShiftLow();
		}
	}

	private static int[] ProbPrices = new int[kBitModelTotal >>> kNumMoveReducingBits];

	static {
		int kNumBits = (kNumBitModelTotalBits - kNumMoveReducingBits);
		for (int i = kNumBits - 1; i >= 0; i--) {
			int start = 1 << (kNumBits - i - 1);
			int end = 1 << (kNumBits - i);
			for (int j = start; j < end; j++)
				ProbPrices[j] = (i << kNumBitPriceShiftBits) + (((end - j) << kNumBitPriceShiftBits) >>> (kNumBits - i - 1));
		}
	}

	static public int GetPrice (int Prob, int symbol) {
		return ProbPrices[(((Prob - symbol) ^ ((-symbol))) & (kBitModelTotal - 1)) >>> kNumMoveReducingBits];
	}

	static public int GetPrice0 (int Prob) {
		return ProbPrices[Prob >>> kNumMoveReducingBits];
	}

	static public int GetPrice1 (int Prob) {
		return ProbPrices[(kBitModelTotal - Prob) >>> kNumMoveReducingBits];
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy