www in docker support
This commit is contained in:
parent
539a848e95
commit
c227fce036
2145 changed files with 399596 additions and 58 deletions
|
|
@ -0,0 +1,426 @@
|
|||
package org.jcodec.common;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
|
||||
public class ArrayUtil {
|
||||
public static <T> void shiftRight1(T[] array) {
|
||||
for (int i = 1; i < array.length; i++)
|
||||
array[i] = array[i - 1];
|
||||
array[0] = null;
|
||||
}
|
||||
|
||||
public static <T> void shiftLeft1(T[] array) {
|
||||
for (int i = 0; i < array.length - 1; i++)
|
||||
array[i] = array[i + 1];
|
||||
array[array.length - 1] = null;
|
||||
}
|
||||
|
||||
public static <T> void shiftRight3(T[] array, int from, int to) {
|
||||
for (int i = to - 1; i > from; i--)
|
||||
array[i] = array[i - 1];
|
||||
array[from] = null;
|
||||
}
|
||||
|
||||
public static <T> void shiftLeft3(T[] array, int from, int to) {
|
||||
for (int i = from; i < to - 1; i++)
|
||||
array[i] = array[i + 1];
|
||||
array[to - 1] = null;
|
||||
}
|
||||
|
||||
public static <T> void shiftLeft2(T[] array, int from) {
|
||||
shiftLeft3(array, from, array.length);
|
||||
}
|
||||
|
||||
public static <T> void shiftRight2(T[] array, int to) {
|
||||
shiftRight3(array, 0, to);
|
||||
}
|
||||
|
||||
public static final void swap(int[] arr, int ind1, int ind2) {
|
||||
if (ind1 == ind2)
|
||||
return;
|
||||
int tmp = arr[ind1];
|
||||
arr[ind1] = arr[ind2];
|
||||
arr[ind2] = tmp;
|
||||
}
|
||||
|
||||
public static final int sumInt(int[] array) {
|
||||
int result = 0;
|
||||
for (int i = 0; i < array.length; i++)
|
||||
result += array[i];
|
||||
return result;
|
||||
}
|
||||
|
||||
public static final int sumByte(byte[] array) {
|
||||
int result = 0;
|
||||
for (int i = 0; i < array.length; i++)
|
||||
result += array[i];
|
||||
return result;
|
||||
}
|
||||
|
||||
public static int sumInt3(int[] array, int from, int count) {
|
||||
int result = 0;
|
||||
for (int i = from; i < from + count; i++)
|
||||
result += array[i];
|
||||
return result;
|
||||
}
|
||||
|
||||
public static int sumByte3(byte[] array, int from, int count) {
|
||||
int result = 0;
|
||||
for (int i = from; i < from + count; i++)
|
||||
result += array[i];
|
||||
return result;
|
||||
}
|
||||
|
||||
public static void addInt(int[] array, int val) {
|
||||
for (int i = 0; i < array.length; i++)
|
||||
array[i] = array[i] + val;
|
||||
}
|
||||
|
||||
public static int[] addAllInt(int[] array1, int[] array2) {
|
||||
if (array1 == null)
|
||||
return cloneInt(array2);
|
||||
if (array2 == null)
|
||||
return cloneInt(array1);
|
||||
int[] joinedArray = new int[array1.length + array2.length];
|
||||
System.arraycopy(array1, 0, joinedArray, 0, array1.length);
|
||||
System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
|
||||
return joinedArray;
|
||||
}
|
||||
|
||||
public static long[] addAllLong(long[] array1, long[] array2) {
|
||||
if (array1 == null)
|
||||
return cloneLong(array2);
|
||||
if (array2 == null)
|
||||
return cloneLong(array1);
|
||||
long[] joinedArray = new long[array1.length + array2.length];
|
||||
System.arraycopy(array1, 0, joinedArray, 0, array1.length);
|
||||
System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
|
||||
return joinedArray;
|
||||
}
|
||||
|
||||
public static Object[] addAllObj(Object[] array1, Object[] array2) {
|
||||
if (array1 == null)
|
||||
return cloneObj(array2);
|
||||
if (array2 == null)
|
||||
return cloneObj(array1);
|
||||
Object[] joinedArray = (Object[])Array.newInstance(array1.getClass().getComponentType(), array1.length + array2.length);
|
||||
System.arraycopy(array1, 0, joinedArray, 0, array1.length);
|
||||
System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
|
||||
return joinedArray;
|
||||
}
|
||||
|
||||
public static int[] cloneInt(int[] array) {
|
||||
if (array == null)
|
||||
return null;
|
||||
return (int[])array.clone();
|
||||
}
|
||||
|
||||
public static long[] cloneLong(long[] array) {
|
||||
if (array == null)
|
||||
return null;
|
||||
return (long[])array.clone();
|
||||
}
|
||||
|
||||
public static Object[] cloneObj(Object[] array) {
|
||||
if (array == null)
|
||||
return null;
|
||||
return (Object[])array.clone();
|
||||
}
|
||||
|
||||
public static byte[] toByteArrayShifted(int[] array) {
|
||||
byte[] result = new byte[array.length];
|
||||
for (int i = 0; i < array.length; i++)
|
||||
result[i] = (byte)(array[i] - 128);
|
||||
return result;
|
||||
}
|
||||
|
||||
public static byte[][] toByteArrayShifted2(int[][] intArray) {
|
||||
byte[][] result = new byte[intArray.length][];
|
||||
for (int i = 0; i < intArray.length; i++)
|
||||
result[i] = toByteArrayShifted(intArray[i]);
|
||||
return result;
|
||||
}
|
||||
|
||||
public static int[] toIntArrayUnshifted(byte[] bytes) {
|
||||
int[] result = new int[bytes.length];
|
||||
for (int i = 0; i < result.length; i++)
|
||||
result[i] = (byte)(bytes[i] + 128);
|
||||
return result;
|
||||
}
|
||||
|
||||
public static byte[] toByteArray(int[] ints) {
|
||||
byte[] result = new byte[ints.length];
|
||||
for (int i = 0; i < ints.length; i++)
|
||||
result[i] = (byte)ints[i];
|
||||
return result;
|
||||
}
|
||||
|
||||
public static int[] toIntArray(byte[] bytes) {
|
||||
int[] result = new int[bytes.length];
|
||||
for (int i = 0; i < result.length; i++)
|
||||
result[i] = bytes[i];
|
||||
return result;
|
||||
}
|
||||
|
||||
public static int[] toUnsignedIntArray(byte[] bytes) {
|
||||
int[] result = new int[bytes.length];
|
||||
for (int i = 0; i < bytes.length; i++)
|
||||
result[i] = bytes[i] & 0xFF;
|
||||
return result;
|
||||
}
|
||||
|
||||
public static <T> void reverse(T[] frames) {
|
||||
for (int i = 0, j = frames.length - 1; i < frames.length >> 1; i++, j--) {
|
||||
T tmp = frames[i];
|
||||
frames[i] = frames[j];
|
||||
frames[j] = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
public static int max(int[] array) {
|
||||
int max = Integer.MIN_VALUE;
|
||||
for (int i = 0; i < array.length; i++) {
|
||||
if (array[i] > max)
|
||||
max = array[i];
|
||||
}
|
||||
return max;
|
||||
}
|
||||
|
||||
public static int[][] rotate(int[][] src) {
|
||||
int[][] dst = new int[(src[0]).length][src.length];
|
||||
for (int i = 0; i < src.length; i++) {
|
||||
for (int j = 0; j < (src[0]).length; j++)
|
||||
dst[j][i] = src[i][j];
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
|
||||
public static byte[][] create2D(int width, int height) {
|
||||
byte[][] result = new byte[height][];
|
||||
for (int i = 0; i < height; i++)
|
||||
result[i] = new byte[width];
|
||||
return result;
|
||||
}
|
||||
|
||||
public static void printMatrixBytes(byte[] array, String format, int width) {
|
||||
String[] strings = new String[array.length];
|
||||
int maxLen = 0;
|
||||
for (int i = 0; i < array.length; i++) {
|
||||
strings[i] = String.format(format, array[i]);
|
||||
maxLen = Math.max(maxLen, strings[i].length());
|
||||
}
|
||||
for (int ind = 0; ind < strings.length; ) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for (int j = 0; j < width && ind < strings.length; j++, ind++) {
|
||||
for (int k = 0; k < maxLen - strings[ind].length() + 1; k++)
|
||||
builder.append(" ");
|
||||
builder.append(strings[ind]);
|
||||
}
|
||||
System.out.println(builder);
|
||||
}
|
||||
}
|
||||
|
||||
public static void printMatrix(int[] array, String format, int width) {
|
||||
String[] strings = new String[array.length];
|
||||
int maxLen = 0;
|
||||
for (int i = 0; i < array.length; i++) {
|
||||
strings[i] = String.format(format, array[i]);
|
||||
maxLen = Math.max(maxLen, strings[i].length());
|
||||
}
|
||||
for (int ind = 0; ind < strings.length; ) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for (int j = 0; j < width && ind < strings.length; j++, ind++) {
|
||||
for (int k = 0; k < maxLen - strings[ind].length() + 1; k++)
|
||||
builder.append(" ");
|
||||
builder.append(strings[ind]);
|
||||
}
|
||||
System.out.println(builder);
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] padLeft(byte[] array, int padLength) {
|
||||
byte[] result = new byte[array.length + padLength];
|
||||
for (int i = padLength; i < result.length; i++)
|
||||
result[i] = array[i - padLength];
|
||||
return result;
|
||||
}
|
||||
|
||||
public static int[] randomIntArray(int size, int from, int to) {
|
||||
int width = to - from;
|
||||
int[] result = new int[size];
|
||||
for (int i = 0; i < size; i++)
|
||||
result[i] = (int)(Math.random() * (double)width % (double)width) + from;
|
||||
return result;
|
||||
}
|
||||
|
||||
public static byte[] randomByteArray(int size, byte from, byte to) {
|
||||
byte width = (byte)(to - from);
|
||||
byte[] result = new byte[size];
|
||||
for (int i = 0; i < size; i++)
|
||||
result[i] = (byte)(int)(Math.random() * (double)width % (double)width + (double)from);
|
||||
return result;
|
||||
}
|
||||
|
||||
public static void quickSort(int[] a, int start, int end, int[] p) {
|
||||
int len = end - start;
|
||||
if (len < 2)
|
||||
return;
|
||||
int startPlus1 = start + 1;
|
||||
if (len == 2) {
|
||||
if (a[start] > a[startPlus1]) {
|
||||
swap(a, start, startPlus1);
|
||||
if (p != null)
|
||||
swap(p, start, startPlus1);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (len == 3) {
|
||||
if (a[start] > a[startPlus1]) {
|
||||
swap(a, start, startPlus1);
|
||||
if (p != null)
|
||||
swap(p, start, startPlus1);
|
||||
}
|
||||
int startPlus2 = start + 2;
|
||||
if (a[startPlus1] > a[startPlus2]) {
|
||||
swap(a, startPlus1, startPlus2);
|
||||
if (p != null)
|
||||
swap(p, startPlus1, startPlus2);
|
||||
}
|
||||
if (a[start] > a[startPlus1]) {
|
||||
swap(a, start, startPlus1);
|
||||
if (p != null)
|
||||
swap(p, start, startPlus1);
|
||||
}
|
||||
}
|
||||
int pivot = a[0];
|
||||
int p_large = end - 1;
|
||||
for (int i = end - 1; i >= start; i--) {
|
||||
if (a[i] > pivot) {
|
||||
swap(a, i, p_large);
|
||||
if (p != null)
|
||||
swap(p, i, p_large);
|
||||
p_large--;
|
||||
}
|
||||
}
|
||||
swap(a, start, p_large);
|
||||
if (p != null)
|
||||
swap(p, start, p_large);
|
||||
quickSort(a, start, p_large, p);
|
||||
quickSort(a, p_large + 1, end, p);
|
||||
}
|
||||
|
||||
public static int[] flatten5D(int[][][][][] is) {
|
||||
IntArrayList list = new IntArrayList(128);
|
||||
flatten5DL(is, list);
|
||||
return list.toArray();
|
||||
}
|
||||
|
||||
public static int[] flatten4D(int[][][][] is) {
|
||||
IntArrayList list = new IntArrayList(128);
|
||||
flatten4DL(is, list);
|
||||
return list.toArray();
|
||||
}
|
||||
|
||||
public static int[] flatten3D(int[][][] is) {
|
||||
IntArrayList list = new IntArrayList(128);
|
||||
flatten3DL(is, list);
|
||||
return list.toArray();
|
||||
}
|
||||
|
||||
public static int[] flatten2D(int[][] is) {
|
||||
IntArrayList list = new IntArrayList(128);
|
||||
flatten2DL(is, list);
|
||||
return list.toArray();
|
||||
}
|
||||
|
||||
private static void flatten5DL(int[][][][][] is, IntArrayList list) {
|
||||
for (int i = 0; i < is.length; i++)
|
||||
flatten4DL(is[i], list);
|
||||
}
|
||||
|
||||
private static void flatten4DL(int[][][][] is, IntArrayList list) {
|
||||
for (int i = 0; i < is.length; i++)
|
||||
flatten3DL(is[i], list);
|
||||
}
|
||||
|
||||
private static void flatten3DL(int[][][] is, IntArrayList list) {
|
||||
for (int i = 0; i < is.length; i++)
|
||||
flatten2DL(is[i], list);
|
||||
}
|
||||
|
||||
private static void flatten2DL(int[][] is, IntArrayList list) {
|
||||
for (int i = 0; i < is.length; i++)
|
||||
flatten1DL(is[i], list);
|
||||
}
|
||||
|
||||
private static void flatten1DL(int[] is, IntArrayList list) {
|
||||
for (int i = 0; i < is.length; i++)
|
||||
list.add(is[i]);
|
||||
}
|
||||
|
||||
public static void copy6D(int[][][][][][] to, int[][][][][][] from) {
|
||||
for (int i = 0; i < Math.min(to.length, from.length); i++)
|
||||
copy5D(to[i], from[i]);
|
||||
}
|
||||
|
||||
public static void copy5D(int[][][][][] to, int[][][][][] from) {
|
||||
for (int i = 0; i < Math.min(to.length, from.length); i++)
|
||||
copy4D(to[i], from[i]);
|
||||
}
|
||||
|
||||
public static void copy4D(int[][][][] to, int[][][][] from) {
|
||||
for (int i = 0; i < Math.min(to.length, from.length); i++)
|
||||
copy3D(to[i], from[i]);
|
||||
}
|
||||
|
||||
public static void copy3D(int[][][] to, int[][][] from) {
|
||||
for (int i = 0; i < Math.min(to.length, from.length); i++)
|
||||
copy2D(to[i], from[i]);
|
||||
}
|
||||
|
||||
public static void copy2D(int[][] to, int[][] from) {
|
||||
for (int i = 0; i < Math.min(to.length, from.length); i++)
|
||||
copy1D(to[i], from[i]);
|
||||
}
|
||||
|
||||
public static void copy1D(int[] to, int[] from) {
|
||||
for (int i = 0; i < Math.min(to.length, from.length); i++)
|
||||
to[i] = from[i];
|
||||
}
|
||||
|
||||
public static int fill6D(int[][][][][][] to, int[] from, int index) {
|
||||
for (int i = 0; i < to.length; i++)
|
||||
index = fill5D(to[i], from, index);
|
||||
return index;
|
||||
}
|
||||
|
||||
public static int fill5D(int[][][][][] to, int[] from, int index) {
|
||||
for (int i = 0; i < to.length; i++)
|
||||
index = fill4D(to[i], from, index);
|
||||
return index;
|
||||
}
|
||||
|
||||
public static int fill4D(int[][][][] to, int[] from, int index) {
|
||||
for (int i = 0; i < to.length; i++)
|
||||
index = fill3D(to[i], from, index);
|
||||
return index;
|
||||
}
|
||||
|
||||
public static int fill3D(int[][][] to, int[] from, int index) {
|
||||
for (int i = 0; i < to.length; i++)
|
||||
index = fill2D(to[i], from, index);
|
||||
return index;
|
||||
}
|
||||
|
||||
public static int fill2D(int[][] to, int[] from, int index) {
|
||||
for (int i = 0; i < to.length; i++)
|
||||
index = fill1D(to[i], from, index);
|
||||
return index;
|
||||
}
|
||||
|
||||
public static int fill1D(int[] to, int[] from, int index) {
|
||||
for (int i = 0; i < to.length; i++)
|
||||
to[i] = from[index++];
|
||||
return index;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,119 @@
|
|||
package org.jcodec.common;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import org.jcodec.common.model.Label;
|
||||
|
||||
public class AudioCodecMeta extends CodecMeta {
|
||||
private int sampleSize;
|
||||
|
||||
private int channelCount;
|
||||
|
||||
private int sampleRate;
|
||||
|
||||
private ByteOrder endian;
|
||||
|
||||
private int samplesPerPacket;
|
||||
|
||||
private int bytesPerPacket;
|
||||
|
||||
private int bytesPerFrame;
|
||||
|
||||
private boolean pcm;
|
||||
|
||||
private Label[] labels;
|
||||
|
||||
public static AudioCodecMeta createAudioCodecMeta(String fourcc, int sampleSize, int channelCount, int sampleRate, ByteOrder endian, boolean pcm, Label[] labels, ByteBuffer codecPrivate) {
|
||||
AudioCodecMeta self = new AudioCodecMeta(fourcc, codecPrivate);
|
||||
self.sampleSize = sampleSize;
|
||||
self.channelCount = channelCount;
|
||||
self.sampleRate = sampleRate;
|
||||
self.endian = endian;
|
||||
self.pcm = pcm;
|
||||
self.labels = labels;
|
||||
return self;
|
||||
}
|
||||
|
||||
public static AudioCodecMeta createAudioCodecMeta2(String fourcc, int sampleSize, int channelCount, int sampleRate, ByteOrder endian, boolean pcm, Label[] labels, int samplesPerPacket, int bytesPerPacket, int bytesPerFrame, ByteBuffer codecPrivate) {
|
||||
AudioCodecMeta self = new AudioCodecMeta(fourcc, codecPrivate);
|
||||
self.sampleSize = sampleSize;
|
||||
self.channelCount = channelCount;
|
||||
self.sampleRate = sampleRate;
|
||||
self.endian = endian;
|
||||
self.samplesPerPacket = samplesPerPacket;
|
||||
self.bytesPerPacket = bytesPerPacket;
|
||||
self.bytesPerFrame = bytesPerFrame;
|
||||
self.pcm = pcm;
|
||||
self.labels = labels;
|
||||
return self;
|
||||
}
|
||||
|
||||
public static AudioCodecMeta createAudioCodecMeta3(String fourcc, ByteBuffer codecPrivate, AudioFormat format, boolean pcm, Label[] labels) {
|
||||
AudioCodecMeta self = new AudioCodecMeta(fourcc, codecPrivate);
|
||||
self.sampleSize = format.getSampleSizeInBits() >> 3;
|
||||
self.channelCount = format.getChannels();
|
||||
self.sampleRate = format.getSampleRate();
|
||||
self.endian = format.isBigEndian() ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN;
|
||||
self.pcm = pcm;
|
||||
self.labels = labels;
|
||||
return self;
|
||||
}
|
||||
|
||||
public AudioCodecMeta(String fourcc, ByteBuffer codecPrivate) {
|
||||
super(fourcc, codecPrivate);
|
||||
}
|
||||
|
||||
public int getFrameSize() {
|
||||
return this.sampleSize * this.channelCount;
|
||||
}
|
||||
|
||||
public int getSampleRate() {
|
||||
return this.sampleRate;
|
||||
}
|
||||
|
||||
public int getSampleSize() {
|
||||
return this.sampleSize;
|
||||
}
|
||||
|
||||
public int getChannelCount() {
|
||||
return this.channelCount;
|
||||
}
|
||||
|
||||
public int getSamplesPerPacket() {
|
||||
return this.samplesPerPacket;
|
||||
}
|
||||
|
||||
public int getBytesPerPacket() {
|
||||
return this.bytesPerPacket;
|
||||
}
|
||||
|
||||
public int getBytesPerFrame() {
|
||||
return this.bytesPerFrame;
|
||||
}
|
||||
|
||||
public ByteOrder getEndian() {
|
||||
return this.endian;
|
||||
}
|
||||
|
||||
public boolean isPCM() {
|
||||
return this.pcm;
|
||||
}
|
||||
|
||||
public AudioFormat getFormat() {
|
||||
return new AudioFormat(this.sampleRate, this.sampleSize << 3, this.channelCount, true, (this.endian == ByteOrder.BIG_ENDIAN));
|
||||
}
|
||||
|
||||
public Label[] getChannelLabels() {
|
||||
return this.labels;
|
||||
}
|
||||
|
||||
public static AudioCodecMeta fromAudioFormat(AudioFormat format) {
|
||||
AudioCodecMeta self = new AudioCodecMeta(null, null);
|
||||
self.sampleSize = format.getSampleSizeInBits() >> 3;
|
||||
self.channelCount = format.getChannels();
|
||||
self.sampleRate = format.getSampleRate();
|
||||
self.endian = format.isBigEndian() ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN;
|
||||
self.pcm = false;
|
||||
return self;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
package org.jcodec.common;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import org.jcodec.common.model.AudioBuffer;
|
||||
|
||||
public interface AudioDecoder {
|
||||
AudioBuffer decodeFrame(ByteBuffer paramByteBuffer1, ByteBuffer paramByteBuffer2) throws IOException;
|
||||
|
||||
AudioCodecMeta getCodecMeta(ByteBuffer paramByteBuffer) throws IOException;
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
package org.jcodec.common;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
public interface AudioEncoder {
|
||||
ByteBuffer encode(ByteBuffer paramByteBuffer1, ByteBuffer paramByteBuffer2);
|
||||
}
|
||||
|
|
@ -0,0 +1,171 @@
|
|||
package org.jcodec.common;
|
||||
|
||||
public class AudioFormat {
|
||||
private int sampleRate;
|
||||
|
||||
private int sampleSizeInBits;
|
||||
|
||||
private int channelCount;
|
||||
|
||||
private boolean signed;
|
||||
|
||||
private boolean bigEndian;
|
||||
|
||||
public static AudioFormat STEREO_48K_S16_BE = new AudioFormat(48000, 16, 2, true, true);
|
||||
|
||||
public static AudioFormat STEREO_48K_S16_LE = new AudioFormat(48000, 16, 2, true, false);
|
||||
|
||||
public static AudioFormat STEREO_48K_S24_BE = new AudioFormat(48000, 24, 2, true, true);
|
||||
|
||||
public static AudioFormat STEREO_48K_S24_LE = new AudioFormat(48000, 24, 2, true, false);
|
||||
|
||||
public static AudioFormat MONO_48K_S16_BE = new AudioFormat(48000, 16, 1, true, true);
|
||||
|
||||
public static AudioFormat MONO_48K_S16_LE = new AudioFormat(48000, 16, 1, true, false);
|
||||
|
||||
public static AudioFormat MONO_48K_S24_BE = new AudioFormat(48000, 24, 1, true, true);
|
||||
|
||||
public static AudioFormat MONO_48K_S24_LE = new AudioFormat(48000, 24, 1, true, false);
|
||||
|
||||
public static AudioFormat STEREO_44K_S16_BE = new AudioFormat(44100, 16, 2, true, true);
|
||||
|
||||
public static AudioFormat STEREO_44K_S16_LE = new AudioFormat(44100, 16, 2, true, false);
|
||||
|
||||
public static AudioFormat STEREO_44K_S24_BE = new AudioFormat(44100, 24, 2, true, true);
|
||||
|
||||
public static AudioFormat STEREO_44K_S24_LE = new AudioFormat(44100, 24, 2, true, false);
|
||||
|
||||
public static AudioFormat MONO_44K_S16_BE = new AudioFormat(44100, 16, 1, true, true);
|
||||
|
||||
public static AudioFormat MONO_44K_S16_LE = new AudioFormat(44100, 16, 1, true, false);
|
||||
|
||||
public static AudioFormat MONO_44K_S24_BE = new AudioFormat(44100, 24, 1, true, true);
|
||||
|
||||
public static AudioFormat MONO_44K_S24_LE = new AudioFormat(44100, 24, 1, true, false);
|
||||
|
||||
public static AudioFormat STEREO_S16_BE(int rate) {
|
||||
return new AudioFormat(rate, 16, 2, true, true);
|
||||
}
|
||||
|
||||
public static AudioFormat STEREO_S16_LE(int rate) {
|
||||
return new AudioFormat(rate, 16, 2, true, false);
|
||||
}
|
||||
|
||||
public static AudioFormat STEREO_S24_BE(int rate) {
|
||||
return new AudioFormat(rate, 24, 2, true, true);
|
||||
}
|
||||
|
||||
public static AudioFormat STEREO_S24_LE(int rate) {
|
||||
return new AudioFormat(rate, 24, 2, true, false);
|
||||
}
|
||||
|
||||
public static AudioFormat MONO_S16_BE(int rate) {
|
||||
return new AudioFormat(rate, 16, 1, true, true);
|
||||
}
|
||||
|
||||
public static AudioFormat MONO_S16_LE(int rate) {
|
||||
return new AudioFormat(rate, 16, 1, true, false);
|
||||
}
|
||||
|
||||
public static AudioFormat MONO_S24_BE(int rate) {
|
||||
return new AudioFormat(rate, 24, 1, true, true);
|
||||
}
|
||||
|
||||
public static AudioFormat MONO_S24_LE(int rate) {
|
||||
return new AudioFormat(rate, 24, 1, true, false);
|
||||
}
|
||||
|
||||
public static AudioFormat NCH_48K_S16_BE(int n) {
|
||||
return new AudioFormat(48000, 16, n, true, true);
|
||||
}
|
||||
|
||||
public static AudioFormat NCH_48K_S16_LE(int n) {
|
||||
return new AudioFormat(48000, 16, n, true, false);
|
||||
}
|
||||
|
||||
public static AudioFormat NCH_48K_S24_BE(int n) {
|
||||
return new AudioFormat(48000, 24, n, true, true);
|
||||
}
|
||||
|
||||
public static AudioFormat NCH_48K_S24_LE(int n) {
|
||||
return new AudioFormat(48000, 24, n, true, false);
|
||||
}
|
||||
|
||||
public static AudioFormat NCH_44K_S16_BE(int n) {
|
||||
return new AudioFormat(44100, 16, n, true, true);
|
||||
}
|
||||
|
||||
public static AudioFormat NCH_44K_S16_LE(int n) {
|
||||
return new AudioFormat(44100, 16, n, true, false);
|
||||
}
|
||||
|
||||
public static AudioFormat NCH_44K_S24_BE(int n) {
|
||||
return new AudioFormat(44100, 24, n, true, true);
|
||||
}
|
||||
|
||||
public static AudioFormat NCH_44K_S24_LE(int n) {
|
||||
return new AudioFormat(44100, 24, n, true, false);
|
||||
}
|
||||
|
||||
public static AudioFormat createAudioFormat(AudioFormat format) {
|
||||
return new AudioFormat(format.sampleRate, format.sampleSizeInBits, format.channelCount, format.signed, format.bigEndian);
|
||||
}
|
||||
|
||||
public static AudioFormat createAudioFormat2(AudioFormat format, int newSampleRate) {
|
||||
AudioFormat af = new AudioFormat(format.sampleRate, format.sampleSizeInBits, format.channelCount, format.signed, format.bigEndian);
|
||||
af.sampleRate = newSampleRate;
|
||||
return af;
|
||||
}
|
||||
|
||||
public AudioFormat(int sampleRate, int sampleSizeInBits, int channelCount, boolean signed, boolean bigEndian) {
|
||||
this.sampleRate = sampleRate;
|
||||
this.sampleSizeInBits = sampleSizeInBits;
|
||||
this.channelCount = channelCount;
|
||||
this.signed = signed;
|
||||
this.bigEndian = bigEndian;
|
||||
}
|
||||
|
||||
public int getChannels() {
|
||||
return this.channelCount;
|
||||
}
|
||||
|
||||
public int getSampleSizeInBits() {
|
||||
return this.sampleSizeInBits;
|
||||
}
|
||||
|
||||
public int getSampleRate() {
|
||||
return this.sampleRate;
|
||||
}
|
||||
|
||||
public short getFrameSize() {
|
||||
return (short)((this.sampleSizeInBits >> 3) * this.channelCount);
|
||||
}
|
||||
|
||||
public int getFrameRate() {
|
||||
return this.sampleRate;
|
||||
}
|
||||
|
||||
public boolean isBigEndian() {
|
||||
return this.bigEndian;
|
||||
}
|
||||
|
||||
public boolean isSigned() {
|
||||
return this.signed;
|
||||
}
|
||||
|
||||
public int bytesToFrames(int bytes) {
|
||||
return bytes / (this.channelCount * this.sampleSizeInBits >> 3);
|
||||
}
|
||||
|
||||
public int framesToBytes(int samples) {
|
||||
return samples * (this.channelCount * this.sampleSizeInBits >> 3);
|
||||
}
|
||||
|
||||
public int bytesToSamples(int bytes) {
|
||||
return bytes / (this.sampleSizeInBits >> 3);
|
||||
}
|
||||
|
||||
public int samplesToBytes(int samples) {
|
||||
return samples * (this.sampleSizeInBits >> 3);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,238 @@
|
|||
package org.jcodec.common;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.FloatBuffer;
|
||||
import org.jcodec.api.NotSupportedException;
|
||||
import org.jcodec.common.tools.MathUtil;
|
||||
|
||||
public class AudioUtil {
|
||||
private static final float f24 = 8388607.0F;
|
||||
|
||||
private static final float f16 = 32767.0F;
|
||||
|
||||
public static final float r16 = 3.0517578E-5F;
|
||||
|
||||
public static final float r24 = 1.1920929E-7F;
|
||||
|
||||
public static void toFloat(AudioFormat format, ByteBuffer buf, FloatBuffer floatBuf) {
|
||||
if (!format.isSigned())
|
||||
throw new NotSupportedException("Unsigned PCM is not supported ( yet? ).");
|
||||
if (format.getSampleSizeInBits() != 16 && format.getSampleSizeInBits() != 24)
|
||||
throw new NotSupportedException("" + format.getSampleSizeInBits() + " bit PCM is not supported ( yet? ).");
|
||||
if (format.isBigEndian()) {
|
||||
if (format.getSampleSizeInBits() == 16) {
|
||||
toFloat16BE(buf, floatBuf);
|
||||
} else {
|
||||
toFloat24BE(buf, floatBuf);
|
||||
}
|
||||
} else if (format.getSampleSizeInBits() == 16) {
|
||||
toFloat16LE(buf, floatBuf);
|
||||
} else {
|
||||
toFloat24LE(buf, floatBuf);
|
||||
}
|
||||
}
|
||||
|
||||
public static void fromFloat(FloatBuffer floatBuf, AudioFormat format, ByteBuffer buf) {
|
||||
if (!format.isSigned())
|
||||
throw new NotSupportedException("Unsigned PCM is not supported ( yet? ).");
|
||||
if (format.getSampleSizeInBits() != 16 && format.getSampleSizeInBits() != 24)
|
||||
throw new NotSupportedException("" + format.getSampleSizeInBits() + " bit PCM is not supported ( yet? ).");
|
||||
if (format.isBigEndian()) {
|
||||
if (format.getSampleSizeInBits() == 16) {
|
||||
fromFloat16BE(buf, floatBuf);
|
||||
} else {
|
||||
fromFloat24BE(buf, floatBuf);
|
||||
}
|
||||
} else if (format.getSampleSizeInBits() == 16) {
|
||||
fromFloat16LE(buf, floatBuf);
|
||||
} else {
|
||||
fromFloat24LE(buf, floatBuf);
|
||||
}
|
||||
}
|
||||
|
||||
private static void toFloat24LE(ByteBuffer buf, FloatBuffer out) {
|
||||
while (buf.remaining() >= 3 && out.hasRemaining())
|
||||
out.put(1.1920929E-7F * (float)(((buf.get() & 0xFF) << 8 | (buf.get() & 0xFF) << 16 | (buf.get() & 0xFF) << 24) >> 8));
|
||||
}
|
||||
|
||||
private static void toFloat16LE(ByteBuffer buf, FloatBuffer out) {
|
||||
while (buf.remaining() >= 2 && out.hasRemaining())
|
||||
out.put(3.0517578E-5F * (float)(short)(buf.get() & 0xFF | (buf.get() & 0xFF) << 8));
|
||||
}
|
||||
|
||||
private static void toFloat24BE(ByteBuffer buf, FloatBuffer out) {
|
||||
while (buf.remaining() >= 3 && out.hasRemaining())
|
||||
out.put(1.1920929E-7F * (float)(((buf.get() & 0xFF) << 24 | (buf.get() & 0xFF) << 16 | (buf.get() & 0xFF) << 8) >> 8));
|
||||
}
|
||||
|
||||
private static void toFloat16BE(ByteBuffer buf, FloatBuffer out) {
|
||||
while (buf.remaining() >= 2 && out.hasRemaining())
|
||||
out.put(3.0517578E-5F * (float)(short)((buf.get() & 0xFF) << 8 | buf.get() & 0xFF));
|
||||
}
|
||||
|
||||
private static void fromFloat24LE(ByteBuffer buf, FloatBuffer _in) {
|
||||
while (buf.remaining() >= 3 && _in.hasRemaining()) {
|
||||
int val = MathUtil.clip((int)(_in.get() * 8388607.0F), -8388608, 8388607) & 0xFFFFFF;
|
||||
buf.put((byte)val);
|
||||
buf.put((byte)(val >> 8));
|
||||
buf.put((byte)(val >> 16));
|
||||
}
|
||||
}
|
||||
|
||||
private static void fromFloat16LE(ByteBuffer buf, FloatBuffer _in) {
|
||||
while (buf.remaining() >= 2 && _in.hasRemaining()) {
|
||||
int val = MathUtil.clip((int)(_in.get() * 32767.0F), -32768, 32767) & 0xFFFF;
|
||||
buf.put((byte)val);
|
||||
buf.put((byte)(val >> 8));
|
||||
}
|
||||
}
|
||||
|
||||
private static void fromFloat24BE(ByteBuffer buf, FloatBuffer _in) {
|
||||
while (buf.remaining() >= 3 && _in.hasRemaining()) {
|
||||
int val = MathUtil.clip((int)(_in.get() * 8388607.0F), -8388608, 8388607) & 0xFFFFFF;
|
||||
buf.put((byte)(val >> 16));
|
||||
buf.put((byte)(val >> 8));
|
||||
buf.put((byte)val);
|
||||
}
|
||||
}
|
||||
|
||||
private static void fromFloat16BE(ByteBuffer buf, FloatBuffer _in) {
|
||||
while (buf.remaining() >= 2 && _in.hasRemaining()) {
|
||||
int val = MathUtil.clip((int)(_in.get() * 32767.0F), -32768, 32767) & 0xFFFF;
|
||||
buf.put((byte)(val >> 8));
|
||||
buf.put((byte)val);
|
||||
}
|
||||
}
|
||||
|
||||
public static int fromInt(int[] data, int len, AudioFormat format, ByteBuffer buf) {
|
||||
if (!format.isSigned())
|
||||
throw new NotSupportedException("Unsigned PCM is not supported ( yet? ).");
|
||||
if (format.getSampleSizeInBits() != 16 && format.getSampleSizeInBits() != 24)
|
||||
throw new NotSupportedException("" + format.getSampleSizeInBits() + " bit PCM is not supported ( yet? ).");
|
||||
if (format.isBigEndian()) {
|
||||
if (format.getSampleSizeInBits() == 16)
|
||||
return fromInt16BE(buf, data, len);
|
||||
return fromInt24BE(buf, data, len);
|
||||
}
|
||||
if (format.getSampleSizeInBits() == 16)
|
||||
return fromInt16LE(buf, data, len);
|
||||
return fromInt24LE(buf, data, len);
|
||||
}
|
||||
|
||||
private static int fromInt24LE(ByteBuffer buf, int[] out, int len) {
|
||||
int samples = 0;
|
||||
while (buf.remaining() >= 3 && samples < len) {
|
||||
int val = out[samples++];
|
||||
buf.put((byte)val);
|
||||
buf.put((byte)(val >> 8));
|
||||
buf.put((byte)(val >> 16));
|
||||
}
|
||||
return samples;
|
||||
}
|
||||
|
||||
private static int fromInt16LE(ByteBuffer buf, int[] out, int len) {
|
||||
int samples = 0;
|
||||
while (buf.remaining() >= 2 && samples < len) {
|
||||
int val = out[samples++];
|
||||
buf.put((byte)val);
|
||||
buf.put((byte)(val >> 8));
|
||||
}
|
||||
return samples;
|
||||
}
|
||||
|
||||
private static int fromInt24BE(ByteBuffer buf, int[] out, int len) {
|
||||
int samples = 0;
|
||||
while (buf.remaining() >= 3 && samples < len) {
|
||||
int val = out[samples++];
|
||||
buf.put((byte)(val >> 16));
|
||||
buf.put((byte)(val >> 8));
|
||||
buf.put((byte)val);
|
||||
}
|
||||
return samples;
|
||||
}
|
||||
|
||||
private static int fromInt16BE(ByteBuffer buf, int[] out, int len) {
|
||||
int samples = 0;
|
||||
while (buf.remaining() >= 2 && samples < len) {
|
||||
int val = out[samples++];
|
||||
buf.put((byte)(val >> 8));
|
||||
buf.put((byte)val);
|
||||
}
|
||||
return samples;
|
||||
}
|
||||
|
||||
public static int toInt(AudioFormat format, ByteBuffer buf, int[] samples) {
|
||||
if (!format.isSigned())
|
||||
throw new NotSupportedException("Unsigned PCM is not supported ( yet? ).");
|
||||
if (format.getSampleSizeInBits() != 16 && format.getSampleSizeInBits() != 24)
|
||||
throw new NotSupportedException("" + format.getSampleSizeInBits() + " bit PCM is not supported ( yet? ).");
|
||||
if (format.isBigEndian()) {
|
||||
if (format.getSampleSizeInBits() == 16)
|
||||
return toInt16BE(buf, samples);
|
||||
return toInt24BE(buf, samples);
|
||||
}
|
||||
if (format.getSampleSizeInBits() == 16)
|
||||
return toInt16LE(buf, samples);
|
||||
return toInt24LE(buf, samples);
|
||||
}
|
||||
|
||||
private static int toInt24LE(ByteBuffer buf, int[] out) {
|
||||
int samples = 0;
|
||||
while (buf.remaining() >= 3 && samples < out.length)
|
||||
out[samples++] = ((buf.get() & 0xFF) << 8 | (buf.get() & 0xFF) << 16 | (buf.get() & 0xFF) << 24) >> 8;
|
||||
return samples;
|
||||
}
|
||||
|
||||
private static int toInt16LE(ByteBuffer buf, int[] out) {
|
||||
int samples = 0;
|
||||
while (buf.remaining() >= 2 && samples < out.length)
|
||||
out[samples++] = (short)(buf.get() & 0xFF | (buf.get() & 0xFF) << 8);
|
||||
return samples;
|
||||
}
|
||||
|
||||
private static int toInt24BE(ByteBuffer buf, int[] out) {
|
||||
int samples = 0;
|
||||
while (buf.remaining() >= 3 && samples < out.length)
|
||||
out[samples++] = ((buf.get() & 0xFF) << 24 | (buf.get() & 0xFF) << 16 | (buf.get() & 0xFF) << 8) >> 8;
|
||||
return samples;
|
||||
}
|
||||
|
||||
private static int toInt16BE(ByteBuffer buf, int[] out) {
|
||||
int samples = 0;
|
||||
while (buf.remaining() >= 2 && samples < out.length)
|
||||
out[samples++] = (short)((buf.get() & 0xFF) << 8 | buf.get() & 0xFF);
|
||||
return samples;
|
||||
}
|
||||
|
||||
public static void interleave(AudioFormat format, ByteBuffer[] ins, ByteBuffer outb) {
|
||||
int bytesPerSample = format.getSampleSizeInBits() >> 3;
|
||||
int bytesPerFrame = bytesPerSample * ins.length;
|
||||
int max = 0;
|
||||
for (int i = 0; i < ins.length; i++) {
|
||||
if (ins[i].remaining() > max)
|
||||
max = ins[i].remaining();
|
||||
}
|
||||
for (int frames = 0; frames < max && outb.remaining() >= bytesPerFrame; frames++) {
|
||||
for (int j = 0; j < ins.length; j++) {
|
||||
if (ins[j].remaining() < bytesPerSample) {
|
||||
for (int k = 0; k < bytesPerSample; k++)
|
||||
outb.put((byte)0);
|
||||
} else {
|
||||
for (int k = 0; k < bytesPerSample; k++)
|
||||
outb.put(ins[j].get());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void deinterleave(AudioFormat format, ByteBuffer inb, ByteBuffer[] outs) {
|
||||
int bytesPerSample = format.getSampleSizeInBits() >> 3;
|
||||
int bytesPerFrame = bytesPerSample * outs.length;
|
||||
while (inb.remaining() >= bytesPerFrame) {
|
||||
for (int j = 0; j < outs.length; j++) {
|
||||
for (int i = 0; i < bytesPerSample; i++)
|
||||
outs[j].put(inb.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,99 @@
|
|||
package org.jcodec.common;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.FileChannel;
|
||||
import org.jcodec.common.io.AutoPool;
|
||||
import org.jcodec.common.io.AutoResource;
|
||||
import org.jcodec.common.io.SeekableByteChannel;
|
||||
|
||||
public class AutoFileChannelWrapper implements SeekableByteChannel, AutoResource {
|
||||
private static final long THRESHOLD = 5000L;
|
||||
|
||||
private FileChannel ch;
|
||||
|
||||
private File file;
|
||||
|
||||
private long savedPos;
|
||||
|
||||
private long curTime;
|
||||
|
||||
private long accessTime;
|
||||
|
||||
public AutoFileChannelWrapper(File file) throws IOException {
|
||||
this.file = file;
|
||||
this.curTime = System.currentTimeMillis();
|
||||
AutoPool.getInstance().add(this);
|
||||
ensureOpen();
|
||||
}
|
||||
|
||||
private void ensureOpen() throws IOException {
|
||||
this.accessTime = this.curTime;
|
||||
if (this.ch == null || !this.ch.isOpen()) {
|
||||
this.ch = new FileInputStream(this.file).getChannel();
|
||||
this.ch.position(this.savedPos);
|
||||
}
|
||||
}
|
||||
|
||||
public int read(ByteBuffer arg0) throws IOException {
|
||||
ensureOpen();
|
||||
int r = this.ch.read(arg0);
|
||||
this.savedPos = this.ch.position();
|
||||
return r;
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
if (this.ch != null && this.ch.isOpen()) {
|
||||
this.savedPos = this.ch.position();
|
||||
this.ch.close();
|
||||
this.ch = null;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isOpen() {
|
||||
return (this.ch != null && this.ch.isOpen());
|
||||
}
|
||||
|
||||
public int write(ByteBuffer arg0) throws IOException {
|
||||
ensureOpen();
|
||||
int w = this.ch.write(arg0);
|
||||
this.savedPos = this.ch.position();
|
||||
return w;
|
||||
}
|
||||
|
||||
public long position() throws IOException {
|
||||
ensureOpen();
|
||||
return this.ch.position();
|
||||
}
|
||||
|
||||
public SeekableByteChannel setPosition(long newPosition) throws IOException {
|
||||
ensureOpen();
|
||||
this.ch.position(newPosition);
|
||||
this.savedPos = newPosition;
|
||||
return this;
|
||||
}
|
||||
|
||||
public long size() throws IOException {
|
||||
ensureOpen();
|
||||
return this.ch.size();
|
||||
}
|
||||
|
||||
public SeekableByteChannel truncate(long size) throws IOException {
|
||||
ensureOpen();
|
||||
this.ch.truncate(size);
|
||||
this.savedPos = this.ch.position();
|
||||
return this;
|
||||
}
|
||||
|
||||
public void setCurTime(long curTime) {
|
||||
this.curTime = curTime;
|
||||
if (this.ch != null && this.ch.isOpen() && curTime - this.accessTime > 5000L)
|
||||
try {
|
||||
close();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
package org.jcodec.common;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public class ByteArrayList {
|
||||
private static final int DEFAULT_GROW_AMOUNT = 2048;
|
||||
|
||||
private byte[] storage;
|
||||
|
||||
private int _size;
|
||||
|
||||
private int growAmount;
|
||||
|
||||
public static ByteArrayList createByteArrayList() {
|
||||
return new ByteArrayList(2048);
|
||||
}
|
||||
|
||||
public ByteArrayList(int growAmount) {
|
||||
this.growAmount = growAmount;
|
||||
this.storage = new byte[growAmount];
|
||||
}
|
||||
|
||||
public byte[] toArray() {
|
||||
byte[] result = new byte[this._size];
|
||||
System.arraycopy(this.storage, 0, result, 0, this._size);
|
||||
return result;
|
||||
}
|
||||
|
||||
public void add(byte val) {
|
||||
if (this._size >= this.storage.length) {
|
||||
byte[] ns = new byte[this.storage.length + this.growAmount];
|
||||
System.arraycopy(this.storage, 0, ns, 0, this.storage.length);
|
||||
this.storage = ns;
|
||||
}
|
||||
this.storage[this._size++] = val;
|
||||
}
|
||||
|
||||
public void push(byte id) {
|
||||
add(id);
|
||||
}
|
||||
|
||||
public void pop() {
|
||||
if (this._size == 0)
|
||||
return;
|
||||
this._size--;
|
||||
}
|
||||
|
||||
public void set(int index, byte value) {
|
||||
this.storage[index] = value;
|
||||
}
|
||||
|
||||
public byte get(int index) {
|
||||
return this.storage[index];
|
||||
}
|
||||
|
||||
public void fill(int start, int end, byte val) {
|
||||
if (end > this.storage.length) {
|
||||
byte[] ns = new byte[end + this.growAmount];
|
||||
System.arraycopy(this.storage, 0, ns, 0, this.storage.length);
|
||||
this.storage = ns;
|
||||
}
|
||||
Arrays.fill(this.storage, start, end, val);
|
||||
this._size = Math.max(this._size, end);
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return this._size;
|
||||
}
|
||||
|
||||
public void addAll(byte[] other) {
|
||||
if (this._size + other.length >= this.storage.length) {
|
||||
byte[] ns = new byte[this._size + this.growAmount + other.length];
|
||||
System.arraycopy(this.storage, 0, ns, 0, this._size);
|
||||
this.storage = ns;
|
||||
}
|
||||
System.arraycopy(other, 0, this.storage, this._size, other.length);
|
||||
this._size += other.length;
|
||||
}
|
||||
|
||||
public boolean contains(byte needle) {
|
||||
for (int i = 0; i < this._size; i++) {
|
||||
if (this.storage[i] == needle)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,153 @@
|
|||
package org.jcodec.common;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public final class Codec {
|
||||
public static final Codec H264 = new Codec("H264", TrackType.VIDEO);
|
||||
|
||||
public static final Codec MPEG2 = new Codec("MPEG2", TrackType.VIDEO);
|
||||
|
||||
public static final Codec MPEG4 = new Codec("MPEG4", TrackType.VIDEO);
|
||||
|
||||
public static final Codec PRORES = new Codec("PRORES", TrackType.VIDEO);
|
||||
|
||||
public static final Codec DV = new Codec("DV", TrackType.VIDEO);
|
||||
|
||||
public static final Codec VC1 = new Codec("VC1", TrackType.VIDEO);
|
||||
|
||||
public static final Codec VC3 = new Codec("VC3", TrackType.VIDEO);
|
||||
|
||||
public static final Codec V210 = new Codec("V210", TrackType.VIDEO);
|
||||
|
||||
public static final Codec SORENSON = new Codec("SORENSON", TrackType.VIDEO);
|
||||
|
||||
public static final Codec FLASH_SCREEN_VIDEO = new Codec("FLASH_SCREEN_VIDEO", TrackType.VIDEO);
|
||||
|
||||
public static final Codec FLASH_SCREEN_V2 = new Codec("FLASH_SCREEN_V2", TrackType.VIDEO);
|
||||
|
||||
public static final Codec PNG = new Codec("PNG", TrackType.VIDEO);
|
||||
|
||||
public static final Codec JPEG = new Codec("JPEG", TrackType.VIDEO);
|
||||
|
||||
public static final Codec J2K = new Codec("J2K", TrackType.VIDEO);
|
||||
|
||||
public static final Codec VP6 = new Codec("VP6", TrackType.VIDEO);
|
||||
|
||||
public static final Codec VP8 = new Codec("VP8", TrackType.VIDEO);
|
||||
|
||||
public static final Codec VP9 = new Codec("VP9", TrackType.VIDEO);
|
||||
|
||||
public static final Codec VORBIS = new Codec("VORBIS", TrackType.VIDEO);
|
||||
|
||||
public static final Codec AAC = new Codec("AAC", TrackType.AUDIO);
|
||||
|
||||
public static final Codec MP3 = new Codec("MP3", TrackType.AUDIO);
|
||||
|
||||
public static final Codec MP2 = new Codec("MP2", TrackType.AUDIO);
|
||||
|
||||
public static final Codec MP1 = new Codec("MP1", TrackType.AUDIO);
|
||||
|
||||
public static final Codec AC3 = new Codec("AC3", TrackType.AUDIO);
|
||||
|
||||
public static final Codec DTS = new Codec("DTS", TrackType.AUDIO);
|
||||
|
||||
public static final Codec TRUEHD = new Codec("TRUEHD", TrackType.AUDIO);
|
||||
|
||||
public static final Codec PCM_DVD = new Codec("PCM_DVD", TrackType.AUDIO);
|
||||
|
||||
public static final Codec PCM = new Codec("PCM", TrackType.AUDIO);
|
||||
|
||||
public static final Codec ADPCM = new Codec("ADPCM", TrackType.AUDIO);
|
||||
|
||||
public static final Codec ALAW = new Codec("ALAW", TrackType.AUDIO);
|
||||
|
||||
public static final Codec NELLYMOSER = new Codec("NELLYMOSER", TrackType.AUDIO);
|
||||
|
||||
public static final Codec G711 = new Codec("G711", TrackType.AUDIO);
|
||||
|
||||
public static final Codec SPEEX = new Codec("SPEEX", TrackType.AUDIO);
|
||||
|
||||
public static final Codec RAW = new Codec("RAW", null);
|
||||
|
||||
public static final Codec TIMECODE = new Codec("TIMECODE", TrackType.OTHER);
|
||||
|
||||
private static final Map<String, Codec> _values = new LinkedHashMap<>();
|
||||
|
||||
private final String _name;
|
||||
|
||||
private final TrackType type;
|
||||
|
||||
static {
|
||||
_values.put("H264", H264);
|
||||
_values.put("MPEG2", MPEG2);
|
||||
_values.put("MPEG4", MPEG4);
|
||||
_values.put("PRORES", PRORES);
|
||||
_values.put("DV", DV);
|
||||
_values.put("VC1", VC1);
|
||||
_values.put("VC3", VC3);
|
||||
_values.put("V210", V210);
|
||||
_values.put("SORENSON", SORENSON);
|
||||
_values.put("FLASH_SCREEN_VIDEO", FLASH_SCREEN_VIDEO);
|
||||
_values.put("FLASH_SCREEN_V2", FLASH_SCREEN_V2);
|
||||
_values.put("PNG", PNG);
|
||||
_values.put("JPEG", JPEG);
|
||||
_values.put("J2K", J2K);
|
||||
_values.put("VP6", VP6);
|
||||
_values.put("VP8", VP8);
|
||||
_values.put("VP9", VP9);
|
||||
_values.put("VORBIS", VORBIS);
|
||||
_values.put("AAC", AAC);
|
||||
_values.put("MP3", MP3);
|
||||
_values.put("MP2", MP2);
|
||||
_values.put("MP1", MP1);
|
||||
_values.put("AC3", AC3);
|
||||
_values.put("DTS", DTS);
|
||||
_values.put("TRUEHD", TRUEHD);
|
||||
_values.put("PCM_DVD", PCM_DVD);
|
||||
_values.put("PCM", PCM);
|
||||
_values.put("ADPCM", ADPCM);
|
||||
_values.put("ALAW", ALAW);
|
||||
_values.put("NELLYMOSER", NELLYMOSER);
|
||||
_values.put("G711", G711);
|
||||
_values.put("SPEEX", SPEEX);
|
||||
_values.put("RAW", RAW);
|
||||
_values.put("TIMECODE", TIMECODE);
|
||||
}
|
||||
|
||||
public Codec(String name, TrackType type) {
|
||||
this._name = name;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public TrackType getType() {
|
||||
return this.type;
|
||||
}
|
||||
|
||||
public static Codec codecByFourcc(String fourcc) {
|
||||
if (fourcc.equals("avc1"))
|
||||
return H264;
|
||||
if (fourcc.equals("m1v1") || fourcc.equals("m2v1"))
|
||||
return MPEG2;
|
||||
if (fourcc.equals("apco") || fourcc.equals("apcs") || fourcc.equals("apcn") || fourcc.equals("apch") ||
|
||||
fourcc.equals("ap4h"))
|
||||
return PRORES;
|
||||
if (fourcc.equals("mp4a"))
|
||||
return AAC;
|
||||
if (fourcc.equals("jpeg"))
|
||||
return JPEG;
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Codec valueOf(String s) {
|
||||
return _values.get(s);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return this._name;
|
||||
}
|
||||
|
||||
public String name() {
|
||||
return this._name;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
package org.jcodec.common;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
public class CodecMeta {
|
||||
private String fourcc;
|
||||
|
||||
private ByteBuffer codecPrivate;
|
||||
|
||||
public CodecMeta(String fourcc, ByteBuffer codecPrivate) {
|
||||
this.fourcc = fourcc;
|
||||
this.codecPrivate = codecPrivate;
|
||||
}
|
||||
|
||||
public String getFourcc() {
|
||||
return this.fourcc;
|
||||
}
|
||||
|
||||
public ByteBuffer getCodecPrivate() {
|
||||
return this.codecPrivate;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
package org.jcodec.common;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.util.List;
|
||||
|
||||
public interface Demuxer extends Closeable {
|
||||
List<? extends DemuxerTrack> getTracks();
|
||||
|
||||
List<? extends DemuxerTrack> getVideoTracks();
|
||||
|
||||
List<? extends DemuxerTrack> getAudioTracks();
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
package org.jcodec.common;
|
||||
|
||||
import java.io.IOException;
|
||||
import org.jcodec.common.model.Packet;
|
||||
|
||||
public interface DemuxerTrack {
|
||||
Packet nextFrame() throws IOException;
|
||||
|
||||
DemuxerTrackMeta getMeta();
|
||||
}
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
package org.jcodec.common;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
public class DemuxerTrackMeta {
|
||||
private TrackType type;
|
||||
|
||||
private Codec codec;
|
||||
|
||||
private double totalDuration;
|
||||
|
||||
private int[] seekFrames;
|
||||
|
||||
private int totalFrames;
|
||||
|
||||
private ByteBuffer codecPrivate;
|
||||
|
||||
private VideoCodecMeta videoCodecMeta;
|
||||
|
||||
private AudioCodecMeta audioCodecMeta;
|
||||
|
||||
private int index;
|
||||
|
||||
private Orientation orientation;
|
||||
|
||||
public enum Orientation {
|
||||
D_0, D_90, D_180, D_270;
|
||||
}
|
||||
|
||||
public DemuxerTrackMeta(TrackType type, Codec codec, double totalDuration, int[] seekFrames, int totalFrames, ByteBuffer codecPrivate, VideoCodecMeta videoCodecMeta, AudioCodecMeta audioCodecMeta) {
|
||||
this.type = type;
|
||||
this.codec = codec;
|
||||
this.totalDuration = totalDuration;
|
||||
this.seekFrames = seekFrames;
|
||||
this.totalFrames = totalFrames;
|
||||
this.codecPrivate = codecPrivate;
|
||||
this.videoCodecMeta = videoCodecMeta;
|
||||
this.audioCodecMeta = audioCodecMeta;
|
||||
this.orientation = Orientation.D_0;
|
||||
}
|
||||
|
||||
public TrackType getType() {
|
||||
return this.type;
|
||||
}
|
||||
|
||||
public Codec getCodec() {
|
||||
return this.codec;
|
||||
}
|
||||
|
||||
public double getTotalDuration() {
|
||||
return this.totalDuration;
|
||||
}
|
||||
|
||||
public int[] getSeekFrames() {
|
||||
return this.seekFrames;
|
||||
}
|
||||
|
||||
public int getTotalFrames() {
|
||||
return this.totalFrames;
|
||||
}
|
||||
|
||||
public int getIndex() {
|
||||
return this.index;
|
||||
}
|
||||
|
||||
public ByteBuffer getCodecPrivate() {
|
||||
return this.codecPrivate;
|
||||
}
|
||||
|
||||
public VideoCodecMeta getVideoCodecMeta() {
|
||||
return this.videoCodecMeta;
|
||||
}
|
||||
|
||||
public AudioCodecMeta getAudioCodecMeta() {
|
||||
return this.audioCodecMeta;
|
||||
}
|
||||
|
||||
public void setOrientation(Orientation orientation) {
|
||||
this.orientation = orientation;
|
||||
}
|
||||
|
||||
public Orientation getOrientation() {
|
||||
return this.orientation;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,115 @@
|
|||
package org.jcodec.common;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Arrays;
|
||||
import org.jcodec.common.io.BitWriter;
|
||||
import org.jcodec.common.io.VLC;
|
||||
import org.jcodec.common.tools.MathUtil;
|
||||
import org.jcodec.platform.Platform;
|
||||
|
||||
public class DictionaryCompressor {
|
||||
protected VLC buildCodes(int[] counts, int esc) {
|
||||
int[] codes = new int[counts.length];
|
||||
int[] codeSizes = new int[counts.length];
|
||||
int code = 0;
|
||||
for (; code < Math.min(codes.length, esc); code++) {
|
||||
int max = 0;
|
||||
for (int j = 0; j < counts.length; j++) {
|
||||
if (counts[j] > counts[max])
|
||||
max = j;
|
||||
}
|
||||
codes[max] = code;
|
||||
codeSizes[max] = Math.max(1, MathUtil.log2(code));
|
||||
counts[max] = Integer.MIN_VALUE;
|
||||
}
|
||||
int escSize = MathUtil.log2(esc);
|
||||
for (int i = 0; i < counts.length; i++) {
|
||||
if (counts[i] >= 0) {
|
||||
codes[i] = esc;
|
||||
codeSizes[i] = escSize;
|
||||
}
|
||||
}
|
||||
return new VLC(codes, codeSizes);
|
||||
}
|
||||
|
||||
public static class Long extends DictionaryCompressor {
|
||||
public void compress(long[] values, ByteBuffer bb) {
|
||||
RunLength.Long rl = getValueStats(values);
|
||||
int[] counts = rl.getCounts();
|
||||
long[] keys = rl.getValues();
|
||||
VLC vlc = buildCodes(counts, values.length / 10);
|
||||
int[] codes = vlc.getCodes();
|
||||
int[] codeSizes = vlc.getCodeSizes();
|
||||
bb.putInt(codes.length);
|
||||
for (int i = 0; i < codes.length; i++) {
|
||||
bb.put((byte)codeSizes[i]);
|
||||
bb.putShort((short)(codes[i] >>> 16));
|
||||
bb.putLong(keys[i]);
|
||||
}
|
||||
BitWriter br = new BitWriter(bb);
|
||||
for (int j = 0; j < values.length; j++) {
|
||||
long l = values[j];
|
||||
for (int k = 0; k < keys.length; k++) {
|
||||
if (keys[k] == l) {
|
||||
vlc.writeVLC(br, k);
|
||||
if (codes[k] == 15)
|
||||
br.writeNBit(16, k);
|
||||
}
|
||||
}
|
||||
}
|
||||
br.flush();
|
||||
}
|
||||
|
||||
private RunLength.Long getValueStats(long[] values) {
|
||||
long[] copy = Platform.copyOfLong(values, values.length);
|
||||
Arrays.sort(copy);
|
||||
RunLength.Long rl = new RunLength.Long();
|
||||
for (int i = 0; i < copy.length; i++) {
|
||||
long l = copy[i];
|
||||
rl.add(l);
|
||||
}
|
||||
return rl;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Int extends DictionaryCompressor {
|
||||
public void compress(int[] values, ByteBuffer bb) {
|
||||
RunLength.Integer rl = getValueStats(values);
|
||||
int[] counts = rl.getCounts();
|
||||
int[] keys = rl.getValues();
|
||||
int esc = Math.max(1, (1 << MathUtil.log2(counts.length) - 2) - 1);
|
||||
VLC vlc = buildCodes(counts, esc);
|
||||
int[] codes = vlc.getCodes();
|
||||
int[] codeSizes = vlc.getCodeSizes();
|
||||
bb.putInt(codes.length);
|
||||
for (int i = 0; i < codes.length; i++) {
|
||||
bb.put((byte)codeSizes[i]);
|
||||
bb.putShort((short)(codes[i] >>> 16));
|
||||
bb.putInt(keys[i]);
|
||||
}
|
||||
BitWriter br = new BitWriter(bb);
|
||||
for (int j = 0; j < values.length; j++) {
|
||||
int l = values[j];
|
||||
for (int k = 0; k < keys.length; k++) {
|
||||
if (keys[k] == l) {
|
||||
vlc.writeVLC(br, k);
|
||||
if (codes[k] == esc)
|
||||
br.writeNBit(k, 16);
|
||||
}
|
||||
}
|
||||
}
|
||||
br.flush();
|
||||
}
|
||||
|
||||
private RunLength.Integer getValueStats(int[] values) {
|
||||
int[] copy = Platform.copyOfInt(values, values.length);
|
||||
Arrays.sort(copy);
|
||||
RunLength.Integer rl = new RunLength.Integer();
|
||||
for (int i = 0; i < copy.length; i++) {
|
||||
int l = copy[i];
|
||||
rl.add(l);
|
||||
}
|
||||
return rl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,80 @@
|
|||
package org.jcodec.common;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public final class Format {
|
||||
public static final Format MOV = new Format("MOV", true, true);
|
||||
|
||||
public static final Format MPEG_PS = new Format("MPEG_PS", true, true);
|
||||
|
||||
public static final Format MPEG_TS = new Format("MPEG_TS", true, true);
|
||||
|
||||
public static final Format MKV = new Format("MKV", true, true);
|
||||
|
||||
public static final Format H264 = new Format("H264", true, false);
|
||||
|
||||
public static final Format RAW = new Format("RAW", true, true);
|
||||
|
||||
public static final Format FLV = new Format("FLV", true, true);
|
||||
|
||||
public static final Format AVI = new Format("AVI", true, true);
|
||||
|
||||
public static final Format IMG = new Format("IMG", true, false);
|
||||
|
||||
public static final Format IVF = new Format("IVF", true, false);
|
||||
|
||||
public static final Format MJPEG = new Format("MJPEG", true, false);
|
||||
|
||||
public static final Format Y4M = new Format("Y4M", true, false);
|
||||
|
||||
public static final Format WAV = new Format("WAV", false, true);
|
||||
|
||||
public static final Format WEBP = new Format("WEBP", true, false);
|
||||
|
||||
public static final Format MPEG_AUDIO = new Format("MPEG_AUDIO", false, true);
|
||||
|
||||
private static final Map<String, Format> _values = new LinkedHashMap<>();
|
||||
|
||||
private final boolean video;
|
||||
|
||||
private final boolean audio;
|
||||
|
||||
private final String name;
|
||||
|
||||
static {
|
||||
_values.put("MOV", MOV);
|
||||
_values.put("MPEG_PS", MPEG_PS);
|
||||
_values.put("MPEG_TS", MPEG_TS);
|
||||
_values.put("MKV", MKV);
|
||||
_values.put("H264", H264);
|
||||
_values.put("RAW", RAW);
|
||||
_values.put("FLV", FLV);
|
||||
_values.put("AVI", AVI);
|
||||
_values.put("IMG", IMG);
|
||||
_values.put("IVF", IVF);
|
||||
_values.put("MJPEG", MJPEG);
|
||||
_values.put("Y4M", Y4M);
|
||||
_values.put("WAV", WAV);
|
||||
_values.put("WEBP", WEBP);
|
||||
_values.put("MPEG_AUDIO", MPEG_AUDIO);
|
||||
}
|
||||
|
||||
private Format(String name, boolean video, boolean audio) {
|
||||
this.name = name;
|
||||
this.video = video;
|
||||
this.audio = audio;
|
||||
}
|
||||
|
||||
public boolean isAudio() {
|
||||
return this.audio;
|
||||
}
|
||||
|
||||
public boolean isVideo() {
|
||||
return this.video;
|
||||
}
|
||||
|
||||
public static Format valueOf(String s) {
|
||||
return _values.get(s);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
package org.jcodec.common;
|
||||
|
||||
import org.jcodec.platform.Platform;
|
||||
|
||||
public class Fourcc {
|
||||
public static int makeInt(byte b3, byte b2, byte b1, byte b0) {
|
||||
return b3 << 24 | (b2 & 0xFF) << 16 | (b1 & 0xFF) << 8 | b0 & 0xFF;
|
||||
}
|
||||
|
||||
public static int intFourcc(String string) {
|
||||
byte[] b = Platform.getBytes(string);
|
||||
return makeInt(b[0], b[1], b[2], b[3]);
|
||||
}
|
||||
|
||||
public static final int ftyp = intFourcc("ftyp");
|
||||
|
||||
public static final int free = intFourcc("free");
|
||||
|
||||
public static final int moov = intFourcc("moov");
|
||||
|
||||
public static final int mdat = intFourcc("mdat");
|
||||
|
||||
public static final int wide = intFourcc("wide");
|
||||
}
|
||||
|
|
@ -0,0 +1,91 @@
|
|||
package org.jcodec.common;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public class IntArrayList {
|
||||
private static final int DEFAULT_GROW_AMOUNT = 128;
|
||||
|
||||
private int[] storage;
|
||||
|
||||
private int _size;
|
||||
|
||||
private int growAmount;
|
||||
|
||||
public static IntArrayList createIntArrayList() {
|
||||
return new IntArrayList(128);
|
||||
}
|
||||
|
||||
public IntArrayList(int growAmount) {
|
||||
this.growAmount = growAmount;
|
||||
this.storage = new int[growAmount];
|
||||
}
|
||||
|
||||
public int[] toArray() {
|
||||
int[] result = new int[this._size];
|
||||
System.arraycopy(this.storage, 0, result, 0, this._size);
|
||||
return result;
|
||||
}
|
||||
|
||||
public void add(int val) {
|
||||
if (this._size >= this.storage.length) {
|
||||
int[] ns = new int[this.storage.length + this.growAmount];
|
||||
System.arraycopy(this.storage, 0, ns, 0, this.storage.length);
|
||||
this.storage = ns;
|
||||
}
|
||||
this.storage[this._size++] = val;
|
||||
}
|
||||
|
||||
public void push(int id) {
|
||||
add(id);
|
||||
}
|
||||
|
||||
public void pop() {
|
||||
if (this._size == 0)
|
||||
return;
|
||||
this._size--;
|
||||
}
|
||||
|
||||
public void set(int index, int value) {
|
||||
this.storage[index] = value;
|
||||
}
|
||||
|
||||
public int get(int index) {
|
||||
return this.storage[index];
|
||||
}
|
||||
|
||||
public void fill(int start, int end, int val) {
|
||||
if (end > this.storage.length) {
|
||||
int[] ns = new int[end + this.growAmount];
|
||||
System.arraycopy(this.storage, 0, ns, 0, this.storage.length);
|
||||
this.storage = ns;
|
||||
}
|
||||
Arrays.fill(this.storage, start, end, val);
|
||||
this._size = Math.max(this._size, end);
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return this._size;
|
||||
}
|
||||
|
||||
public void addAll(int[] other) {
|
||||
if (this._size + other.length >= this.storage.length) {
|
||||
int[] ns = new int[this._size + this.growAmount + other.length];
|
||||
System.arraycopy(this.storage, 0, ns, 0, this._size);
|
||||
this.storage = ns;
|
||||
}
|
||||
System.arraycopy(other, 0, this.storage, this._size, other.length);
|
||||
this._size += other.length;
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
this._size = 0;
|
||||
}
|
||||
|
||||
public boolean contains(int needle) {
|
||||
for (int i = 0; i < this._size; i++) {
|
||||
if (this.storage[i] == needle)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
package org.jcodec.common;
|
||||
|
||||
public class IntIntHistogram extends IntIntMap {
|
||||
private int maxBin = -1;
|
||||
|
||||
public int max() {
|
||||
return this.maxBin;
|
||||
}
|
||||
|
||||
public void increment(int bin) {
|
||||
int count = get(bin);
|
||||
count = (count == Integer.MIN_VALUE) ? 1 : (1 + count);
|
||||
put(bin, count);
|
||||
if (this.maxBin == -1)
|
||||
this.maxBin = bin;
|
||||
int maxCount = get(this.maxBin);
|
||||
if (count > maxCount) {
|
||||
this.maxBin = bin;
|
||||
maxCount = count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
package org.jcodec.common;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public class IntIntMap {
|
||||
private static final int GROW_BY = 128;
|
||||
|
||||
private static final int MIN_VALUE = -2147483648;
|
||||
|
||||
private int[] storage;
|
||||
|
||||
private int _size;
|
||||
|
||||
public IntIntMap() {
|
||||
this.storage = createArray(128);
|
||||
Arrays.fill(this.storage, Integer.MIN_VALUE);
|
||||
}
|
||||
|
||||
public void put(int key, int val) {
|
||||
if (val == Integer.MIN_VALUE)
|
||||
throw new IllegalArgumentException("This implementation can not store -2147483648");
|
||||
if (this.storage.length <= key) {
|
||||
int[] ns = createArray(key + 128);
|
||||
System.arraycopy(this.storage, 0, ns, 0, this.storage.length);
|
||||
Arrays.fill(ns, this.storage.length, ns.length, Integer.MIN_VALUE);
|
||||
this.storage = ns;
|
||||
}
|
||||
if (this.storage[key] == Integer.MIN_VALUE)
|
||||
this._size++;
|
||||
this.storage[key] = val;
|
||||
}
|
||||
|
||||
public int get(int key) {
|
||||
return (key >= this.storage.length) ? Integer.MIN_VALUE : this.storage[key];
|
||||
}
|
||||
|
||||
public boolean contains(int key) {
|
||||
return (key >= 0 && key < this.storage.length);
|
||||
}
|
||||
|
||||
public int[] keys() {
|
||||
int[] result = new int[this._size];
|
||||
for (int i = 0, r = 0; i < this.storage.length; i++) {
|
||||
if (this.storage[i] != Integer.MIN_VALUE)
|
||||
result[r++] = i;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
for (int i = 0; i < this.storage.length; i++)
|
||||
this.storage[i] = Integer.MIN_VALUE;
|
||||
this._size = 0;
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return this._size;
|
||||
}
|
||||
|
||||
public void remove(int key) {
|
||||
if (this.storage[key] != Integer.MIN_VALUE)
|
||||
this._size--;
|
||||
this.storage[key] = Integer.MIN_VALUE;
|
||||
}
|
||||
|
||||
public int[] values() {
|
||||
int[] result = createArray(this._size);
|
||||
for (int i = 0, r = 0; i < this.storage.length; i++) {
|
||||
if (this.storage[i] != Integer.MIN_VALUE)
|
||||
result[r++] = this.storage[i];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static int[] createArray(int size) {
|
||||
return new int[size];
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
package org.jcodec.common;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import org.jcodec.platform.Platform;
|
||||
|
||||
public class IntObjectMap<T> {
|
||||
private static final int GROW_BY = 128;
|
||||
|
||||
private Object[] storage = new Object[128];
|
||||
|
||||
private int _size;
|
||||
|
||||
public void put(int key, T val) {
|
||||
if (this.storage.length <= key) {
|
||||
Object[] ns = new Object[key + 128];
|
||||
System.arraycopy(this.storage, 0, ns, 0, this.storage.length);
|
||||
this.storage = ns;
|
||||
}
|
||||
if (this.storage[key] == null)
|
||||
this._size++;
|
||||
this.storage[key] = val;
|
||||
}
|
||||
|
||||
public T get(int key) {
|
||||
return (key >= this.storage.length) ? null : (T)this.storage[key];
|
||||
}
|
||||
|
||||
public int[] keys() {
|
||||
int[] result = new int[this._size];
|
||||
for (int i = 0, r = 0; i < this.storage.length; i++) {
|
||||
if (this.storage[i] != null)
|
||||
result[r++] = i;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
for (int i = 0; i < this.storage.length; i++)
|
||||
this.storage[i] = null;
|
||||
this._size = 0;
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return this._size;
|
||||
}
|
||||
|
||||
public void remove(int key) {
|
||||
if (this.storage[key] != null)
|
||||
this._size--;
|
||||
this.storage[key] = null;
|
||||
}
|
||||
|
||||
public T[] values(T[] runtime) {
|
||||
T[] result = (T[])Array.newInstance(Platform.arrayComponentType(runtime), this._size);
|
||||
for (int i = 0, r = 0; i < this.storage.length; i++) {
|
||||
if (this.storage[i] != null)
|
||||
result[r++] = (T)this.storage[i];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
package org.jcodec.common;
|
||||
|
||||
public class Ints {
|
||||
public static int checkedCast(long value) {
|
||||
int result = (int)value;
|
||||
if ((long)result != value)
|
||||
throw new IllegalArgumentException("Out of range: " + value);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,239 @@
|
|||
package org.jcodec.common;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.ReadableByteChannel;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import org.jcodec.codecs.aac.AACDecoder;
|
||||
import org.jcodec.codecs.h264.BufferH264ES;
|
||||
import org.jcodec.codecs.h264.H264Decoder;
|
||||
import org.jcodec.codecs.mjpeg.JpegDecoder;
|
||||
import org.jcodec.codecs.mpeg12.MPEGDecoder;
|
||||
import org.jcodec.codecs.mpeg4.MPEG4Decoder;
|
||||
import org.jcodec.codecs.ppm.PPMEncoder;
|
||||
import org.jcodec.codecs.prores.ProresDecoder;
|
||||
import org.jcodec.codecs.vpx.VP8Decoder;
|
||||
import org.jcodec.codecs.wav.WavDemuxer;
|
||||
import org.jcodec.common.io.FileChannelWrapper;
|
||||
import org.jcodec.common.io.NIOUtils;
|
||||
import org.jcodec.common.logging.Logger;
|
||||
import org.jcodec.common.model.ColorSpace;
|
||||
import org.jcodec.common.model.Picture;
|
||||
import org.jcodec.common.tools.MathUtil;
|
||||
import org.jcodec.containers.imgseq.ImageSequenceDemuxer;
|
||||
import org.jcodec.containers.mkv.demuxer.MKVDemuxer;
|
||||
import org.jcodec.containers.mp3.MPEGAudioDemuxer;
|
||||
import org.jcodec.containers.mp4.demuxer.MP4Demuxer;
|
||||
import org.jcodec.containers.mps.MPSDemuxer;
|
||||
import org.jcodec.containers.mps.MTSDemuxer;
|
||||
import org.jcodec.containers.webp.WebpDemuxer;
|
||||
import org.jcodec.containers.y4m.Y4MDemuxer;
|
||||
import org.jcodec.platform.Platform;
|
||||
import org.jcodec.scale.ColorUtil;
|
||||
import org.jcodec.scale.Transform;
|
||||
|
||||
public class JCodecUtil {
|
||||
private static final Map<Codec, Class<?>> decoders = new HashMap<>();
|
||||
|
||||
private static final Map<Format, Class<?>> demuxers = new HashMap<>();
|
||||
|
||||
static {
|
||||
decoders.put(Codec.VP8, VP8Decoder.class);
|
||||
decoders.put(Codec.PRORES, ProresDecoder.class);
|
||||
decoders.put(Codec.MPEG2, MPEGDecoder.class);
|
||||
decoders.put(Codec.H264, H264Decoder.class);
|
||||
decoders.put(Codec.AAC, AACDecoder.class);
|
||||
decoders.put(Codec.MPEG4, MPEG4Decoder.class);
|
||||
demuxers.put(Format.MPEG_TS, MTSDemuxer.class);
|
||||
demuxers.put(Format.MPEG_PS, MPSDemuxer.class);
|
||||
demuxers.put(Format.MOV, MP4Demuxer.class);
|
||||
demuxers.put(Format.WEBP, WebpDemuxer.class);
|
||||
demuxers.put(Format.MPEG_AUDIO, MPEGAudioDemuxer.class);
|
||||
}
|
||||
|
||||
public static Format detectFormat(File f) throws IOException {
|
||||
return detectFormatBuffer(NIOUtils.fetchFromFileL(f, 204800));
|
||||
}
|
||||
|
||||
public static Format detectFormatChannel(ReadableByteChannel f) throws IOException {
|
||||
return detectFormatBuffer(NIOUtils.fetchFromChannel(f, 204800));
|
||||
}
|
||||
|
||||
public static Format detectFormatBuffer(ByteBuffer b) {
|
||||
int maxScore = 0;
|
||||
Format selected = null;
|
||||
for (Map.Entry<Format, Class<?>> vd : demuxers.entrySet()) {
|
||||
int score = probe(b.duplicate(), vd.getValue());
|
||||
if (score > maxScore) {
|
||||
selected = vd.getKey();
|
||||
maxScore = score;
|
||||
}
|
||||
}
|
||||
return selected;
|
||||
}
|
||||
|
||||
public static Codec detectDecoder(ByteBuffer b) {
|
||||
int maxScore = 0;
|
||||
Codec selected = null;
|
||||
for (Map.Entry<Codec, Class<?>> vd : decoders.entrySet()) {
|
||||
int score = probe(b.duplicate(), vd.getValue());
|
||||
if (score > maxScore) {
|
||||
selected = vd.getKey();
|
||||
maxScore = score;
|
||||
}
|
||||
}
|
||||
return selected;
|
||||
}
|
||||
|
||||
private static int probe(ByteBuffer b, Class<?> vd) {
|
||||
try {
|
||||
return Platform.invokeStaticMethod(vd, "probe", new Object[] { b });
|
||||
} catch (Exception e) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public static VideoDecoder getVideoDecoder(String fourcc) {
|
||||
if ("apch".equals(fourcc) || "apcs".equals(fourcc) || "apco".equals(fourcc) || "apcn".equals(fourcc) || "ap4h"
|
||||
.equals(fourcc))
|
||||
return new ProresDecoder();
|
||||
if ("m2v1".equals(fourcc))
|
||||
return new MPEGDecoder();
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void savePictureAsPPM(Picture pic, File file) throws IOException {
|
||||
Transform transform = ColorUtil.getTransform(pic.getColor(), ColorSpace.RGB);
|
||||
Picture rgb = Picture.create(pic.getWidth(), pic.getHeight(), ColorSpace.RGB);
|
||||
transform.transform(pic, rgb);
|
||||
NIOUtils.writeTo(new PPMEncoder().encodeFrame(rgb), file);
|
||||
}
|
||||
|
||||
public static byte[] asciiString(String fourcc) {
|
||||
char[] ch = fourcc.toCharArray();
|
||||
byte[] result = new byte[ch.length];
|
||||
for (int i = 0; i < ch.length; i++)
|
||||
result[i] = (byte)ch[i];
|
||||
return result;
|
||||
}
|
||||
|
||||
public static void writeBER32(ByteBuffer buffer, int value) {
|
||||
buffer.put((byte)(value >> 21 | 0x80));
|
||||
buffer.put((byte)(value >> 14 | 0x80));
|
||||
buffer.put((byte)(value >> 7 | 0x80));
|
||||
buffer.put((byte)(value & 0x7F));
|
||||
}
|
||||
|
||||
public static void writeBER32Var(ByteBuffer bb, int value) {
|
||||
for (int i = 0, bits = MathUtil.log2(value); i < 4 && bits > 0; i++) {
|
||||
bits -= 7;
|
||||
int out = value >> bits;
|
||||
if (bits > 0)
|
||||
out |= 0x80;
|
||||
bb.put((byte)out);
|
||||
}
|
||||
}
|
||||
|
||||
public static int readBER32(ByteBuffer input) {
|
||||
int size = 0;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
byte b = input.get();
|
||||
size = size << 7 | b & Byte.MAX_VALUE;
|
||||
if ((b & 0xFF) >> 7 == 0)
|
||||
break;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
public static int[] getAsIntArray(ByteBuffer yuv, int size) {
|
||||
byte[] b = new byte[size];
|
||||
int[] result = new int[size];
|
||||
yuv.get(b);
|
||||
for (int i = 0; i < b.length; i++)
|
||||
result[i] = b[i] & 0xFF;
|
||||
return result;
|
||||
}
|
||||
|
||||
public static String removeExtension(String name) {
|
||||
if (name == null)
|
||||
return null;
|
||||
return name.replaceAll("\\.[^\\.]+$", "");
|
||||
}
|
||||
|
||||
public static Demuxer createDemuxer(Format format, File input) throws IOException {
|
||||
FileChannelWrapper ch = null;
|
||||
if (format != Format.IMG)
|
||||
ch = NIOUtils.readableChannel(input);
|
||||
if (Format.MOV == format)
|
||||
return MP4Demuxer.createMP4Demuxer(ch);
|
||||
if (Format.MPEG_PS == format)
|
||||
return new MPSDemuxer(ch);
|
||||
if (Format.MKV == format)
|
||||
return new MKVDemuxer(ch);
|
||||
if (Format.IMG == format)
|
||||
return new ImageSequenceDemuxer(input.getAbsolutePath(), Integer.MAX_VALUE);
|
||||
if (Format.Y4M == format)
|
||||
return new Y4MDemuxer(ch);
|
||||
if (Format.WEBP == format)
|
||||
return new WebpDemuxer(ch);
|
||||
if (Format.H264 == format)
|
||||
return new BufferH264ES(NIOUtils.fetchAllFromChannel(ch));
|
||||
if (Format.WAV == format)
|
||||
return new WavDemuxer(ch);
|
||||
if (Format.MPEG_AUDIO == format)
|
||||
return new MPEGAudioDemuxer(ch);
|
||||
Logger.error("Format " + String.valueOf(format) + " is not supported");
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Tuple._2<Integer, Demuxer> createM2TSDemuxer(File input, TrackType targetTrack) throws IOException {
|
||||
FileChannelWrapper ch = NIOUtils.readableChannel(input);
|
||||
MTSDemuxer mts = new MTSDemuxer(ch);
|
||||
Set<Integer> programs = mts.getPrograms();
|
||||
if (programs.size() == 0) {
|
||||
Logger.error("The MPEG TS stream contains no programs");
|
||||
return null;
|
||||
}
|
||||
Tuple._2<Integer, Demuxer> found = null;
|
||||
for (Integer pid : programs) {
|
||||
ReadableByteChannel program = mts.getProgram(pid.intValue());
|
||||
if (found != null) {
|
||||
program.close();
|
||||
continue;
|
||||
}
|
||||
MPSDemuxer demuxer = new MPSDemuxer(program);
|
||||
if ((targetTrack == TrackType.AUDIO && demuxer.getAudioTracks().size() > 0) || (targetTrack == TrackType.VIDEO &&
|
||||
demuxer.getVideoTracks().size() > 0)) {
|
||||
found = Tuple.pair(pid, demuxer);
|
||||
Logger.info("Using M2TS program: " + pid + " for " + String.valueOf(targetTrack) + " track.");
|
||||
continue;
|
||||
}
|
||||
program.close();
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
public static AudioDecoder createAudioDecoder(Codec codec, ByteBuffer decoderSpecific) throws IOException {
|
||||
if (Codec.AAC == codec)
|
||||
return new AACDecoder(decoderSpecific);
|
||||
Logger.error("Codec " + String.valueOf(codec) + " is not supported");
|
||||
return null;
|
||||
}
|
||||
|
||||
public static VideoDecoder createVideoDecoder(Codec codec, ByteBuffer decoderSpecific) {
|
||||
if (Codec.H264 == codec)
|
||||
return (decoderSpecific != null) ? H264Decoder.createH264DecoderFromCodecPrivate(decoderSpecific) :
|
||||
new H264Decoder();
|
||||
if (Codec.MPEG2 == codec)
|
||||
return new MPEGDecoder();
|
||||
if (Codec.VP8 == codec)
|
||||
return new VP8Decoder();
|
||||
if (Codec.JPEG == codec)
|
||||
return new JpegDecoder();
|
||||
Logger.error("Codec " + String.valueOf(codec) + " is not supported");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
package org.jcodec.common;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import org.jcodec.common.tools.MathUtil;
|
||||
import org.jcodec.platform.Platform;
|
||||
|
||||
public class JCodecUtil2 {
|
||||
public static void writeBER32(ByteBuffer buffer, int value) {
|
||||
buffer.put((byte)(value >> 21 | 0x80));
|
||||
buffer.put((byte)(value >> 14 | 0x80));
|
||||
buffer.put((byte)(value >> 7 | 0x80));
|
||||
buffer.put((byte)(value & 0x7F));
|
||||
}
|
||||
|
||||
public static int readBER32(ByteBuffer input) {
|
||||
int size = 0;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
byte b = input.get();
|
||||
size = size << 7 | b & Byte.MAX_VALUE;
|
||||
if ((b & 0xFF) >> 7 == 0)
|
||||
break;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
public static void writeBER32Var(ByteBuffer bb, int value) {
|
||||
for (int i = 0, bits = MathUtil.log2(value); i < 4 && bits > 0; i++) {
|
||||
bits -= 7;
|
||||
int out = value >> bits;
|
||||
if (bits > 0)
|
||||
out |= 0x80;
|
||||
bb.put((byte)out);
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] asciiString(String fourcc) {
|
||||
return Platform.getBytes(fourcc);
|
||||
}
|
||||
|
||||
public static int[] getAsIntArray(ByteBuffer yuv, int size) {
|
||||
byte[] b = new byte[size];
|
||||
int[] result = new int[size];
|
||||
yuv.get(b);
|
||||
for (int i = 0; i < b.length; i++)
|
||||
result[i] = b[i] & 0xFF;
|
||||
return result;
|
||||
}
|
||||
|
||||
public static String removeExtension(String name) {
|
||||
if (name == null)
|
||||
return null;
|
||||
return name.replaceAll("\\.[^\\.]+$", "");
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,102 @@
|
|||
package org.jcodec.common;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public class LongArrayList {
|
||||
private static final int DEFAULT_GROW_AMOUNT = 128;
|
||||
|
||||
private long[] storage;
|
||||
|
||||
private int limit;
|
||||
|
||||
private int start;
|
||||
|
||||
private int growAmount;
|
||||
|
||||
public static LongArrayList createLongArrayList() {
|
||||
return new LongArrayList(128);
|
||||
}
|
||||
|
||||
public LongArrayList(int growAmount) {
|
||||
this.growAmount = growAmount;
|
||||
this.storage = new long[growAmount];
|
||||
}
|
||||
|
||||
public long[] toArray() {
|
||||
long[] result = new long[this.limit - this.start];
|
||||
System.arraycopy(this.storage, this.start, result, 0, this.limit - this.start);
|
||||
return result;
|
||||
}
|
||||
|
||||
public void add(long val) {
|
||||
if (this.limit > this.storage.length - 1) {
|
||||
long[] ns = new long[this.storage.length + this.growAmount - this.start];
|
||||
System.arraycopy(this.storage, this.start, ns, 0, this.storage.length - this.start);
|
||||
this.storage = ns;
|
||||
this.limit -= this.start;
|
||||
this.start = 0;
|
||||
}
|
||||
this.storage[this.limit++] = val;
|
||||
}
|
||||
|
||||
public void push(long id) {
|
||||
add(id);
|
||||
}
|
||||
|
||||
public long pop() {
|
||||
if (this.limit <= this.start)
|
||||
throw new IllegalStateException();
|
||||
return this.storage[this.limit--];
|
||||
}
|
||||
|
||||
public void set(int index, int value) {
|
||||
this.storage[index + this.start] = (long)value;
|
||||
}
|
||||
|
||||
public long get(int index) {
|
||||
return this.storage[index + this.start];
|
||||
}
|
||||
|
||||
public long shift() {
|
||||
if (this.start >= this.limit)
|
||||
throw new IllegalStateException();
|
||||
return this.storage[this.start++];
|
||||
}
|
||||
|
||||
public void fill(int from, int to, int val) {
|
||||
if (to > this.storage.length) {
|
||||
long[] ns = new long[to + this.growAmount - this.start];
|
||||
System.arraycopy(this.storage, this.start, ns, 0, this.storage.length - this.start);
|
||||
this.storage = ns;
|
||||
}
|
||||
Arrays.fill(this.storage, from, to, (long)val);
|
||||
this.limit = Math.max(this.limit, to);
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return this.limit - this.start;
|
||||
}
|
||||
|
||||
public void addAll(long[] other) {
|
||||
if (this.limit + other.length >= this.storage.length) {
|
||||
long[] ns = new long[this.limit + this.growAmount + other.length - this.start];
|
||||
System.arraycopy(this.storage, this.start, ns, 0, this.limit);
|
||||
this.storage = ns;
|
||||
}
|
||||
System.arraycopy(other, 0, this.storage, this.limit, other.length);
|
||||
this.limit += other.length;
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
this.limit = 0;
|
||||
this.start = 0;
|
||||
}
|
||||
|
||||
public boolean contains(long needle) {
|
||||
for (int i = this.start; i < this.limit; i++) {
|
||||
if (this.storage[i] == needle)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
package org.jcodec.common;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public interface Muxer {
|
||||
MuxerTrack addVideoTrack(Codec paramCodec, VideoCodecMeta paramVideoCodecMeta);
|
||||
|
||||
MuxerTrack addAudioTrack(Codec paramCodec, AudioCodecMeta paramAudioCodecMeta);
|
||||
|
||||
void finish() throws IOException;
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
package org.jcodec.common;
|
||||
|
||||
import java.io.IOException;
|
||||
import org.jcodec.common.model.Packet;
|
||||
|
||||
public interface MuxerTrack {
|
||||
void addFrame(Packet paramPacket) throws IOException;
|
||||
}
|
||||
|
|
@ -0,0 +1,480 @@
|
|||
package org.jcodec.common;
|
||||
|
||||
public final class Preconditions {
|
||||
public static void checkArgument(boolean expression) {
|
||||
if (!expression)
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
public static void checkArgument(boolean expression, Object errorMessage) {
|
||||
if (!expression)
|
||||
throw new IllegalArgumentException(String.valueOf(errorMessage));
|
||||
}
|
||||
|
||||
public static void checkArgument(boolean expression, String errorMessageTemplate, Object... errorMessageArgs) {
|
||||
if (!expression)
|
||||
throw new IllegalArgumentException(format(errorMessageTemplate, errorMessageArgs));
|
||||
}
|
||||
|
||||
public static void checkArgument(boolean b, String errorMessageTemplate, char p1) {
|
||||
if (!b)
|
||||
throw new IllegalArgumentException(format(errorMessageTemplate, new Object[] { p1 }));
|
||||
}
|
||||
|
||||
public static void checkArgument(boolean b, String errorMessageTemplate, int p1) {
|
||||
if (!b)
|
||||
throw new IllegalArgumentException(format(errorMessageTemplate, new Object[] { p1 }));
|
||||
}
|
||||
|
||||
public static void checkArgument(boolean b, String errorMessageTemplate, long p1) {
|
||||
if (!b)
|
||||
throw new IllegalArgumentException(format(errorMessageTemplate, new Object[] { p1 }));
|
||||
}
|
||||
|
||||
public static void checkArgument(boolean b, String errorMessageTemplate, Object p1) {
|
||||
if (!b)
|
||||
throw new IllegalArgumentException(format(errorMessageTemplate, new Object[] { p1 }));
|
||||
}
|
||||
|
||||
public static void checkArgument(boolean b, String errorMessageTemplate, char p1, char p2) {
|
||||
if (!b)
|
||||
throw new IllegalArgumentException(format(errorMessageTemplate, new Object[] { p1, p2 }));
|
||||
}
|
||||
|
||||
public static void checkArgument(boolean b, String errorMessageTemplate, char p1, int p2) {
|
||||
if (!b)
|
||||
throw new IllegalArgumentException(format(errorMessageTemplate, new Object[] { p1, p2 }));
|
||||
}
|
||||
|
||||
public static void checkArgument(boolean b, String errorMessageTemplate, char p1, long p2) {
|
||||
if (!b)
|
||||
throw new IllegalArgumentException(format(errorMessageTemplate, new Object[] { p1, p2 }));
|
||||
}
|
||||
|
||||
public static void checkArgument(boolean b, String errorMessageTemplate, char p1, Object p2) {
|
||||
if (!b)
|
||||
throw new IllegalArgumentException(format(errorMessageTemplate, new Object[] { p1, p2 }));
|
||||
}
|
||||
|
||||
public static void checkArgument(boolean b, String errorMessageTemplate, int p1, char p2) {
|
||||
if (!b)
|
||||
throw new IllegalArgumentException(format(errorMessageTemplate, new Object[] { p1, p2 }));
|
||||
}
|
||||
|
||||
public static void checkArgument(boolean b, String errorMessageTemplate, int p1, int p2) {
|
||||
if (!b)
|
||||
throw new IllegalArgumentException(format(errorMessageTemplate, new Object[] { p1, p2 }));
|
||||
}
|
||||
|
||||
public static void checkArgument(boolean b, String errorMessageTemplate, int p1, long p2) {
|
||||
if (!b)
|
||||
throw new IllegalArgumentException(format(errorMessageTemplate, new Object[] { p1, p2 }));
|
||||
}
|
||||
|
||||
public static void checkArgument(boolean b, String errorMessageTemplate, int p1, Object p2) {
|
||||
if (!b)
|
||||
throw new IllegalArgumentException(format(errorMessageTemplate, new Object[] { p1, p2 }));
|
||||
}
|
||||
|
||||
public static void checkArgument(boolean b, String errorMessageTemplate, long p1, char p2) {
|
||||
if (!b)
|
||||
throw new IllegalArgumentException(format(errorMessageTemplate, new Object[] { p1, p2 }));
|
||||
}
|
||||
|
||||
public static void checkArgument(boolean b, String errorMessageTemplate, long p1, int p2) {
|
||||
if (!b)
|
||||
throw new IllegalArgumentException(format(errorMessageTemplate, new Object[] { p1, p2 }));
|
||||
}
|
||||
|
||||
public static void checkArgument(boolean b, String errorMessageTemplate, long p1, long p2) {
|
||||
if (!b)
|
||||
throw new IllegalArgumentException(format(errorMessageTemplate, new Object[] { p1, p2 }));
|
||||
}
|
||||
|
||||
public static void checkArgument(boolean b, String errorMessageTemplate, long p1, Object p2) {
|
||||
if (!b)
|
||||
throw new IllegalArgumentException(format(errorMessageTemplate, new Object[] { p1, p2 }));
|
||||
}
|
||||
|
||||
public static void checkArgument(boolean b, String errorMessageTemplate, Object p1, char p2) {
|
||||
if (!b)
|
||||
throw new IllegalArgumentException(format(errorMessageTemplate, new Object[] { p1, p2 }));
|
||||
}
|
||||
|
||||
public static void checkArgument(boolean b, String errorMessageTemplate, Object p1, int p2) {
|
||||
if (!b)
|
||||
throw new IllegalArgumentException(format(errorMessageTemplate, new Object[] { p1, p2 }));
|
||||
}
|
||||
|
||||
public static void checkArgument(boolean b, String errorMessageTemplate, Object p1, long p2) {
|
||||
if (!b)
|
||||
throw new IllegalArgumentException(format(errorMessageTemplate, new Object[] { p1, p2 }));
|
||||
}
|
||||
|
||||
public static void checkArgument(boolean b, String errorMessageTemplate, Object p1, Object p2) {
|
||||
if (!b)
|
||||
throw new IllegalArgumentException(format(errorMessageTemplate, new Object[] { p1, p2 }));
|
||||
}
|
||||
|
||||
public static void checkArgument(boolean b, String errorMessageTemplate, Object p1, Object p2, Object p3) {
|
||||
if (!b)
|
||||
throw new IllegalArgumentException(format(errorMessageTemplate, new Object[] { p1, p2, p3 }));
|
||||
}
|
||||
|
||||
public static void checkArgument(boolean b, String errorMessageTemplate, Object p1, Object p2, Object p3, Object p4) {
|
||||
if (!b)
|
||||
throw new IllegalArgumentException(format(errorMessageTemplate, new Object[] { p1, p2, p3, p4 }));
|
||||
}
|
||||
|
||||
public static void checkState(boolean expression) {
|
||||
if (!expression)
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
public static void checkState(boolean expression, Object errorMessage) {
|
||||
if (!expression)
|
||||
throw new IllegalStateException(String.valueOf(errorMessage));
|
||||
}
|
||||
|
||||
public static void checkState(boolean expression, String errorMessageTemplate, Object... errorMessageArgs) {
|
||||
if (!expression)
|
||||
throw new IllegalStateException(format(errorMessageTemplate, errorMessageArgs));
|
||||
}
|
||||
|
||||
public static void checkState(boolean b, String errorMessageTemplate, char p1) {
|
||||
if (!b)
|
||||
throw new IllegalStateException(format(errorMessageTemplate, new Object[] { p1 }));
|
||||
}
|
||||
|
||||
public static void checkState(boolean b, String errorMessageTemplate, int p1) {
|
||||
if (!b)
|
||||
throw new IllegalStateException(format(errorMessageTemplate, new Object[] { p1 }));
|
||||
}
|
||||
|
||||
public static void checkState(boolean b, String errorMessageTemplate, long p1) {
|
||||
if (!b)
|
||||
throw new IllegalStateException(format(errorMessageTemplate, new Object[] { p1 }));
|
||||
}
|
||||
|
||||
public static void checkState(boolean b, String errorMessageTemplate, Object p1) {
|
||||
if (!b)
|
||||
throw new IllegalStateException(format(errorMessageTemplate, new Object[] { p1 }));
|
||||
}
|
||||
|
||||
public static void checkState(boolean b, String errorMessageTemplate, char p1, char p2) {
|
||||
if (!b)
|
||||
throw new IllegalStateException(format(errorMessageTemplate, new Object[] { p1, p2 }));
|
||||
}
|
||||
|
||||
public static void checkState(boolean b, String errorMessageTemplate, char p1, int p2) {
|
||||
if (!b)
|
||||
throw new IllegalStateException(format(errorMessageTemplate, new Object[] { p1, p2 }));
|
||||
}
|
||||
|
||||
public static void checkState(boolean b, String errorMessageTemplate, char p1, long p2) {
|
||||
if (!b)
|
||||
throw new IllegalStateException(format(errorMessageTemplate, new Object[] { p1, p2 }));
|
||||
}
|
||||
|
||||
public static void checkState(boolean b, String errorMessageTemplate, char p1, Object p2) {
|
||||
if (!b)
|
||||
throw new IllegalStateException(format(errorMessageTemplate, new Object[] { p1, p2 }));
|
||||
}
|
||||
|
||||
public static void checkState(boolean b, String errorMessageTemplate, int p1, char p2) {
|
||||
if (!b)
|
||||
throw new IllegalStateException(format(errorMessageTemplate, new Object[] { p1, p2 }));
|
||||
}
|
||||
|
||||
public static void checkState(boolean b, String errorMessageTemplate, int p1, int p2) {
|
||||
if (!b)
|
||||
throw new IllegalStateException(format(errorMessageTemplate, new Object[] { p1, p2 }));
|
||||
}
|
||||
|
||||
public static void checkState(boolean b, String errorMessageTemplate, int p1, long p2) {
|
||||
if (!b)
|
||||
throw new IllegalStateException(format(errorMessageTemplate, new Object[] { p1, p2 }));
|
||||
}
|
||||
|
||||
public static void checkState(boolean b, String errorMessageTemplate, int p1, Object p2) {
|
||||
if (!b)
|
||||
throw new IllegalStateException(format(errorMessageTemplate, new Object[] { p1, p2 }));
|
||||
}
|
||||
|
||||
public static void checkState(boolean b, String errorMessageTemplate, long p1, char p2) {
|
||||
if (!b)
|
||||
throw new IllegalStateException(format(errorMessageTemplate, new Object[] { p1, p2 }));
|
||||
}
|
||||
|
||||
public static void checkState(boolean b, String errorMessageTemplate, long p1, int p2) {
|
||||
if (!b)
|
||||
throw new IllegalStateException(format(errorMessageTemplate, new Object[] { p1, p2 }));
|
||||
}
|
||||
|
||||
public static void checkState(boolean b, String errorMessageTemplate, long p1, long p2) {
|
||||
if (!b)
|
||||
throw new IllegalStateException(format(errorMessageTemplate, new Object[] { p1, p2 }));
|
||||
}
|
||||
|
||||
public static void checkState(boolean b, String errorMessageTemplate, long p1, Object p2) {
|
||||
if (!b)
|
||||
throw new IllegalStateException(format(errorMessageTemplate, new Object[] { p1, p2 }));
|
||||
}
|
||||
|
||||
public static void checkState(boolean b, String errorMessageTemplate, Object p1, char p2) {
|
||||
if (!b)
|
||||
throw new IllegalStateException(format(errorMessageTemplate, new Object[] { p1, p2 }));
|
||||
}
|
||||
|
||||
public static void checkState(boolean b, String errorMessageTemplate, Object p1, int p2) {
|
||||
if (!b)
|
||||
throw new IllegalStateException(format(errorMessageTemplate, new Object[] { p1, p2 }));
|
||||
}
|
||||
|
||||
public static void checkState(boolean b, String errorMessageTemplate, Object p1, long p2) {
|
||||
if (!b)
|
||||
throw new IllegalStateException(format(errorMessageTemplate, new Object[] { p1, p2 }));
|
||||
}
|
||||
|
||||
public static void checkState(boolean b, String errorMessageTemplate, Object p1, Object p2) {
|
||||
if (!b)
|
||||
throw new IllegalStateException(format(errorMessageTemplate, new Object[] { p1, p2 }));
|
||||
}
|
||||
|
||||
public static void checkState(boolean b, String errorMessageTemplate, Object p1, Object p2, Object p3) {
|
||||
if (!b)
|
||||
throw new IllegalStateException(format(errorMessageTemplate, new Object[] { p1, p2, p3 }));
|
||||
}
|
||||
|
||||
public static void checkState(boolean b, String errorMessageTemplate, Object p1, Object p2, Object p3, Object p4) {
|
||||
if (!b)
|
||||
throw new IllegalStateException(format(errorMessageTemplate, new Object[] { p1, p2, p3, p4 }));
|
||||
}
|
||||
|
||||
public static <T> T checkNotNull(T reference) {
|
||||
if (reference == null)
|
||||
throw new NullPointerException();
|
||||
return reference;
|
||||
}
|
||||
|
||||
public static <T> T checkNotNull(T reference, Object errorMessage) {
|
||||
if (reference == null)
|
||||
throw new NullPointerException(String.valueOf(errorMessage));
|
||||
return reference;
|
||||
}
|
||||
|
||||
public static <T> T checkNotNull(T reference, String errorMessageTemplate, Object... errorMessageArgs) {
|
||||
if (reference == null)
|
||||
throw new NullPointerException(format(errorMessageTemplate, errorMessageArgs));
|
||||
return reference;
|
||||
}
|
||||
|
||||
public static <T> T checkNotNull(T obj, String errorMessageTemplate, char p1) {
|
||||
if (obj == null)
|
||||
throw new NullPointerException(format(errorMessageTemplate, new Object[] { p1 }));
|
||||
return obj;
|
||||
}
|
||||
|
||||
public static <T> T checkNotNull(T obj, String errorMessageTemplate, int p1) {
|
||||
if (obj == null)
|
||||
throw new NullPointerException(format(errorMessageTemplate, new Object[] { p1 }));
|
||||
return obj;
|
||||
}
|
||||
|
||||
public static <T> T checkNotNull(T obj, String errorMessageTemplate, long p1) {
|
||||
if (obj == null)
|
||||
throw new NullPointerException(format(errorMessageTemplate, new Object[] { p1 }));
|
||||
return obj;
|
||||
}
|
||||
|
||||
public static <T> T checkNotNull(T obj, String errorMessageTemplate, Object p1) {
|
||||
if (obj == null)
|
||||
throw new NullPointerException(format(errorMessageTemplate, new Object[] { p1 }));
|
||||
return obj;
|
||||
}
|
||||
|
||||
public static <T> T checkNotNull(T obj, String errorMessageTemplate, char p1, char p2) {
|
||||
if (obj == null)
|
||||
throw new NullPointerException(format(errorMessageTemplate, new Object[] { p1, p2 }));
|
||||
return obj;
|
||||
}
|
||||
|
||||
public static <T> T checkNotNull(T obj, String errorMessageTemplate, char p1, int p2) {
|
||||
if (obj == null)
|
||||
throw new NullPointerException(format(errorMessageTemplate, new Object[] { p1, p2 }));
|
||||
return obj;
|
||||
}
|
||||
|
||||
public static <T> T checkNotNull(T obj, String errorMessageTemplate, char p1, long p2) {
|
||||
if (obj == null)
|
||||
throw new NullPointerException(format(errorMessageTemplate, new Object[] { p1, p2 }));
|
||||
return obj;
|
||||
}
|
||||
|
||||
public static <T> T checkNotNull(T obj, String errorMessageTemplate, char p1, Object p2) {
|
||||
if (obj == null)
|
||||
throw new NullPointerException(format(errorMessageTemplate, new Object[] { p1, p2 }));
|
||||
return obj;
|
||||
}
|
||||
|
||||
public static <T> T checkNotNull(T obj, String errorMessageTemplate, int p1, char p2) {
|
||||
if (obj == null)
|
||||
throw new NullPointerException(format(errorMessageTemplate, new Object[] { p1, p2 }));
|
||||
return obj;
|
||||
}
|
||||
|
||||
public static <T> T checkNotNull(T obj, String errorMessageTemplate, int p1, int p2) {
|
||||
if (obj == null)
|
||||
throw new NullPointerException(format(errorMessageTemplate, new Object[] { p1, p2 }));
|
||||
return obj;
|
||||
}
|
||||
|
||||
public static <T> T checkNotNull(T obj, String errorMessageTemplate, int p1, long p2) {
|
||||
if (obj == null)
|
||||
throw new NullPointerException(format(errorMessageTemplate, new Object[] { p1, p2 }));
|
||||
return obj;
|
||||
}
|
||||
|
||||
public static <T> T checkNotNull(T obj, String errorMessageTemplate, int p1, Object p2) {
|
||||
if (obj == null)
|
||||
throw new NullPointerException(format(errorMessageTemplate, new Object[] { p1, p2 }));
|
||||
return obj;
|
||||
}
|
||||
|
||||
public static <T> T checkNotNull(T obj, String errorMessageTemplate, long p1, char p2) {
|
||||
if (obj == null)
|
||||
throw new NullPointerException(format(errorMessageTemplate, new Object[] { p1, p2 }));
|
||||
return obj;
|
||||
}
|
||||
|
||||
public static <T> T checkNotNull(T obj, String errorMessageTemplate, long p1, int p2) {
|
||||
if (obj == null)
|
||||
throw new NullPointerException(format(errorMessageTemplate, new Object[] { p1, p2 }));
|
||||
return obj;
|
||||
}
|
||||
|
||||
public static <T> T checkNotNull(T obj, String errorMessageTemplate, long p1, long p2) {
|
||||
if (obj == null)
|
||||
throw new NullPointerException(format(errorMessageTemplate, new Object[] { p1, p2 }));
|
||||
return obj;
|
||||
}
|
||||
|
||||
public static <T> T checkNotNull(T obj, String errorMessageTemplate, long p1, Object p2) {
|
||||
if (obj == null)
|
||||
throw new NullPointerException(format(errorMessageTemplate, new Object[] { p1, p2 }));
|
||||
return obj;
|
||||
}
|
||||
|
||||
public static <T> T checkNotNull(T obj, String errorMessageTemplate, Object p1, char p2) {
|
||||
if (obj == null)
|
||||
throw new NullPointerException(format(errorMessageTemplate, new Object[] { p1, p2 }));
|
||||
return obj;
|
||||
}
|
||||
|
||||
public static <T> T checkNotNull(T obj, String errorMessageTemplate, Object p1, int p2) {
|
||||
if (obj == null)
|
||||
throw new NullPointerException(format(errorMessageTemplate, new Object[] { p1, p2 }));
|
||||
return obj;
|
||||
}
|
||||
|
||||
public static <T> T checkNotNull(T obj, String errorMessageTemplate, Object p1, long p2) {
|
||||
if (obj == null)
|
||||
throw new NullPointerException(format(errorMessageTemplate, new Object[] { p1, p2 }));
|
||||
return obj;
|
||||
}
|
||||
|
||||
public static <T> T checkNotNull(T obj, String errorMessageTemplate, Object p1, Object p2) {
|
||||
if (obj == null)
|
||||
throw new NullPointerException(format(errorMessageTemplate, new Object[] { p1, p2 }));
|
||||
return obj;
|
||||
}
|
||||
|
||||
public static <T> T checkNotNull(T obj, String errorMessageTemplate, Object p1, Object p2, Object p3) {
|
||||
if (obj == null)
|
||||
throw new NullPointerException(format(errorMessageTemplate, new Object[] { p1, p2, p3 }));
|
||||
return obj;
|
||||
}
|
||||
|
||||
public static <T> T checkNotNull(T obj, String errorMessageTemplate, Object p1, Object p2, Object p3, Object p4) {
|
||||
if (obj == null)
|
||||
throw new NullPointerException(format(errorMessageTemplate, new Object[] { p1, p2, p3, p4 }));
|
||||
return obj;
|
||||
}
|
||||
|
||||
public static int checkElementIndex(int index, int size) {
|
||||
return checkElementIndex(index, size, "index");
|
||||
}
|
||||
|
||||
public static int checkElementIndex(int index, int size, String desc) {
|
||||
if (index < 0 || index >= size)
|
||||
throw new IndexOutOfBoundsException(badElementIndex(index, size, desc));
|
||||
return index;
|
||||
}
|
||||
|
||||
private static String badElementIndex(int index, int size, String desc) {
|
||||
if (index < 0)
|
||||
return format("%s (%s) must not be negative", new Object[] { desc, index });
|
||||
if (size < 0)
|
||||
throw new IllegalArgumentException("negative size: " + size);
|
||||
return format("%s (%s) must be less than size (%s)", new Object[] { desc, index, size });
|
||||
}
|
||||
|
||||
public static int checkPositionIndex(int index, int size) {
|
||||
return checkPositionIndex(index, size, "index");
|
||||
}
|
||||
|
||||
public static int checkPositionIndex(int index, int size, String desc) {
|
||||
if (index < 0 || index > size)
|
||||
throw new IndexOutOfBoundsException(badPositionIndex(index, size, desc));
|
||||
return index;
|
||||
}
|
||||
|
||||
private static String badPositionIndex(int index, int size, String desc) {
|
||||
if (index < 0)
|
||||
return format("%s (%s) must not be negative", new Object[] { desc, index });
|
||||
if (size < 0)
|
||||
throw new IllegalArgumentException("negative size: " + size);
|
||||
return format("%s (%s) must not be greater than size (%s)", new Object[] { desc, index, size });
|
||||
}
|
||||
|
||||
public static void checkPositionIndexes(int start, int end, int size) {
|
||||
if (start < 0 || end < start || end > size)
|
||||
throw new IndexOutOfBoundsException(badPositionIndexes(start, end, size));
|
||||
}
|
||||
|
||||
private static String badPositionIndexes(int start, int end, int size) {
|
||||
if (start < 0 || start > size)
|
||||
return badPositionIndex(start, size, "start index");
|
||||
if (end < 0 || end > size)
|
||||
return badPositionIndex(end, size, "end index");
|
||||
return format("end index (%s) must not be less than start index (%s)", new Object[] { end, start });
|
||||
}
|
||||
|
||||
static String format(String template, Object... args) {
|
||||
if (args == null)
|
||||
throw new NullPointerException();
|
||||
template = String.valueOf(template);
|
||||
StringBuilder builder = new StringBuilder(template.length() + 16 * args.length);
|
||||
int templateStart = 0;
|
||||
int i = 0;
|
||||
while (i < args.length) {
|
||||
int placeholderStart = template.indexOf("%s", templateStart);
|
||||
if (placeholderStart == -1)
|
||||
break;
|
||||
builder.append(template, templateStart, placeholderStart);
|
||||
builder.append(args[i++]);
|
||||
templateStart = placeholderStart + 2;
|
||||
}
|
||||
builder.append(template, templateStart, template.length());
|
||||
if (i < args.length) {
|
||||
builder.append(" [");
|
||||
builder.append(args[i++]);
|
||||
while (i < args.length) {
|
||||
builder.append(", ");
|
||||
builder.append(args[i++]);
|
||||
}
|
||||
builder.append(']');
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
package org.jcodec.common;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
public interface PriorityCallable<T> extends Callable<T> {
|
||||
int getPriority();
|
||||
}
|
||||
|
|
@ -0,0 +1,217 @@
|
|||
package org.jcodec.common;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import org.jcodec.common.io.NIOUtils;
|
||||
|
||||
public abstract class RunLength {
|
||||
protected IntArrayList counts = IntArrayList.createIntArrayList();
|
||||
|
||||
public int estimateSize() {
|
||||
int[] counts = getCounts();
|
||||
int recCount = 0;
|
||||
for (int i = 0; i < counts.length; i++, recCount++) {
|
||||
int count = counts[i];
|
||||
while (count >= 256) {
|
||||
recCount++;
|
||||
count -= 256;
|
||||
}
|
||||
}
|
||||
return recCount * recSize() + 4;
|
||||
}
|
||||
|
||||
protected abstract int recSize();
|
||||
|
||||
protected abstract void finish();
|
||||
|
||||
public int[] getCounts() {
|
||||
finish();
|
||||
return this.counts.toArray();
|
||||
}
|
||||
|
||||
public static class Integer extends RunLength {
|
||||
private static final int MIN_VALUE = -2147483648;
|
||||
|
||||
private int lastValue;
|
||||
|
||||
private int count = 0;
|
||||
|
||||
private IntArrayList values;
|
||||
|
||||
public Integer() {
|
||||
this.lastValue = Integer.MIN_VALUE;
|
||||
this.values = IntArrayList.createIntArrayList();
|
||||
}
|
||||
|
||||
public void add(int value) {
|
||||
if (this.lastValue == Integer.MIN_VALUE || this.lastValue != value) {
|
||||
if (this.lastValue != Integer.MIN_VALUE) {
|
||||
this.values.add(this.lastValue);
|
||||
this.counts.add(this.count);
|
||||
this.count = 0;
|
||||
}
|
||||
this.lastValue = value;
|
||||
}
|
||||
this.count++;
|
||||
}
|
||||
|
||||
public int[] getValues() {
|
||||
finish();
|
||||
return this.values.toArray();
|
||||
}
|
||||
|
||||
protected void finish() {
|
||||
if (this.lastValue != Integer.MIN_VALUE) {
|
||||
this.values.add(this.lastValue);
|
||||
this.counts.add(this.count);
|
||||
this.lastValue = Integer.MIN_VALUE;
|
||||
this.count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public void serialize(ByteBuffer bb) {
|
||||
ByteBuffer dup = bb.duplicate();
|
||||
int[] counts = getCounts();
|
||||
int[] values = getValues();
|
||||
NIOUtils.skip(bb, 4);
|
||||
int recCount = 0;
|
||||
for (int i = 0; i < counts.length; i++, recCount++) {
|
||||
int count = counts[i];
|
||||
while (count >= 256) {
|
||||
bb.put((byte)-1);
|
||||
bb.putInt(values[i]);
|
||||
recCount++;
|
||||
count -= 256;
|
||||
}
|
||||
bb.put((byte)(count - 1));
|
||||
bb.putInt(values[i]);
|
||||
}
|
||||
dup.putInt(recCount);
|
||||
}
|
||||
|
||||
public static Integer parse(ByteBuffer bb) {
|
||||
Integer rl = new Integer();
|
||||
int recCount = bb.getInt();
|
||||
for (int i = 0; i < recCount; i++) {
|
||||
int count = (bb.get() & 0xFF) + 1;
|
||||
int value = bb.getInt();
|
||||
rl.counts.add(count);
|
||||
rl.values.add(value);
|
||||
}
|
||||
return rl;
|
||||
}
|
||||
|
||||
protected int recSize() {
|
||||
return 5;
|
||||
}
|
||||
|
||||
public int[] flattern() {
|
||||
int[] counts = getCounts();
|
||||
int total = 0;
|
||||
for (int i = 0; i < counts.length; i++)
|
||||
total += counts[i];
|
||||
int[] values = getValues();
|
||||
int[] result = new int[total];
|
||||
for (int j = 0, ind = 0; j < counts.length; j++) {
|
||||
for (int k = 0; k < counts[j]; k++, ind++)
|
||||
result[ind] = values[j];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Long extends RunLength {
|
||||
private static final long MIN_VALUE = -9223372036854775808L;
|
||||
|
||||
private long lastValue;
|
||||
|
||||
private int count = 0;
|
||||
|
||||
private LongArrayList values;
|
||||
|
||||
public Long() {
|
||||
this.lastValue = Long.MIN_VALUE;
|
||||
this.values = LongArrayList.createLongArrayList();
|
||||
}
|
||||
|
||||
public void add(long value) {
|
||||
if (this.lastValue == Long.MIN_VALUE || this.lastValue != value) {
|
||||
if (this.lastValue != Long.MIN_VALUE) {
|
||||
this.values.add(this.lastValue);
|
||||
this.counts.add(this.count);
|
||||
this.count = 0;
|
||||
}
|
||||
this.lastValue = value;
|
||||
}
|
||||
this.count++;
|
||||
}
|
||||
|
||||
public int[] getCounts() {
|
||||
finish();
|
||||
return this.counts.toArray();
|
||||
}
|
||||
|
||||
public long[] getValues() {
|
||||
finish();
|
||||
return this.values.toArray();
|
||||
}
|
||||
|
||||
protected void finish() {
|
||||
if (this.lastValue != Long.MIN_VALUE) {
|
||||
this.values.add(this.lastValue);
|
||||
this.counts.add(this.count);
|
||||
this.lastValue = Long.MIN_VALUE;
|
||||
this.count = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public void serialize(ByteBuffer bb) {
|
||||
ByteBuffer dup = bb.duplicate();
|
||||
int[] counts = getCounts();
|
||||
long[] values = getValues();
|
||||
NIOUtils.skip(bb, 4);
|
||||
int recCount = 0;
|
||||
for (int i = 0; i < counts.length; i++, recCount++) {
|
||||
int count = counts[i];
|
||||
while (count >= 256) {
|
||||
bb.put((byte)-1);
|
||||
bb.putLong(values[i]);
|
||||
recCount++;
|
||||
count -= 256;
|
||||
}
|
||||
bb.put((byte)(count - 1));
|
||||
bb.putLong(values[i]);
|
||||
}
|
||||
dup.putInt(recCount);
|
||||
}
|
||||
|
||||
public static Long parse(ByteBuffer bb) {
|
||||
Long rl = new Long();
|
||||
int recCount = bb.getInt();
|
||||
for (int i = 0; i < recCount; i++) {
|
||||
int count = (bb.get() & 0xFF) + 1;
|
||||
long value = bb.getLong();
|
||||
rl.counts.add(count);
|
||||
rl.values.add(value);
|
||||
}
|
||||
return rl;
|
||||
}
|
||||
|
||||
protected int recSize() {
|
||||
return 9;
|
||||
}
|
||||
|
||||
public long[] flattern() {
|
||||
int[] counts = getCounts();
|
||||
int total = 0;
|
||||
for (int i = 0; i < counts.length; i++)
|
||||
total += counts[i];
|
||||
long[] values = getValues();
|
||||
long[] result = new long[total];
|
||||
for (int j = 0, ind = 0; j < counts.length; j++) {
|
||||
for (int k = 0; k < counts[j]; k++, ind++)
|
||||
result[ind] = values[j];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
package org.jcodec.common;
|
||||
|
||||
public interface SaveRestore {
|
||||
void save();
|
||||
|
||||
void restore();
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
package org.jcodec.common;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public interface SeekableDemuxerTrack extends DemuxerTrack {
|
||||
boolean gotoFrame(long paramLong) throws IOException;
|
||||
|
||||
boolean gotoSyncFrame(long paramLong) throws IOException;
|
||||
|
||||
long getCurFrame();
|
||||
|
||||
void seek(double paramDouble) throws IOException;
|
||||
}
|
||||
|
|
@ -0,0 +1,236 @@
|
|||
package org.jcodec.common;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class StringUtils {
|
||||
public static final String[] zeroPad00 = new String[] { "00", "01", "02", "03", "04", "05", "06", "07", "08", "09" };
|
||||
|
||||
private static String[] splitWorker4(String str, String separatorChars, int max, boolean preserveAllTokens) {
|
||||
if (str == null)
|
||||
return null;
|
||||
int len = str.length();
|
||||
if (len == 0)
|
||||
return new String[0];
|
||||
List<String> list = new ArrayList<>();
|
||||
int sizePlus1 = 1;
|
||||
int i = 0, start = 0;
|
||||
boolean match = false;
|
||||
boolean lastMatch = false;
|
||||
if (separatorChars == null) {
|
||||
while (i < len) {
|
||||
if (Character.isWhitespace(str.charAt(i))) {
|
||||
if (match || preserveAllTokens) {
|
||||
lastMatch = true;
|
||||
if (sizePlus1++ == max) {
|
||||
i = len;
|
||||
lastMatch = false;
|
||||
}
|
||||
list.add(str.substring(start, i));
|
||||
match = false;
|
||||
}
|
||||
start = ++i;
|
||||
continue;
|
||||
}
|
||||
lastMatch = false;
|
||||
match = true;
|
||||
i++;
|
||||
}
|
||||
} else if (separatorChars.length() == 1) {
|
||||
char sep = separatorChars.charAt(0);
|
||||
while (i < len) {
|
||||
if (str.charAt(i) == sep) {
|
||||
if (match || preserveAllTokens) {
|
||||
lastMatch = true;
|
||||
if (sizePlus1++ == max) {
|
||||
i = len;
|
||||
lastMatch = false;
|
||||
}
|
||||
list.add(str.substring(start, i));
|
||||
match = false;
|
||||
}
|
||||
start = ++i;
|
||||
continue;
|
||||
}
|
||||
lastMatch = false;
|
||||
match = true;
|
||||
i++;
|
||||
}
|
||||
} else {
|
||||
while (i < len) {
|
||||
if (separatorChars.indexOf(str.charAt(i)) >= 0) {
|
||||
if (match || preserveAllTokens) {
|
||||
lastMatch = true;
|
||||
if (sizePlus1++ == max) {
|
||||
i = len;
|
||||
lastMatch = false;
|
||||
}
|
||||
list.add(str.substring(start, i));
|
||||
match = false;
|
||||
}
|
||||
start = ++i;
|
||||
continue;
|
||||
}
|
||||
lastMatch = false;
|
||||
match = true;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
if (match || (preserveAllTokens && lastMatch))
|
||||
list.add(str.substring(start, i));
|
||||
return list.<String>toArray(new String[list.size()]);
|
||||
}
|
||||
|
||||
private static String[] splitWorker(String str, char separatorChar, boolean preserveAllTokens) {
|
||||
if (str == null)
|
||||
return null;
|
||||
int len = str.length();
|
||||
if (len == 0)
|
||||
return new String[0];
|
||||
List<String> list = new ArrayList<>();
|
||||
int i = 0, start = 0;
|
||||
boolean match = false;
|
||||
boolean lastMatch = false;
|
||||
while (i < len) {
|
||||
if (str.charAt(i) == separatorChar) {
|
||||
if (match || preserveAllTokens) {
|
||||
list.add(str.substring(start, i));
|
||||
match = false;
|
||||
lastMatch = true;
|
||||
}
|
||||
start = ++i;
|
||||
continue;
|
||||
}
|
||||
lastMatch = false;
|
||||
match = true;
|
||||
i++;
|
||||
}
|
||||
if (match || (preserveAllTokens && lastMatch))
|
||||
list.add(str.substring(start, i));
|
||||
return list.<String>toArray(new String[list.size()]);
|
||||
}
|
||||
|
||||
public static String[] split(String str) {
|
||||
return splitS3(str, null, -1);
|
||||
}
|
||||
|
||||
public static String[] splitS(String str, String separatorChars) {
|
||||
return splitWorker4(str, separatorChars, -1, false);
|
||||
}
|
||||
|
||||
public static String[] splitS3(String str, String separatorChars, int max) {
|
||||
return splitWorker4(str, separatorChars, max, false);
|
||||
}
|
||||
|
||||
public static String[] splitC(String str, char separatorChar) {
|
||||
return splitWorker(str, separatorChar, false);
|
||||
}
|
||||
|
||||
public static boolean isEmpty(String str) {
|
||||
return (str == null || str.length() == 0);
|
||||
}
|
||||
|
||||
private static boolean isDelimiter(char ch, char[] delimiters) {
|
||||
if (delimiters == null)
|
||||
return Character.isWhitespace(ch);
|
||||
for (int i = 0, isize = delimiters.length; i < isize; i++) {
|
||||
if (ch == delimiters[i])
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static String capitaliseAllWords(String str) {
|
||||
return capitalize(str);
|
||||
}
|
||||
|
||||
public static String capitalize(String str) {
|
||||
return capitalizeD(str, null);
|
||||
}
|
||||
|
||||
public static String capitalizeD(String str, char[] delimiters) {
|
||||
int delimLen = (delimiters == null) ? -1 : delimiters.length;
|
||||
if (str == null || str.length() == 0 || delimLen == 0)
|
||||
return str;
|
||||
int strLen = str.length();
|
||||
StringBuilder buffer = new StringBuilder(strLen);
|
||||
boolean capitalizeNext = true;
|
||||
for (int i = 0; i < strLen; i++) {
|
||||
char ch = str.charAt(i);
|
||||
if (isDelimiter(ch, delimiters)) {
|
||||
buffer.append(ch);
|
||||
capitalizeNext = true;
|
||||
} else if (capitalizeNext) {
|
||||
buffer.append(Character.toTitleCase(ch));
|
||||
capitalizeNext = false;
|
||||
} else {
|
||||
buffer.append(ch);
|
||||
}
|
||||
}
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
public static String join(Object[] array) {
|
||||
return joinS(array, null);
|
||||
}
|
||||
|
||||
public static String join2(Object[] array, char separator) {
|
||||
if (array == null)
|
||||
return null;
|
||||
return join4(array, separator, 0, array.length);
|
||||
}
|
||||
|
||||
public static String join4(Object[] array, char separator, int startIndex, int endIndex) {
|
||||
if (array == null)
|
||||
return null;
|
||||
int bufSize = endIndex - startIndex;
|
||||
if (bufSize <= 0)
|
||||
return "";
|
||||
bufSize *= ((array[startIndex] == null) ? 16 : array[startIndex].toString().length()) + 1;
|
||||
StringBuilder buf = new StringBuilder(bufSize);
|
||||
for (int i = startIndex; i < endIndex; i++) {
|
||||
if (i > startIndex)
|
||||
buf.append(separator);
|
||||
if (array[i] != null)
|
||||
buf.append(array[i]);
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
public static String joinS(Object[] array, String separator) {
|
||||
if (array == null)
|
||||
return null;
|
||||
return joinS4(array, separator, 0, array.length);
|
||||
}
|
||||
|
||||
public static String joinS4(Object[] array, String separator, int startIndex, int endIndex) {
|
||||
if (array == null)
|
||||
return null;
|
||||
if (separator == null)
|
||||
separator = "";
|
||||
int bufSize = endIndex - startIndex;
|
||||
if (bufSize <= 0)
|
||||
return "";
|
||||
bufSize *= ((array[startIndex] == null) ? 16 : array[startIndex].toString().length()) +
|
||||
separator.length();
|
||||
StringBuilder buf = new StringBuilder(bufSize);
|
||||
for (int i = startIndex; i < endIndex; i++) {
|
||||
if (i > startIndex)
|
||||
buf.append(separator);
|
||||
if (array[i] != null)
|
||||
buf.append(array[i]);
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
public static String zeroPad2(int x) {
|
||||
if (x >= 0 && x < 10)
|
||||
return zeroPad00[x];
|
||||
return "" + x;
|
||||
}
|
||||
|
||||
public static String zeroPad3(int n) {
|
||||
String s1 = zeroPad2(n);
|
||||
return (s1.length() == 2) ? ("0" + s1) : s1;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
package org.jcodec.common;
|
||||
|
||||
public enum TrackType {
|
||||
VIDEO, AUDIO, TEXT, OTHER;
|
||||
}
|
||||
|
|
@ -0,0 +1,243 @@
|
|||
package org.jcodec.common;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class Tuple {
|
||||
public static class _1<T0> {
|
||||
public final T0 v0;
|
||||
|
||||
public _1(T0 v0) {
|
||||
this.v0 = v0;
|
||||
}
|
||||
}
|
||||
|
||||
public static class _2<T0, T1> {
|
||||
public final T0 v0;
|
||||
|
||||
public final T1 v1;
|
||||
|
||||
public _2(T0 v0, T1 v1) {
|
||||
this.v0 = v0;
|
||||
this.v1 = v1;
|
||||
}
|
||||
}
|
||||
|
||||
public static class _3<T0, T1, T2> {
|
||||
public final T0 v0;
|
||||
|
||||
public final T1 v1;
|
||||
|
||||
public final T2 v2;
|
||||
|
||||
public _3(T0 v0, T1 v1, T2 v2) {
|
||||
this.v0 = v0;
|
||||
this.v1 = v1;
|
||||
this.v2 = v2;
|
||||
}
|
||||
}
|
||||
|
||||
public static class _4<T0, T1, T2, T3> {
|
||||
public final T0 v0;
|
||||
|
||||
public final T1 v1;
|
||||
|
||||
public final T2 v2;
|
||||
|
||||
public final T3 v3;
|
||||
|
||||
public _4(T0 v0, T1 v1, T2 v2, T3 v3) {
|
||||
this.v0 = v0;
|
||||
this.v1 = v1;
|
||||
this.v2 = v2;
|
||||
this.v3 = v3;
|
||||
}
|
||||
}
|
||||
|
||||
public static <T0> _1<T0> single(T0 v0) {
|
||||
return new _1<>(v0);
|
||||
}
|
||||
|
||||
public static <T0, T1> _2<T0, T1> pair(T0 v0, T1 v1) {
|
||||
return new _2<>(v0, v1);
|
||||
}
|
||||
|
||||
public static <T0, T1, T2> _3<T0, T1, T2> triple(T0 v0, T1 v1, T2 v2) {
|
||||
return new _3<>(v0, v1, v2);
|
||||
}
|
||||
|
||||
public static <T0, T1, T2, T3> _4<T0, T1, T2, T3> quad(T0 v0, T1 v1, T2 v2, T3 v3) {
|
||||
return new _4<>(v0, v1, v2, v3);
|
||||
}
|
||||
|
||||
public static <T0, T1> Map<T0, T1> asMap(Iterable<_2<T0, T1>> it) {
|
||||
HashMap<T0, T1> result = new HashMap<>();
|
||||
for (_2<T0, T1> el : it)
|
||||
result.put(el.v0, el.v1);
|
||||
return result;
|
||||
}
|
||||
|
||||
public static <T0, T1> Map<T0, T1> arrayAsMap(_2<T0, T1>[] arr) {
|
||||
HashMap<T0, T1> result = new HashMap<>();
|
||||
for (int i = 0; i < arr.length; i++) {
|
||||
_2<T0, T1> el = arr[i];
|
||||
result.put(el.v0, el.v1);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static <T0, T1> List<_2<T0, T1>> asList(Map<T0, T1> m) {
|
||||
LinkedList<_2<T0, T1>> result = new LinkedList<>();
|
||||
Set<Map.Entry<T0, T1>> entrySet = m.entrySet();
|
||||
for (Map.Entry<T0, T1> entry : entrySet)
|
||||
result.add(pair(entry.getKey(), entry.getValue()));
|
||||
return result;
|
||||
}
|
||||
|
||||
public static <T0> List<T0> _1_project0(List<_1<T0>> temp) {
|
||||
List<T0> result = new LinkedList<>();
|
||||
for (_1<T0> _1 : temp)
|
||||
result.add(_1.v0);
|
||||
return result;
|
||||
}
|
||||
|
||||
public static <T0, T1> List<T0> _2_project0(List<_2<T0, T1>> temp) {
|
||||
List<T0> result = new LinkedList<>();
|
||||
for (_2<T0, T1> _2 : temp)
|
||||
result.add(_2.v0);
|
||||
return result;
|
||||
}
|
||||
|
||||
public static <T0, T1> List<T1> _2_project1(List<_2<T0, T1>> temp) {
|
||||
List<T1> result = new LinkedList<>();
|
||||
for (_2<T0, T1> _2 : temp)
|
||||
result.add(_2.v1);
|
||||
return result;
|
||||
}
|
||||
|
||||
public static <T0, T1, T2, T3> List<T0> _3_project0(List<_3<T0, T1, T2>> temp) {
|
||||
List<T0> result = new LinkedList<>();
|
||||
for (_3<T0, T1, T2> _3 : temp)
|
||||
result.add(_3.v0);
|
||||
return result;
|
||||
}
|
||||
|
||||
public static <T0, T1, T2, T3> List<T1> _3_project1(List<_3<T0, T1, T2>> temp) {
|
||||
List<T1> result = new LinkedList<>();
|
||||
for (_3<T0, T1, T2> _3 : temp)
|
||||
result.add(_3.v1);
|
||||
return result;
|
||||
}
|
||||
|
||||
public static <T0, T1, T2, T3> List<T2> _3_project2(List<_3<T0, T1, T2>> temp) {
|
||||
List<T2> result = new LinkedList<>();
|
||||
for (_3<T0, T1, T2> _3 : temp)
|
||||
result.add(_3.v2);
|
||||
return result;
|
||||
}
|
||||
|
||||
public static <T0, T1, T2, T3> List<T0> _4_project0(List<_4<T0, T1, T2, T3>> temp) {
|
||||
List<T0> result = new LinkedList<>();
|
||||
for (_4<T0, T1, T2, T3> _4 : temp)
|
||||
result.add(_4.v0);
|
||||
return result;
|
||||
}
|
||||
|
||||
public static <T0, T1, T2, T3> List<T1> _4_project1(List<_4<T0, T1, T2, T3>> temp) {
|
||||
List<T1> result = new LinkedList<>();
|
||||
for (_4<T0, T1, T2, T3> _4 : temp)
|
||||
result.add(_4.v1);
|
||||
return result;
|
||||
}
|
||||
|
||||
public static <T0, T1, T2, T3> List<T2> _4_project2(List<_4<T0, T1, T2, T3>> temp) {
|
||||
List<T2> result = new LinkedList<>();
|
||||
for (_4<T0, T1, T2, T3> _4 : temp)
|
||||
result.add(_4.v2);
|
||||
return result;
|
||||
}
|
||||
|
||||
public static <T0, T1, T2, T3> List<T3> _4_project3(List<_4<T0, T1, T2, T3>> temp) {
|
||||
List<T3> result = new LinkedList<>();
|
||||
for (_4<T0, T1, T2, T3> _4 : temp)
|
||||
result.add(_4.v3);
|
||||
return result;
|
||||
}
|
||||
|
||||
public static <T0, U> List<_1<U>> _1map0(List<_1<T0>> l, Mapper<T0, U> mapper) {
|
||||
LinkedList<_1<U>> result = new LinkedList<>();
|
||||
for (_1<T0> _1 : l)
|
||||
result.add(single(mapper.map(_1.v0)));
|
||||
return result;
|
||||
}
|
||||
|
||||
public static <T0, T1, U> List<_2<U, T1>> _2map0(List<_2<T0, T1>> l, Mapper<T0, U> mapper) {
|
||||
LinkedList<_2<U, T1>> result = new LinkedList<>();
|
||||
for (_2<T0, T1> _2 : l)
|
||||
result.add(pair(mapper.map(_2.v0), _2.v1));
|
||||
return result;
|
||||
}
|
||||
|
||||
public static <T0, T1, U> List<_2<T0, U>> _2map1(List<_2<T0, T1>> l, Mapper<T1, U> mapper) {
|
||||
LinkedList<_2<T0, U>> result = new LinkedList<>();
|
||||
for (_2<T0, T1> _2 : l)
|
||||
result.add(pair(_2.v0, mapper.map(_2.v1)));
|
||||
return result;
|
||||
}
|
||||
|
||||
public static <T0, T1, T2, U> List<_3<U, T1, T2>> _3map0(List<_3<T0, T1, T2>> l, Mapper<T0, U> mapper) {
|
||||
LinkedList<_3<U, T1, T2>> result = new LinkedList<>();
|
||||
for (_3<T0, T1, T2> _3 : l)
|
||||
result.add(triple(mapper.map(_3.v0), _3.v1, _3.v2));
|
||||
return result;
|
||||
}
|
||||
|
||||
public static <T0, T1, T2, U> List<_3<T0, U, T2>> _3map1(List<_3<T0, T1, T2>> l, Mapper<T1, U> mapper) {
|
||||
LinkedList<_3<T0, U, T2>> result = new LinkedList<>();
|
||||
for (_3<T0, T1, T2> _3 : l)
|
||||
result.add(triple(_3.v0, mapper.map(_3.v1), _3.v2));
|
||||
return result;
|
||||
}
|
||||
|
||||
public static <T0, T1, T2, U> List<_3<T0, T1, U>> _3map3(List<_3<T0, T1, T2>> l, Mapper<T2, U> mapper) {
|
||||
LinkedList<_3<T0, T1, U>> result = new LinkedList<>();
|
||||
for (_3<T0, T1, T2> _3 : l)
|
||||
result.add(triple(_3.v0, _3.v1, mapper.map(_3.v2)));
|
||||
return result;
|
||||
}
|
||||
|
||||
public static <T0, T1, T2, T3, U> List<_4<U, T1, T2, T3>> _4map0(List<_4<T0, T1, T2, T3>> l, Mapper<T0, U> mapper) {
|
||||
LinkedList<_4<U, T1, T2, T3>> result = new LinkedList<>();
|
||||
for (_4<T0, T1, T2, T3> _4 : l)
|
||||
result.add(quad(mapper.map(_4.v0), _4.v1, _4.v2, _4.v3));
|
||||
return result;
|
||||
}
|
||||
|
||||
public static <T0, T1, T2, T3, U> List<_4<T0, U, T2, T3>> _4map1(List<_4<T0, T1, T2, T3>> l, Mapper<T1, U> mapper) {
|
||||
LinkedList<_4<T0, U, T2, T3>> result = new LinkedList<>();
|
||||
for (_4<T0, T1, T2, T3> _4 : l)
|
||||
result.add(quad(_4.v0, mapper.map(_4.v1), _4.v2, _4.v3));
|
||||
return result;
|
||||
}
|
||||
|
||||
public static <T0, T1, T2, T3, U> List<_4<T0, T1, U, T3>> _4map3(List<_4<T0, T1, T2, T3>> l, Mapper<T2, U> mapper) {
|
||||
LinkedList<_4<T0, T1, U, T3>> result = new LinkedList<>();
|
||||
for (_4<T0, T1, T2, T3> _4 : l)
|
||||
result.add(quad(_4.v0, _4.v1, mapper.map(_4.v2), _4.v3));
|
||||
return result;
|
||||
}
|
||||
|
||||
public static <T0, T1, T2, T3, U> List<_4<T0, T1, T2, U>> _4map4(List<_4<T0, T1, T2, T3>> l, Mapper<T3, U> mapper) {
|
||||
LinkedList<_4<T0, T1, T2, U>> result = new LinkedList<>();
|
||||
for (_4<T0, T1, T2, T3> _4 : l)
|
||||
result.add(quad(_4.v0, _4.v1, _4.v2, mapper.map(_4.v3)));
|
||||
return result;
|
||||
}
|
||||
|
||||
public static interface Mapper<T, U> {
|
||||
U map(T param1T);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
package org.jcodec.common;
|
||||
|
||||
public @interface UsedViaReflection {}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
package org.jcodec.common;
|
||||
|
||||
public class Vector2Int {
|
||||
public static int el16_0(int packed) {
|
||||
return packed << 16 >> 16;
|
||||
}
|
||||
|
||||
public static int el16_1(int packed) {
|
||||
return packed >> 16;
|
||||
}
|
||||
|
||||
public static int el16(int packed, int n) {
|
||||
switch (n) {
|
||||
case 0:
|
||||
return el16_0(packed);
|
||||
}
|
||||
return el16_1(packed);
|
||||
}
|
||||
|
||||
public static int set16_0(int packed, int el) {
|
||||
return packed & 0xFFFF0000 | el & 0xFFFF;
|
||||
}
|
||||
|
||||
public static int set16_1(int packed, int el) {
|
||||
return packed & 0xFFFF | (el & 0xFFFF) << 16;
|
||||
}
|
||||
|
||||
public static int set16(int packed, int el, int n) {
|
||||
switch (n) {
|
||||
case 0:
|
||||
return set16_0(packed, el);
|
||||
}
|
||||
return set16_1(packed, el);
|
||||
}
|
||||
|
||||
public static int pack16(int el0, int el1) {
|
||||
return (el1 & 0xFFFF) << 16 | el0 & 0xFFFF;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
package org.jcodec.common;
|
||||
|
||||
public class Vector4Int {
|
||||
public static int el8_0(int packed) {
|
||||
return packed << 24 >> 24;
|
||||
}
|
||||
|
||||
public static int el8_1(int packed) {
|
||||
return packed << 16 >> 24;
|
||||
}
|
||||
|
||||
public static int el8_2(int packed) {
|
||||
return packed << 8 >> 24;
|
||||
}
|
||||
|
||||
public static int el8_3(int packed) {
|
||||
return packed >> 24;
|
||||
}
|
||||
|
||||
public static int el8(int packed, int n) {
|
||||
switch (n) {
|
||||
case 0:
|
||||
return el8_0(packed);
|
||||
case 1:
|
||||
return el8_1(packed);
|
||||
case 2:
|
||||
return el8_2(packed);
|
||||
}
|
||||
return el8_3(packed);
|
||||
}
|
||||
|
||||
public static int set8_0(int packed, int el) {
|
||||
return packed & 0xFFFFFF00 | el & 0xFF;
|
||||
}
|
||||
|
||||
public static int set8_1(int packed, int el) {
|
||||
return packed & 0xFFFF00FF | (el & 0xFF) << 8;
|
||||
}
|
||||
|
||||
public static int set8_2(int packed, int el) {
|
||||
return packed & 0xFF00FFFF | (el & 0xFF) << 16;
|
||||
}
|
||||
|
||||
public static int set8_3(int packed, int el) {
|
||||
return packed & 0xFF00FFFF | (el & 0xFF) << 24;
|
||||
}
|
||||
|
||||
public static int set8(int packed, int el, int n) {
|
||||
switch (n) {
|
||||
case 0:
|
||||
return set8_0(packed, el);
|
||||
case 1:
|
||||
return set8_1(packed, el);
|
||||
case 2:
|
||||
return set8_2(packed, el);
|
||||
}
|
||||
return set8_3(packed, el);
|
||||
}
|
||||
|
||||
public static int pack8(int el0, int el1, int el2, int el3) {
|
||||
return (el3 & 0xFF) << 24 | (el2 & 0xFF) << 16 | (el1 & 0xFF) << 8 | el0 & 0xFF;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
package org.jcodec.common;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import org.jcodec.common.model.ColorSpace;
|
||||
import org.jcodec.common.model.Rational;
|
||||
import org.jcodec.common.model.Size;
|
||||
|
||||
public class VideoCodecMeta extends CodecMeta {
|
||||
private Size size;
|
||||
|
||||
private Rational pasp;
|
||||
|
||||
private boolean interlaced;
|
||||
|
||||
private boolean topFieldFirst;
|
||||
|
||||
private ColorSpace color;
|
||||
|
||||
public static VideoCodecMeta createVideoCodecMeta(String fourcc, ByteBuffer codecPrivate, Size size, Rational pasp) {
|
||||
VideoCodecMeta self = new VideoCodecMeta(fourcc, codecPrivate);
|
||||
self.size = size;
|
||||
self.pasp = pasp;
|
||||
return self;
|
||||
}
|
||||
|
||||
public static VideoCodecMeta createVideoCodecMeta2(String fourcc, ByteBuffer codecPrivate, Size size, Rational pasp, boolean interlaced, boolean topFieldFirst) {
|
||||
VideoCodecMeta self = new VideoCodecMeta(fourcc, codecPrivate);
|
||||
self.size = size;
|
||||
self.pasp = pasp;
|
||||
self.interlaced = interlaced;
|
||||
self.topFieldFirst = topFieldFirst;
|
||||
return self;
|
||||
}
|
||||
|
||||
public VideoCodecMeta(String fourcc, ByteBuffer codecPrivate) {
|
||||
super(fourcc, codecPrivate);
|
||||
}
|
||||
|
||||
public Size getSize() {
|
||||
return this.size;
|
||||
}
|
||||
|
||||
public Rational getPasp() {
|
||||
return this.pasp;
|
||||
}
|
||||
|
||||
public Rational getPixelAspectRatio() {
|
||||
return this.pasp;
|
||||
}
|
||||
|
||||
public boolean isInterlaced() {
|
||||
return this.interlaced;
|
||||
}
|
||||
|
||||
public boolean isTopFieldFirst() {
|
||||
return this.topFieldFirst;
|
||||
}
|
||||
|
||||
public ColorSpace getColor() {
|
||||
return this.color;
|
||||
}
|
||||
|
||||
public static VideoCodecMeta createSimpleVideoCodecMeta(Size size, ColorSpace color) {
|
||||
VideoCodecMeta self = new VideoCodecMeta(null, null);
|
||||
self.size = size;
|
||||
self.color = color;
|
||||
return self;
|
||||
}
|
||||
|
||||
public void setPixelAspectRatio(Rational pasp) {
|
||||
this.pasp = pasp;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
package org.jcodec.common;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import org.jcodec.common.model.Picture;
|
||||
|
||||
public abstract class VideoDecoder {
|
||||
private byte[][] byteBuffer;
|
||||
|
||||
public abstract Picture decodeFrame(ByteBuffer paramByteBuffer, byte[][] paramArrayOfbyte);
|
||||
|
||||
public abstract VideoCodecMeta getCodecMeta(ByteBuffer paramByteBuffer);
|
||||
|
||||
protected byte[][] getSameSizeBuffer(int[][] buffer) {
|
||||
if (this.byteBuffer == null || this.byteBuffer.length != buffer.length || (this.byteBuffer[0]).length != (buffer[0]).length)
|
||||
this.byteBuffer = ArrayUtil.create2D((buffer[0]).length, buffer.length);
|
||||
return this.byteBuffer;
|
||||
}
|
||||
|
||||
public VideoDecoder downscaled(int ratio) {
|
||||
if (ratio == 1)
|
||||
return this;
|
||||
return null;
|
||||
}
|
||||
|
||||
public void shutdownThreadPool() {}
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
package org.jcodec.common;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import org.jcodec.common.model.ColorSpace;
|
||||
import org.jcodec.common.model.Picture;
|
||||
|
||||
public abstract class VideoEncoder {
|
||||
public abstract EncodedFrame encodeFrame(Picture paramPicture, ByteBuffer paramByteBuffer);
|
||||
|
||||
public abstract ColorSpace[] getSupportedColorSpaces();
|
||||
|
||||
public abstract int estimateBufferSize(Picture paramPicture);
|
||||
|
||||
public static class EncodedFrame {
|
||||
private ByteBuffer data;
|
||||
|
||||
private boolean keyFrame;
|
||||
|
||||
public EncodedFrame(ByteBuffer data, boolean keyFrame) {
|
||||
this.data = data;
|
||||
this.keyFrame = keyFrame;
|
||||
}
|
||||
|
||||
public ByteBuffer getData() {
|
||||
return this.data;
|
||||
}
|
||||
|
||||
public boolean isKeyFrame() {
|
||||
return this.keyFrame;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
package org.jcodec.common.dct;
|
||||
|
||||
import org.jcodec.api.NotSupportedException;
|
||||
|
||||
public abstract class DCT {
|
||||
public short[] encode(byte[] orig) {
|
||||
throw new NotSupportedException("");
|
||||
}
|
||||
|
||||
public abstract int[] decode(int[] paramArrayOfint);
|
||||
|
||||
public void decodeAll(int[][] src) {
|
||||
for (int i = 0; i < src.length; i++)
|
||||
src[i] = decode(src[i]);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
package org.jcodec.common.dct;
|
||||
|
||||
public class DCTRef {
|
||||
static double[] coefficients = new double[64];
|
||||
|
||||
static {
|
||||
for (int j = 0; j < 8; j++) {
|
||||
coefficients[j] = Math.sqrt(0.125D);
|
||||
for (int i = 8; i < 64; i += 8)
|
||||
coefficients[i + j] = 0.5D * Math.cos((double)i * ((double)j + 0.5D) * Math.PI / 64.0D);
|
||||
}
|
||||
}
|
||||
|
||||
public static void fdct(int[] block, int off) {
|
||||
double[] out = new double[64];
|
||||
for (int i = 0; i < 64; i += 8) {
|
||||
for (int k = 0; k < 8; k++) {
|
||||
double tmp = 0.0D;
|
||||
for (int m = 0; m < 8; m++)
|
||||
tmp += coefficients[i + m] * (double)block[m * 8 + k + off];
|
||||
out[i + k] = tmp * 4.0D;
|
||||
}
|
||||
}
|
||||
for (int j = 0; j < 8; j++) {
|
||||
for (int k = 0; k < 64; k += 8) {
|
||||
double tmp = 0.0D;
|
||||
for (int m = 0; m < 8; m++)
|
||||
tmp += out[k + m] * coefficients[j * 8 + m];
|
||||
block[k + j + off] = (int)(tmp + 0.499999999999D);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void idct(int[] block, int off) {
|
||||
double[] out = new double[64];
|
||||
for (int j = 0; j < 64; j += 8) {
|
||||
for (int k = 0; k < 8; k++) {
|
||||
double tmp = 0.0D;
|
||||
for (int m = 0; m < 8; m++)
|
||||
tmp += (double)block[j + m] * coefficients[m * 8 + k];
|
||||
out[j + k] = tmp;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < 8; i++) {
|
||||
for (int k = 0; k < 8; k++) {
|
||||
double tmp = 0.0D;
|
||||
for (int m = 0; m < 64; m += 8)
|
||||
tmp += coefficients[m + i] * out[m + k];
|
||||
block[i * 8 + k] = (int)(tmp + 0.5D);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,637 @@
|
|||
package org.jcodec.common.dct;
|
||||
|
||||
import java.nio.ShortBuffer;
|
||||
|
||||
public class FfmpegIntDct {
|
||||
private static final int DCTSIZE = 8;
|
||||
|
||||
private static final int DCTSIZE_6 = 48;
|
||||
|
||||
private static final int DCTSIZE_5 = 40;
|
||||
|
||||
private static final int DCTSIZE_4 = 32;
|
||||
|
||||
private static final int DCTSIZE_3 = 24;
|
||||
|
||||
private static final int DCTSIZE_2 = 16;
|
||||
|
||||
private static final int DCTSIZE_1 = 8;
|
||||
|
||||
private static final int DCTSIZE_7 = 56;
|
||||
|
||||
private static final int DCTSIZE_0 = 0;
|
||||
|
||||
private static final int PASS1_BITS = 2;
|
||||
|
||||
private static final int CONST_BITS = 13;
|
||||
|
||||
private static final int D1 = 11;
|
||||
|
||||
private static final int D2 = 18;
|
||||
|
||||
private static final int ONEHALF_11 = 1024;
|
||||
|
||||
private static final int ONEHALF_18 = 131072;
|
||||
|
||||
private static final short FIX_0_211164243 = 1730;
|
||||
|
||||
private static final short FIX_0_275899380 = 2260;
|
||||
|
||||
private static final short FIX_0_298631336 = 2446;
|
||||
|
||||
private static final short FIX_0_390180644 = 3196;
|
||||
|
||||
private static final short FIX_0_509795579 = 4176;
|
||||
|
||||
private static final short FIX_0_541196100 = 4433;
|
||||
|
||||
private static final short FIX_0_601344887 = 4926;
|
||||
|
||||
private static final short FIX_0_765366865 = 6270;
|
||||
|
||||
private static final short FIX_0_785694958 = 6436;
|
||||
|
||||
private static final short FIX_0_899976223 = 7373;
|
||||
|
||||
private static final short FIX_1_061594337 = 8697;
|
||||
|
||||
private static final short FIX_1_111140466 = 9102;
|
||||
|
||||
private static final short FIX_1_175875602 = 9633;
|
||||
|
||||
private static final short FIX_1_306562965 = 10703;
|
||||
|
||||
private static final short FIX_1_387039845 = 11363;
|
||||
|
||||
private static final short FIX_1_451774981 = 11893;
|
||||
|
||||
private static final short FIX_1_501321110 = 12299;
|
||||
|
||||
private static final short FIX_1_662939225 = 13623;
|
||||
|
||||
private static final short FIX_1_847759065 = 15137;
|
||||
|
||||
private static final short FIX_1_961570560 = 16069;
|
||||
|
||||
private static final short FIX_2_053119869 = 16819;
|
||||
|
||||
private static final short FIX_2_172734803 = 17799;
|
||||
|
||||
private static final short FIX_2_562915447 = 20995;
|
||||
|
||||
private static final short FIX_3_072711026 = 25172;
|
||||
|
||||
public short[] decode(short[] orig) {
|
||||
ShortBuffer data = ShortBuffer.wrap(orig);
|
||||
pass1(data);
|
||||
pass2(data);
|
||||
return orig;
|
||||
}
|
||||
|
||||
private static ShortBuffer advance(ShortBuffer dataptr, int size) {
|
||||
dataptr.position(dataptr.position() + size);
|
||||
return dataptr.slice();
|
||||
}
|
||||
|
||||
private static final void pass1(ShortBuffer data) {
|
||||
ShortBuffer dataptr = data.duplicate();
|
||||
for (int rowctr = 7; rowctr >= 0; rowctr--) {
|
||||
int d0 = dataptr.get(0);
|
||||
int d2 = dataptr.get(1);
|
||||
int d4 = dataptr.get(2);
|
||||
int d6 = dataptr.get(3);
|
||||
int d1 = dataptr.get(4);
|
||||
int d3 = dataptr.get(5);
|
||||
int d5 = dataptr.get(6);
|
||||
int d7 = dataptr.get(7);
|
||||
if ((d1 | d2 | d3 | d4 | d5 | d6 | d7) == 0) {
|
||||
if (d0 != 0) {
|
||||
int dcval = d0 << 2;
|
||||
for (int i = 0; i < 8; i++)
|
||||
dataptr.put(i, (short)dcval);
|
||||
}
|
||||
dataptr = advance(dataptr, 8);
|
||||
} else {
|
||||
int tmp2, tmp3, tmp0, tmp1, tmp10, tmp13, tmp11, tmp12;
|
||||
if (d6 != 0) {
|
||||
if (d2 != 0) {
|
||||
int z1 = MULTIPLY(d2 + d6, (short)4433);
|
||||
tmp2 = z1 + MULTIPLY(-d6, (short)15137);
|
||||
tmp3 = z1 + MULTIPLY(d2, (short)6270);
|
||||
tmp0 = d0 + d4 << 13;
|
||||
tmp1 = d0 - d4 << 13;
|
||||
tmp10 = tmp0 + tmp3;
|
||||
tmp13 = tmp0 - tmp3;
|
||||
tmp11 = tmp1 + tmp2;
|
||||
tmp12 = tmp1 - tmp2;
|
||||
} else {
|
||||
tmp2 = MULTIPLY(-d6, (short)10703);
|
||||
tmp3 = MULTIPLY(d6, (short)4433);
|
||||
tmp0 = d0 + d4 << 13;
|
||||
tmp1 = d0 - d4 << 13;
|
||||
tmp10 = tmp0 + tmp3;
|
||||
tmp13 = tmp0 - tmp3;
|
||||
tmp11 = tmp1 + tmp2;
|
||||
tmp12 = tmp1 - tmp2;
|
||||
}
|
||||
} else if (d2 != 0) {
|
||||
tmp2 = MULTIPLY(d2, (short)4433);
|
||||
tmp3 = MULTIPLY(d2, (short)10703);
|
||||
tmp0 = d0 + d4 << 13;
|
||||
tmp1 = d0 - d4 << 13;
|
||||
tmp10 = tmp0 + tmp3;
|
||||
tmp13 = tmp0 - tmp3;
|
||||
tmp11 = tmp1 + tmp2;
|
||||
tmp12 = tmp1 - tmp2;
|
||||
} else {
|
||||
tmp10 = tmp13 = d0 + d4 << 13;
|
||||
tmp11 = tmp12 = d0 - d4 << 13;
|
||||
}
|
||||
if (d7 != 0) {
|
||||
if (d5 != 0) {
|
||||
if (d3 != 0) {
|
||||
if (d1 != 0) {
|
||||
int z1 = d7 + d1;
|
||||
int z2 = d5 + d3;
|
||||
int z3 = d7 + d3;
|
||||
int z4 = d5 + d1;
|
||||
int z5 = MULTIPLY(z3 + z4, (short)9633);
|
||||
tmp0 = MULTIPLY(d7, (short)2446);
|
||||
tmp1 = MULTIPLY(d5, (short)16819);
|
||||
tmp2 = MULTIPLY(d3, (short)25172);
|
||||
tmp3 = MULTIPLY(d1, (short)12299);
|
||||
z1 = MULTIPLY(-z1, (short)7373);
|
||||
z2 = MULTIPLY(-z2, (short)20995);
|
||||
z3 = MULTIPLY(-z3, (short)16069);
|
||||
z4 = MULTIPLY(-z4, (short)3196);
|
||||
z3 += z5;
|
||||
z4 += z5;
|
||||
tmp0 += z1 + z3;
|
||||
tmp1 += z2 + z4;
|
||||
tmp2 += z2 + z3;
|
||||
tmp3 += z1 + z4;
|
||||
} else {
|
||||
int z2 = d5 + d3;
|
||||
int z3 = d7 + d3;
|
||||
int z5 = MULTIPLY(z3 + d5, (short)9633);
|
||||
tmp0 = MULTIPLY(d7, (short)2446);
|
||||
tmp1 = MULTIPLY(d5, (short)16819);
|
||||
tmp2 = MULTIPLY(d3, (short)25172);
|
||||
int z1 = MULTIPLY(-d7, (short)7373);
|
||||
z2 = MULTIPLY(-z2, (short)20995);
|
||||
z3 = MULTIPLY(-z3, (short)16069);
|
||||
int z4 = MULTIPLY(-d5, (short)3196);
|
||||
z3 += z5;
|
||||
z4 += z5;
|
||||
tmp0 += z1 + z3;
|
||||
tmp1 += z2 + z4;
|
||||
tmp2 += z2 + z3;
|
||||
tmp3 = z1 + z4;
|
||||
}
|
||||
} else if (d1 != 0) {
|
||||
int z1 = d7 + d1;
|
||||
int z4 = d5 + d1;
|
||||
int z5 = MULTIPLY(d7 + z4, (short)9633);
|
||||
tmp0 = MULTIPLY(d7, (short)2446);
|
||||
tmp1 = MULTIPLY(d5, (short)16819);
|
||||
tmp3 = MULTIPLY(d1, (short)12299);
|
||||
z1 = MULTIPLY(-z1, (short)7373);
|
||||
int z2 = MULTIPLY(-d5, (short)20995);
|
||||
int z3 = MULTIPLY(-d7, (short)16069);
|
||||
z4 = MULTIPLY(-z4, (short)3196);
|
||||
z3 += z5;
|
||||
z4 += z5;
|
||||
tmp0 += z1 + z3;
|
||||
tmp1 += z2 + z4;
|
||||
tmp2 = z2 + z3;
|
||||
tmp3 += z1 + z4;
|
||||
} else {
|
||||
tmp0 = MULTIPLY(-d7, (short)4926);
|
||||
int z1 = MULTIPLY(-d7, (short)7373);
|
||||
int z3 = MULTIPLY(-d7, (short)16069);
|
||||
tmp1 = MULTIPLY(-d5, (short)4176);
|
||||
int z2 = MULTIPLY(-d5, (short)20995);
|
||||
int z4 = MULTIPLY(-d5, (short)3196);
|
||||
int z5 = MULTIPLY(d5 + d7, (short)9633);
|
||||
z3 += z5;
|
||||
z4 += z5;
|
||||
tmp0 += z3;
|
||||
tmp1 += z4;
|
||||
tmp2 = z2 + z3;
|
||||
tmp3 = z1 + z4;
|
||||
}
|
||||
} else if (d3 != 0) {
|
||||
if (d1 != 0) {
|
||||
int z1 = d7 + d1;
|
||||
int z3 = d7 + d3;
|
||||
int z5 = MULTIPLY(z3 + d1, (short)9633);
|
||||
tmp0 = MULTIPLY(d7, (short)2446);
|
||||
tmp2 = MULTIPLY(d3, (short)25172);
|
||||
tmp3 = MULTIPLY(d1, (short)12299);
|
||||
z1 = MULTIPLY(-z1, (short)7373);
|
||||
int z2 = MULTIPLY(-d3, (short)20995);
|
||||
z3 = MULTIPLY(-z3, (short)16069);
|
||||
int z4 = MULTIPLY(-d1, (short)3196);
|
||||
z3 += z5;
|
||||
z4 += z5;
|
||||
tmp0 += z1 + z3;
|
||||
tmp1 = z2 + z4;
|
||||
tmp2 += z2 + z3;
|
||||
tmp3 += z1 + z4;
|
||||
} else {
|
||||
int z3 = d7 + d3;
|
||||
tmp0 = MULTIPLY(-d7, (short)4926);
|
||||
int z1 = MULTIPLY(-d7, (short)7373);
|
||||
tmp2 = MULTIPLY(d3, (short)4176);
|
||||
int z2 = MULTIPLY(-d3, (short)20995);
|
||||
int z5 = MULTIPLY(z3, (short)9633);
|
||||
z3 = MULTIPLY(-z3, (short)6436);
|
||||
tmp0 += z3;
|
||||
tmp1 = z2 + z5;
|
||||
tmp2 += z3;
|
||||
tmp3 = z1 + z5;
|
||||
}
|
||||
} else if (d1 != 0) {
|
||||
int z1 = d7 + d1;
|
||||
int z5 = MULTIPLY(z1, (short)9633);
|
||||
z1 = MULTIPLY(z1, (short)2260);
|
||||
int z3 = MULTIPLY(-d7, (short)16069);
|
||||
tmp0 = MULTIPLY(-d7, (short)13623);
|
||||
int z4 = MULTIPLY(-d1, (short)3196);
|
||||
tmp3 = MULTIPLY(d1, (short)9102);
|
||||
tmp0 += z1;
|
||||
tmp1 = z4 + z5;
|
||||
tmp2 = z3 + z5;
|
||||
tmp3 += z1;
|
||||
} else {
|
||||
tmp0 = MULTIPLY(-d7, (short)11363);
|
||||
tmp1 = MULTIPLY(d7, (short)9633);
|
||||
tmp2 = MULTIPLY(-d7, (short)6436);
|
||||
tmp3 = MULTIPLY(d7, (short)2260);
|
||||
}
|
||||
} else if (d5 != 0) {
|
||||
if (d3 != 0) {
|
||||
if (d1 != 0) {
|
||||
int z2 = d5 + d3;
|
||||
int z4 = d5 + d1;
|
||||
int z5 = MULTIPLY(d3 + z4, (short)9633);
|
||||
tmp1 = MULTIPLY(d5, (short)16819);
|
||||
tmp2 = MULTIPLY(d3, (short)25172);
|
||||
tmp3 = MULTIPLY(d1, (short)12299);
|
||||
int z1 = MULTIPLY(-d1, (short)7373);
|
||||
z2 = MULTIPLY(-z2, (short)20995);
|
||||
int z3 = MULTIPLY(-d3, (short)16069);
|
||||
z4 = MULTIPLY(-z4, (short)3196);
|
||||
z3 += z5;
|
||||
z4 += z5;
|
||||
tmp0 = z1 + z3;
|
||||
tmp1 += z2 + z4;
|
||||
tmp2 += z2 + z3;
|
||||
tmp3 += z1 + z4;
|
||||
} else {
|
||||
int z2 = d5 + d3;
|
||||
int z5 = MULTIPLY(z2, (short)9633);
|
||||
tmp1 = MULTIPLY(d5, (short)13623);
|
||||
int z4 = MULTIPLY(-d5, (short)3196);
|
||||
z2 = MULTIPLY(-z2, (short)11363);
|
||||
tmp2 = MULTIPLY(d3, (short)9102);
|
||||
int z3 = MULTIPLY(-d3, (short)16069);
|
||||
tmp0 = z3 + z5;
|
||||
tmp1 += z2;
|
||||
tmp2 += z2;
|
||||
tmp3 = z4 + z5;
|
||||
}
|
||||
} else if (d1 != 0) {
|
||||
int z4 = d5 + d1;
|
||||
int z5 = MULTIPLY(z4, (short)9633);
|
||||
int z1 = MULTIPLY(-d1, (short)7373);
|
||||
tmp3 = MULTIPLY(d1, (short)4926);
|
||||
tmp1 = MULTIPLY(-d5, (short)4176);
|
||||
int z2 = MULTIPLY(-d5, (short)20995);
|
||||
z4 = MULTIPLY(z4, (short)6436);
|
||||
tmp0 = z1 + z5;
|
||||
tmp1 += z4;
|
||||
tmp2 = z2 + z5;
|
||||
tmp3 += z4;
|
||||
} else {
|
||||
tmp0 = MULTIPLY(d5, (short)9633);
|
||||
tmp1 = MULTIPLY(d5, (short)2260);
|
||||
tmp2 = MULTIPLY(-d5, (short)11363);
|
||||
tmp3 = MULTIPLY(d5, (short)6436);
|
||||
}
|
||||
} else if (d3 != 0) {
|
||||
if (d1 != 0) {
|
||||
int z5 = d1 + d3;
|
||||
tmp3 = MULTIPLY(d1, (short)1730);
|
||||
tmp2 = MULTIPLY(-d3, (short)11893);
|
||||
int z1 = MULTIPLY(d1, (short)8697);
|
||||
int z2 = MULTIPLY(-d3, (short)17799);
|
||||
int z4 = MULTIPLY(z5, (short)6436);
|
||||
z5 = MULTIPLY(z5, (short)9633);
|
||||
tmp0 = z1 - z4;
|
||||
tmp1 = z2 + z4;
|
||||
tmp2 += z5;
|
||||
tmp3 += z5;
|
||||
} else {
|
||||
tmp0 = MULTIPLY(-d3, (short)6436);
|
||||
tmp1 = MULTIPLY(-d3, (short)11363);
|
||||
tmp2 = MULTIPLY(-d3, (short)2260);
|
||||
tmp3 = MULTIPLY(d3, (short)9633);
|
||||
}
|
||||
} else if (d1 != 0) {
|
||||
tmp0 = MULTIPLY(d1, (short)2260);
|
||||
tmp1 = MULTIPLY(d1, (short)6436);
|
||||
tmp2 = MULTIPLY(d1, (short)9633);
|
||||
tmp3 = MULTIPLY(d1, (short)11363);
|
||||
} else {
|
||||
tmp0 = tmp1 = tmp2 = tmp3 = 0;
|
||||
}
|
||||
dataptr.put(0, DESCALE11(tmp10 + tmp3));
|
||||
dataptr.put(7, DESCALE11(tmp10 - tmp3));
|
||||
dataptr.put(1, DESCALE11(tmp11 + tmp2));
|
||||
dataptr.put(6, DESCALE11(tmp11 - tmp2));
|
||||
dataptr.put(2, DESCALE11(tmp12 + tmp1));
|
||||
dataptr.put(5, DESCALE11(tmp12 - tmp1));
|
||||
dataptr.put(3, DESCALE11(tmp13 + tmp0));
|
||||
dataptr.put(4, DESCALE11(tmp13 - tmp0));
|
||||
dataptr = advance(dataptr, 8);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static int MULTIPLY(int x, short y) {
|
||||
return y * (short)x;
|
||||
}
|
||||
|
||||
private static final void pass2(ShortBuffer data) {
|
||||
ShortBuffer dataptr = data.duplicate();
|
||||
for (int rowctr = 7; rowctr >= 0; rowctr--) {
|
||||
int tmp0, tmp1, tmp2, tmp3, tmp10, tmp11, tmp12, tmp13;
|
||||
int d0 = dataptr.get(0);
|
||||
int d1 = dataptr.get(8);
|
||||
int d2 = dataptr.get(16);
|
||||
int d3 = dataptr.get(24);
|
||||
int d4 = dataptr.get(32);
|
||||
int d5 = dataptr.get(40);
|
||||
int d6 = dataptr.get(48);
|
||||
int d7 = dataptr.get(56);
|
||||
if (d6 != 0) {
|
||||
if (d2 != 0) {
|
||||
int z1 = MULTIPLY(d2 + d6, (short)4433);
|
||||
tmp2 = z1 + MULTIPLY(-d6, (short)15137);
|
||||
tmp3 = z1 + MULTIPLY(d2, (short)6270);
|
||||
tmp0 = d0 + d4 << 13;
|
||||
tmp1 = d0 - d4 << 13;
|
||||
tmp10 = tmp0 + tmp3;
|
||||
tmp13 = tmp0 - tmp3;
|
||||
tmp11 = tmp1 + tmp2;
|
||||
tmp12 = tmp1 - tmp2;
|
||||
} else {
|
||||
tmp2 = MULTIPLY(-d6, (short)10703);
|
||||
tmp3 = MULTIPLY(d6, (short)4433);
|
||||
tmp0 = d0 + d4 << 13;
|
||||
tmp1 = d0 - d4 << 13;
|
||||
tmp10 = tmp0 + tmp3;
|
||||
tmp13 = tmp0 - tmp3;
|
||||
tmp11 = tmp1 + tmp2;
|
||||
tmp12 = tmp1 - tmp2;
|
||||
}
|
||||
} else if (d2 != 0) {
|
||||
tmp2 = MULTIPLY(d2, (short)4433);
|
||||
tmp3 = MULTIPLY(d2, (short)10703);
|
||||
tmp0 = d0 + d4 << 13;
|
||||
tmp1 = d0 - d4 << 13;
|
||||
tmp10 = tmp0 + tmp3;
|
||||
tmp13 = tmp0 - tmp3;
|
||||
tmp11 = tmp1 + tmp2;
|
||||
tmp12 = tmp1 - tmp2;
|
||||
} else {
|
||||
tmp10 = tmp13 = d0 + d4 << 13;
|
||||
tmp11 = tmp12 = d0 - d4 << 13;
|
||||
}
|
||||
if (d7 != 0) {
|
||||
if (d5 != 0) {
|
||||
if (d3 != 0) {
|
||||
if (d1 != 0) {
|
||||
int z1 = d7 + d1;
|
||||
int z2 = d5 + d3;
|
||||
int z3 = d7 + d3;
|
||||
int z4 = d5 + d1;
|
||||
int z5 = MULTIPLY(z3 + z4, (short)9633);
|
||||
tmp0 = MULTIPLY(d7, (short)2446);
|
||||
tmp1 = MULTIPLY(d5, (short)16819);
|
||||
tmp2 = MULTIPLY(d3, (short)25172);
|
||||
tmp3 = MULTIPLY(d1, (short)12299);
|
||||
z1 = MULTIPLY(-z1, (short)7373);
|
||||
z2 = MULTIPLY(-z2, (short)20995);
|
||||
z3 = MULTIPLY(-z3, (short)16069);
|
||||
z4 = MULTIPLY(-z4, (short)3196);
|
||||
z3 += z5;
|
||||
z4 += z5;
|
||||
tmp0 += z1 + z3;
|
||||
tmp1 += z2 + z4;
|
||||
tmp2 += z2 + z3;
|
||||
tmp3 += z1 + z4;
|
||||
} else {
|
||||
int z1 = d7;
|
||||
int z2 = d5 + d3;
|
||||
int z3 = d7 + d3;
|
||||
int z5 = MULTIPLY(z3 + d5, (short)9633);
|
||||
tmp0 = MULTIPLY(d7, (short)2446);
|
||||
tmp1 = MULTIPLY(d5, (short)16819);
|
||||
tmp2 = MULTIPLY(d3, (short)25172);
|
||||
z1 = MULTIPLY(-d7, (short)7373);
|
||||
z2 = MULTIPLY(-z2, (short)20995);
|
||||
z3 = MULTIPLY(-z3, (short)16069);
|
||||
int z4 = MULTIPLY(-d5, (short)3196);
|
||||
z3 += z5;
|
||||
z4 += z5;
|
||||
tmp0 += z1 + z3;
|
||||
tmp1 += z2 + z4;
|
||||
tmp2 += z2 + z3;
|
||||
tmp3 = z1 + z4;
|
||||
}
|
||||
} else if (d1 != 0) {
|
||||
int z1 = d7 + d1;
|
||||
int z2 = d5;
|
||||
int z3 = d7;
|
||||
int z4 = d5 + d1;
|
||||
int z5 = MULTIPLY(z3 + z4, (short)9633);
|
||||
tmp0 = MULTIPLY(d7, (short)2446);
|
||||
tmp1 = MULTIPLY(d5, (short)16819);
|
||||
tmp3 = MULTIPLY(d1, (short)12299);
|
||||
z1 = MULTIPLY(-z1, (short)7373);
|
||||
z2 = MULTIPLY(-d5, (short)20995);
|
||||
z3 = MULTIPLY(-d7, (short)16069);
|
||||
z4 = MULTIPLY(-z4, (short)3196);
|
||||
z3 += z5;
|
||||
z4 += z5;
|
||||
tmp0 += z1 + z3;
|
||||
tmp1 += z2 + z4;
|
||||
tmp2 = z2 + z3;
|
||||
tmp3 += z1 + z4;
|
||||
} else {
|
||||
tmp0 = MULTIPLY(-d7, (short)4926);
|
||||
int z1 = MULTIPLY(-d7, (short)7373);
|
||||
int z3 = MULTIPLY(-d7, (short)16069);
|
||||
tmp1 = MULTIPLY(-d5, (short)4176);
|
||||
int z2 = MULTIPLY(-d5, (short)20995);
|
||||
int z4 = MULTIPLY(-d5, (short)3196);
|
||||
int z5 = MULTIPLY(d5 + d7, (short)9633);
|
||||
z3 += z5;
|
||||
z4 += z5;
|
||||
tmp0 += z3;
|
||||
tmp1 += z4;
|
||||
tmp2 = z2 + z3;
|
||||
tmp3 = z1 + z4;
|
||||
}
|
||||
} else if (d3 != 0) {
|
||||
if (d1 != 0) {
|
||||
int z1 = d7 + d1;
|
||||
int z3 = d7 + d3;
|
||||
int z5 = MULTIPLY(z3 + d1, (short)9633);
|
||||
tmp0 = MULTIPLY(d7, (short)2446);
|
||||
tmp2 = MULTIPLY(d3, (short)25172);
|
||||
tmp3 = MULTIPLY(d1, (short)12299);
|
||||
z1 = MULTIPLY(-z1, (short)7373);
|
||||
int z2 = MULTIPLY(-d3, (short)20995);
|
||||
z3 = MULTIPLY(-z3, (short)16069);
|
||||
int z4 = MULTIPLY(-d1, (short)3196);
|
||||
z3 += z5;
|
||||
z4 += z5;
|
||||
tmp0 += z1 + z3;
|
||||
tmp1 = z2 + z4;
|
||||
tmp2 += z2 + z3;
|
||||
tmp3 += z1 + z4;
|
||||
} else {
|
||||
int z3 = d7 + d3;
|
||||
tmp0 = MULTIPLY(-d7, (short)4926);
|
||||
int z1 = MULTIPLY(-d7, (short)7373);
|
||||
tmp2 = MULTIPLY(d3, (short)4176);
|
||||
int z2 = MULTIPLY(-d3, (short)20995);
|
||||
int z5 = MULTIPLY(z3, (short)9633);
|
||||
z3 = MULTIPLY(-z3, (short)6436);
|
||||
tmp0 += z3;
|
||||
tmp1 = z2 + z5;
|
||||
tmp2 += z3;
|
||||
tmp3 = z1 + z5;
|
||||
}
|
||||
} else if (d1 != 0) {
|
||||
int z1 = d7 + d1;
|
||||
int z5 = MULTIPLY(z1, (short)9633);
|
||||
z1 = MULTIPLY(z1, (short)2260);
|
||||
int z3 = MULTIPLY(-d7, (short)16069);
|
||||
tmp0 = MULTIPLY(-d7, (short)13623);
|
||||
int z4 = MULTIPLY(-d1, (short)3196);
|
||||
tmp3 = MULTIPLY(d1, (short)9102);
|
||||
tmp0 += z1;
|
||||
tmp1 = z4 + z5;
|
||||
tmp2 = z3 + z5;
|
||||
tmp3 += z1;
|
||||
} else {
|
||||
tmp0 = MULTIPLY(-d7, (short)11363);
|
||||
tmp1 = MULTIPLY(d7, (short)9633);
|
||||
tmp2 = MULTIPLY(-d7, (short)6436);
|
||||
tmp3 = MULTIPLY(d7, (short)2260);
|
||||
}
|
||||
} else if (d5 != 0) {
|
||||
if (d3 != 0) {
|
||||
if (d1 != 0) {
|
||||
int z2 = d5 + d3;
|
||||
int z4 = d5 + d1;
|
||||
int z5 = MULTIPLY(d3 + z4, (short)9633);
|
||||
tmp1 = MULTIPLY(d5, (short)16819);
|
||||
tmp2 = MULTIPLY(d3, (short)25172);
|
||||
tmp3 = MULTIPLY(d1, (short)12299);
|
||||
int z1 = MULTIPLY(-d1, (short)7373);
|
||||
z2 = MULTIPLY(-z2, (short)20995);
|
||||
int z3 = MULTIPLY(-d3, (short)16069);
|
||||
z4 = MULTIPLY(-z4, (short)3196);
|
||||
z3 += z5;
|
||||
z4 += z5;
|
||||
tmp0 = z1 + z3;
|
||||
tmp1 += z2 + z4;
|
||||
tmp2 += z2 + z3;
|
||||
tmp3 += z1 + z4;
|
||||
} else {
|
||||
int z2 = d5 + d3;
|
||||
int z5 = MULTIPLY(z2, (short)9633);
|
||||
tmp1 = MULTIPLY(d5, (short)13623);
|
||||
int z4 = MULTIPLY(-d5, (short)3196);
|
||||
z2 = MULTIPLY(-z2, (short)11363);
|
||||
tmp2 = MULTIPLY(d3, (short)9102);
|
||||
int z3 = MULTIPLY(-d3, (short)16069);
|
||||
tmp0 = z3 + z5;
|
||||
tmp1 += z2;
|
||||
tmp2 += z2;
|
||||
tmp3 = z4 + z5;
|
||||
}
|
||||
} else if (d1 != 0) {
|
||||
int z4 = d5 + d1;
|
||||
int z5 = MULTIPLY(z4, (short)9633);
|
||||
int z1 = MULTIPLY(-d1, (short)7373);
|
||||
tmp3 = MULTIPLY(d1, (short)4926);
|
||||
tmp1 = MULTIPLY(-d5, (short)4176);
|
||||
int z2 = MULTIPLY(-d5, (short)20995);
|
||||
z4 = MULTIPLY(z4, (short)6436);
|
||||
tmp0 = z1 + z5;
|
||||
tmp1 += z4;
|
||||
tmp2 = z2 + z5;
|
||||
tmp3 += z4;
|
||||
} else {
|
||||
tmp0 = MULTIPLY(d5, (short)9633);
|
||||
tmp1 = MULTIPLY(d5, (short)2260);
|
||||
tmp2 = MULTIPLY(-d5, (short)11363);
|
||||
tmp3 = MULTIPLY(d5, (short)6436);
|
||||
}
|
||||
} else if (d3 != 0) {
|
||||
if (d1 != 0) {
|
||||
int z5 = d1 + d3;
|
||||
tmp3 = MULTIPLY(d1, (short)1730);
|
||||
tmp2 = MULTIPLY(-d3, (short)11893);
|
||||
int z1 = MULTIPLY(d1, (short)8697);
|
||||
int z2 = MULTIPLY(-d3, (short)17799);
|
||||
int z4 = MULTIPLY(z5, (short)6436);
|
||||
z5 = MULTIPLY(z5, (short)9633);
|
||||
tmp0 = z1 - z4;
|
||||
tmp1 = z2 + z4;
|
||||
tmp2 += z5;
|
||||
tmp3 += z5;
|
||||
} else {
|
||||
tmp0 = MULTIPLY(-d3, (short)6436);
|
||||
tmp1 = MULTIPLY(-d3, (short)11363);
|
||||
tmp2 = MULTIPLY(-d3, (short)2260);
|
||||
tmp3 = MULTIPLY(d3, (short)9633);
|
||||
}
|
||||
} else if (d1 != 0) {
|
||||
tmp0 = MULTIPLY(d1, (short)2260);
|
||||
tmp1 = MULTIPLY(d1, (short)6436);
|
||||
tmp2 = MULTIPLY(d1, (short)9633);
|
||||
tmp3 = MULTIPLY(d1, (short)11363);
|
||||
} else {
|
||||
tmp0 = tmp1 = tmp2 = tmp3 = 0;
|
||||
}
|
||||
dataptr.put(0, DESCALE18(tmp10 + tmp3));
|
||||
dataptr.put(56, DESCALE18(tmp10 - tmp3));
|
||||
dataptr.put(8, DESCALE18(tmp11 + tmp2));
|
||||
dataptr.put(48, DESCALE18(tmp11 - tmp2));
|
||||
dataptr.put(16, DESCALE18(tmp12 + tmp1));
|
||||
dataptr.put(40, DESCALE18(tmp12 - tmp1));
|
||||
dataptr.put(24, DESCALE18(tmp13 + tmp0));
|
||||
dataptr.put(32, DESCALE18(tmp13 - tmp0));
|
||||
dataptr = advance(dataptr, 1);
|
||||
}
|
||||
}
|
||||
|
||||
private static final int DESCALE(int x, int n) {
|
||||
return x + (1 << n - 1) >> n;
|
||||
}
|
||||
|
||||
private static final short DESCALE11(int x) {
|
||||
return (short)(x + 1024 >> 11);
|
||||
}
|
||||
|
||||
private static final short DESCALE18(int x) {
|
||||
return (short)(x + 131072 >> 18);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
package org.jcodec.common.dct;
|
||||
|
||||
public class IDCT2x2 {
|
||||
public static void idct(int[] blk, int off) {
|
||||
int x0 = blk[off], x1 = blk[off + 1], x2 = blk[off + 2], x3 = blk[off + 3];
|
||||
int t0 = x0 + x2;
|
||||
int t2 = x0 - x2;
|
||||
int t1 = x1 + x3;
|
||||
int t3 = x1 - x3;
|
||||
blk[off] = t0 + t1 >> 3;
|
||||
blk[off + 1] = t0 - t1 >> 3;
|
||||
blk[off + 2] = t2 + t3 >> 3;
|
||||
blk[off + 3] = t2 - t3 >> 3;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
package org.jcodec.common.dct;
|
||||
|
||||
public class IDCT4x4 {
|
||||
public static final int CN_SHIFT = 12;
|
||||
|
||||
public static void idct(int[] blk, int off) {
|
||||
for (int j = 0; j < 4; j++)
|
||||
idct4row(blk, off + (j << 2));
|
||||
for (int i = 0; i < 4; i++)
|
||||
idct4col_add(blk, off + i);
|
||||
}
|
||||
|
||||
public static final int C_FIX(double x) {
|
||||
return (int)(x * 1.414213562D * 4096.0D + 0.5D);
|
||||
}
|
||||
|
||||
public static final int C1 = C_FIX(0.6532814824D);
|
||||
|
||||
public static final int C2 = C_FIX(0.2705980501D);
|
||||
|
||||
public static final int C3 = C_FIX(0.5D);
|
||||
|
||||
public static final int C_SHIFT = 18;
|
||||
|
||||
public static final int RN_SHIFT = 15;
|
||||
|
||||
private static void idct4col_add(int[] blk, int off) {
|
||||
int a0 = blk[off];
|
||||
int a1 = blk[off + 4];
|
||||
int a2 = blk[off + 8];
|
||||
int a3 = blk[off + 12];
|
||||
int c0 = (a0 + a2) * C3 + 131072;
|
||||
int c2 = (a0 - a2) * C3 + 131072;
|
||||
int c1 = a1 * C1 + a3 * C2;
|
||||
int c3 = a1 * C2 - a3 * C1;
|
||||
blk[off] = c0 + c1 >> 18;
|
||||
blk[off + 4] = c2 + c3 >> 18;
|
||||
blk[off + 8] = c2 - c3 >> 18;
|
||||
blk[off + 12] = c0 - c1 >> 18;
|
||||
}
|
||||
|
||||
public static final int R_FIX(double x) {
|
||||
return (int)(x * 1.414213562D * 32768.0D + 0.5D);
|
||||
}
|
||||
|
||||
public static final int R1 = R_FIX(0.6532814824D);
|
||||
|
||||
public static final int R2 = R_FIX(0.2705980501D);
|
||||
|
||||
public static final int R3 = R_FIX(0.5D);
|
||||
|
||||
public static final int R_SHIFT = 11;
|
||||
|
||||
private static void idct4row(int[] blk, int off) {
|
||||
int a0 = blk[off];
|
||||
int a1 = blk[off + 1];
|
||||
int a2 = blk[off + 2];
|
||||
int a3 = blk[off + 3];
|
||||
int c0 = (a0 + a2) * R3 + 1024;
|
||||
int c2 = (a0 - a2) * R3 + 1024;
|
||||
int c1 = a1 * R1 + a3 * R2;
|
||||
int c3 = a1 * R2 - a3 * R1;
|
||||
blk[off] = c0 + c1 >> 11;
|
||||
blk[off + 1] = c2 + c3 >> 11;
|
||||
blk[off + 2] = c2 - c3 >> 11;
|
||||
blk[off + 3] = c0 - c1 >> 11;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,234 @@
|
|||
package org.jcodec.common.dct;
|
||||
|
||||
import java.nio.IntBuffer;
|
||||
|
||||
public class IntDCT extends DCT {
|
||||
public static final IntDCT INSTANCE = new IntDCT();
|
||||
|
||||
private static final int DCTSIZE = 8;
|
||||
|
||||
private static final int PASS1_BITS = 2;
|
||||
|
||||
private static final int MAXJSAMPLE = 255;
|
||||
|
||||
private static final int CENTERJSAMPLE = 128;
|
||||
|
||||
private static final int RANGE_MASK = 1023;
|
||||
|
||||
public int[] decode(int[] orig) {
|
||||
IntBuffer inptr = IntBuffer.wrap(orig);
|
||||
IntBuffer workspace = IntBuffer.allocate(64);
|
||||
IntBuffer outptr = IntBuffer.allocate(64);
|
||||
doDecode(inptr, workspace, outptr);
|
||||
return outptr.array();
|
||||
}
|
||||
|
||||
protected static IntBuffer doDecode(IntBuffer inptr, IntBuffer workspace, IntBuffer outptr) {
|
||||
pass1(inptr, workspace.duplicate());
|
||||
pass2(outptr, workspace.duplicate());
|
||||
return outptr;
|
||||
}
|
||||
|
||||
private static void pass2(IntBuffer outptr, IntBuffer wsptr) {
|
||||
for (int ctr = 0; ctr < 8; ctr++) {
|
||||
int z2 = wsptr.get(2);
|
||||
int z3 = wsptr.get(6);
|
||||
int z1 = MULTIPLY(z2 + z3, FIX_0_541196100);
|
||||
int tmp2 = z1 + MULTIPLY(z3, -FIX_1_847759065);
|
||||
int tmp3 = z1 + MULTIPLY(z2, FIX_0_765366865);
|
||||
int tmp0 = wsptr.get(0) + wsptr.get(4) << 13;
|
||||
int tmp1 = wsptr.get(0) - wsptr.get(4) << 13;
|
||||
int tmp10 = tmp0 + tmp3;
|
||||
int tmp13 = tmp0 - tmp3;
|
||||
int tmp11 = tmp1 + tmp2;
|
||||
int tmp12 = tmp1 - tmp2;
|
||||
tmp0 = wsptr.get(7);
|
||||
tmp1 = wsptr.get(5);
|
||||
tmp2 = wsptr.get(3);
|
||||
tmp3 = wsptr.get(1);
|
||||
z1 = tmp0 + tmp3;
|
||||
z2 = tmp1 + tmp2;
|
||||
z3 = tmp0 + tmp2;
|
||||
int z4 = tmp1 + tmp3;
|
||||
int z5 = MULTIPLY(z3 + z4, FIX_1_175875602);
|
||||
tmp0 = MULTIPLY(tmp0, FIX_0_298631336);
|
||||
tmp1 = MULTIPLY(tmp1, FIX_2_053119869);
|
||||
tmp2 = MULTIPLY(tmp2, FIX_3_072711026);
|
||||
tmp3 = MULTIPLY(tmp3, FIX_1_501321110);
|
||||
z1 = MULTIPLY(z1, -FIX_0_899976223);
|
||||
z2 = MULTIPLY(z2, -FIX_2_562915447);
|
||||
z3 = MULTIPLY(z3, -FIX_1_961570560);
|
||||
z4 = MULTIPLY(z4, -FIX_0_390180644);
|
||||
z3 += z5;
|
||||
z4 += z5;
|
||||
tmp0 += z1 + z3;
|
||||
tmp1 += z2 + z4;
|
||||
tmp2 += z2 + z3;
|
||||
tmp3 += z1 + z4;
|
||||
int D = 18;
|
||||
outptr.put(range_limit(DESCALE(tmp10 + tmp3, D) & 0x3FF));
|
||||
outptr.put(range_limit(DESCALE(tmp11 + tmp2, D) & 0x3FF));
|
||||
outptr.put(range_limit(DESCALE(tmp12 + tmp1, D) & 0x3FF));
|
||||
outptr.put(range_limit(DESCALE(tmp13 + tmp0, D) & 0x3FF));
|
||||
outptr.put(range_limit(DESCALE(tmp13 - tmp0, D) & 0x3FF));
|
||||
outptr.put(range_limit(DESCALE(tmp12 - tmp1, D) & 0x3FF));
|
||||
outptr.put(range_limit(DESCALE(tmp11 - tmp2, D) & 0x3FF));
|
||||
outptr.put(range_limit(DESCALE(tmp10 - tmp3, D) & 0x3FF));
|
||||
wsptr = doAdvance(wsptr, 8);
|
||||
}
|
||||
}
|
||||
|
||||
public static int range_limit(int i) {
|
||||
return idct_sample_range_limit.get(i + 256);
|
||||
}
|
||||
|
||||
private static final IntBuffer sample_range_limit = IntBuffer.allocate(1408);
|
||||
|
||||
private static final IntBuffer idct_sample_range_limit = IntBuffer.allocate(sample_range_limit.capacity() - 128);
|
||||
|
||||
private static final int CONST_BITS = 13;
|
||||
|
||||
private static final int ONE_HALF = 4096;
|
||||
|
||||
static {
|
||||
prepare_range_limit_table();
|
||||
}
|
||||
|
||||
private static void prepare_range_limit_table() {
|
||||
sample_range_limit.position(256);
|
||||
for (int i1 = 0; i1 < 128; i1++)
|
||||
sample_range_limit.put(i1);
|
||||
for (int n = -128; n < 0; n++)
|
||||
sample_range_limit.put(n);
|
||||
for (int m = 0; m < 384; m++)
|
||||
sample_range_limit.put(-1);
|
||||
for (int k = 0; k < 384; k++)
|
||||
sample_range_limit.put(0);
|
||||
for (int j = 0; j < 128; j++)
|
||||
sample_range_limit.put(j);
|
||||
for (int i = 0; i < idct_sample_range_limit.capacity(); i++)
|
||||
idct_sample_range_limit.put(sample_range_limit.get(i + 128) & 0xFF);
|
||||
}
|
||||
|
||||
private static boolean shortcut(IntBuffer inptr, IntBuffer wsptr) {
|
||||
if (inptr.get(8) == 0 && inptr.get(16) == 0 &&
|
||||
inptr.get(24) == 0 && inptr.get(32) == 0 &&
|
||||
inptr.get(40) == 0 && inptr.get(48) == 0 &&
|
||||
inptr.get(56) == 0) {
|
||||
int dcval = inptr.get(0) << 2;
|
||||
wsptr.put(0, dcval);
|
||||
wsptr.put(8, dcval);
|
||||
wsptr.put(16, dcval);
|
||||
wsptr.put(24, dcval);
|
||||
wsptr.put(32, dcval);
|
||||
wsptr.put(40, dcval);
|
||||
wsptr.put(48, dcval);
|
||||
wsptr.put(56, dcval);
|
||||
inptr = advance(inptr);
|
||||
wsptr = advance(wsptr);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static void pass1(IntBuffer inptr, IntBuffer wsptr) {
|
||||
for (int ctr = 8; ctr > 0; ctr--) {
|
||||
int z2 = inptr.get(16);
|
||||
int z3 = inptr.get(48);
|
||||
int z1 = MULTIPLY(z2 + z3, FIX_0_541196100);
|
||||
int tmp2 = z1 + MULTIPLY(z3, -FIX_1_847759065);
|
||||
int tmp3 = z1 + MULTIPLY(z2, FIX_0_765366865);
|
||||
z2 = inptr.get(0);
|
||||
z3 = inptr.get(32);
|
||||
int tmp0 = z2 + z3 << 13;
|
||||
int tmp1 = z2 - z3 << 13;
|
||||
int tmp10 = tmp0 + tmp3;
|
||||
int tmp13 = tmp0 - tmp3;
|
||||
int tmp11 = tmp1 + tmp2;
|
||||
int tmp12 = tmp1 - tmp2;
|
||||
tmp0 = inptr.get(56);
|
||||
tmp1 = inptr.get(40);
|
||||
tmp2 = inptr.get(24);
|
||||
tmp3 = inptr.get(8);
|
||||
z1 = tmp0 + tmp3;
|
||||
z2 = tmp1 + tmp2;
|
||||
z3 = tmp0 + tmp2;
|
||||
int z4 = tmp1 + tmp3;
|
||||
int z5 = MULTIPLY(z3 + z4, FIX_1_175875602);
|
||||
tmp0 = MULTIPLY(tmp0, FIX_0_298631336);
|
||||
tmp1 = MULTIPLY(tmp1, FIX_2_053119869);
|
||||
tmp2 = MULTIPLY(tmp2, FIX_3_072711026);
|
||||
tmp3 = MULTIPLY(tmp3, FIX_1_501321110);
|
||||
z1 = MULTIPLY(z1, -FIX_0_899976223);
|
||||
z2 = MULTIPLY(z2, -FIX_2_562915447);
|
||||
z3 = MULTIPLY(z3, -FIX_1_961570560);
|
||||
z4 = MULTIPLY(z4, -FIX_0_390180644);
|
||||
z3 += z5;
|
||||
z4 += z5;
|
||||
tmp0 += z1 + z3;
|
||||
tmp1 += z2 + z4;
|
||||
tmp2 += z2 + z3;
|
||||
tmp3 += z1 + z4;
|
||||
int D = 11;
|
||||
wsptr.put(0, DESCALE(tmp10 + tmp3, D));
|
||||
wsptr.put(56, DESCALE(tmp10 - tmp3, D));
|
||||
wsptr.put(8, DESCALE(tmp11 + tmp2, D));
|
||||
wsptr.put(48, DESCALE(tmp11 - tmp2, D));
|
||||
wsptr.put(16, DESCALE(tmp12 + tmp1, D));
|
||||
wsptr.put(40, DESCALE(tmp12 - tmp1, D));
|
||||
wsptr.put(24, DESCALE(tmp13 + tmp0, D));
|
||||
wsptr.put(32, DESCALE(tmp13 - tmp0, D));
|
||||
inptr = advance(inptr);
|
||||
wsptr = advance(wsptr);
|
||||
}
|
||||
}
|
||||
|
||||
private static IntBuffer advance(IntBuffer ptr) {
|
||||
return doAdvance(ptr, 1);
|
||||
}
|
||||
|
||||
private static IntBuffer doAdvance(IntBuffer ptr, int size) {
|
||||
ptr.position(ptr.position() + size);
|
||||
return ptr.slice();
|
||||
}
|
||||
|
||||
static int DESCALE(int x, int n) {
|
||||
return RIGHT_SHIFT(x + (1 << n - 1), n);
|
||||
}
|
||||
|
||||
private static int RIGHT_SHIFT(int x, int shft) {
|
||||
return x >> shft;
|
||||
}
|
||||
|
||||
private static int MULTIPLY(int i, int j) {
|
||||
return i * j;
|
||||
}
|
||||
|
||||
private static int FIX(double x) {
|
||||
return (int)(x * 8192.0D + 0.5D);
|
||||
}
|
||||
|
||||
private static final int FIX_0_298631336 = FIX(0.298631336D);
|
||||
|
||||
private static final int FIX_0_390180644 = FIX(0.390180644D);
|
||||
|
||||
private static final int FIX_0_541196100 = FIX(0.5411961D);
|
||||
|
||||
private static final int FIX_0_765366865 = FIX(0.765366865D);
|
||||
|
||||
private static final int FIX_0_899976223 = FIX(0.899976223D);
|
||||
|
||||
private static final int FIX_1_175875602 = FIX(1.175875602D);
|
||||
|
||||
private static final int FIX_1_501321110 = FIX(1.50132111D);
|
||||
|
||||
private static final int FIX_1_847759065 = FIX(1.847759065D);
|
||||
|
||||
private static final int FIX_1_961570560 = FIX(1.96157056D);
|
||||
|
||||
private static final int FIX_2_053119869 = FIX(2.053119869D);
|
||||
|
||||
private static final int FIX_2_562915447 = FIX(2.562915447D);
|
||||
|
||||
private static final int FIX_3_072711026 = FIX(3.072711026D);
|
||||
}
|
||||
|
|
@ -0,0 +1,203 @@
|
|||
package org.jcodec.common.dct;
|
||||
|
||||
public class SimpleIDCT10Bit {
|
||||
private static final int ROUND_COL = 8192;
|
||||
|
||||
private static final int ROUND_ROW = 32768;
|
||||
|
||||
private static final int SHIFT_COL = 14;
|
||||
|
||||
private static final int SHIFT_ROW = 16;
|
||||
|
||||
public static final int C0 = 23170;
|
||||
|
||||
public static final int C1 = 32138;
|
||||
|
||||
public static final int C2 = 27246;
|
||||
|
||||
public static final int C3 = 18205;
|
||||
|
||||
public static final int C4 = 6393;
|
||||
|
||||
public static final int C5 = 30274;
|
||||
|
||||
public static final int C6 = 12540;
|
||||
|
||||
public static int W1 = 90901;
|
||||
|
||||
public static int W2 = 85627;
|
||||
|
||||
public static int W3 = 77062;
|
||||
|
||||
public static int W4 = 65535;
|
||||
|
||||
public static int W5 = 51491;
|
||||
|
||||
public static int W6 = 35468;
|
||||
|
||||
public static int W7 = 18081;
|
||||
|
||||
public static int ROW_SHIFT = 15;
|
||||
|
||||
public static int COL_SHIFT = 20;
|
||||
|
||||
public static final void idct10(int[] buf, int off) {
|
||||
for (int j = 0; j < 8; j++)
|
||||
idctRow(buf, off + (j << 3));
|
||||
for (int i = 0; i < 8; i++)
|
||||
idctCol(buf, off + i);
|
||||
}
|
||||
|
||||
private static final void idctCol(int[] buf, int off) {
|
||||
int a0 = W4 * (buf[off + 0] + (1 << COL_SHIFT - 1) / W4);
|
||||
int a1 = a0;
|
||||
int a2 = a0;
|
||||
int a3 = a0;
|
||||
a0 += W2 * buf[off + 16];
|
||||
a1 += W6 * buf[off + 16];
|
||||
a2 += -W6 * buf[off + 16];
|
||||
a3 += -W2 * buf[off + 16];
|
||||
int b0 = W1 * buf[off + 8];
|
||||
int b1 = W3 * buf[off + 8];
|
||||
int b2 = W5 * buf[off + 8];
|
||||
int b3 = W7 * buf[off + 8];
|
||||
b0 += W3 * buf[off + 24];
|
||||
b1 += -W7 * buf[off + 24];
|
||||
b2 += -W1 * buf[off + 24];
|
||||
b3 += -W5 * buf[off + 24];
|
||||
if (buf[off + 32] != 0) {
|
||||
a0 += W4 * buf[off + 32];
|
||||
a1 += -W4 * buf[off + 32];
|
||||
a2 += -W4 * buf[off + 32];
|
||||
a3 += W4 * buf[off + 32];
|
||||
}
|
||||
if (buf[off + 40] != 0) {
|
||||
b0 += W5 * buf[off + 40];
|
||||
b1 += -W1 * buf[off + 40];
|
||||
b2 += W7 * buf[off + 40];
|
||||
b3 += W3 * buf[off + 40];
|
||||
}
|
||||
if (buf[off + 48] != 0) {
|
||||
a0 += W6 * buf[off + 48];
|
||||
a1 += -W2 * buf[off + 48];
|
||||
a2 += W2 * buf[off + 48];
|
||||
a3 += -W6 * buf[off + 48];
|
||||
}
|
||||
if (buf[off + 56] != 0) {
|
||||
b0 += W7 * buf[off + 56];
|
||||
b1 += -W5 * buf[off + 56];
|
||||
b2 += W3 * buf[off + 56];
|
||||
b3 += -W1 * buf[off + 56];
|
||||
}
|
||||
buf[off] = a0 + b0 >> COL_SHIFT;
|
||||
buf[off + 8] = a1 + b1 >> COL_SHIFT;
|
||||
buf[off + 16] = a2 + b2 >> COL_SHIFT;
|
||||
buf[off + 24] = a3 + b3 >> COL_SHIFT;
|
||||
buf[off + 32] = a3 - b3 >> COL_SHIFT;
|
||||
buf[off + 40] = a2 - b2 >> COL_SHIFT;
|
||||
buf[off + 48] = a1 - b1 >> COL_SHIFT;
|
||||
buf[off + 56] = a0 - b0 >> COL_SHIFT;
|
||||
}
|
||||
|
||||
private static final void idctRow(int[] buf, int off) {
|
||||
int a0 = W4 * buf[off] + (1 << ROW_SHIFT - 1);
|
||||
int a1 = a0;
|
||||
int a2 = a0;
|
||||
int a3 = a0;
|
||||
a0 += W2 * buf[off + 2];
|
||||
a1 += W6 * buf[off + 2];
|
||||
a2 -= W6 * buf[off + 2];
|
||||
a3 -= W2 * buf[off + 2];
|
||||
int b0 = W1 * buf[off + 1];
|
||||
b0 += W3 * buf[off + 3];
|
||||
int b1 = W3 * buf[off + 1];
|
||||
b1 += -W7 * buf[off + 3];
|
||||
int b2 = W5 * buf[off + 1];
|
||||
b2 += -W1 * buf[off + 3];
|
||||
int b3 = W7 * buf[off + 1];
|
||||
b3 += -W5 * buf[off + 3];
|
||||
if (buf[off + 4] != 0 || buf[off + 5] != 0 || buf[off + 6] != 0 || buf[off + 7] != 0) {
|
||||
a0 += W4 * buf[off + 4] + W6 * buf[off + 6];
|
||||
a1 += -W4 * buf[off + 4] - W2 * buf[off + 6];
|
||||
a2 += -W4 * buf[off + 4] + W2 * buf[off + 6];
|
||||
a3 += W4 * buf[off + 4] - W6 * buf[off + 6];
|
||||
b0 += W5 * buf[off + 5];
|
||||
b0 += W7 * buf[off + 7];
|
||||
b1 += -W1 * buf[off + 5];
|
||||
b1 += -W5 * buf[off + 7];
|
||||
b2 += W7 * buf[off + 5];
|
||||
b2 += W3 * buf[off + 7];
|
||||
b3 += W3 * buf[off + 5];
|
||||
b3 += -W1 * buf[off + 7];
|
||||
}
|
||||
buf[off + 0] = a0 + b0 >> ROW_SHIFT;
|
||||
buf[off + 7] = a0 - b0 >> ROW_SHIFT;
|
||||
buf[off + 1] = a1 + b1 >> ROW_SHIFT;
|
||||
buf[off + 6] = a1 - b1 >> ROW_SHIFT;
|
||||
buf[off + 2] = a2 + b2 >> ROW_SHIFT;
|
||||
buf[off + 5] = a2 - b2 >> ROW_SHIFT;
|
||||
buf[off + 3] = a3 + b3 >> ROW_SHIFT;
|
||||
buf[off + 4] = a3 - b3 >> ROW_SHIFT;
|
||||
}
|
||||
|
||||
public static void fdctProres10(int[] block, int off) {
|
||||
for (int j = 0; j < 8; j++)
|
||||
fdctCol(block, off + j);
|
||||
for (int i = 0; i < 64; i += 8)
|
||||
fdctRow(block, off + i);
|
||||
}
|
||||
|
||||
private static void fdctRow(int[] block, int off) {
|
||||
int z0 = block[off + 0] - block[off + 7];
|
||||
int z1 = block[off + 1] - block[off + 6];
|
||||
int z2 = block[off + 2] - block[off + 5];
|
||||
int z3 = block[off + 3] - block[off + 4];
|
||||
int z4 = block[off + 0] + block[off + 7];
|
||||
int z5 = block[off + 3] + block[off + 4];
|
||||
int z6 = block[off + 1] + block[off + 6];
|
||||
int z7 = block[off + 2] + block[off + 5];
|
||||
int u0 = z4 - z5;
|
||||
int u1 = z6 - z7;
|
||||
int c0 = (z4 + z5) * 23170;
|
||||
int c1 = (z6 + z7) * 23170;
|
||||
int c2 = u0 * 30274;
|
||||
int c3 = u1 * 12540;
|
||||
int c4 = u0 * 12540;
|
||||
int c5 = u1 * 30274;
|
||||
block[1 + off] = z0 * 32138 + z1 * 27246 + z2 * 18205 + z3 * 6393 + 32768 >> 16;
|
||||
block[3 + off] = z0 * 27246 - z1 * 6393 - z2 * 32138 - z3 * 18205 + 32768 >> 16;
|
||||
block[5 + off] = z0 * 18205 - z1 * 32138 + z2 * 6393 + z3 * 27246 + 32768 >> 16;
|
||||
block[7 + off] = z0 * 6393 - z1 * 18205 + z2 * 27246 - z3 * 32138 + 32768 >> 16;
|
||||
block[0 + off] = c0 + c1 + 32768 >> 16;
|
||||
block[2 + off] = c2 + c3 + 32768 >> 16;
|
||||
block[4 + off] = c0 - c1 + 32768 >> 16;
|
||||
block[6 + off] = c4 - c5 + 32768 >> 16;
|
||||
}
|
||||
|
||||
private static void fdctCol(int[] block, int off) {
|
||||
int z0 = block[off + 0] - block[off + 56];
|
||||
int z1 = block[off + 8] - block[off + 48];
|
||||
int z2 = block[off + 16] - block[off + 40];
|
||||
int z3 = block[off + 24] - block[off + 32];
|
||||
int z4 = block[off + 0] + block[off + 56];
|
||||
int z5 = block[off + 24] + block[off + 32];
|
||||
int z6 = block[off + 8] + block[off + 48];
|
||||
int z7 = block[off + 16] + block[off + 40];
|
||||
int u0 = z4 - z5;
|
||||
int u1 = z6 - z7;
|
||||
int c0 = (z4 + z5) * 23170;
|
||||
int c1 = (z6 + z7) * 23170;
|
||||
int c2 = u0 * 30274;
|
||||
int c3 = u1 * 12540;
|
||||
int c4 = u0 * 12540;
|
||||
int c5 = u1 * 30274;
|
||||
block[8 + off] = z0 * 32138 + z1 * 27246 + z2 * 18205 + z3 * 6393 + 8192 >> 14;
|
||||
block[24 + off] = z0 * 27246 - z1 * 6393 - z2 * 32138 - z3 * 18205 + 8192 >> 14;
|
||||
block[40 + off] = z0 * 18205 - z1 * 32138 + z2 * 6393 + z3 * 27246 + 8192 >> 14;
|
||||
block[56 + off] = z0 * 6393 - z1 * 18205 + z2 * 27246 - z3 * 32138 + 8192 >> 14;
|
||||
block[0 + off] = c0 + c1 + 8192 >> 14;
|
||||
block[16 + off] = c2 + c3 + 8192 >> 14;
|
||||
block[32 + off] = c0 - c1 + 8192 >> 14;
|
||||
block[48 + off] = c4 - c5 + 8192 >> 14;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
package org.jcodec.common.dct;
|
||||
|
||||
import org.jcodec.scale.ImageConvert;
|
||||
|
||||
public class SlowDCT extends DCT {
|
||||
public static final SlowDCT INSTANCE = new SlowDCT();
|
||||
|
||||
private static final double rSqrt2 = 1.0D / Math.sqrt(2.0D);
|
||||
|
||||
public short[] encode(byte[] orig) {
|
||||
short[] result = new short[64];
|
||||
for (int u = 0; u < 8; u++) {
|
||||
for (int v = 0; v < 8; v++) {
|
||||
float sum = 0.0F;
|
||||
for (int j = 0; j < 8; j++) {
|
||||
for (int k = 0; k < 8; k++)
|
||||
sum = (float)((double)sum + (double)(float)orig[j * 8 + k] * Math.cos(0.39269908169872414D * ((double)j + 0.5D) * (double)u) * Math.cos(0.39269908169872414D * ((double)k + 0.5D) * (double)v));
|
||||
}
|
||||
result[u * 8 + v] = (short)(byte)(int)sum;
|
||||
}
|
||||
}
|
||||
result[0] = (short)(byte)(int)((float)result[0] / 8.0F);
|
||||
double sqrt2 = Math.sqrt(2.0D);
|
||||
for (int i = 1; i < 8; i++) {
|
||||
result[i] = (short)(byte)(int)((double)(float)result[0] * sqrt2 / 8.0D);
|
||||
result[i * 8] = (short)(byte)(int)((double)(float)result[0] * sqrt2 / 8.0D);
|
||||
for (int j = 1; j < 8; j++)
|
||||
result[i * 8 + j] = (short)(byte)(int)((float)result[0] / 4.0F);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public int[] decode(int[] orig) {
|
||||
int[] res = new int[64];
|
||||
int i = 0;
|
||||
for (int y = 0; y < 8; y++) {
|
||||
for (int x = 0; x < 8; x++) {
|
||||
double sum = 0.0D;
|
||||
int pixOffset = 0;
|
||||
for (int u = 0; u < 8; u++) {
|
||||
double cu = (u == 0) ? rSqrt2 : 1.0D;
|
||||
for (int v = 0; v < 8; v++) {
|
||||
double cv = (v == 0) ? rSqrt2 : 1.0D;
|
||||
double svu = (double)orig[pixOffset];
|
||||
double c1 = (double)((2 * x + 1) * v) * Math.PI / 16.0D;
|
||||
double c2 = (double)((2 * y + 1) * u) * Math.PI / 16.0D;
|
||||
sum += cu * cv * svu * Math.cos(c1) * Math.cos(c2);
|
||||
pixOffset++;
|
||||
}
|
||||
}
|
||||
sum *= 0.25D;
|
||||
sum = (double)Math.round(sum + 128.0D);
|
||||
int isum = (int)sum;
|
||||
res[i++] = ImageConvert.icrop(isum);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
package org.jcodec.common.dct;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public class SparseIDCT {
|
||||
public static final int[][] COEFF = new int[64][];
|
||||
|
||||
public static final int PRECISION = 13;
|
||||
|
||||
public static final int DC_SHIFT = 10;
|
||||
|
||||
static {
|
||||
COEFF[0] = new int[64];
|
||||
Arrays.fill(COEFF[0], 1024);
|
||||
int ac = 8192;
|
||||
for (int i = 1; i < 64; i++) {
|
||||
COEFF[i] = new int[64];
|
||||
COEFF[i][i] = ac;
|
||||
SimpleIDCT10Bit.idct10(COEFF[i], 0);
|
||||
}
|
||||
}
|
||||
|
||||
public static final void start(int[] block, int dc) {
|
||||
dc <<= 10;
|
||||
for (int i = 0; i < 64; i += 4) {
|
||||
block[i + 0] = dc;
|
||||
block[i + 1] = dc;
|
||||
block[i + 2] = dc;
|
||||
block[i + 3] = dc;
|
||||
}
|
||||
}
|
||||
|
||||
public static final void coeff(int[] block, int ind, int level) {
|
||||
for (int i = 0; i < 64; i += 4) {
|
||||
block[i] = block[i] + COEFF[ind][i] * level;
|
||||
block[i + 1] = block[i + 1] + COEFF[ind][i + 1] * level;
|
||||
block[i + 2] = block[i + 2] + COEFF[ind][i + 2] * level;
|
||||
block[i + 3] = block[i + 3] + COEFF[ind][i + 3] * level;
|
||||
}
|
||||
}
|
||||
|
||||
public static final void finish(int[] block) {
|
||||
for (int i = 0; i < 64; i += 4) {
|
||||
block[i] = div(block[i]);
|
||||
block[i + 1] = div(block[i + 1]);
|
||||
block[i + 2] = div(block[i + 2]);
|
||||
block[i + 3] = div(block[i + 3]);
|
||||
}
|
||||
}
|
||||
|
||||
private static final int div(int x) {
|
||||
int m = x >> 31;
|
||||
int n = x >>> 31;
|
||||
return ((x ^ m) + n >> 13 ^ m) + n;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
package org.jcodec.common.io;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class AutoPool {
|
||||
private final List<AutoResource> resources = Collections.synchronizedList(new ArrayList<>());
|
||||
|
||||
private ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1, daemonThreadFactory());
|
||||
|
||||
private AutoPool() {
|
||||
final List<AutoResource> res = this.resources;
|
||||
this.scheduler.scheduleAtFixedRate(new Runnable() {
|
||||
public void run() {
|
||||
long curTime = System.currentTimeMillis();
|
||||
for (AutoResource autoResource : (Iterable<AutoResource>)res)
|
||||
autoResource.setCurTime(curTime);
|
||||
}
|
||||
}, 0L, 100L, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
private ThreadFactory daemonThreadFactory() {
|
||||
return new ThreadFactory() {
|
||||
public Thread newThread(Runnable r) {
|
||||
Thread t = new Thread(r);
|
||||
t.setDaemon(true);
|
||||
t.setName(AutoPool.class.getName());
|
||||
return t;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static AutoPool getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
public void add(AutoResource res) {
|
||||
this.resources.add(res);
|
||||
}
|
||||
|
||||
private static AutoPool instance = new AutoPool();
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
package org.jcodec.common.io;
|
||||
|
||||
public interface AutoResource {
|
||||
void setCurTime(long paramLong);
|
||||
}
|
||||
|
|
@ -0,0 +1,221 @@
|
|||
package org.jcodec.common.io;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
public class BitReader {
|
||||
public static BitReader createBitReader(ByteBuffer bb) {
|
||||
BitReader r = new BitReader(bb);
|
||||
r.curInt = r.readInt();
|
||||
r.deficit = 0;
|
||||
return r;
|
||||
}
|
||||
|
||||
private int deficit = -1;
|
||||
|
||||
private int curInt = -1;
|
||||
|
||||
private ByteBuffer bb;
|
||||
|
||||
private int initPos;
|
||||
|
||||
private BitReader(ByteBuffer bb) {
|
||||
this.bb = bb;
|
||||
this.initPos = bb.position();
|
||||
}
|
||||
|
||||
public BitReader fork() {
|
||||
BitReader fork = new BitReader(this.bb.duplicate());
|
||||
fork.initPos = 0;
|
||||
fork.curInt = this.curInt;
|
||||
fork.deficit = this.deficit;
|
||||
return fork;
|
||||
}
|
||||
|
||||
public final int readInt() {
|
||||
if (this.bb.remaining() >= 4) {
|
||||
this.deficit -= 32;
|
||||
return (this.bb.get() & 0xFF) << 24 | (this.bb.get() & 0xFF) << 16 | (this.bb.get() & 0xFF) << 8 | this.bb.get() & 0xFF;
|
||||
}
|
||||
return readIntSafe();
|
||||
}
|
||||
|
||||
private int readIntSafe() {
|
||||
this.deficit -= this.bb.remaining() << 3;
|
||||
int res = 0;
|
||||
if (this.bb.hasRemaining())
|
||||
res |= this.bb.get() & 0xFF;
|
||||
res <<= 8;
|
||||
if (this.bb.hasRemaining())
|
||||
res |= this.bb.get() & 0xFF;
|
||||
res <<= 8;
|
||||
if (this.bb.hasRemaining())
|
||||
res |= this.bb.get() & 0xFF;
|
||||
res <<= 8;
|
||||
if (this.bb.hasRemaining())
|
||||
res |= this.bb.get() & 0xFF;
|
||||
return res;
|
||||
}
|
||||
|
||||
public int read1Bit() {
|
||||
int ret = this.curInt >>> 31;
|
||||
this.curInt <<= 1;
|
||||
this.deficit++;
|
||||
if (this.deficit == 32)
|
||||
this.curInt = readInt();
|
||||
return ret;
|
||||
}
|
||||
|
||||
public int readNBitSigned(int n) {
|
||||
int v = readNBit(n);
|
||||
return (read1Bit() == 0) ? v : -v;
|
||||
}
|
||||
|
||||
public int readNBit(int n) {
|
||||
if (n > 32)
|
||||
throw new IllegalArgumentException("Can not read more then 32 bit");
|
||||
int nn = n;
|
||||
int ret = 0;
|
||||
if (n + this.deficit > 31) {
|
||||
ret |= this.curInt >>> this.deficit;
|
||||
n -= 32 - this.deficit;
|
||||
ret <<= n;
|
||||
this.deficit = 32;
|
||||
this.curInt = readInt();
|
||||
}
|
||||
if (n != 0) {
|
||||
ret |= this.curInt >>> 32 - n;
|
||||
this.curInt <<= n;
|
||||
this.deficit += n;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public boolean moreData() {
|
||||
int remaining = this.bb.remaining() + 4 - (this.deficit + 7 >> 3);
|
||||
return (remaining > 1 || (remaining == 1 && this.curInt != 0));
|
||||
}
|
||||
|
||||
public int remaining() {
|
||||
return (this.bb.remaining() << 3) + 32 - this.deficit;
|
||||
}
|
||||
|
||||
public final boolean isByteAligned() {
|
||||
return ((this.deficit & 0x7) == 0);
|
||||
}
|
||||
|
||||
public int skip(int bits) {
|
||||
int left = bits;
|
||||
if (left + this.deficit > 31) {
|
||||
left -= 32 - this.deficit;
|
||||
this.deficit = 32;
|
||||
if (left > 31) {
|
||||
int skip = Math.min(left >> 3, this.bb.remaining());
|
||||
this.bb.position(this.bb.position() + skip);
|
||||
left -= skip << 3;
|
||||
}
|
||||
this.curInt = readInt();
|
||||
}
|
||||
this.deficit += left;
|
||||
this.curInt <<= left;
|
||||
return bits;
|
||||
}
|
||||
|
||||
public int skipFast(int bits) {
|
||||
this.deficit += bits;
|
||||
this.curInt <<= bits;
|
||||
return bits;
|
||||
}
|
||||
|
||||
public int bitsToAlign() {
|
||||
return ((this.deficit & 0x7) > 0) ? (8 - (this.deficit & 0x7)) : 0;
|
||||
}
|
||||
|
||||
public int align() {
|
||||
return ((this.deficit & 0x7) > 0) ? skip(8 - (this.deficit & 0x7)) : 0;
|
||||
}
|
||||
|
||||
public int check24Bits() {
|
||||
if (this.deficit > 16) {
|
||||
this.deficit -= 16;
|
||||
this.curInt |= nextIgnore16() << this.deficit;
|
||||
}
|
||||
if (this.deficit > 8) {
|
||||
this.deficit -= 8;
|
||||
this.curInt |= nextIgnore() << this.deficit;
|
||||
}
|
||||
return this.curInt >>> 8;
|
||||
}
|
||||
|
||||
public int check16Bits() {
|
||||
if (this.deficit > 16) {
|
||||
this.deficit -= 16;
|
||||
this.curInt |= nextIgnore16() << this.deficit;
|
||||
}
|
||||
return this.curInt >>> 16;
|
||||
}
|
||||
|
||||
public int readFast16(int n) {
|
||||
if (n == 0)
|
||||
return 0;
|
||||
if (this.deficit > 16) {
|
||||
this.deficit -= 16;
|
||||
this.curInt |= nextIgnore16() << this.deficit;
|
||||
}
|
||||
int ret = this.curInt >>> 32 - n;
|
||||
this.deficit += n;
|
||||
this.curInt <<= n;
|
||||
return ret;
|
||||
}
|
||||
|
||||
public int checkNBit(int n) {
|
||||
if (n > 24)
|
||||
throw new IllegalArgumentException("Can not check more then 24 bit");
|
||||
return checkNBitDontCare(n);
|
||||
}
|
||||
|
||||
public int checkNBitDontCare(int n) {
|
||||
while (this.deficit + n > 32) {
|
||||
this.deficit -= 8;
|
||||
this.curInt |= nextIgnore() << this.deficit;
|
||||
}
|
||||
int res = this.curInt >>> 32 - n;
|
||||
return res;
|
||||
}
|
||||
|
||||
private int nextIgnore16() {
|
||||
return (this.bb.remaining() > 1) ? (this.bb.getShort() & 0xFFFF) : (this.bb.hasRemaining() ? ((this.bb.get() & 0xFF) << 8) : 0);
|
||||
}
|
||||
|
||||
private int nextIgnore() {
|
||||
return this.bb.hasRemaining() ? (this.bb.get() & 0xFF) : 0;
|
||||
}
|
||||
|
||||
public int curBit() {
|
||||
return this.deficit & 0x7;
|
||||
}
|
||||
|
||||
public boolean lastByte() {
|
||||
return (this.bb.remaining() + 4 - (this.deficit >> 3) <= 1);
|
||||
}
|
||||
|
||||
public void terminate() {
|
||||
int putBack = 32 - this.deficit >> 3;
|
||||
this.bb.position(this.bb.position() - putBack);
|
||||
}
|
||||
|
||||
public int position() {
|
||||
return (this.bb.position() - this.initPos - 4 << 3) + this.deficit;
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
this.bb.position(this.bb.position() - (32 - this.deficit >> 3));
|
||||
}
|
||||
|
||||
public int checkAllBits() {
|
||||
return this.curInt;
|
||||
}
|
||||
|
||||
public boolean readBool() {
|
||||
return (read1Bit() == 1);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
package org.jcodec.common.io;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
public class BitWriter {
|
||||
private final ByteBuffer buf;
|
||||
|
||||
private int curInt;
|
||||
|
||||
private int _curBit;
|
||||
|
||||
private int initPos;
|
||||
|
||||
public BitWriter(ByteBuffer buf) {
|
||||
this.buf = buf;
|
||||
this.initPos = buf.position();
|
||||
}
|
||||
|
||||
public BitWriter fork() {
|
||||
BitWriter fork = new BitWriter(this.buf.duplicate());
|
||||
fork._curBit = this._curBit;
|
||||
fork.curInt = this.curInt;
|
||||
fork.initPos = this.initPos;
|
||||
return fork;
|
||||
}
|
||||
|
||||
public void flush() {
|
||||
int toWrite = this._curBit + 7 >> 3;
|
||||
for (int i = 0; i < toWrite; i++) {
|
||||
this.buf.put((byte)(this.curInt >>> 24));
|
||||
this.curInt <<= 8;
|
||||
}
|
||||
}
|
||||
|
||||
private final void putInt(int i) {
|
||||
this.buf.put((byte)(i >>> 24));
|
||||
this.buf.put((byte)(i >> 16));
|
||||
this.buf.put((byte)(i >> 8));
|
||||
this.buf.put((byte)i);
|
||||
}
|
||||
|
||||
public final void writeNBit(int value, int n) {
|
||||
if (n > 32)
|
||||
throw new IllegalArgumentException("Max 32 bit to write");
|
||||
if (n == 0)
|
||||
return;
|
||||
value &= -1 >>> 32 - n;
|
||||
if (32 - this._curBit >= n) {
|
||||
this.curInt |= value << 32 - this._curBit - n;
|
||||
this._curBit += n;
|
||||
if (this._curBit == 32) {
|
||||
putInt(this.curInt);
|
||||
this._curBit = 0;
|
||||
this.curInt = 0;
|
||||
}
|
||||
} else {
|
||||
int secPart = n - (32 - this._curBit);
|
||||
this.curInt |= value >>> secPart;
|
||||
putInt(this.curInt);
|
||||
this.curInt = value << 32 - secPart;
|
||||
this._curBit = secPart;
|
||||
}
|
||||
}
|
||||
|
||||
public void write1Bit(int bit) {
|
||||
this.curInt |= bit << 32 - this._curBit - 1;
|
||||
this._curBit++;
|
||||
if (this._curBit == 32) {
|
||||
putInt(this.curInt);
|
||||
this._curBit = 0;
|
||||
this.curInt = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public int curBit() {
|
||||
return this._curBit & 0x7;
|
||||
}
|
||||
|
||||
public int position() {
|
||||
return (this.buf.position() - this.initPos << 3) + this._curBit;
|
||||
}
|
||||
|
||||
public ByteBuffer getBuffer() {
|
||||
return this.buf;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
package org.jcodec.common.io;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
public class ByteBufferSeekableByteChannel implements SeekableByteChannel {
|
||||
private ByteBuffer backing;
|
||||
|
||||
private boolean open;
|
||||
|
||||
private int contentLength;
|
||||
|
||||
public ByteBufferSeekableByteChannel(ByteBuffer backing, int contentLength) {
|
||||
this.backing = backing;
|
||||
this.contentLength = contentLength;
|
||||
this.open = true;
|
||||
}
|
||||
|
||||
public static ByteBufferSeekableByteChannel writeToByteBuffer(ByteBuffer buf) {
|
||||
return new ByteBufferSeekableByteChannel(buf, 0);
|
||||
}
|
||||
|
||||
public static ByteBufferSeekableByteChannel readFromByteBuffer(ByteBuffer buf) {
|
||||
return new ByteBufferSeekableByteChannel(buf, buf.remaining());
|
||||
}
|
||||
|
||||
public boolean isOpen() {
|
||||
return this.open;
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
this.open = false;
|
||||
}
|
||||
|
||||
public int read(ByteBuffer dst) throws IOException {
|
||||
if (!this.backing.hasRemaining() || this.contentLength <= 0)
|
||||
return -1;
|
||||
int toRead = Math.min(this.backing.remaining(), dst.remaining());
|
||||
toRead = Math.min(toRead, this.contentLength);
|
||||
dst.put(NIOUtils.read(this.backing, toRead));
|
||||
this.contentLength = Math.max(this.contentLength, this.backing.position());
|
||||
return toRead;
|
||||
}
|
||||
|
||||
public int write(ByteBuffer src) throws IOException {
|
||||
int toWrite = Math.min(this.backing.remaining(), src.remaining());
|
||||
this.backing.put(NIOUtils.read(src, toWrite));
|
||||
this.contentLength = Math.max(this.contentLength, this.backing.position());
|
||||
return toWrite;
|
||||
}
|
||||
|
||||
public long position() throws IOException {
|
||||
return (long)this.backing.position();
|
||||
}
|
||||
|
||||
public SeekableByteChannel setPosition(long newPosition) throws IOException {
|
||||
this.backing.position((int)newPosition);
|
||||
this.contentLength = Math.max(this.contentLength, this.backing.position());
|
||||
return this;
|
||||
}
|
||||
|
||||
public long size() throws IOException {
|
||||
return (long)this.contentLength;
|
||||
}
|
||||
|
||||
public SeekableByteChannel truncate(long size) throws IOException {
|
||||
this.contentLength = (int)size;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ByteBuffer getContents() {
|
||||
ByteBuffer contents = this.backing.duplicate();
|
||||
contents.position(0);
|
||||
contents.limit(this.contentLength);
|
||||
return contents;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,127 @@
|
|||
package org.jcodec.common.io;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
|
||||
public class DataReader implements Closeable {
|
||||
private static final int DEFAULT_BUFFER_SIZE = 1048576;
|
||||
|
||||
private SeekableByteChannel channel;
|
||||
|
||||
private ByteBuffer buffer;
|
||||
|
||||
public static DataReader createDataReader(SeekableByteChannel channel, ByteOrder order) {
|
||||
return new DataReader(channel, order, 1048576);
|
||||
}
|
||||
|
||||
public DataReader(SeekableByteChannel channel, ByteOrder order, int bufferSize) {
|
||||
this.channel = channel;
|
||||
this.buffer = ByteBuffer.allocate(bufferSize);
|
||||
this.buffer.limit(0);
|
||||
this.buffer.order(order);
|
||||
}
|
||||
|
||||
public int readFully3(byte[] b, int off, int len) throws IOException {
|
||||
int initOff = off;
|
||||
while (len > 0) {
|
||||
fetchIfNeeded(len);
|
||||
if (this.buffer.remaining() == 0)
|
||||
break;
|
||||
int toRead = Math.min(this.buffer.remaining(), len);
|
||||
this.buffer.get(b, off, toRead);
|
||||
off += toRead;
|
||||
len -= toRead;
|
||||
}
|
||||
return off - initOff;
|
||||
}
|
||||
|
||||
public int skipBytes(int n) throws IOException {
|
||||
long oldPosition = position();
|
||||
if (n < this.buffer.remaining()) {
|
||||
this.buffer.position(this.buffer.position() + n);
|
||||
} else {
|
||||
setPosition(oldPosition + (long)n);
|
||||
}
|
||||
return (int)(position() - oldPosition);
|
||||
}
|
||||
|
||||
public byte readByte() throws IOException {
|
||||
fetchIfNeeded(1);
|
||||
return this.buffer.get();
|
||||
}
|
||||
|
||||
public short readShort() throws IOException {
|
||||
fetchIfNeeded(2);
|
||||
return this.buffer.getShort();
|
||||
}
|
||||
|
||||
public char readChar() throws IOException {
|
||||
fetchIfNeeded(2);
|
||||
return this.buffer.getChar();
|
||||
}
|
||||
|
||||
public int readInt() throws IOException {
|
||||
fetchIfNeeded(4);
|
||||
return this.buffer.getInt();
|
||||
}
|
||||
|
||||
public long readLong() throws IOException {
|
||||
fetchIfNeeded(8);
|
||||
return this.buffer.getLong();
|
||||
}
|
||||
|
||||
public float readFloat() throws IOException {
|
||||
fetchIfNeeded(4);
|
||||
return this.buffer.getFloat();
|
||||
}
|
||||
|
||||
public double readDouble() throws IOException {
|
||||
fetchIfNeeded(8);
|
||||
return this.buffer.getDouble();
|
||||
}
|
||||
|
||||
public long position() throws IOException {
|
||||
return this.channel.position() - (long)this.buffer.limit() + (long)this.buffer.position();
|
||||
}
|
||||
|
||||
public long setPosition(long newPos) throws IOException {
|
||||
int relative = (int)(newPos - (this.channel.position() - (long)this.buffer.limit()));
|
||||
if (relative >= 0 && relative < this.buffer.limit()) {
|
||||
this.buffer.position(relative);
|
||||
} else {
|
||||
this.buffer.limit(0);
|
||||
this.channel.setPosition(newPos);
|
||||
}
|
||||
return position();
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
this.channel.close();
|
||||
}
|
||||
|
||||
private void fetchIfNeeded(int length) throws IOException {
|
||||
if (this.buffer.remaining() < length) {
|
||||
moveRemainderToTheStart(this.buffer);
|
||||
this.channel.read(this.buffer);
|
||||
this.buffer.flip();
|
||||
}
|
||||
}
|
||||
|
||||
private static void moveRemainderToTheStart(ByteBuffer readBuf) {
|
||||
int rem = readBuf.remaining();
|
||||
for (int i = 0; i < rem; i++)
|
||||
readBuf.put(i, readBuf.get());
|
||||
readBuf.clear();
|
||||
readBuf.position(rem);
|
||||
}
|
||||
|
||||
public long size() throws IOException {
|
||||
return this.channel.size();
|
||||
}
|
||||
|
||||
public int readFully(byte[] b) throws IOException {
|
||||
return readFully3(b, 0, b.length);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,164 @@
|
|||
package org.jcodec.common.io;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
public class DummyBitstreamReader {
|
||||
private InputStream is;
|
||||
|
||||
private int curByte;
|
||||
|
||||
private int nextByte;
|
||||
|
||||
private int secondByte;
|
||||
|
||||
int nBit;
|
||||
|
||||
protected static int bitsRead;
|
||||
|
||||
public DummyBitstreamReader(InputStream is) throws IOException {
|
||||
this.is = is;
|
||||
this.curByte = is.read();
|
||||
this.nextByte = is.read();
|
||||
this.secondByte = is.read();
|
||||
}
|
||||
|
||||
int cnt = 0;
|
||||
|
||||
public int read1Bit() throws IOException {
|
||||
return read1BitInt();
|
||||
}
|
||||
|
||||
public int read1BitInt() throws IOException {
|
||||
if (this.nBit == 8) {
|
||||
advance();
|
||||
if (this.curByte == -1)
|
||||
return -1;
|
||||
}
|
||||
int res = this.curByte >> 7 - this.nBit & 0x1;
|
||||
this.nBit++;
|
||||
bitsRead++;
|
||||
return res;
|
||||
}
|
||||
|
||||
public int readNBit(int n) throws IOException {
|
||||
if (n > 32)
|
||||
throw new IllegalArgumentException("Can not read more then 32 bit");
|
||||
int val = 0;
|
||||
for (int i = 0; i < n; i++) {
|
||||
val <<= 1;
|
||||
val |= read1BitInt();
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
private final void advance1() throws IOException {
|
||||
this.curByte = this.nextByte;
|
||||
this.nextByte = this.secondByte;
|
||||
this.secondByte = this.is.read();
|
||||
}
|
||||
|
||||
private final void advance() throws IOException {
|
||||
advance1();
|
||||
this.nBit = 0;
|
||||
}
|
||||
|
||||
public int readByte() throws IOException {
|
||||
if (this.nBit > 0)
|
||||
advance();
|
||||
int res = this.curByte;
|
||||
advance();
|
||||
return res;
|
||||
}
|
||||
|
||||
public boolean moreRBSPData() throws IOException {
|
||||
if (this.nBit == 8)
|
||||
advance();
|
||||
int tail = 1 << 8 - this.nBit - 1;
|
||||
int mask = (tail << 1) - 1;
|
||||
boolean hasTail = ((this.curByte & mask) == tail);
|
||||
return (this.curByte != -1 && (this.nextByte != -1 || !hasTail));
|
||||
}
|
||||
|
||||
public long getBitPosition() {
|
||||
return (long)(bitsRead * 8 + this.nBit % 8);
|
||||
}
|
||||
|
||||
public boolean moreData() throws IOException {
|
||||
if (this.nBit == 8)
|
||||
advance();
|
||||
if (this.curByte == -1)
|
||||
return false;
|
||||
if (this.nextByte == -1 || (this.nextByte == 0 && this.secondByte == -1)) {
|
||||
int mask = (1 << 8 - this.nBit) - 1;
|
||||
return ((this.curByte & mask) != 0);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public long readRemainingByte() throws IOException {
|
||||
return (long)readNBit(8 - this.nBit);
|
||||
}
|
||||
|
||||
public int peakNextBits(int n) throws IOException {
|
||||
if (n > 8)
|
||||
throw new IllegalArgumentException("N should be less then 8");
|
||||
if (this.nBit == 8) {
|
||||
advance();
|
||||
if (this.curByte == -1)
|
||||
return -1;
|
||||
}
|
||||
int[] bits = new int[16 - this.nBit];
|
||||
int cnt = 0;
|
||||
for (int j = this.nBit; j < 8; j++)
|
||||
bits[cnt++] = this.curByte >> 7 - j & 0x1;
|
||||
for (int i = 0; i < 8; i++)
|
||||
bits[cnt++] = this.nextByte >> 7 - i & 0x1;
|
||||
int result = 0;
|
||||
for (int k = 0; k < n; k++) {
|
||||
result <<= 1;
|
||||
result |= bits[k];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public boolean isByteAligned() {
|
||||
return (this.nBit % 8 == 0);
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
this.is.close();
|
||||
}
|
||||
|
||||
public int getCurBit() {
|
||||
return this.nBit;
|
||||
}
|
||||
|
||||
public final int skip(int bits) throws IOException {
|
||||
this.nBit += bits;
|
||||
int was = this.nBit;
|
||||
while (this.nBit >= 8 && this.curByte != -1) {
|
||||
advance1();
|
||||
this.nBit -= 8;
|
||||
}
|
||||
return was - this.nBit;
|
||||
}
|
||||
|
||||
public int align() throws IOException {
|
||||
int n = 8 - this.nBit & 0x7;
|
||||
skip(8 - this.nBit & 0x7);
|
||||
return n;
|
||||
}
|
||||
|
||||
public int checkNBit(int n) throws IOException {
|
||||
return peakNextBits(n);
|
||||
}
|
||||
|
||||
public int curBit() {
|
||||
return this.nBit;
|
||||
}
|
||||
|
||||
public boolean lastByte() throws IOException {
|
||||
return (this.nextByte == -1 && this.secondByte == -1);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
package org.jcodec.common.io;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.FileChannel;
|
||||
|
||||
public class FileChannelWrapper implements SeekableByteChannel {
|
||||
private FileChannel ch;
|
||||
|
||||
public FileChannelWrapper(FileChannel ch) throws FileNotFoundException {
|
||||
this.ch = ch;
|
||||
}
|
||||
|
||||
public int read(ByteBuffer arg0) throws IOException {
|
||||
return this.ch.read(arg0);
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
this.ch.close();
|
||||
}
|
||||
|
||||
public boolean isOpen() {
|
||||
return this.ch.isOpen();
|
||||
}
|
||||
|
||||
public int write(ByteBuffer arg0) throws IOException {
|
||||
return this.ch.write(arg0);
|
||||
}
|
||||
|
||||
public long position() throws IOException {
|
||||
return this.ch.position();
|
||||
}
|
||||
|
||||
public SeekableByteChannel setPosition(long newPosition) throws IOException {
|
||||
this.ch.position(newPosition);
|
||||
return this;
|
||||
}
|
||||
|
||||
public long size() throws IOException {
|
||||
return this.ch.size();
|
||||
}
|
||||
|
||||
public SeekableByteChannel truncate(long size) throws IOException {
|
||||
this.ch.truncate(size);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
package org.jcodec.common.io;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.Closeable;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
import org.jcodec.platform.Platform;
|
||||
|
||||
public class IOUtils {
|
||||
public static final int DEFAULT_BUFFER_SIZE = 4096;
|
||||
|
||||
public static void closeQuietly(Closeable c) {
|
||||
if (c == null)
|
||||
return;
|
||||
try {
|
||||
c.close();
|
||||
} catch (IOException e) {}
|
||||
}
|
||||
|
||||
public static byte[] toByteArray(InputStream input) throws IOException {
|
||||
ByteArrayOutputStream output = new ByteArrayOutputStream();
|
||||
copy(input, output);
|
||||
return output.toByteArray();
|
||||
}
|
||||
|
||||
public static int copy(InputStream input, OutputStream output) throws IOException {
|
||||
byte[] buffer = new byte[4096];
|
||||
int count = 0;
|
||||
int n = 0;
|
||||
while (-1 != (n = input.read(buffer))) {
|
||||
output.write(buffer, 0, n);
|
||||
count += n;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
public static int copyDumb(InputStream input, OutputStream output) throws IOException {
|
||||
int count = 0;
|
||||
int n = 0;
|
||||
while (-1 != (n = input.read())) {
|
||||
output.write(n);
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
public static byte[] readFileToByteArray(File file) throws IOException {
|
||||
return NIOUtils.toArray(NIOUtils.fetchFromFile(file));
|
||||
}
|
||||
|
||||
public static String readToString(InputStream is) throws IOException {
|
||||
return Platform.stringFromBytes(toByteArray(is));
|
||||
}
|
||||
|
||||
public static void writeStringToFile(File file, String str) throws IOException {
|
||||
NIOUtils.writeTo(ByteBuffer.wrap(str.getBytes()), file);
|
||||
}
|
||||
|
||||
public static void forceMkdir(File directory) throws IOException {
|
||||
if (directory.exists()) {
|
||||
if (!directory.isDirectory()) {
|
||||
String message = "File " + String.valueOf(directory) + " exists and is not a directory. Unable to create directory.";
|
||||
throw new IOException(message);
|
||||
}
|
||||
} else if (!directory.mkdirs()) {
|
||||
if (!directory.isDirectory()) {
|
||||
String message = "Unable to create directory " + String.valueOf(directory);
|
||||
throw new IOException(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void copyFile(File src, File dst) throws IOException {
|
||||
FileChannelWrapper _in = null;
|
||||
FileChannelWrapper out = null;
|
||||
try {
|
||||
_in = NIOUtils.readableChannel(src);
|
||||
out = NIOUtils.writableChannel(dst);
|
||||
NIOUtils.copy(_in, out, Long.MAX_VALUE);
|
||||
} finally {
|
||||
NIOUtils.closeQuietly(_in);
|
||||
NIOUtils.closeQuietly(out);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,429 @@
|
|||
package org.jcodec.common.io;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.MappedByteBuffer;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.nio.channels.ReadableByteChannel;
|
||||
import java.nio.channels.WritableByteChannel;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.jcodec.common.ArrayUtil;
|
||||
import org.jcodec.common.AutoFileChannelWrapper;
|
||||
import org.jcodec.platform.Platform;
|
||||
|
||||
public class NIOUtils {
|
||||
public static ByteBuffer search(ByteBuffer buffer, int n, byte[] param) {
|
||||
ByteBuffer result = buffer.duplicate();
|
||||
int step = 0, rem = buffer.position();
|
||||
while (buffer.hasRemaining()) {
|
||||
int b = buffer.get();
|
||||
if (b == param[step]) {
|
||||
step++;
|
||||
if (step == param.length) {
|
||||
if (n == 0) {
|
||||
buffer.position(rem);
|
||||
result.limit(buffer.position());
|
||||
break;
|
||||
}
|
||||
n--;
|
||||
step = 0;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (step != 0) {
|
||||
step = 0;
|
||||
rem++;
|
||||
buffer.position(rem);
|
||||
continue;
|
||||
}
|
||||
rem = buffer.position();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static final ByteBuffer read(ByteBuffer buffer, int count) {
|
||||
ByteBuffer slice = buffer.duplicate();
|
||||
int limit = buffer.position() + count;
|
||||
slice.limit(limit);
|
||||
buffer.position(limit);
|
||||
return slice;
|
||||
}
|
||||
|
||||
public static ByteBuffer fetchFromFile(File file) throws IOException {
|
||||
return fetchFromFileL(file, (int)file.length());
|
||||
}
|
||||
|
||||
public static ByteBuffer fetchFromChannel(ReadableByteChannel ch, int size) throws IOException {
|
||||
ByteBuffer buf = ByteBuffer.allocate(size);
|
||||
readFromChannel(ch, buf);
|
||||
buf.flip();
|
||||
return buf;
|
||||
}
|
||||
|
||||
public static ByteBuffer fetchAllFromChannel(SeekableByteChannel ch) throws IOException {
|
||||
ByteBuffer buf;
|
||||
List<ByteBuffer> buffers = new ArrayList<>();
|
||||
do {
|
||||
buf = fetchFromChannel(ch, 1048576);
|
||||
buffers.add(buf);
|
||||
} while (buf.hasRemaining());
|
||||
return combineBuffers(buffers);
|
||||
}
|
||||
|
||||
public static ByteBuffer fetchFrom(ByteBuffer buf, ReadableByteChannel ch, int size) throws IOException {
|
||||
ByteBuffer result = buf.duplicate();
|
||||
result.limit(size);
|
||||
readFromChannel(ch, result);
|
||||
result.flip();
|
||||
return result;
|
||||
}
|
||||
|
||||
public static ByteBuffer fetchFromFileL(File file, int length) throws IOException {
|
||||
FileChannel is = null;
|
||||
try {
|
||||
is = new FileInputStream(file).getChannel();
|
||||
return fetchFromChannel(is, length);
|
||||
} finally {
|
||||
closeQuietly(is);
|
||||
}
|
||||
}
|
||||
|
||||
public static void writeTo(ByteBuffer buffer, File file) throws IOException {
|
||||
FileChannel out = null;
|
||||
try {
|
||||
out = new FileOutputStream(file).getChannel();
|
||||
out.write(buffer);
|
||||
} finally {
|
||||
closeQuietly(out);
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] toArray(ByteBuffer buffer) {
|
||||
byte[] result = new byte[buffer.remaining()];
|
||||
buffer.duplicate().get(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
public static byte[] toArrayL(ByteBuffer buffer, int count) {
|
||||
byte[] result = new byte[Math.min(buffer.remaining(), count)];
|
||||
buffer.duplicate().get(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
public static int readL(ReadableByteChannel channel, ByteBuffer buffer, int length) throws IOException {
|
||||
ByteBuffer fork = buffer.duplicate();
|
||||
fork.limit(Math.min(fork.position() + length, fork.limit()));
|
||||
while (channel.read(fork) != -1 && fork.hasRemaining());
|
||||
buffer.position(fork.position());
|
||||
return (buffer.position() == 0) ? -1 : buffer.position();
|
||||
}
|
||||
|
||||
public static int readFromChannel(ReadableByteChannel channel, ByteBuffer buffer) throws IOException {
|
||||
int rem = buffer.position();
|
||||
while (channel.read(buffer) != -1 && buffer.hasRemaining());
|
||||
return buffer.position() - rem;
|
||||
}
|
||||
|
||||
public static void write(ByteBuffer to, ByteBuffer from) {
|
||||
if (from.hasArray()) {
|
||||
to.put(from.array(), from.arrayOffset() + from.position(), Math.min(to.remaining(), from.remaining()));
|
||||
} else {
|
||||
to.put(toArrayL(from, to.remaining()));
|
||||
}
|
||||
}
|
||||
|
||||
public static void writeL(ByteBuffer to, ByteBuffer from, int count) {
|
||||
if (from.hasArray()) {
|
||||
to.put(from.array(), from.arrayOffset() + from.position(), Math.min(from.remaining(), count));
|
||||
} else {
|
||||
to.put(toArrayL(from, count));
|
||||
}
|
||||
}
|
||||
|
||||
public static void fill(ByteBuffer buffer, byte val) {
|
||||
while (buffer.hasRemaining())
|
||||
buffer.put(val);
|
||||
}
|
||||
|
||||
public static final MappedByteBuffer map(String fileName) throws IOException {
|
||||
return mapFile(new File(fileName));
|
||||
}
|
||||
|
||||
public static final MappedByteBuffer mapFile(File file) throws IOException {
|
||||
FileInputStream is = new FileInputStream(file);
|
||||
MappedByteBuffer map = is.getChannel().map(FileChannel.MapMode.READ_ONLY, 0L, file.length());
|
||||
is.close();
|
||||
return map;
|
||||
}
|
||||
|
||||
public static int skip(ByteBuffer buffer, int count) {
|
||||
int toSkip = Math.min(buffer.remaining(), count);
|
||||
buffer.position(buffer.position() + toSkip);
|
||||
return toSkip;
|
||||
}
|
||||
|
||||
public static ByteBuffer from(ByteBuffer buffer, int offset) {
|
||||
ByteBuffer dup = buffer.duplicate();
|
||||
dup.position(dup.position() + offset);
|
||||
return dup;
|
||||
}
|
||||
|
||||
public static ByteBuffer combineBuffers(Iterable<ByteBuffer> picture) {
|
||||
int size = 0;
|
||||
for (ByteBuffer byteBuffer : picture)
|
||||
size += byteBuffer.remaining();
|
||||
ByteBuffer result = ByteBuffer.allocate(size);
|
||||
for (ByteBuffer byteBuffer : picture)
|
||||
write(result, byteBuffer);
|
||||
result.flip();
|
||||
return result;
|
||||
}
|
||||
|
||||
public static boolean combineBuffersInto(ByteBuffer dup, List<ByteBuffer> buffers) {
|
||||
throw new RuntimeException("Stan");
|
||||
}
|
||||
|
||||
public static String readString(ByteBuffer buffer, int len) {
|
||||
return Platform.stringFromBytes(toArray(read(buffer, len)));
|
||||
}
|
||||
|
||||
public static String readPascalStringL(ByteBuffer buffer, int maxLen) {
|
||||
ByteBuffer sub = read(buffer, maxLen + 1);
|
||||
return Platform.stringFromBytes(toArray(read(sub, Math.min(sub.get() & 0xFF, maxLen))));
|
||||
}
|
||||
|
||||
public static void writePascalStringL(ByteBuffer buffer, String string, int maxLen) {
|
||||
buffer.put((byte)string.length());
|
||||
buffer.put(asciiString(string));
|
||||
skip(buffer, maxLen - string.length());
|
||||
}
|
||||
|
||||
public static byte[] asciiString(String fourcc) {
|
||||
return Platform.getBytes(fourcc);
|
||||
}
|
||||
|
||||
public static void writePascalString(ByteBuffer buffer, String name) {
|
||||
buffer.put((byte)name.length());
|
||||
buffer.put(asciiString(name));
|
||||
}
|
||||
|
||||
public static String readPascalString(ByteBuffer buffer) {
|
||||
return readString(buffer, buffer.get() & 0xFF);
|
||||
}
|
||||
|
||||
public static String readNullTermString(ByteBuffer buffer) {
|
||||
return readNullTermStringCharset(buffer, "UTF-8");
|
||||
}
|
||||
|
||||
public static String readNullTermStringCharset(ByteBuffer buffer, String charset) {
|
||||
ByteBuffer fork = buffer.duplicate();
|
||||
while (buffer.hasRemaining() && buffer.get() != 0);
|
||||
if (buffer.hasRemaining())
|
||||
fork.limit(buffer.position() - 1);
|
||||
return Platform.stringFromCharset(toArray(fork), charset);
|
||||
}
|
||||
|
||||
public static ByteBuffer readBuf(ByteBuffer buffer) {
|
||||
ByteBuffer result = buffer.duplicate();
|
||||
buffer.position(buffer.limit());
|
||||
return result;
|
||||
}
|
||||
|
||||
public static void copy(ReadableByteChannel _in, WritableByteChannel out, long amount) throws IOException {
|
||||
int read;
|
||||
ByteBuffer buf = ByteBuffer.allocate(65536);
|
||||
do {
|
||||
buf.position(0);
|
||||
buf.limit((int)Math.min(amount, (long)buf.capacity()));
|
||||
read = _in.read(buf);
|
||||
if (read == -1)
|
||||
continue;
|
||||
buf.flip();
|
||||
out.write(buf);
|
||||
amount -= (long)read;
|
||||
} while (read != -1 && amount > 0L);
|
||||
}
|
||||
|
||||
public static void closeQuietly(Closeable channel) {
|
||||
if (channel == null)
|
||||
return;
|
||||
try {
|
||||
channel.close();
|
||||
} catch (IOException e) {}
|
||||
}
|
||||
|
||||
public static byte readByte(ReadableByteChannel channel) throws IOException {
|
||||
ByteBuffer buf = ByteBuffer.allocate(1);
|
||||
channel.read(buf);
|
||||
buf.flip();
|
||||
return buf.get();
|
||||
}
|
||||
|
||||
public static byte[] readNByte(ReadableByteChannel channel, int n) throws IOException {
|
||||
byte[] result = new byte[n];
|
||||
channel.read(ByteBuffer.wrap(result));
|
||||
return result;
|
||||
}
|
||||
|
||||
public static int readInt(ReadableByteChannel channel) throws IOException {
|
||||
ByteBuffer buf = ByteBuffer.allocate(4);
|
||||
channel.read(buf);
|
||||
buf.flip();
|
||||
return buf.getInt();
|
||||
}
|
||||
|
||||
public static int readIntOrder(ReadableByteChannel channel, ByteOrder order) throws IOException {
|
||||
ByteBuffer buf = ByteBuffer.allocate(4).order(order);
|
||||
channel.read(buf);
|
||||
buf.flip();
|
||||
return buf.getInt();
|
||||
}
|
||||
|
||||
public static void writeByte(WritableByteChannel channel, byte value) throws IOException {
|
||||
channel.write(ByteBuffer.allocate(1).put(value).flip());
|
||||
}
|
||||
|
||||
public static void writeIntOrder(WritableByteChannel channel, int value, ByteOrder order) throws IOException {
|
||||
ByteBuffer order2 = ByteBuffer.allocate(4).order(order);
|
||||
channel.write(order2.putInt(value).flip());
|
||||
}
|
||||
|
||||
public static void writeIntLE(WritableByteChannel channel, int value) throws IOException {
|
||||
ByteBuffer allocate = ByteBuffer.allocate(4);
|
||||
allocate.order(ByteOrder.LITTLE_ENDIAN);
|
||||
channel.write(allocate.putInt(value).flip());
|
||||
}
|
||||
|
||||
public static void writeInt(WritableByteChannel channel, int value) throws IOException {
|
||||
channel.write(ByteBuffer.allocate(4).putInt(value).flip());
|
||||
}
|
||||
|
||||
public static void writeLong(WritableByteChannel channel, long value) throws IOException {
|
||||
channel.write(ByteBuffer.allocate(8).putLong(value).flip());
|
||||
}
|
||||
|
||||
public static FileChannelWrapper readableChannel(File file) throws FileNotFoundException {
|
||||
return new FileChannelWrapper(new FileInputStream(file).getChannel());
|
||||
}
|
||||
|
||||
public static FileChannelWrapper writableChannel(File file) throws FileNotFoundException {
|
||||
return new FileChannelWrapper(new FileOutputStream(file).getChannel());
|
||||
}
|
||||
|
||||
public static FileChannelWrapper rwChannel(File file) throws FileNotFoundException {
|
||||
return new FileChannelWrapper(new RandomAccessFile(file, "rw").getChannel());
|
||||
}
|
||||
|
||||
public static FileChannelWrapper readableFileChannel(String file) throws FileNotFoundException {
|
||||
return new FileChannelWrapper(new FileInputStream(file).getChannel());
|
||||
}
|
||||
|
||||
public static FileChannelWrapper writableFileChannel(String file) throws FileNotFoundException {
|
||||
return new FileChannelWrapper(new FileOutputStream(file).getChannel());
|
||||
}
|
||||
|
||||
public static FileChannelWrapper rwFileChannel(String file) throws FileNotFoundException {
|
||||
return new FileChannelWrapper(new RandomAccessFile(file, "rw").getChannel());
|
||||
}
|
||||
|
||||
public static AutoFileChannelWrapper autoChannel(File file) throws IOException {
|
||||
return new AutoFileChannelWrapper(file);
|
||||
}
|
||||
|
||||
public static ByteBuffer duplicate(ByteBuffer bb) {
|
||||
ByteBuffer out = ByteBuffer.allocate(bb.remaining());
|
||||
out.put(bb.duplicate());
|
||||
out.flip();
|
||||
return out;
|
||||
}
|
||||
|
||||
public static int find(List<ByteBuffer> catalog, ByteBuffer key) {
|
||||
byte[] keyA = toArray(key);
|
||||
for (int i = 0; i < catalog.size(); i++) {
|
||||
if (Platform.arrayEqualsByte(toArray(catalog.get(i)), keyA))
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static abstract class FileReader {
|
||||
private int oldPd;
|
||||
|
||||
protected abstract void data(ByteBuffer param1ByteBuffer, long param1Long);
|
||||
|
||||
protected abstract void done();
|
||||
|
||||
public void readChannel(SeekableByteChannel ch, int bufferSize, NIOUtils.FileReaderListener listener) throws IOException {
|
||||
ByteBuffer buf = ByteBuffer.allocate(bufferSize);
|
||||
long size = ch.size();
|
||||
for (long pos = ch.position(); ch.read(buf) != -1; pos = ch.position()) {
|
||||
buf.flip();
|
||||
data(buf, pos);
|
||||
buf.flip();
|
||||
if (listener != null) {
|
||||
int newPd = (int)(100L * pos / size);
|
||||
if (newPd != this.oldPd)
|
||||
listener.progress(newPd);
|
||||
this.oldPd = newPd;
|
||||
}
|
||||
}
|
||||
done();
|
||||
}
|
||||
|
||||
public void readFile(File source, int bufferSize, NIOUtils.FileReaderListener listener) throws IOException {
|
||||
SeekableByteChannel ch = null;
|
||||
try {
|
||||
ch = NIOUtils.readableChannel(source);
|
||||
readChannel(ch, bufferSize, listener);
|
||||
} finally {
|
||||
NIOUtils.closeQuietly(ch);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static byte getRel(ByteBuffer bb, int rel) {
|
||||
return bb.get(bb.position() + rel);
|
||||
}
|
||||
|
||||
public static ByteBuffer cloneBuffer(ByteBuffer pesBuffer) {
|
||||
ByteBuffer res = ByteBuffer.allocate(pesBuffer.remaining());
|
||||
res.put(pesBuffer.duplicate());
|
||||
res.clear();
|
||||
return res;
|
||||
}
|
||||
|
||||
public static ByteBuffer clone(ByteBuffer byteBuffer) {
|
||||
ByteBuffer result = ByteBuffer.allocate(byteBuffer.remaining());
|
||||
result.put(byteBuffer.duplicate());
|
||||
result.flip();
|
||||
return result;
|
||||
}
|
||||
|
||||
public static ByteBuffer asByteBuffer(byte[] bytes) {
|
||||
return ByteBuffer.wrap(bytes);
|
||||
}
|
||||
|
||||
public static ByteBuffer asByteBufferInt(int[] ints) {
|
||||
return asByteBuffer(ArrayUtil.toByteArray(ints));
|
||||
}
|
||||
|
||||
public static void relocateLeftover(ByteBuffer bb) {
|
||||
int pos;
|
||||
for (pos = 0; bb.hasRemaining(); pos++)
|
||||
bb.put(pos, bb.get());
|
||||
bb.position(pos);
|
||||
bb.limit(bb.capacity());
|
||||
}
|
||||
|
||||
public static interface FileReaderListener {
|
||||
void progress(int param1Int);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
package org.jcodec.common.io;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.nio.channels.ByteChannel;
|
||||
import java.nio.channels.Channel;
|
||||
import java.nio.channels.ReadableByteChannel;
|
||||
import java.nio.channels.WritableByteChannel;
|
||||
|
||||
public interface SeekableByteChannel extends ByteChannel, Channel, Closeable, ReadableByteChannel, WritableByteChannel {
|
||||
long position() throws IOException;
|
||||
|
||||
SeekableByteChannel setPosition(long paramLong) throws IOException;
|
||||
|
||||
long size() throws IOException;
|
||||
|
||||
SeekableByteChannel truncate(long paramLong) throws IOException;
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
package org.jcodec.common.io;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import org.jcodec.platform.Platform;
|
||||
|
||||
public abstract class StringReader {
|
||||
public static String readString(InputStream input, int len) throws IOException {
|
||||
byte[] bs = _sureRead(input, len);
|
||||
return (bs == null) ? null : Platform.stringFromBytes(bs);
|
||||
}
|
||||
|
||||
public static byte[] _sureRead(InputStream input, int len) throws IOException {
|
||||
byte[] res = new byte[len];
|
||||
if (sureRead(input, res, res.length) == len)
|
||||
return res;
|
||||
return null;
|
||||
}
|
||||
|
||||
public static int sureRead(InputStream input, byte[] buf, int len) throws IOException {
|
||||
int read = 0;
|
||||
while (read < len) {
|
||||
int tmp = input.read(buf, read, len - read);
|
||||
if (tmp == -1)
|
||||
break;
|
||||
read += tmp;
|
||||
}
|
||||
return read;
|
||||
}
|
||||
|
||||
public static void sureSkip(InputStream is, long l) throws IOException {
|
||||
while (l > 0L)
|
||||
l -= is.skip(l);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,130 @@
|
|||
package org.jcodec.common.io;
|
||||
|
||||
import java.io.PrintStream;
|
||||
import org.jcodec.common.IntArrayList;
|
||||
import org.jcodec.platform.Platform;
|
||||
|
||||
public class VLC {
|
||||
private int[] codes;
|
||||
|
||||
private int[] codeSizes;
|
||||
|
||||
private int[] values;
|
||||
|
||||
private int[] valueSizes;
|
||||
|
||||
public static VLC createVLC(String[] codes) {
|
||||
IntArrayList _codes = IntArrayList.createIntArrayList();
|
||||
IntArrayList _codeSizes = IntArrayList.createIntArrayList();
|
||||
for (int i = 0; i < codes.length; i++) {
|
||||
String string = codes[i];
|
||||
_codes.add(Integer.parseInt(string, 2) << 32 - string.length());
|
||||
_codeSizes.add(string.length());
|
||||
}
|
||||
VLC vlc = new VLC(_codes.toArray(), _codeSizes.toArray());
|
||||
return vlc;
|
||||
}
|
||||
|
||||
public VLC(int[] codes, int[] codeSizes) {
|
||||
this.codes = codes;
|
||||
this.codeSizes = codeSizes;
|
||||
_invert();
|
||||
}
|
||||
|
||||
private void _invert() {
|
||||
IntArrayList values = IntArrayList.createIntArrayList();
|
||||
IntArrayList valueSizes = IntArrayList.createIntArrayList();
|
||||
invert(0, 0, 0, values, valueSizes);
|
||||
this.values = values.toArray();
|
||||
this.valueSizes = valueSizes.toArray();
|
||||
}
|
||||
|
||||
private int invert(int startOff, int level, int prefix, IntArrayList values, IntArrayList valueSizes) {
|
||||
int tableEnd = startOff + 256;
|
||||
values.fill(startOff, tableEnd, -1);
|
||||
valueSizes.fill(startOff, tableEnd, 0);
|
||||
int prefLen = level << 3;
|
||||
for (int i = 0; i < this.codeSizes.length; i++) {
|
||||
if (this.codeSizes[i] > prefLen && (level <= 0 || this.codes[i] >>> 32 - prefLen == prefix)) {
|
||||
int pref = this.codes[i] >>> 32 - prefLen - 8;
|
||||
int code = pref & 0xFF;
|
||||
int len = this.codeSizes[i] - prefLen;
|
||||
if (len <= 8) {
|
||||
for (int k = 0; k < 1 << 8 - len; k++) {
|
||||
values.set(startOff + code + k, i);
|
||||
valueSizes.set(startOff + code + k, len);
|
||||
}
|
||||
} else if (values.get(startOff + code) == -1) {
|
||||
values.set(startOff + code, tableEnd);
|
||||
tableEnd = invert(tableEnd, level + 1, pref, values, valueSizes);
|
||||
}
|
||||
}
|
||||
}
|
||||
return tableEnd;
|
||||
}
|
||||
|
||||
public int readVLC16(BitReader _in) {
|
||||
int string = _in.check16Bits();
|
||||
int b = string >>> 8;
|
||||
int code = this.values[b];
|
||||
int len = this.valueSizes[b];
|
||||
if (len == 0) {
|
||||
b = (string & 0xFF) + code;
|
||||
code = this.values[b];
|
||||
_in.skipFast(8 + this.valueSizes[b]);
|
||||
} else {
|
||||
_in.skipFast(len);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
public int readVLC(BitReader _in) {
|
||||
int code = 0, len = 0, overall = 0, total = 0;
|
||||
for (int i = 0; len == 0; i++) {
|
||||
int string = _in.checkNBit(8);
|
||||
int ind = string + code;
|
||||
code = this.values[ind];
|
||||
len = this.valueSizes[ind];
|
||||
int bits = (len != 0) ? len : 8;
|
||||
total += bits;
|
||||
overall = overall << bits | string >> 8 - bits;
|
||||
_in.skip(bits);
|
||||
if (code == -1)
|
||||
throw new RuntimeException("Invalid code prefix " + binary(overall, (i << 3) + bits));
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
private static String binary(int string, int len) {
|
||||
char[] symb = new char[len];
|
||||
for (int i = 0; i < len; i++)
|
||||
symb[i] = ((string & 1 << len - i - 1) != 0) ? '1' : '0';
|
||||
return Platform.stringFromChars(symb);
|
||||
}
|
||||
|
||||
public void writeVLC(BitWriter out, int code) {
|
||||
out.writeNBit(this.codes[code] >>> 32 - this.codeSizes[code], this.codeSizes[code]);
|
||||
}
|
||||
|
||||
public void printTable(PrintStream ps) {
|
||||
for (int i = 0; i < this.values.length; i++)
|
||||
ps.println("" + i + ": " + i + " (" + extracted(i) + ") -> " + this.valueSizes[i]);
|
||||
}
|
||||
|
||||
private static String extracted(int num) {
|
||||
String str = Integer.toString(num & 0xFF, 2);
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for (int i = 0; i < 8 - str.length(); i++)
|
||||
builder.append("0");
|
||||
builder.append(str);
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
public int[] getCodes() {
|
||||
return this.codes;
|
||||
}
|
||||
|
||||
public int[] getCodeSizes() {
|
||||
return this.codeSizes;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
package org.jcodec.common.io;
|
||||
|
||||
import org.jcodec.common.IntArrayList;
|
||||
import org.jcodec.common.IntIntMap;
|
||||
|
||||
public class VLCBuilder {
|
||||
private IntIntMap forward;
|
||||
|
||||
private IntIntMap inverse;
|
||||
|
||||
private IntArrayList codes;
|
||||
|
||||
private IntArrayList codesSizes;
|
||||
|
||||
public static VLCBuilder createVLCBuilder(int[] codes, int[] lens, int[] vals) {
|
||||
VLCBuilder b = new VLCBuilder();
|
||||
for (int i = 0; i < codes.length; i++)
|
||||
b.setInt(codes[i], lens[i], vals[i]);
|
||||
return b;
|
||||
}
|
||||
|
||||
public VLCBuilder() {
|
||||
this.forward = new IntIntMap();
|
||||
this.inverse = new IntIntMap();
|
||||
this.codes = IntArrayList.createIntArrayList();
|
||||
this.codesSizes = IntArrayList.createIntArrayList();
|
||||
}
|
||||
|
||||
public VLCBuilder set(int val, String code) {
|
||||
setInt(Integer.parseInt(code, 2), code.length(), val);
|
||||
return this;
|
||||
}
|
||||
|
||||
public VLCBuilder setInt(int code, int len, int val) {
|
||||
this.codes.add(code << 32 - len);
|
||||
this.codesSizes.add(len);
|
||||
this.forward.put(val, this.codes.size() - 1);
|
||||
this.inverse.put(this.codes.size() - 1, val);
|
||||
return this;
|
||||
}
|
||||
|
||||
public VLC getVLC() {
|
||||
final VLCBuilder self = this;
|
||||
return new VLC(this.codes.toArray(), this.codesSizes.toArray()) {
|
||||
public int readVLC(BitReader _in) {
|
||||
return self.inverse.get(super.readVLC(_in));
|
||||
}
|
||||
|
||||
public int readVLC16(BitReader _in) {
|
||||
return self.inverse.get(super.readVLC16(_in));
|
||||
}
|
||||
|
||||
public void writeVLC(BitWriter out, int code) {
|
||||
super.writeVLC(out, self.forward.get(code));
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
package org.jcodec.common.logging;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
public class BufferLogSink implements LogSink {
|
||||
private List<Message> messages = new LinkedList<>();
|
||||
|
||||
public void postMessage(Message msg) {
|
||||
this.messages.add(msg);
|
||||
}
|
||||
|
||||
public List<Message> getMessages() {
|
||||
return this.messages;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
package org.jcodec.common.logging;
|
||||
|
||||
public enum LogLevel {
|
||||
DEBUG, INFO, WARN, ERROR;
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
package org.jcodec.common.logging;
|
||||
|
||||
public interface LogSink {
|
||||
void postMessage(Message paramMessage);
|
||||
}
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
package org.jcodec.common.logging;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
public class Logger {
|
||||
private static List<LogSink> stageSinks = new LinkedList<>();
|
||||
|
||||
private static List<LogSink> sinks;
|
||||
|
||||
public static void debug(String message) {
|
||||
message(LogLevel.DEBUG, message, null);
|
||||
}
|
||||
|
||||
public static void debug(String message, Object... args) {
|
||||
message(LogLevel.DEBUG, message, args);
|
||||
}
|
||||
|
||||
public static void info(String message) {
|
||||
message(LogLevel.INFO, message, null);
|
||||
}
|
||||
|
||||
public static void info(String message, Object... args) {
|
||||
message(LogLevel.INFO, message, args);
|
||||
}
|
||||
|
||||
public static void warn(String message) {
|
||||
message(LogLevel.WARN, message, null);
|
||||
}
|
||||
|
||||
public static void warn(String message, Object... args) {
|
||||
message(LogLevel.WARN, message, args);
|
||||
}
|
||||
|
||||
public static void error(String message) {
|
||||
message(LogLevel.ERROR, message, null);
|
||||
}
|
||||
|
||||
public static void error(String message, Object... args) {
|
||||
message(LogLevel.ERROR, message, args);
|
||||
}
|
||||
|
||||
private static void message(LogLevel level, String message, Object[] args) {
|
||||
Message msg;
|
||||
if (globalLogLevel.ordinal() >= level.ordinal())
|
||||
return;
|
||||
if (sinks == null)
|
||||
synchronized (Logger.class) {
|
||||
if (sinks == null) {
|
||||
sinks = stageSinks;
|
||||
stageSinks = null;
|
||||
if (sinks.isEmpty())
|
||||
sinks.add(OutLogSink.createOutLogSink());
|
||||
}
|
||||
}
|
||||
if (LogLevel.DEBUG.equals(globalLogLevel)) {
|
||||
StackTraceElement tr = Thread.currentThread().getStackTrace()[3];
|
||||
msg = new Message(level, tr.getFileName(), tr.getClassName(), tr.getMethodName(), tr.getLineNumber(), message, args);
|
||||
} else {
|
||||
msg = new Message(level, "", "", "", 0, message, args);
|
||||
}
|
||||
for (LogSink logSink : sinks)
|
||||
logSink.postMessage(msg);
|
||||
}
|
||||
|
||||
private static LogLevel globalLogLevel = LogLevel.INFO;
|
||||
|
||||
public static synchronized void setLevel(LogLevel level) {
|
||||
globalLogLevel = level;
|
||||
}
|
||||
|
||||
public static synchronized LogLevel getLevel() {
|
||||
return globalLogLevel;
|
||||
}
|
||||
|
||||
public static void addSink(LogSink sink) {
|
||||
if (stageSinks == null)
|
||||
throw new IllegalStateException("Logger already started");
|
||||
stageSinks.add(sink);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
package org.jcodec.common.logging;
|
||||
|
||||
public class Message {
|
||||
private LogLevel level;
|
||||
|
||||
private String fileName;
|
||||
|
||||
private String className;
|
||||
|
||||
private int lineNumber;
|
||||
|
||||
private String message;
|
||||
|
||||
private String methodName;
|
||||
|
||||
private Object[] args;
|
||||
|
||||
public Message(LogLevel level, String fileName, String className, String methodName, int lineNumber, String message, Object[] args) {
|
||||
this.level = level;
|
||||
this.fileName = fileName;
|
||||
this.className = className;
|
||||
this.methodName = methodName;
|
||||
this.message = methodName;
|
||||
this.lineNumber = lineNumber;
|
||||
this.message = message;
|
||||
this.args = args;
|
||||
}
|
||||
|
||||
public LogLevel getLevel() {
|
||||
return this.level;
|
||||
}
|
||||
|
||||
public String getFileName() {
|
||||
return this.fileName;
|
||||
}
|
||||
|
||||
public String getClassName() {
|
||||
return this.className;
|
||||
}
|
||||
|
||||
public String getMethodName() {
|
||||
return this.methodName;
|
||||
}
|
||||
|
||||
public int getLineNumber() {
|
||||
return this.lineNumber;
|
||||
}
|
||||
|
||||
public String getMessage() {
|
||||
return this.message;
|
||||
}
|
||||
|
||||
public Object[] getArgs() {
|
||||
return this.args;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
package org.jcodec.common.logging;
|
||||
|
||||
import java.io.PrintStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import org.jcodec.common.tools.MainUtils;
|
||||
|
||||
public class OutLogSink implements LogSink {
|
||||
private static String empty = " ";
|
||||
|
||||
public static interface MessageFormat {
|
||||
String formatMessage(Message param1Message);
|
||||
}
|
||||
|
||||
public static class SimpleFormat implements MessageFormat {
|
||||
private String fmt;
|
||||
|
||||
private static Map<LogLevel, MainUtils.ANSIColor> colorMap = new HashMap<>();
|
||||
|
||||
static {
|
||||
colorMap.put(LogLevel.DEBUG, MainUtils.ANSIColor.BROWN);
|
||||
colorMap.put(LogLevel.INFO, MainUtils.ANSIColor.GREEN);
|
||||
colorMap.put(LogLevel.WARN, MainUtils.ANSIColor.MAGENTA);
|
||||
colorMap.put(LogLevel.ERROR, MainUtils.ANSIColor.RED);
|
||||
}
|
||||
|
||||
public SimpleFormat(String fmt) {
|
||||
this.fmt = fmt;
|
||||
}
|
||||
|
||||
public String formatMessage(Message msg) {
|
||||
String str = this.fmt.replace("#level", String.valueOf(msg.getLevel()))
|
||||
.replace("#color_code", String.valueOf(30 + colorMap.get(msg.getLevel()).ordinal()))
|
||||
.replace("#class", msg.getClassName()).replace("#method", msg.getMethodName())
|
||||
.replace("#file", msg.getFileName()).replace("#line", String.valueOf(msg.getLineNumber()))
|
||||
.replace("#message", msg.getMessage());
|
||||
return str;
|
||||
}
|
||||
}
|
||||
|
||||
public static SimpleFormat DEFAULT_FORMAT = new SimpleFormat(
|
||||
MainUtils.colorString("[#level]", "#color_code") + MainUtils.colorString("[#level]", "#color_code") + "\t#message");
|
||||
|
||||
private PrintStream out;
|
||||
|
||||
private MessageFormat fmt;
|
||||
|
||||
private LogLevel minLevel;
|
||||
|
||||
public static OutLogSink createOutLogSink() {
|
||||
return new OutLogSink(System.out, DEFAULT_FORMAT, LogLevel.INFO);
|
||||
}
|
||||
|
||||
public OutLogSink(PrintStream out, MessageFormat fmt, LogLevel minLevel) {
|
||||
this.out = out;
|
||||
this.fmt = fmt;
|
||||
this.minLevel = minLevel;
|
||||
}
|
||||
|
||||
public void postMessage(Message msg) {
|
||||
if (msg.getLevel().ordinal() < this.minLevel.ordinal())
|
||||
return;
|
||||
String str = this.fmt.formatMessage(msg);
|
||||
this.out.println(str);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
package org.jcodec.common.model;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import org.jcodec.common.AudioFormat;
|
||||
|
||||
public class AudioBuffer {
|
||||
protected ByteBuffer data;
|
||||
|
||||
protected AudioFormat format;
|
||||
|
||||
protected int nFrames;
|
||||
|
||||
public AudioBuffer(ByteBuffer data, AudioFormat format, int nFrames) {
|
||||
this.data = data;
|
||||
this.format = format;
|
||||
this.nFrames = nFrames;
|
||||
}
|
||||
|
||||
public ByteBuffer getData() {
|
||||
return this.data;
|
||||
}
|
||||
|
||||
public AudioFormat getFormat() {
|
||||
return this.format;
|
||||
}
|
||||
|
||||
public int getNFrames() {
|
||||
return this.nFrames;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
package org.jcodec.common.model;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import org.jcodec.common.AudioFormat;
|
||||
|
||||
public class AudioFrame extends AudioBuffer {
|
||||
private long pts;
|
||||
|
||||
private long duration;
|
||||
|
||||
private long timescale;
|
||||
|
||||
private int frameNo;
|
||||
|
||||
public AudioFrame(ByteBuffer buffer, AudioFormat format, int nFrames, long pts, long duration, long timescale, int frameNo) {
|
||||
super(buffer, format, nFrames);
|
||||
this.pts = pts;
|
||||
this.duration = duration;
|
||||
this.timescale = timescale;
|
||||
this.frameNo = frameNo;
|
||||
}
|
||||
|
||||
public long getPts() {
|
||||
return this.pts;
|
||||
}
|
||||
|
||||
public long getDuration() {
|
||||
return this.duration;
|
||||
}
|
||||
|
||||
public long getTimescale() {
|
||||
return this.timescale;
|
||||
}
|
||||
|
||||
public int getFrameNo() {
|
||||
return this.frameNo;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
package org.jcodec.common.model;
|
||||
|
||||
public enum ChannelLabel {
|
||||
MONO, STEREO_LEFT, STEREO_RIGHT, LEFT_TOTAL, RIGHT_TOTAL, FRONT_LEFT, FRONT_RIGHT, CENTER, LFE, REAR_LEFT, REAR_RIGHT, FRONT_CENTER_LEFT, FRONT_CENTER_RIGHT, REAR_CENTER, SIDE_LEFT, SIDE_RIGHT;
|
||||
}
|
||||
|
|
@ -0,0 +1,102 @@
|
|||
package org.jcodec.common.model;
|
||||
|
||||
public final class ColorSpace {
|
||||
public static final int MAX_PLANES = 4;
|
||||
|
||||
public int nComp;
|
||||
|
||||
public int[] compPlane;
|
||||
|
||||
public int[] compWidth;
|
||||
|
||||
public int[] compHeight;
|
||||
|
||||
public boolean planar;
|
||||
|
||||
private String _name;
|
||||
|
||||
public int bitsPerPixel;
|
||||
|
||||
private ColorSpace(String name, int nComp, int[] compPlane, int[] compWidth, int[] compHeight, boolean planar) {
|
||||
this._name = name;
|
||||
this.nComp = nComp;
|
||||
this.compPlane = compPlane;
|
||||
this.compWidth = compWidth;
|
||||
this.compHeight = compHeight;
|
||||
this.planar = planar;
|
||||
this.bitsPerPixel = calcBitsPerPixel(nComp, compWidth, compHeight);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return this._name;
|
||||
}
|
||||
|
||||
private static int calcBitsPerPixel(int nComp, int[] compWidth, int[] compHeight) {
|
||||
int bitsPerPixel = 0;
|
||||
for (int i = 0; i < nComp; i++)
|
||||
bitsPerPixel += 8 >> compWidth[i] >> compHeight[i];
|
||||
return bitsPerPixel;
|
||||
}
|
||||
|
||||
public int getWidthMask() {
|
||||
return ((this.nComp > 1) ? this.compWidth[1] : 0) ^ 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
public int getHeightMask() {
|
||||
return ((this.nComp > 1) ? this.compHeight[1] : 0) ^ 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
public boolean matches(ColorSpace inputColor) {
|
||||
if (inputColor == this)
|
||||
return true;
|
||||
if (inputColor == ANY || this == ANY)
|
||||
return true;
|
||||
if ((inputColor == ANY_INTERLEAVED || this == ANY_INTERLEAVED || inputColor == ANY_PLANAR || this == ANY_PLANAR) && inputColor.planar == this.planar)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
public Size compSize(Size size, int comp) {
|
||||
if (this.compWidth[comp] == 0 && this.compHeight[comp] == 0)
|
||||
return size;
|
||||
return new Size(size.getWidth() >> this.compWidth[comp], size.getHeight() >> this.compHeight[comp]);
|
||||
}
|
||||
|
||||
private static final int[] _000 = new int[] { 0, 0, 0 };
|
||||
|
||||
private static final int[] _011 = new int[] { 0, 1, 1 };
|
||||
|
||||
private static final int[] _012 = new int[] { 0, 1, 2 };
|
||||
|
||||
public static final ColorSpace BGR = new ColorSpace("BGR", 3, _000, _000, _000, false);
|
||||
|
||||
public static final ColorSpace RGB = new ColorSpace("RGB", 3, _000, _000, _000, false);
|
||||
|
||||
public static final ColorSpace YUV420 = new ColorSpace("YUV420", 3, _012, _011, _011, true);
|
||||
|
||||
public static final ColorSpace YUV420J = new ColorSpace("YUV420J", 3, _012, _011, _011, true);
|
||||
|
||||
public static final ColorSpace YUV422 = new ColorSpace("YUV422", 3, _012, _011, _000, true);
|
||||
|
||||
public static final ColorSpace YUV422J = new ColorSpace("YUV422J", 3, _012, _011, _000, true);
|
||||
|
||||
public static final ColorSpace YUV444 = new ColorSpace("YUV444", 3, _012, _000, _000, true);
|
||||
|
||||
public static final ColorSpace YUV444J = new ColorSpace("YUV444J", 3, _012, _000, _000, true);
|
||||
|
||||
public static final ColorSpace YUV422_10 = new ColorSpace("YUV422_10", 3, _012, _011, _000, true);
|
||||
|
||||
public static final ColorSpace GREY = new ColorSpace("GREY", 1, new int[] { 0 }, new int[] { 0 }, new int[] { 0 }, true);
|
||||
|
||||
public static final ColorSpace MONO = new ColorSpace("MONO", 1, _000, _000, _000, true);
|
||||
|
||||
public static final ColorSpace YUV444_10 = new ColorSpace("YUV444_10", 3, _012, _000, _000, true);
|
||||
|
||||
public static final ColorSpace ANY = new ColorSpace("ANY", 0, null, null, null, true);
|
||||
|
||||
public static final ColorSpace ANY_PLANAR = new ColorSpace("ANY_PLANAR", 0, null, null, null, true);
|
||||
|
||||
public static final ColorSpace ANY_INTERLEAVED = new ColorSpace("ANY_INTERLEAVED", 0, null, null, null, false);
|
||||
|
||||
public static final ColorSpace SAME = new ColorSpace("SAME", 0, null, null, null, false);
|
||||
}
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
package org.jcodec.common.model;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class Frame {
|
||||
private Picture pic;
|
||||
|
||||
private RationalLarge pts;
|
||||
|
||||
private RationalLarge duration;
|
||||
|
||||
private Rational pixelAspect;
|
||||
|
||||
private TapeTimecode tapeTimecode;
|
||||
|
||||
private int frameNo;
|
||||
|
||||
private List<String> messages;
|
||||
|
||||
public Frame(Picture pic, RationalLarge pts, RationalLarge duration, Rational pixelAspect, int frameNo, TapeTimecode tapeTimecode, List<String> messages) {
|
||||
this.pic = pic;
|
||||
this.pts = pts;
|
||||
this.duration = duration;
|
||||
this.pixelAspect = pixelAspect;
|
||||
this.tapeTimecode = tapeTimecode;
|
||||
this.frameNo = frameNo;
|
||||
this.messages = messages;
|
||||
}
|
||||
|
||||
public Picture getPic() {
|
||||
return this.pic;
|
||||
}
|
||||
|
||||
public RationalLarge getPts() {
|
||||
return this.pts;
|
||||
}
|
||||
|
||||
public RationalLarge getDuration() {
|
||||
return this.duration;
|
||||
}
|
||||
|
||||
public Rational getPixelAspect() {
|
||||
return this.pixelAspect;
|
||||
}
|
||||
|
||||
public TapeTimecode getTapeTimecode() {
|
||||
return this.tapeTimecode;
|
||||
}
|
||||
|
||||
public int getFrameNo() {
|
||||
return this.frameNo;
|
||||
}
|
||||
|
||||
public List<String> getMessages() {
|
||||
return this.messages;
|
||||
}
|
||||
|
||||
public boolean isAvailable() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,165 @@
|
|||
package org.jcodec.common.model;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public final class Label {
|
||||
private static final List<Label> _values = new ArrayList<>();
|
||||
|
||||
public static final Label Unknown = new Label(-1);
|
||||
|
||||
public static final Label Unused = new Label(0);
|
||||
|
||||
public static final Label UseCoordinates = new Label(100);
|
||||
|
||||
public static final Label Left = new Label(1);
|
||||
|
||||
public static final Label Right = new Label(2);
|
||||
|
||||
public static final Label Center = new Label(3);
|
||||
|
||||
public static final Label LFEScreen = new Label(4);
|
||||
|
||||
public static final Label LeftSurround = new Label(5);
|
||||
|
||||
public static final Label RightSurround = new Label(6);
|
||||
|
||||
public static final Label LeftCenter = new Label(7);
|
||||
|
||||
public static final Label RightCenter = new Label(8);
|
||||
|
||||
public static final Label CenterSurround = new Label(9);
|
||||
|
||||
public static final Label LeftSurroundDirect = new Label(10);
|
||||
|
||||
public static final Label RightSurroundDirect = new Label(11);
|
||||
|
||||
public static final Label TopCenterSurround = new Label(12);
|
||||
|
||||
public static final Label VerticalHeightLeft = new Label(13);
|
||||
|
||||
public static final Label VerticalHeightCenter = new Label(14);
|
||||
|
||||
public static final Label VerticalHeightRight = new Label(15);
|
||||
|
||||
public static final Label TopBackLeft = new Label(16);
|
||||
|
||||
public static final Label TopBackCenter = new Label(17);
|
||||
|
||||
public static final Label TopBackRight = new Label(18);
|
||||
|
||||
public static final Label RearSurroundLeft = new Label(33);
|
||||
|
||||
public static final Label RearSurroundRight = new Label(34);
|
||||
|
||||
public static final Label LeftWide = new Label(35);
|
||||
|
||||
public static final Label RightWide = new Label(36);
|
||||
|
||||
public static final Label LFE2 = new Label(37);
|
||||
|
||||
public static final Label LeftTotal = new Label(38);
|
||||
|
||||
public static final Label RightTotal = new Label(39);
|
||||
|
||||
public static final Label HearingImpaired = new Label(40);
|
||||
|
||||
public static final Label Narration = new Label(41);
|
||||
|
||||
public static final Label Mono = new Label(42);
|
||||
|
||||
public static final Label DialogCentricMix = new Label(43);
|
||||
|
||||
public static final Label CenterSurroundDirect = new Label(44);
|
||||
|
||||
public static final Label Ambisonic_W = new Label(200);
|
||||
|
||||
public static final Label Ambisonic_X = new Label(201);
|
||||
|
||||
public static final Label Ambisonic_Y = new Label(202);
|
||||
|
||||
public static final Label Ambisonic_Z = new Label(203);
|
||||
|
||||
public static final Label MS_Mid = new Label(204);
|
||||
|
||||
public static final Label MS_Side = new Label(205);
|
||||
|
||||
public static final Label XY_X = new Label(206);
|
||||
|
||||
public static final Label XY_Y = new Label(207);
|
||||
|
||||
public static final Label HeadphonesLeft = new Label(301);
|
||||
|
||||
public static final Label HeadphonesRight = new Label(302);
|
||||
|
||||
public static final Label ClickTrack = new Label(304);
|
||||
|
||||
public static final Label ForeignLanguage = new Label(305);
|
||||
|
||||
public static final Label Discrete = new Label(400);
|
||||
|
||||
public static final Label Discrete_0 = new Label(65536);
|
||||
|
||||
public static final Label Discrete_1 = new Label(65537);
|
||||
|
||||
public static final Label Discrete_2 = new Label(65538);
|
||||
|
||||
public static final Label Discrete_3 = new Label(65539);
|
||||
|
||||
public static final Label Discrete_4 = new Label(65540);
|
||||
|
||||
public static final Label Discrete_5 = new Label(65541);
|
||||
|
||||
public static final Label Discrete_6 = new Label(65542);
|
||||
|
||||
public static final Label Discrete_7 = new Label(65543);
|
||||
|
||||
public static final Label Discrete_8 = new Label(65544);
|
||||
|
||||
public static final Label Discrete_9 = new Label(65545);
|
||||
|
||||
public static final Label Discrete_10 = new Label(65546);
|
||||
|
||||
public static final Label Discrete_11 = new Label(65547);
|
||||
|
||||
public static final Label Discrete_12 = new Label(65548);
|
||||
|
||||
public static final Label Discrete_13 = new Label(65549);
|
||||
|
||||
public static final Label Discrete_14 = new Label(65550);
|
||||
|
||||
public static final Label Discrete_15 = new Label(65551);
|
||||
|
||||
public static final Label Discrete_65535 = new Label(131071);
|
||||
|
||||
final int labelVal;
|
||||
|
||||
public final long bitmapVal;
|
||||
|
||||
public static final Pattern channelMappingRegex = Pattern.compile("[_\\ \\.][a-zA-Z]+$");
|
||||
|
||||
private Label(int val) {
|
||||
this.labelVal = val;
|
||||
this.bitmapVal = (this.labelVal > 18 || this.labelVal < 1) ? 0L : (long)(1 << this.labelVal - 1);
|
||||
_values.add(this);
|
||||
}
|
||||
|
||||
public static Label[] values() {
|
||||
return _values.<Label>toArray(new Label[0]);
|
||||
}
|
||||
|
||||
public static Label getByVal(int val) {
|
||||
Label[] values = values();
|
||||
for (int i = 0; i < values.length; i++) {
|
||||
Label label = values[i];
|
||||
if (label.labelVal == val)
|
||||
return label;
|
||||
}
|
||||
return Mono;
|
||||
}
|
||||
|
||||
public int getVal() {
|
||||
return this.labelVal;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,133 @@
|
|||
package org.jcodec.common.model;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Comparator;
|
||||
|
||||
public class Packet {
|
||||
public ByteBuffer data;
|
||||
|
||||
public long pts;
|
||||
|
||||
public int timescale;
|
||||
|
||||
public long duration;
|
||||
|
||||
public long frameNo;
|
||||
|
||||
public FrameType frameType;
|
||||
|
||||
public TapeTimecode tapeTimecode;
|
||||
|
||||
public int displayOrder;
|
||||
|
||||
public enum FrameType {
|
||||
KEY, INTER, UNKNOWN;
|
||||
}
|
||||
|
||||
public static Packet createPacket(ByteBuffer data, long pts, int timescale, long duration, long frameNo, FrameType frameType, TapeTimecode tapeTimecode) {
|
||||
return new Packet(data, pts, timescale, duration, frameNo, frameType, tapeTimecode, 0);
|
||||
}
|
||||
|
||||
public static Packet createPacketWithData(Packet other, ByteBuffer data) {
|
||||
return new Packet(data, other.pts, other.timescale, other.duration, other.frameNo, other.frameType, other.tapeTimecode, other.displayOrder);
|
||||
}
|
||||
|
||||
public Packet(ByteBuffer data, long pts, int timescale, long duration, long frameNo, FrameType frameType, TapeTimecode tapeTimecode, int displayOrder) {
|
||||
this.data = data;
|
||||
this.pts = pts;
|
||||
this.timescale = timescale;
|
||||
this.duration = duration;
|
||||
this.frameNo = frameNo;
|
||||
this.frameType = frameType;
|
||||
this.tapeTimecode = tapeTimecode;
|
||||
this.displayOrder = displayOrder;
|
||||
}
|
||||
|
||||
public ByteBuffer getData() {
|
||||
return this.data.duplicate();
|
||||
}
|
||||
|
||||
public long getPts() {
|
||||
return this.pts;
|
||||
}
|
||||
|
||||
public int getTimescale() {
|
||||
return this.timescale;
|
||||
}
|
||||
|
||||
public long getDuration() {
|
||||
return this.duration;
|
||||
}
|
||||
|
||||
public long getFrameNo() {
|
||||
return this.frameNo;
|
||||
}
|
||||
|
||||
public void setTimescale(int timescale) {
|
||||
this.timescale = timescale;
|
||||
}
|
||||
|
||||
public TapeTimecode getTapeTimecode() {
|
||||
return this.tapeTimecode;
|
||||
}
|
||||
|
||||
public void setTapeTimecode(TapeTimecode tapeTimecode) {
|
||||
this.tapeTimecode = tapeTimecode;
|
||||
}
|
||||
|
||||
public int getDisplayOrder() {
|
||||
return this.displayOrder;
|
||||
}
|
||||
|
||||
public void setDisplayOrder(int displayOrder) {
|
||||
this.displayOrder = displayOrder;
|
||||
}
|
||||
|
||||
public FrameType getFrameType() {
|
||||
return this.frameType;
|
||||
}
|
||||
|
||||
public void setFrameType(FrameType frameType) {
|
||||
this.frameType = frameType;
|
||||
}
|
||||
|
||||
public RationalLarge getPtsR() {
|
||||
return RationalLarge.R(this.pts, (long)this.timescale);
|
||||
}
|
||||
|
||||
public double getPtsD() {
|
||||
return (double)this.pts / (double)this.timescale;
|
||||
}
|
||||
|
||||
public double getDurationD() {
|
||||
return (double)this.duration / (double)this.timescale;
|
||||
}
|
||||
|
||||
public void setData(ByteBuffer data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public void setPts(long pts) {
|
||||
this.pts = pts;
|
||||
}
|
||||
|
||||
public static final Comparator<Packet> FRAME_ASC = new Comparator<>() {
|
||||
public int compare(Packet o1, Packet o2) {
|
||||
if (o1 == null && o2 == null)
|
||||
return 0;
|
||||
if (o1 == null)
|
||||
return -1;
|
||||
if (o2 == null)
|
||||
return 1;
|
||||
return (o1.frameNo < o2.frameNo) ? -1 : ((o1.frameNo == o2.frameNo) ? 0 : 1);
|
||||
}
|
||||
};
|
||||
|
||||
public void setDuration(long duration) {
|
||||
this.duration = duration;
|
||||
}
|
||||
|
||||
public boolean isKeyFrame() {
|
||||
return (this.frameType == FrameType.KEY);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,307 @@
|
|||
package org.jcodec.common.model;
|
||||
|
||||
import java.util.Arrays;
|
||||
import org.jcodec.common.tools.MathUtil;
|
||||
|
||||
public class Picture {
|
||||
private ColorSpace color;
|
||||
|
||||
private int width;
|
||||
|
||||
private int height;
|
||||
|
||||
private byte[][] data;
|
||||
|
||||
private byte[][] lowBits;
|
||||
|
||||
private int lowBitsNum;
|
||||
|
||||
private Rect crop;
|
||||
|
||||
public static Picture createPicture(int width, int height, byte[][] data, ColorSpace color) {
|
||||
return new Picture(width, height, data, null, color, 0, new Rect(0, 0, width, height));
|
||||
}
|
||||
|
||||
public static Picture createPictureHiBD(int width, int height, byte[][] data, byte[][] lowBits, ColorSpace color, int lowBitsNum) {
|
||||
return new Picture(width, height, data, lowBits, color, lowBitsNum, new Rect(0, 0, width, height));
|
||||
}
|
||||
|
||||
public Picture(int width, int height, byte[][] data, byte[][] lowBits, ColorSpace color, int lowBitsNum, Rect crop) {
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.data = data;
|
||||
this.lowBits = lowBits;
|
||||
this.color = color;
|
||||
this.lowBitsNum = lowBitsNum;
|
||||
this.crop = crop;
|
||||
if (color != null)
|
||||
for (int i = 0; i < color.nComp; i++) {
|
||||
int mask = 255 >> 8 - color.compWidth[i];
|
||||
if ((width & mask) != 0)
|
||||
throw new IllegalArgumentException("Component " + i + " width should be a multiple of " + (1 << color.compWidth[i]) + " for colorspace: " + String.valueOf(color));
|
||||
if (crop != null && (crop.getWidth() & mask) != 0)
|
||||
throw new IllegalArgumentException("Component " + i + " cropped width should be a multiple of " + (1 << color.compWidth[i]) + " for colorspace: " + String.valueOf(color));
|
||||
mask = 255 >> 8 - color.compHeight[i];
|
||||
if ((height & mask) != 0)
|
||||
throw new IllegalArgumentException("Component " + i + " height should be a multiple of " + (1 << color.compHeight[i]) + " for colorspace: " + String.valueOf(color));
|
||||
if (crop != null && (crop.getHeight() & mask) != 0)
|
||||
throw new IllegalArgumentException("Component " + i + " cropped height should be a multiple of " + (1 << color.compHeight[i]) + " for colorspace: " + String.valueOf(color));
|
||||
}
|
||||
}
|
||||
|
||||
public static Picture copyPicture(Picture other) {
|
||||
return new Picture(other.width, other.height, other.data, other.lowBits, other.color, 0, other.crop);
|
||||
}
|
||||
|
||||
public static Picture create(int width, int height, ColorSpace colorSpace) {
|
||||
return createCropped(width, height, colorSpace, null);
|
||||
}
|
||||
|
||||
public static Picture createCropped(int width, int height, ColorSpace colorSpace, Rect crop) {
|
||||
int[] planeSizes = new int[4];
|
||||
for (int i = 0; i < colorSpace.nComp; i++)
|
||||
planeSizes[colorSpace.compPlane[i]] = planeSizes[colorSpace.compPlane[i]] + (width >> colorSpace.compWidth[i]) * (height >> colorSpace.compHeight[i]);
|
||||
int nPlanes = 0;
|
||||
for (int j = 0; j < 4; j++)
|
||||
nPlanes += (planeSizes[j] != 0) ? 1 : 0;
|
||||
byte[][] data = new byte[nPlanes][];
|
||||
for (int k = 0, plane = 0; k < 4; k++) {
|
||||
if (planeSizes[k] != 0)
|
||||
data[plane++] = new byte[planeSizes[k]];
|
||||
}
|
||||
return new Picture(width, height, data, null, colorSpace, 0, crop);
|
||||
}
|
||||
|
||||
public static Picture createCroppedHiBD(int width, int height, int lowBitsNum, ColorSpace colorSpace, Rect crop) {
|
||||
Picture result = createCropped(width, height, colorSpace, crop);
|
||||
if (lowBitsNum <= 0)
|
||||
return result;
|
||||
byte[][] data = result.getData();
|
||||
int nPlanes = data.length;
|
||||
byte[][] lowBits = new byte[nPlanes][];
|
||||
for (int i = 0, plane = 0; i < nPlanes; i++)
|
||||
lowBits[plane++] = new byte[(data[i]).length];
|
||||
result.setLowBits(lowBits);
|
||||
result.setLowBitsNum(lowBitsNum);
|
||||
return result;
|
||||
}
|
||||
|
||||
private void setLowBitsNum(int lowBitsNum) {
|
||||
this.lowBitsNum = lowBitsNum;
|
||||
}
|
||||
|
||||
private void setLowBits(byte[][] lowBits) {
|
||||
this.lowBits = lowBits;
|
||||
}
|
||||
|
||||
public int getWidth() {
|
||||
return this.width;
|
||||
}
|
||||
|
||||
public int getHeight() {
|
||||
return this.height;
|
||||
}
|
||||
|
||||
public byte[] getPlaneData(int plane) {
|
||||
return this.data[plane];
|
||||
}
|
||||
|
||||
public ColorSpace getColor() {
|
||||
return this.color;
|
||||
}
|
||||
|
||||
public byte[][] getData() {
|
||||
return this.data;
|
||||
}
|
||||
|
||||
public byte[][] getLowBits() {
|
||||
return this.lowBits;
|
||||
}
|
||||
|
||||
public Rect getCrop() {
|
||||
return this.crop;
|
||||
}
|
||||
|
||||
public int getPlaneWidth(int plane) {
|
||||
return this.width >> this.color.compWidth[plane];
|
||||
}
|
||||
|
||||
public int getPlaneHeight(int plane) {
|
||||
return this.height >> this.color.compHeight[plane];
|
||||
}
|
||||
|
||||
public boolean compatible(Picture src) {
|
||||
return (src.color == this.color && src.width == this.width && src.height == this.height);
|
||||
}
|
||||
|
||||
public Picture createCompatible() {
|
||||
return create(this.width, this.height, this.color);
|
||||
}
|
||||
|
||||
public void copyFrom(Picture src) {
|
||||
if (!compatible(src))
|
||||
throw new IllegalArgumentException("Can not copy to incompatible picture");
|
||||
for (int plane = 0; plane < this.color.nComp; plane++) {
|
||||
if (this.data[plane] != null)
|
||||
System.arraycopy(src.data[plane], 0, this.data[plane], 0, (this.width >> this.color.compWidth[plane]) * (this.height >> this.color.compHeight[plane]));
|
||||
}
|
||||
}
|
||||
|
||||
public Picture cloneCropped() {
|
||||
if (cropNeeded())
|
||||
return cropped();
|
||||
Picture clone = createCompatible();
|
||||
clone.copyFrom(this);
|
||||
return clone;
|
||||
}
|
||||
|
||||
public Picture cropped() {
|
||||
if (!cropNeeded())
|
||||
return this;
|
||||
Picture result = create(this.crop.getWidth(), this.crop.getHeight(), this.color);
|
||||
if (this.color.planar) {
|
||||
for (int plane = 0; plane < this.data.length; plane++) {
|
||||
if (this.data[plane] != null)
|
||||
cropSub(this.data[plane], this.crop.getX() >> this.color.compWidth[plane], this.crop.getY() >> this.color.compHeight[plane],
|
||||
this.crop.getWidth() >> this.color.compWidth[plane], this.crop.getHeight() >> this.color.compHeight[plane], this.width >> this.color.compWidth[plane],
|
||||
this.crop.getWidth() >> this.color.compWidth[plane], result.data[plane]);
|
||||
}
|
||||
} else {
|
||||
cropSub(this.data[0], this.crop.getX(), this.crop.getY(), this.crop.getWidth(),
|
||||
this.crop.getHeight(), this.width * this.color.nComp, this.crop.getWidth() * this.color.nComp, result.data[0]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
protected boolean cropNeeded() {
|
||||
return (this.crop != null && (
|
||||
this.crop.getX() != 0 || this.crop.getY() != 0 || this.crop.getWidth() != this.width || this.crop.getHeight() != this.height));
|
||||
}
|
||||
|
||||
private void cropSub(byte[] src, int x, int y, int w, int h, int srcStride, int dstStride, byte[] tgt) {
|
||||
int srcOff = y * srcStride + x, dstOff = 0;
|
||||
for (int i = 0; i < h; i++) {
|
||||
for (int j = 0; j < dstStride; j++)
|
||||
tgt[dstOff + j] = src[srcOff + j];
|
||||
srcOff += srcStride;
|
||||
dstOff += dstStride;
|
||||
}
|
||||
}
|
||||
|
||||
public void setCrop(Rect crop) {
|
||||
this.crop = crop;
|
||||
}
|
||||
|
||||
public int getCroppedWidth() {
|
||||
return (this.crop == null) ? this.width : this.crop.getWidth();
|
||||
}
|
||||
|
||||
public int getCroppedHeight() {
|
||||
return (this.crop == null) ? this.height : this.crop.getHeight();
|
||||
}
|
||||
|
||||
public int getLowBitsNum() {
|
||||
return this.lowBitsNum;
|
||||
}
|
||||
|
||||
public static Picture fromPictureHiBD(PictureHiBD pic) {
|
||||
int lowBitsNum = pic.getBitDepth() - 8;
|
||||
int lowBitsRound = 1 << lowBitsNum >> 1;
|
||||
Picture result = createCroppedHiBD(pic.getWidth(), pic.getHeight(), lowBitsNum, pic.getColor(),
|
||||
pic.getCrop());
|
||||
for (int i = 0; i < Math.min((pic.getData()).length, (result.getData()).length); i++) {
|
||||
for (int j = 0; j < Math.min((pic.getData()[i]).length, (result.getData()[i]).length); j++) {
|
||||
int val = pic.getData()[i][j];
|
||||
int round = MathUtil.clip(val + lowBitsRound >> lowBitsNum, 0, 255);
|
||||
result.getData()[i][j] = (byte)(round - 128);
|
||||
}
|
||||
}
|
||||
byte[][] lowBits = result.getLowBits();
|
||||
if (lowBits != null)
|
||||
for (int j = 0; j < Math.min((pic.getData()).length, (result.getData()).length); j++) {
|
||||
for (int k = 0; k < Math.min((pic.getData()[j]).length, (result.getData()[j]).length); k++) {
|
||||
int val = pic.getData()[j][k];
|
||||
int round = MathUtil.clip(val + lowBitsRound >> lowBitsNum, 0, 255);
|
||||
lowBits[j][k] = (byte)(val - (round << 2));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public PictureHiBD toPictureHiBD() {
|
||||
PictureHiBD create = PictureHiBD.doCreate(this.width, this.height, this.color, this.lowBitsNum + 8, this.crop);
|
||||
return toPictureHiBDInternal(create);
|
||||
}
|
||||
|
||||
public PictureHiBD toPictureHiBDWithBuffer(int[][] buffer) {
|
||||
PictureHiBD create = new PictureHiBD(this.width, this.height, buffer, this.color, this.lowBitsNum + 8, this.crop);
|
||||
return toPictureHiBDInternal(create);
|
||||
}
|
||||
|
||||
private PictureHiBD toPictureHiBDInternal(PictureHiBD pic) {
|
||||
int[][] dstData = pic.getData();
|
||||
for (int i = 0; i < this.data.length; i++) {
|
||||
int planeSize = getPlaneWidth(i) * getPlaneHeight(i);
|
||||
for (int j = 0; j < planeSize; j++)
|
||||
dstData[i][j] = this.data[i][j] + 128 << this.lowBitsNum;
|
||||
}
|
||||
if (this.lowBits != null)
|
||||
for (int j = 0; j < this.lowBits.length; j++) {
|
||||
int planeSize = getPlaneWidth(j) * getPlaneHeight(j);
|
||||
for (int k = 0; k < planeSize; k++)
|
||||
dstData[j][k] = dstData[j][k] + this.lowBits[j][k];
|
||||
}
|
||||
return pic;
|
||||
}
|
||||
|
||||
public void fill(int val) {
|
||||
for (int i = 0; i < this.data.length; i++)
|
||||
Arrays.fill(this.data[i], (byte)val);
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == null || !(obj instanceof Picture))
|
||||
return false;
|
||||
Picture other = (Picture)obj;
|
||||
if (other.getCroppedWidth() != getCroppedWidth() || other.getCroppedHeight() != getCroppedHeight() ||
|
||||
other.getColor() != this.color)
|
||||
return false;
|
||||
for (int i = 0; i < (getData()).length; i++) {
|
||||
if (!planeEquals(other, i))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean planeEquals(Picture other, int plane) {
|
||||
int cw = this.color.compWidth[plane];
|
||||
int ch = this.color.compHeight[plane];
|
||||
int offA = (other.getCrop() == null) ? 0 : ((other.getCrop().getX() >> cw) + (other.getCrop().getY() >> ch) * (
|
||||
other.getWidth() >> cw));
|
||||
int offB = (this.crop == null) ? 0 : ((this.crop.getX() >> cw) + (this.crop.getY() >> ch) * (this.width >> cw));
|
||||
byte[] planeData = other.getPlaneData(plane);
|
||||
for (int i = 0; i < getCroppedHeight() >> ch; i++, offA += other.getWidth() >> cw, offB += this.width >> cw) {
|
||||
for (int j = 0; j < getCroppedWidth() >> cw; j++) {
|
||||
if (planeData[offA + j] != this.data[plane][offB + j])
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public int getStartX() {
|
||||
return (this.crop == null) ? 0 : this.crop.getX();
|
||||
}
|
||||
|
||||
public int getStartY() {
|
||||
return (this.crop == null) ? 0 : this.crop.getY();
|
||||
}
|
||||
|
||||
public boolean isHiBD() {
|
||||
return (this.lowBits != null);
|
||||
}
|
||||
|
||||
public Size getSize() {
|
||||
return new Size(this.width, this.height);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,189 @@
|
|||
package org.jcodec.common.model;
|
||||
|
||||
public class PictureHiBD {
|
||||
private ColorSpace color;
|
||||
|
||||
private int width;
|
||||
|
||||
private int height;
|
||||
|
||||
private int[][] data;
|
||||
|
||||
private Rect crop;
|
||||
|
||||
private int bitDepth;
|
||||
|
||||
public static PictureHiBD createPicture(int width, int height, int[][] data, ColorSpace color) {
|
||||
return new PictureHiBD(width, height, data, color, 8, new Rect(0, 0, width, height));
|
||||
}
|
||||
|
||||
public static PictureHiBD createPictureWithDepth(int width, int height, int[][] data, ColorSpace color, int bitDepth) {
|
||||
return new PictureHiBD(width, height, data, color, bitDepth, new Rect(0, 0, width, height));
|
||||
}
|
||||
|
||||
public static PictureHiBD createPictureCropped(int width, int height, int[][] data, ColorSpace color, Rect crop) {
|
||||
return new PictureHiBD(width, height, data, color, 8, crop);
|
||||
}
|
||||
|
||||
public PictureHiBD(int width, int height, int[][] data, ColorSpace color, int bitDepth, Rect crop) {
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.data = data;
|
||||
this.color = color;
|
||||
this.crop = crop;
|
||||
this.bitDepth = bitDepth;
|
||||
}
|
||||
|
||||
public static PictureHiBD clonePicture(PictureHiBD other) {
|
||||
return new PictureHiBD(other.width, other.height, other.data, other.color, other.bitDepth, other.crop);
|
||||
}
|
||||
|
||||
public static PictureHiBD create(int width, int height, ColorSpace colorSpace) {
|
||||
return doCreate(width, height, colorSpace, 8, null);
|
||||
}
|
||||
|
||||
public static PictureHiBD createWithDepth(int width, int height, ColorSpace colorSpace, int bitDepth) {
|
||||
return doCreate(width, height, colorSpace, bitDepth, null);
|
||||
}
|
||||
|
||||
public static PictureHiBD createCropped(int width, int height, ColorSpace colorSpace, Rect crop) {
|
||||
return doCreate(width, height, colorSpace, 8, crop);
|
||||
}
|
||||
|
||||
public static PictureHiBD doCreate(int width, int height, ColorSpace colorSpace, int bitDepth, Rect crop) {
|
||||
int[] planeSizes = new int[4];
|
||||
for (int i = 0; i < colorSpace.nComp; i++)
|
||||
planeSizes[colorSpace.compPlane[i]] = planeSizes[colorSpace.compPlane[i]] + (width >> colorSpace.compWidth[i]) * (height >> colorSpace.compHeight[i]);
|
||||
int nPlanes = 0;
|
||||
for (int j = 0; j < 4; j++)
|
||||
nPlanes += (planeSizes[j] != 0) ? 1 : 0;
|
||||
int[][] data = new int[nPlanes][];
|
||||
for (int k = 0, plane = 0; k < 4; k++) {
|
||||
if (planeSizes[k] != 0)
|
||||
data[plane++] = new int[planeSizes[k]];
|
||||
}
|
||||
return new PictureHiBD(width, height, data, colorSpace, 8, crop);
|
||||
}
|
||||
|
||||
public int getWidth() {
|
||||
return this.width;
|
||||
}
|
||||
|
||||
public int getHeight() {
|
||||
return this.height;
|
||||
}
|
||||
|
||||
public int[] getPlaneData(int plane) {
|
||||
return this.data[plane];
|
||||
}
|
||||
|
||||
public ColorSpace getColor() {
|
||||
return this.color;
|
||||
}
|
||||
|
||||
public int[][] getData() {
|
||||
return this.data;
|
||||
}
|
||||
|
||||
public Rect getCrop() {
|
||||
return this.crop;
|
||||
}
|
||||
|
||||
public int getPlaneWidth(int plane) {
|
||||
return this.width >> this.color.compWidth[plane];
|
||||
}
|
||||
|
||||
public int getPlaneHeight(int plane) {
|
||||
return this.height >> this.color.compHeight[plane];
|
||||
}
|
||||
|
||||
public boolean compatible(PictureHiBD src) {
|
||||
return (src.color == this.color && src.width == this.width && src.height == this.height);
|
||||
}
|
||||
|
||||
public PictureHiBD createCompatible() {
|
||||
return create(this.width, this.height, this.color);
|
||||
}
|
||||
|
||||
public void copyFrom(PictureHiBD src) {
|
||||
if (!compatible(src))
|
||||
throw new IllegalArgumentException("Can not copy to incompatible picture");
|
||||
for (int plane = 0; plane < this.color.nComp; plane++) {
|
||||
if (this.data[plane] != null)
|
||||
System.arraycopy(src.data[plane], 0, this.data[plane], 0, (this.width >> this.color.compWidth[plane]) * (this.height >> this.color.compHeight[plane]));
|
||||
}
|
||||
}
|
||||
|
||||
public PictureHiBD cropped() {
|
||||
if (this.crop == null || (
|
||||
this.crop.getX() == 0 && this.crop.getY() == 0 && this.crop.getWidth() == this.width && this.crop.getHeight() == this.height))
|
||||
return this;
|
||||
PictureHiBD result = create(this.crop.getWidth(), this.crop.getHeight(), this.color);
|
||||
for (int plane = 0; plane < this.color.nComp; plane++) {
|
||||
if (this.data[plane] != null)
|
||||
cropSub(this.data[plane], this.crop.getX() >> this.color.compWidth[plane], this.crop.getY() >> this.color.compHeight[plane],
|
||||
this.crop.getWidth() >> this.color.compWidth[plane], this.crop.getHeight() >> this.color.compHeight[plane], this.width >> this.color.compWidth[plane], result.data[plane]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private void cropSub(int[] src, int x, int y, int w, int h, int srcStride, int[] tgt) {
|
||||
int srcOff = y * srcStride + x, dstOff = 0;
|
||||
for (int i = 0; i < h; i++) {
|
||||
for (int j = 0; j < w; j++)
|
||||
tgt[dstOff + j] = src[srcOff + j];
|
||||
srcOff += srcStride;
|
||||
dstOff += w;
|
||||
}
|
||||
}
|
||||
|
||||
public void setCrop(Rect crop) {
|
||||
this.crop = crop;
|
||||
}
|
||||
|
||||
public int getCroppedWidth() {
|
||||
return (this.crop == null) ? this.width : this.crop.getWidth();
|
||||
}
|
||||
|
||||
public int getCroppedHeight() {
|
||||
return (this.crop == null) ? this.height : this.crop.getHeight();
|
||||
}
|
||||
|
||||
public void setBitDepth(int bitDepth) {
|
||||
this.bitDepth = bitDepth;
|
||||
}
|
||||
|
||||
public int getBitDepth() {
|
||||
return this.bitDepth;
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == null || !(obj instanceof PictureHiBD))
|
||||
return false;
|
||||
PictureHiBD other = (PictureHiBD)obj;
|
||||
if (other.getCroppedWidth() != getCroppedWidth() || other.getCroppedHeight() != getCroppedHeight() ||
|
||||
other.getColor() != this.color)
|
||||
return false;
|
||||
for (int i = 0; i < (getData()).length; i++) {
|
||||
if (!planeEquals(other, i))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean planeEquals(PictureHiBD other, int plane) {
|
||||
int cw = this.color.compWidth[plane];
|
||||
int ch = this.color.compHeight[plane];
|
||||
int offA = (other.getCrop() == null) ? 0 : ((
|
||||
other.getCrop().getX() >> cw) + (other.getCrop().getY() >> ch) * (other.getWidth() >> cw));
|
||||
int offB = (this.crop == null) ? 0 : ((this.crop.getX() >> cw) + (this.crop.getY() >> ch) * (this.width >> cw));
|
||||
int[] planeData = other.getPlaneData(plane);
|
||||
for (int i = 0; i < getCroppedHeight() >> ch; i++, offA += other.getWidth() >> cw, offB += this.width >> cw) {
|
||||
for (int j = 0; j < getCroppedWidth() >> cw; j++) {
|
||||
if (planeData[offA + j] != this.data[plane][offB + j])
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
package org.jcodec.common.model;
|
||||
|
||||
public class Plane {
|
||||
int[] data;
|
||||
|
||||
Size size;
|
||||
|
||||
public Plane(int[] data, Size size) {
|
||||
this.data = data;
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
public int[] getData() {
|
||||
return this.data;
|
||||
}
|
||||
|
||||
public Size getSize() {
|
||||
return this.size;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
package org.jcodec.common.model;
|
||||
|
||||
public class Point {
|
||||
private int x;
|
||||
|
||||
private int y;
|
||||
|
||||
public Point(int x, int y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
public int getX() {
|
||||
return this.x;
|
||||
}
|
||||
|
||||
public int getY() {
|
||||
return this.y;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,204 @@
|
|||
package org.jcodec.common.model;
|
||||
|
||||
import org.jcodec.common.tools.MathUtil;
|
||||
|
||||
public class Rational {
|
||||
public static final Rational ONE = new Rational(1, 1);
|
||||
|
||||
public static final Rational HALF = new Rational(1, 2);
|
||||
|
||||
public static final Rational ZERO = new Rational(0, 1);
|
||||
|
||||
public final int num;
|
||||
|
||||
public final int den;
|
||||
|
||||
public static Rational R(int num, int den) {
|
||||
return new Rational(num, den);
|
||||
}
|
||||
|
||||
public static Rational R1(int num) {
|
||||
return R(num, 1);
|
||||
}
|
||||
|
||||
public Rational(int num, int den) {
|
||||
this.num = num;
|
||||
this.den = den;
|
||||
}
|
||||
|
||||
public int getNum() {
|
||||
return this.num;
|
||||
}
|
||||
|
||||
public int getDen() {
|
||||
return this.den;
|
||||
}
|
||||
|
||||
public static Rational parseRational(String string) {
|
||||
return parse(string);
|
||||
}
|
||||
|
||||
public static Rational parse(String string) {
|
||||
int idx = string.indexOf(":");
|
||||
if (idx < 0)
|
||||
idx = string.indexOf("/");
|
||||
if (idx > 0) {
|
||||
String num = string.substring(0, idx);
|
||||
String den = string.substring(idx + 1);
|
||||
return new Rational(Integer.parseInt(num), Integer.parseInt(den));
|
||||
}
|
||||
return R(Integer.parseInt(string), 1);
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
int prime = 31;
|
||||
int result = 1;
|
||||
result = 31 * result + this.den;
|
||||
result = 31 * result + this.num;
|
||||
return result;
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
Rational other = (Rational)obj;
|
||||
if (this.den != other.den)
|
||||
return false;
|
||||
if (this.num != other.num)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public int multiplyS(int val) {
|
||||
return (int)((long)this.num * (long)val / (long)this.den);
|
||||
}
|
||||
|
||||
public int divideS(int val) {
|
||||
return (int)((long)this.den * (long)val / (long)this.num);
|
||||
}
|
||||
|
||||
public int divideByS(int val) {
|
||||
return this.num / (this.den * val);
|
||||
}
|
||||
|
||||
public long multiplyLong(long val) {
|
||||
return (long)this.num * val / (long)this.den;
|
||||
}
|
||||
|
||||
public long divideLong(long val) {
|
||||
return (long)this.den * val / (long)this.num;
|
||||
}
|
||||
|
||||
public Rational flip() {
|
||||
return new Rational(this.den, this.num);
|
||||
}
|
||||
|
||||
public boolean smallerThen(Rational sec) {
|
||||
return (this.num * sec.den < sec.num * this.den);
|
||||
}
|
||||
|
||||
public boolean greaterThen(Rational sec) {
|
||||
return (this.num * sec.den > sec.num * this.den);
|
||||
}
|
||||
|
||||
public boolean smallerOrEqualTo(Rational sec) {
|
||||
return (this.num * sec.den <= sec.num * this.den);
|
||||
}
|
||||
|
||||
public boolean greaterOrEqualTo(Rational sec) {
|
||||
return (this.num * sec.den >= sec.num * this.den);
|
||||
}
|
||||
|
||||
public boolean equalsRational(Rational other) {
|
||||
return (this.num * other.den == other.num * this.den);
|
||||
}
|
||||
|
||||
public Rational plus(Rational other) {
|
||||
return reduce(this.num * other.den + other.num * this.den, this.den * other.den);
|
||||
}
|
||||
|
||||
public RationalLarge plusLarge(RationalLarge other) {
|
||||
return RationalLarge.reduceLong((long)this.num * other.den + other.num * (long)this.den, (long)this.den * other.den);
|
||||
}
|
||||
|
||||
public Rational minus(Rational other) {
|
||||
return reduce(this.num * other.den - other.num * this.den, this.den * other.den);
|
||||
}
|
||||
|
||||
public RationalLarge minusLarge(RationalLarge other) {
|
||||
return RationalLarge.reduceLong((long)this.num * other.den - other.num * (long)this.den, (long)this.den * other.den);
|
||||
}
|
||||
|
||||
public Rational plusInt(int scalar) {
|
||||
return new Rational(this.num + scalar * this.den, this.den);
|
||||
}
|
||||
|
||||
public Rational minusInt(int scalar) {
|
||||
return new Rational(this.num - scalar * this.den, this.den);
|
||||
}
|
||||
|
||||
public Rational multiplyInt(int scalar) {
|
||||
return new Rational(this.num * scalar, this.den);
|
||||
}
|
||||
|
||||
public Rational divideInt(int scalar) {
|
||||
return new Rational(this.den * scalar, this.num);
|
||||
}
|
||||
|
||||
public Rational divideByInt(int scalar) {
|
||||
return new Rational(this.num, this.den * scalar);
|
||||
}
|
||||
|
||||
public Rational multiply(Rational other) {
|
||||
return reduce(this.num * other.num, this.den * other.den);
|
||||
}
|
||||
|
||||
public RationalLarge multiplyLarge(RationalLarge other) {
|
||||
return RationalLarge.reduceLong((long)this.num * other.num, (long)this.den * other.den);
|
||||
}
|
||||
|
||||
public Rational divide(Rational other) {
|
||||
return reduce(other.num * this.den, other.den * this.num);
|
||||
}
|
||||
|
||||
public RationalLarge divideLarge(RationalLarge other) {
|
||||
return RationalLarge.reduceLong(other.num * (long)this.den, other.den * (long)this.num);
|
||||
}
|
||||
|
||||
public Rational divideBy(Rational other) {
|
||||
return reduce(this.num * other.den, this.den * other.num);
|
||||
}
|
||||
|
||||
public RationalLarge divideByLarge(RationalLarge other) {
|
||||
return RationalLarge.reduceLong((long)this.num * other.den, (long)this.den * other.num);
|
||||
}
|
||||
|
||||
public float scalar() {
|
||||
return (float)this.num / (float)this.den;
|
||||
}
|
||||
|
||||
public int scalarClip() {
|
||||
return this.num / this.den;
|
||||
}
|
||||
|
||||
public static Rational reduce(int num, int den) {
|
||||
int gcd = MathUtil.gcd(num, den);
|
||||
return new Rational(num / gcd, den / gcd);
|
||||
}
|
||||
|
||||
public static Rational reduceRational(Rational r) {
|
||||
return reduce(r.getNum(), r.getDen());
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "" + this.num + "/" + this.num;
|
||||
}
|
||||
|
||||
public double toDouble() {
|
||||
return (double)this.num / (double)this.den;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,179 @@
|
|||
package org.jcodec.common.model;
|
||||
|
||||
import org.jcodec.common.StringUtils;
|
||||
import org.jcodec.common.tools.MathUtil;
|
||||
|
||||
public class RationalLarge {
|
||||
public static final RationalLarge ONE = new RationalLarge(1L, 1L);
|
||||
|
||||
public static final RationalLarge HALF = new RationalLarge(1L, 2L);
|
||||
|
||||
public static final RationalLarge ZERO = new RationalLarge(0L, 1L);
|
||||
|
||||
final long num;
|
||||
|
||||
final long den;
|
||||
|
||||
public RationalLarge(long num, long den) {
|
||||
this.num = num;
|
||||
this.den = den;
|
||||
}
|
||||
|
||||
public long getNum() {
|
||||
return this.num;
|
||||
}
|
||||
|
||||
public long getDen() {
|
||||
return this.den;
|
||||
}
|
||||
|
||||
public static RationalLarge parse(String string) {
|
||||
String[] split = StringUtils.splitS(string, ":");
|
||||
return (split.length > 1) ? R(Long.parseLong(split[0]), Long.parseLong(split[1])) :
|
||||
R(Long.parseLong(string), 1L);
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
int prime = 31;
|
||||
int result = 1;
|
||||
result = 31 * result + (int)(this.den ^ this.den >>> 32L);
|
||||
result = 31 * result + (int)(this.num ^ this.num >>> 32L);
|
||||
return result;
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
RationalLarge other = (RationalLarge)obj;
|
||||
if (this.den != other.den)
|
||||
return false;
|
||||
if (this.num != other.num)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public long multiplyS(long scalar) {
|
||||
return this.num * scalar / this.den;
|
||||
}
|
||||
|
||||
public long divideS(long scalar) {
|
||||
return this.den * scalar / this.num;
|
||||
}
|
||||
|
||||
public long divideByS(long scalar) {
|
||||
return this.num / (this.den * scalar);
|
||||
}
|
||||
|
||||
public RationalLarge flip() {
|
||||
return new RationalLarge(this.den, this.num);
|
||||
}
|
||||
|
||||
public static RationalLarge R(long num, long den) {
|
||||
return new RationalLarge(num, den);
|
||||
}
|
||||
|
||||
public static RationalLarge R1(long num) {
|
||||
return R(num, 1L);
|
||||
}
|
||||
|
||||
public boolean lessThen(RationalLarge sec) {
|
||||
return (this.num * sec.den < sec.num * this.den);
|
||||
}
|
||||
|
||||
public boolean greaterThen(RationalLarge sec) {
|
||||
return (this.num * sec.den > sec.num * this.den);
|
||||
}
|
||||
|
||||
public boolean smallerOrEqualTo(RationalLarge sec) {
|
||||
return (this.num * sec.den <= sec.num * this.den);
|
||||
}
|
||||
|
||||
public boolean greaterOrEqualTo(RationalLarge sec) {
|
||||
return (this.num * sec.den >= sec.num * this.den);
|
||||
}
|
||||
|
||||
public boolean equalsLarge(RationalLarge other) {
|
||||
return (this.num * other.den == other.num * this.den);
|
||||
}
|
||||
|
||||
public RationalLarge plus(RationalLarge other) {
|
||||
return reduceLong(this.num * other.den + other.num * this.den, this.den * other.den);
|
||||
}
|
||||
|
||||
public RationalLarge plusR(Rational other) {
|
||||
return reduceLong(this.num * (long)other.den + (long)other.num * this.den, this.den * (long)other.den);
|
||||
}
|
||||
|
||||
public RationalLarge minus(RationalLarge other) {
|
||||
return reduceLong(this.num * other.den - other.num * this.den, this.den * other.den);
|
||||
}
|
||||
|
||||
public RationalLarge minusR(Rational other) {
|
||||
return reduceLong(this.num * (long)other.den - (long)other.num * this.den, this.den * (long)other.den);
|
||||
}
|
||||
|
||||
public RationalLarge plusLong(long scalar) {
|
||||
return new RationalLarge(this.num + scalar * this.den, this.den);
|
||||
}
|
||||
|
||||
public RationalLarge minusLong(long scalar) {
|
||||
return new RationalLarge(this.num - scalar * this.den, this.den);
|
||||
}
|
||||
|
||||
public RationalLarge multiplyLong(long scalar) {
|
||||
return new RationalLarge(this.num * scalar, this.den);
|
||||
}
|
||||
|
||||
public RationalLarge divideLong(long scalar) {
|
||||
return new RationalLarge(this.den * scalar, this.num);
|
||||
}
|
||||
|
||||
public RationalLarge divideByLong(long scalar) {
|
||||
return new RationalLarge(this.num, this.den * scalar);
|
||||
}
|
||||
|
||||
public RationalLarge multiply(RationalLarge other) {
|
||||
return reduceLong(this.num * other.num, this.den * other.den);
|
||||
}
|
||||
|
||||
public RationalLarge multiplyR(Rational other) {
|
||||
return reduceLong(this.num * (long)other.num, this.den * (long)other.den);
|
||||
}
|
||||
|
||||
public RationalLarge divideRL(RationalLarge other) {
|
||||
return reduceLong(other.num * this.den, other.den * this.num);
|
||||
}
|
||||
|
||||
public RationalLarge divideR(Rational other) {
|
||||
return reduceLong((long)other.num * this.den, (long)other.den * this.num);
|
||||
}
|
||||
|
||||
public RationalLarge divideBy(RationalLarge other) {
|
||||
return reduceLong(this.num * other.den, this.den * other.num);
|
||||
}
|
||||
|
||||
public RationalLarge divideByR(Rational other) {
|
||||
return reduceLong(this.num * (long)other.den, this.den * (long)other.num);
|
||||
}
|
||||
|
||||
public double scalar() {
|
||||
return (double)this.num / (double)this.den;
|
||||
}
|
||||
|
||||
public long scalarClip() {
|
||||
return this.num / this.den;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "" + this.num + ":" + this.num;
|
||||
}
|
||||
|
||||
public static RationalLarge reduceLong(long num, long den) {
|
||||
long gcd = MathUtil.gcdLong(num, den);
|
||||
return new RationalLarge(num / gcd, den / gcd);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
package org.jcodec.common.model;
|
||||
|
||||
public class Rect {
|
||||
private int x;
|
||||
|
||||
private int y;
|
||||
|
||||
private int width;
|
||||
|
||||
private int height;
|
||||
|
||||
public Rect(int x, int y, int width, int height) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
public int getX() {
|
||||
return this.x;
|
||||
}
|
||||
|
||||
public int getY() {
|
||||
return this.y;
|
||||
}
|
||||
|
||||
public int getWidth() {
|
||||
return this.width;
|
||||
}
|
||||
|
||||
public int getHeight() {
|
||||
return this.height;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
int prime = 31;
|
||||
int result = 1;
|
||||
result = 31 * result + this.height;
|
||||
result = 31 * result + this.width;
|
||||
result = 31 * result + this.x;
|
||||
result = 31 * result + this.y;
|
||||
return result;
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
Rect other = (Rect)obj;
|
||||
if (this.height != other.height)
|
||||
return false;
|
||||
if (this.width != other.width)
|
||||
return false;
|
||||
if (this.x != other.x)
|
||||
return false;
|
||||
if (this.y != other.y)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "Rect [x=" + this.x + ", y=" + this.y + ", width=" + this.width + ", height=" + this.height + "]";
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
package org.jcodec.common.model;
|
||||
|
||||
public class Size {
|
||||
private int width;
|
||||
|
||||
private int height;
|
||||
|
||||
public Size(int width, int height) {
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
public int getWidth() {
|
||||
return this.width;
|
||||
}
|
||||
|
||||
public int getHeight() {
|
||||
return this.height;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
int prime = 31;
|
||||
int result = 1;
|
||||
result = 31 * result + this.height;
|
||||
result = 31 * result + this.width;
|
||||
return result;
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
Size other = (Size)obj;
|
||||
if (this.height != other.height)
|
||||
return false;
|
||||
if (this.width != other.width)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
package org.jcodec.common.model;
|
||||
|
||||
import org.jcodec.common.StringUtils;
|
||||
|
||||
public class TapeTimecode {
|
||||
public static final TapeTimecode ZERO_TAPE_TIMECODE = new TapeTimecode((short)0, (byte)0, (byte)0, (byte)0, false, 0);
|
||||
|
||||
private final short hour;
|
||||
|
||||
private final byte minute;
|
||||
|
||||
private final byte second;
|
||||
|
||||
private final byte frame;
|
||||
|
||||
private final boolean dropFrame;
|
||||
|
||||
private final int tapeFps;
|
||||
|
||||
public TapeTimecode(short hour, byte minute, byte second, byte frame, boolean dropFrame, int tapeFps) {
|
||||
this.hour = hour;
|
||||
this.minute = minute;
|
||||
this.second = second;
|
||||
this.frame = frame;
|
||||
this.dropFrame = dropFrame;
|
||||
this.tapeFps = tapeFps;
|
||||
}
|
||||
|
||||
public short getHour() {
|
||||
return this.hour;
|
||||
}
|
||||
|
||||
public byte getMinute() {
|
||||
return this.minute;
|
||||
}
|
||||
|
||||
public byte getSecond() {
|
||||
return this.second;
|
||||
}
|
||||
|
||||
public byte getFrame() {
|
||||
return this.frame;
|
||||
}
|
||||
|
||||
public boolean isDropFrame() {
|
||||
return this.dropFrame;
|
||||
}
|
||||
|
||||
public int getTapeFps() {
|
||||
return this.tapeFps;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return StringUtils.zeroPad2(this.hour) + ":" + StringUtils.zeroPad2(this.hour) + ":" +
|
||||
StringUtils.zeroPad2(this.minute) +
|
||||
StringUtils.zeroPad2(this.second) + (this.dropFrame ? ";" : ":");
|
||||
}
|
||||
|
||||
public static TapeTimecode tapeTimecode(long frame, boolean dropFrame, int tapeFps) {
|
||||
if (dropFrame) {
|
||||
long D = frame / 17982L;
|
||||
long M = frame % 17982L;
|
||||
frame += 18L * D + 2L * (M - 2L) / 1798L;
|
||||
}
|
||||
long sec = frame / (long)tapeFps;
|
||||
return new TapeTimecode((short)(int)(sec / 3600L), (byte)(int)(sec / 60L % 60L), (byte)(int)(sec % 60L), (byte)(int)(frame % (long)tapeFps), dropFrame, tapeFps);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
package org.jcodec.common.model;
|
||||
|
||||
public enum Unit {
|
||||
FRAME, SEC;
|
||||
}
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
package org.jcodec.common.tools;
|
||||
|
||||
import java.nio.ShortBuffer;
|
||||
import org.jcodec.common.ArrayUtil;
|
||||
|
||||
public class Debug {
|
||||
public static final void print8x8i(int[] output) {
|
||||
int i = 0;
|
||||
for (int x = 0; x < 8; x++) {
|
||||
for (int y = 0; y < 8; y++) {
|
||||
System.out.printf("%3d, ", output[i]);
|
||||
i++;
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
}
|
||||
|
||||
public static final void print8x8s(short[] output) {
|
||||
int i = 0;
|
||||
for (int x = 0; x < 8; x++) {
|
||||
for (int y = 0; y < 8; y++) {
|
||||
System.out.printf("%3d, ", output[i]);
|
||||
i++;
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
}
|
||||
|
||||
public static final void print8x8sb(ShortBuffer output) {
|
||||
for (int x = 0; x < 8; x++) {
|
||||
for (int y = 0; y < 8; y++)
|
||||
System.out.printf("%3d, ", output.get());
|
||||
System.out.println();
|
||||
}
|
||||
}
|
||||
|
||||
public static void prints(short[] table) {
|
||||
int i = 0;
|
||||
for (int x = 0; x < 8; x++) {
|
||||
for (int y = 0; y < 8; y++) {
|
||||
System.out.printf("%3d, ", table[i]);
|
||||
i++;
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
}
|
||||
|
||||
public static void trace(Object... arguments) {
|
||||
if (debug && arguments.length > 0) {
|
||||
String format = (String)arguments[0];
|
||||
ArrayUtil.shiftLeft1(arguments);
|
||||
System.out.printf(format + ": %d\n", arguments);
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean debug = false;
|
||||
|
||||
public static void printInt(int i) {
|
||||
if (debug)
|
||||
System.out.print(i);
|
||||
}
|
||||
|
||||
public static void print(String string) {
|
||||
if (debug)
|
||||
System.out.print(string);
|
||||
}
|
||||
|
||||
public static void println(String string) {
|
||||
if (debug)
|
||||
System.out.println(string);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
package org.jcodec.common.tools;
|
||||
|
||||
import org.jcodec.common.model.ColorSpace;
|
||||
import org.jcodec.common.model.Picture;
|
||||
import org.jcodec.common.model.Rect;
|
||||
|
||||
public class ImageOP {
|
||||
public static void subImageWithFillInt(int[] src, int width, int height, int[] dst, int dstW, int dstH, int offX, int offY) {
|
||||
int srcHeight = Math.min(height - offY, dstH);
|
||||
int srcWidth = Math.min(width - offX, dstW);
|
||||
int srcStride = width;
|
||||
int dstOff = 0, srcOff = offY * srcStride + offX;
|
||||
int i;
|
||||
for (i = 0; i < srcHeight; i++) {
|
||||
int j;
|
||||
for (j = 0; j < srcWidth; j++)
|
||||
dst[dstOff + j] = src[srcOff + j];
|
||||
int lastPix = dst[j - 1];
|
||||
for (; j < dstW; j++)
|
||||
dst[dstOff + j] = lastPix;
|
||||
srcOff += srcStride;
|
||||
dstOff += dstW;
|
||||
}
|
||||
int lastLine = dstOff - dstW;
|
||||
for (; i < dstH; i++) {
|
||||
System.arraycopy(dst, lastLine, dst, dstOff, dstW);
|
||||
dstOff += dstW;
|
||||
}
|
||||
}
|
||||
|
||||
public static void subImageWithFill(byte[] src, int width, int height, byte[] dst, int dstW, int dstH, int offX, int offY) {
|
||||
int srcHeight = Math.min(height - offY, dstH);
|
||||
int srcWidth = Math.min(width - offX, dstW);
|
||||
int srcStride = width;
|
||||
int dstOff = 0, srcOff = offY * srcStride + offX;
|
||||
int i;
|
||||
for (i = 0; i < srcHeight; i++) {
|
||||
int j;
|
||||
for (j = 0; j < srcWidth; j++)
|
||||
dst[dstOff + j] = src[srcOff + j];
|
||||
byte lastPix = dst[j - 1];
|
||||
for (; j < dstW; j++)
|
||||
dst[dstOff + j] = lastPix;
|
||||
srcOff += srcStride;
|
||||
dstOff += dstW;
|
||||
}
|
||||
int lastLine = dstOff - dstW;
|
||||
for (; i < dstH; i++) {
|
||||
System.arraycopy(dst, lastLine, dst, dstOff, dstW);
|
||||
dstOff += dstW;
|
||||
}
|
||||
}
|
||||
|
||||
public static void subImageWithFillPic8(Picture _in, Picture out, Rect rect) {
|
||||
int width = _in.getWidth();
|
||||
int height = _in.getHeight();
|
||||
ColorSpace color = _in.getColor();
|
||||
byte[][] data = _in.getData();
|
||||
for (int i = 0; i < data.length; i++)
|
||||
subImageWithFill(data[i], width >> color.compWidth[i], height >> color.compHeight[i],
|
||||
out.getPlaneData(i), rect.getWidth() >> color.compWidth[i],
|
||||
rect.getHeight() >> color.compHeight[i], rect.getX() >> color.compWidth[i],
|
||||
rect.getY() >> color.compHeight[i]);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
package org.jcodec.common.tools;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
public class MD5 {
|
||||
public static String md5sumBytes(byte[] bytes) {
|
||||
MessageDigest md5 = getDigest();
|
||||
md5.update(bytes);
|
||||
return digestToString(md5.digest());
|
||||
}
|
||||
|
||||
private static String digestToString(byte[] digest) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < digest.length; i++) {
|
||||
byte item = digest[i];
|
||||
int b = item & 0xFF;
|
||||
if (b < 16)
|
||||
sb.append("0");
|
||||
sb.append(Integer.toHexString(b));
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static String md5sum(ByteBuffer bytes) {
|
||||
MessageDigest md5 = getDigest();
|
||||
md5.update(bytes);
|
||||
byte[] digest = md5.digest();
|
||||
return digestToString(digest);
|
||||
}
|
||||
|
||||
public static MessageDigest getDigest() {
|
||||
MessageDigest md5;
|
||||
try {
|
||||
md5 = MessageDigest.getInstance("MD5");
|
||||
} catch (NoSuchAlgorithmException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return md5;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,451 @@
|
|||
package org.jcodec.common.tools;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.PrintStream;
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import org.jcodec.common.StringUtils;
|
||||
import org.jcodec.common.io.IOUtils;
|
||||
import org.jcodec.platform.Platform;
|
||||
|
||||
public class MainUtils {
|
||||
private static final String KEY_GIT_REVISION = "git.commit.id.abbrev";
|
||||
|
||||
private static final String JCODEC_LOG_SINK_COLOR = "jcodec.colorPrint";
|
||||
|
||||
private static final String GIT_PROPERTIES = "git.properties";
|
||||
|
||||
public static boolean isColorSupported = (System.console() != null ||
|
||||
Boolean.parseBoolean(System.getProperty("jcodec.colorPrint")));
|
||||
|
||||
public enum FlagType {
|
||||
VOID, STRING, INT, LONG, DOUBLE, MULT, ENUM, ANY;
|
||||
}
|
||||
|
||||
public static class Flag {
|
||||
private String longName;
|
||||
|
||||
private String shortName;
|
||||
|
||||
private String description;
|
||||
|
||||
private MainUtils.FlagType type;
|
||||
|
||||
public Flag(String longName, String shortName, String description, MainUtils.FlagType type) {
|
||||
this.longName = longName;
|
||||
this.shortName = shortName;
|
||||
this.description = description;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public static Flag flag(String longName, String shortName, String description) {
|
||||
return new Flag(longName, shortName, description, MainUtils.FlagType.ANY);
|
||||
}
|
||||
|
||||
public String getLongName() {
|
||||
return this.longName;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return this.description;
|
||||
}
|
||||
|
||||
public String getShortName() {
|
||||
return this.shortName;
|
||||
}
|
||||
|
||||
public MainUtils.FlagType getType() {
|
||||
return this.type;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Cmd {
|
||||
public Map<String, String> longFlags;
|
||||
|
||||
public Map<String, String> shortFlags;
|
||||
|
||||
public String[] args;
|
||||
|
||||
private Map<String, String>[] longArgFlags;
|
||||
|
||||
private Map<String, String>[] shortArgFlags;
|
||||
|
||||
public Cmd(Map<String, String> longFlags, Map<String, String> shortFlags, String[] args, Map<String, String>[] longArgFlags, Map<String, String>[] shortArgFlags) {
|
||||
this.args = args;
|
||||
this.longFlags = longFlags;
|
||||
this.shortFlags = shortFlags;
|
||||
this.longArgFlags = longArgFlags;
|
||||
this.shortArgFlags = shortArgFlags;
|
||||
}
|
||||
|
||||
private Long getLongFlagInternal(Map<String, String> longFlags, Map<String, String> shortFlags, MainUtils.Flag flag, Long defaultValue) {
|
||||
return longFlags.containsKey(flag.getLongName()) ? new Long(longFlags.get(flag.getLongName())) : (
|
||||
shortFlags.containsKey(flag.getShortName()) ? new Long(shortFlags.get(flag.getShortName())) :
|
||||
defaultValue);
|
||||
}
|
||||
|
||||
private Integer getIntegerFlagInternal(Map<String, String> longFlags, Map<String, String> shortFlags, MainUtils.Flag flag, Integer defaultValue) {
|
||||
return longFlags.containsKey(flag.getLongName()) ? new Integer(longFlags.get(flag.getLongName())) : (
|
||||
shortFlags.containsKey(flag.getShortName()) ? new Integer(shortFlags.get(flag.getShortName())) :
|
||||
defaultValue);
|
||||
}
|
||||
|
||||
private Boolean getBooleanFlagInternal(Map<String, String> longFlags, Map<String, String> shortFlags, MainUtils.Flag flag, Boolean defaultValue) {
|
||||
return longFlags.containsKey(flag.getLongName()) ? (
|
||||
!"false".equalsIgnoreCase(longFlags.get(flag.getLongName()))) : (
|
||||
shortFlags.containsKey(flag.getShortName()) ? (
|
||||
!"false".equalsIgnoreCase(shortFlags.get(flag.getShortName()))) : defaultValue);
|
||||
}
|
||||
|
||||
private Double getDoubleFlagInternal(Map<String, String> longFlags, Map<String, String> shortFlags, MainUtils.Flag flag, Double defaultValue) {
|
||||
return longFlags.containsKey(flag.getLongName()) ? new Double(longFlags.get(flag.getLongName())) : (
|
||||
shortFlags.containsKey(flag.getShortName()) ? new Double(shortFlags.get(flag.getShortName())) :
|
||||
defaultValue);
|
||||
}
|
||||
|
||||
private String getStringFlagInternal(Map<String, String> longFlags, Map<String, String> shortFlags, MainUtils.Flag flag, String defaultValue) {
|
||||
return longFlags.containsKey(flag.getLongName()) ? longFlags.get(flag.getLongName()) : (
|
||||
shortFlags.containsKey(flag.getShortName()) ? shortFlags.get(flag.getShortName()) :
|
||||
defaultValue);
|
||||
}
|
||||
|
||||
private int[] getMultiIntegerFlagInternal(Map<String, String> longFlags, Map<String, String> shortFlags, MainUtils.Flag flag, int[] defaultValue) {
|
||||
String flagValue;
|
||||
if (longFlags.containsKey(flag.getLongName())) {
|
||||
flagValue = longFlags.get(flag.getLongName());
|
||||
} else if (shortFlags.containsKey(flag.getShortName())) {
|
||||
flagValue = shortFlags.get(flag.getShortName());
|
||||
} else {
|
||||
return defaultValue;
|
||||
}
|
||||
String[] split = StringUtils.splitS(flagValue, ",");
|
||||
int[] result = new int[split.length];
|
||||
for (int i = 0; i < split.length; i++)
|
||||
result[i] = Integer.parseInt(split[i]);
|
||||
return result;
|
||||
}
|
||||
|
||||
private <T extends Enum<T>> T getEnumFlagInternal(Map<String, String> longFlags, Map<String, String> shortFlags, MainUtils.Flag flag, T defaultValue, Class<T> class1) {
|
||||
String flagValue;
|
||||
if (longFlags.containsKey(flag.getLongName())) {
|
||||
flagValue = longFlags.get(flag.getLongName());
|
||||
} else if (shortFlags.containsKey(flag.getShortName())) {
|
||||
flagValue = shortFlags.get(flag.getShortName());
|
||||
} else {
|
||||
return defaultValue;
|
||||
}
|
||||
String strVal = flagValue.toLowerCase();
|
||||
EnumSet<T> allOf = EnumSet.allOf(class1);
|
||||
for (T val : (Iterable<T>)allOf) {
|
||||
if (val.name().toLowerCase().equals(strVal))
|
||||
return val;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Long getLongFlagD(MainUtils.Flag flagName, Long defaultValue) {
|
||||
return getLongFlagInternal(this.longFlags, this.shortFlags, flagName, defaultValue);
|
||||
}
|
||||
|
||||
public Long getLongFlag(MainUtils.Flag flagName) {
|
||||
return getLongFlagInternal(this.longFlags, this.shortFlags, flagName, null);
|
||||
}
|
||||
|
||||
public Long getLongFlagID(int arg, MainUtils.Flag flagName, Long defaultValue) {
|
||||
return getLongFlagInternal(this.longArgFlags[arg], this.shortArgFlags[arg], flagName, defaultValue);
|
||||
}
|
||||
|
||||
public Long getLongFlagI(int arg, MainUtils.Flag flagName) {
|
||||
return getLongFlagInternal(this.longArgFlags[arg], this.shortArgFlags[arg], flagName, null);
|
||||
}
|
||||
|
||||
public Integer getIntegerFlagD(MainUtils.Flag flagName, Integer defaultValue) {
|
||||
return getIntegerFlagInternal(this.longFlags, this.shortFlags, flagName, defaultValue);
|
||||
}
|
||||
|
||||
public Integer getIntegerFlag(MainUtils.Flag flagName) {
|
||||
return getIntegerFlagInternal(this.longFlags, this.shortFlags, flagName, null);
|
||||
}
|
||||
|
||||
public Integer getIntegerFlagID(int arg, MainUtils.Flag flagName, Integer defaultValue) {
|
||||
return getIntegerFlagInternal(this.longArgFlags[arg], this.shortArgFlags[arg], flagName, defaultValue);
|
||||
}
|
||||
|
||||
public Integer getIntegerFlagI(int arg, MainUtils.Flag flagName) {
|
||||
return getIntegerFlagInternal(this.longArgFlags[arg], this.shortArgFlags[arg], flagName, null);
|
||||
}
|
||||
|
||||
public Boolean getBooleanFlagD(MainUtils.Flag flagName, Boolean defaultValue) {
|
||||
return getBooleanFlagInternal(this.longFlags, this.shortFlags, flagName, defaultValue);
|
||||
}
|
||||
|
||||
public Boolean getBooleanFlag(MainUtils.Flag flagName) {
|
||||
return getBooleanFlagInternal(this.longFlags, this.shortFlags, flagName, Boolean.valueOf(false));
|
||||
}
|
||||
|
||||
public Boolean getBooleanFlagID(int arg, MainUtils.Flag flagName, Boolean defaultValue) {
|
||||
return getBooleanFlagInternal(this.longArgFlags[arg], this.shortArgFlags[arg], flagName, defaultValue);
|
||||
}
|
||||
|
||||
public Boolean getBooleanFlagI(int arg, MainUtils.Flag flagName) {
|
||||
return getBooleanFlagInternal(this.longArgFlags[arg], this.shortArgFlags[arg], flagName, Boolean.valueOf(false));
|
||||
}
|
||||
|
||||
public Double getDoubleFlagD(MainUtils.Flag flagName, Double defaultValue) {
|
||||
return getDoubleFlagInternal(this.longFlags, this.shortFlags, flagName, defaultValue);
|
||||
}
|
||||
|
||||
public Double getDoubleFlag(MainUtils.Flag flagName) {
|
||||
return getDoubleFlagInternal(this.longFlags, this.shortFlags, flagName, null);
|
||||
}
|
||||
|
||||
public Double getDoubleFlagID(int arg, MainUtils.Flag flagName, Double defaultValue) {
|
||||
return getDoubleFlagInternal(this.longArgFlags[arg], this.shortArgFlags[arg], flagName, defaultValue);
|
||||
}
|
||||
|
||||
public Double getDoubleFlagI(int arg, MainUtils.Flag flagName) {
|
||||
return getDoubleFlagInternal(this.longArgFlags[arg], this.shortArgFlags[arg], flagName, null);
|
||||
}
|
||||
|
||||
public String getStringFlagD(MainUtils.Flag flagName, String defaultValue) {
|
||||
return getStringFlagInternal(this.longFlags, this.shortFlags, flagName, defaultValue);
|
||||
}
|
||||
|
||||
public String getStringFlag(MainUtils.Flag flagName) {
|
||||
return getStringFlagInternal(this.longFlags, this.shortFlags, flagName, null);
|
||||
}
|
||||
|
||||
public String getStringFlagID(int arg, MainUtils.Flag flagName, String defaultValue) {
|
||||
return getStringFlagInternal(this.longArgFlags[arg], this.shortArgFlags[arg], flagName, defaultValue);
|
||||
}
|
||||
|
||||
public String getStringFlagI(int arg, MainUtils.Flag flagName) {
|
||||
return getStringFlagInternal(this.longArgFlags[arg], this.shortArgFlags[arg], flagName, null);
|
||||
}
|
||||
|
||||
public int[] getMultiIntegerFlagD(MainUtils.Flag flagName, int[] defaultValue) {
|
||||
return getMultiIntegerFlagInternal(this.longFlags, this.shortFlags, flagName, defaultValue);
|
||||
}
|
||||
|
||||
public int[] getMultiIntegerFlag(MainUtils.Flag flagName) {
|
||||
return getMultiIntegerFlagInternal(this.longFlags, this.shortFlags, flagName, new int[0]);
|
||||
}
|
||||
|
||||
public int[] getMultiIntegerFlagID(int arg, MainUtils.Flag flagName, int[] defaultValue) {
|
||||
return getMultiIntegerFlagInternal(this.longArgFlags[arg], this.shortArgFlags[arg], flagName, defaultValue);
|
||||
}
|
||||
|
||||
public int[] getMultiIntegerFlagI(int arg, MainUtils.Flag flagName) {
|
||||
return getMultiIntegerFlagInternal(this.longArgFlags[arg], this.shortArgFlags[arg], flagName, new int[0]);
|
||||
}
|
||||
|
||||
public <T extends Enum<T>> T getEnumFlagD(MainUtils.Flag flagName, T defaultValue, Class<T> class1) {
|
||||
return getEnumFlagInternal(this.longFlags, this.shortFlags, flagName, defaultValue, class1);
|
||||
}
|
||||
|
||||
public <T extends Enum<T>> T getEnumFlag(MainUtils.Flag flagName, Class<T> class1) {
|
||||
return getEnumFlagInternal(this.longFlags, this.shortFlags, flagName, null, class1);
|
||||
}
|
||||
|
||||
public <T extends Enum<T>> T getEnumFlagID(int arg, MainUtils.Flag flagName, T defaultValue, Class<T> class1) {
|
||||
return getEnumFlagInternal(this.longArgFlags[arg], this.shortArgFlags[arg], flagName, defaultValue, class1);
|
||||
}
|
||||
|
||||
public <T extends Enum<T>> T getEnumFlagI(int arg, MainUtils.Flag flagName, Class<T> class1) {
|
||||
return getEnumFlagInternal(this.longArgFlags[arg], this.shortArgFlags[arg], flagName, null, class1);
|
||||
}
|
||||
|
||||
public String getArg(int i) {
|
||||
return (i < this.args.length) ? this.args[i] : null;
|
||||
}
|
||||
|
||||
public int argsLength() {
|
||||
return this.args.length;
|
||||
}
|
||||
|
||||
public void popArg() {
|
||||
this.args = Platform.<String>copyOfRangeO(this.args, 1, this.args.length);
|
||||
}
|
||||
}
|
||||
|
||||
private static Pattern flagPattern = Pattern.compile("^--([^=]+)=(.*)$");
|
||||
|
||||
public static Cmd parseArguments(String[] args, Flag[] flags) {
|
||||
Map<String, String> longFlags = new HashMap<>();
|
||||
Map<String, String> shortFlags = new HashMap<>();
|
||||
Map<String, String> allLongFlags = new HashMap<>();
|
||||
Map<String, String> allShortFlags = new HashMap<>();
|
||||
List<String> outArgs = new ArrayList<>();
|
||||
List<Map<String, String>> argLongFlags = new ArrayList<>();
|
||||
List<Map<String, String>> argShortFlags = new ArrayList<>();
|
||||
int arg = 0;
|
||||
for (; arg < args.length; arg++) {
|
||||
if (args[arg].startsWith("--")) {
|
||||
Matcher matcher = flagPattern.matcher(args[arg]);
|
||||
if (matcher.matches()) {
|
||||
longFlags.put(matcher.group(1), matcher.group(2));
|
||||
} else {
|
||||
longFlags.put(args[arg].substring(2), "true");
|
||||
}
|
||||
} else if (args[arg].startsWith("-")) {
|
||||
String shortName = args[arg].substring(1);
|
||||
boolean found = false;
|
||||
for (Flag flag : flags) {
|
||||
if (shortName.equals(flag.getShortName())) {
|
||||
found = true;
|
||||
if (flag.getType() != FlagType.VOID) {
|
||||
shortFlags.put(shortName, args[++arg]);
|
||||
} else {
|
||||
shortFlags.put(shortName, "true");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
arg++;
|
||||
} else {
|
||||
allLongFlags.putAll(longFlags);
|
||||
allShortFlags.putAll(shortFlags);
|
||||
outArgs.add(args[arg]);
|
||||
argLongFlags.add(longFlags);
|
||||
argShortFlags.add(shortFlags);
|
||||
longFlags = new HashMap<>();
|
||||
shortFlags = new HashMap<>();
|
||||
}
|
||||
}
|
||||
return new Cmd(allLongFlags, allShortFlags, outArgs.<String>toArray(new String[0]),
|
||||
argLongFlags.<Map<String, String>>toArray((Map<String, String>[])Array.newInstance(longFlags.getClass(), 0)),
|
||||
argShortFlags.<Map<String, String>>toArray((Map<String, String>[])Array.newInstance(shortFlags.getClass(), 0)));
|
||||
}
|
||||
|
||||
public static void printHelpArgs(Flag[] flags, String[] args) {
|
||||
printHelpOut(System.out, "", flags, Arrays.asList(args));
|
||||
}
|
||||
|
||||
public static void printHelp(Flag[] flags, List<String> params) {
|
||||
printHelpOut(System.out, "", flags, params);
|
||||
}
|
||||
|
||||
public static void printHelpNoFlags(String... arguments) {
|
||||
printHelpOut(System.out, "", new Flag[0], Arrays.asList(arguments));
|
||||
}
|
||||
|
||||
public static void printHelpCmdVa(String command, Flag[] flags, String args) {
|
||||
printHelpOut(System.out, command, flags, Collections.singletonList(args));
|
||||
}
|
||||
|
||||
public static void printHelpCmd(String command, Flag[] flags, List<String> params) {
|
||||
printHelpOut(System.out, command, flags, params);
|
||||
}
|
||||
|
||||
private static String getGitRevision() {
|
||||
InputStream is = null;
|
||||
try {
|
||||
is = Thread.currentThread().getContextClassLoader().getResourceAsStream("git.properties");
|
||||
if (is == null)
|
||||
return null;
|
||||
Properties properties = new Properties();
|
||||
properties.load(is);
|
||||
return (String)properties.get("git.commit.id.abbrev");
|
||||
} catch (IOException e) {
|
||||
|
||||
} finally {
|
||||
IOUtils.closeQuietly(is);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void printHelpOut(PrintStream out, String command, Flag[] flags, List<String> params) {
|
||||
String version = MainUtils.class.getPackage().getImplementationVersion();
|
||||
String gitRevision = getGitRevision();
|
||||
if (command == null || command.isEmpty())
|
||||
command = "jcodec";
|
||||
if (gitRevision != null || version != null) {
|
||||
out.println(command + command);
|
||||
out.println();
|
||||
}
|
||||
out.print(bold("Syntax: " + command));
|
||||
StringBuilder sample = new StringBuilder();
|
||||
StringBuilder detail = new StringBuilder();
|
||||
for (Flag flag : flags) {
|
||||
sample.append(" [");
|
||||
detail.append("\t");
|
||||
if (flag.getLongName() != null) {
|
||||
sample.append(bold(color("--" + flag.getLongName() + "=<value>", ANSIColor.MAGENTA)));
|
||||
detail.append(bold(color("--" + flag.getLongName(), ANSIColor.MAGENTA)));
|
||||
}
|
||||
if (flag.getShortName() != null) {
|
||||
if (flag.getLongName() != null) {
|
||||
sample.append(" (");
|
||||
detail.append(" (");
|
||||
}
|
||||
sample.append(bold(color("-" + flag.getShortName() + " <value>", ANSIColor.MAGENTA)));
|
||||
detail.append(bold(color("-" + flag.getShortName(), ANSIColor.MAGENTA)));
|
||||
if (flag.getLongName() != null) {
|
||||
sample.append(")");
|
||||
detail.append(")");
|
||||
}
|
||||
}
|
||||
sample.append("]");
|
||||
detail.append("\t\t" + flag.getDescription() + "\n");
|
||||
}
|
||||
for (String param : params) {
|
||||
if (param.charAt(0) != '?') {
|
||||
sample.append(bold(" <" + param + ">"));
|
||||
continue;
|
||||
}
|
||||
sample.append(bold(" [" + param.substring(1) + "]"));
|
||||
}
|
||||
out.println(sample);
|
||||
out.println(bold("Where:"));
|
||||
out.println(detail);
|
||||
}
|
||||
|
||||
public enum ANSIColor {
|
||||
BLACK, RED, GREEN, BROWN, BLUE, MAGENTA, CYAN, GREY;
|
||||
}
|
||||
|
||||
public static String bold(String str) {
|
||||
return isColorSupported ? ("\033[1m" + str + "\033[0m") : str;
|
||||
}
|
||||
|
||||
public static String colorString(String str, String placeholder) {
|
||||
return isColorSupported ? ("\033[" + placeholder + "m" + str + "\033[0m") : str;
|
||||
}
|
||||
|
||||
public static String color(String str, ANSIColor fg) {
|
||||
return isColorSupported ? ("\033[" + 30 + (fg.ordinal() & 0x7) + "m" + str + "\033[0m") : str;
|
||||
}
|
||||
|
||||
public static String colorBright(String str, ANSIColor fg, boolean bright) {
|
||||
return isColorSupported ? ("\033[" + 30 + (fg.ordinal() & 0x7) + ";" + (bright ? true : 2) + "m" + str + "\033[0m") :
|
||||
str;
|
||||
}
|
||||
|
||||
public static String color3(String str, ANSIColor fg, ANSIColor bg) {
|
||||
return isColorSupported ? ("\033[" +
|
||||
30 + (fg.ordinal() & 0x7) + ";" + 40 + (bg.ordinal() & 0x7) + ";1m" + str + "\033[0m") :
|
||||
str;
|
||||
}
|
||||
|
||||
public static String color4(String str, ANSIColor fg, ANSIColor bg, boolean bright) {
|
||||
return isColorSupported ? ("\033[" +
|
||||
30 + (fg.ordinal() & 0x7) + ";" + 40 + (bg.ordinal() & 0x7) + ";" + (bright ? true : 2) + "m" + str + "\033[0m") : str;
|
||||
}
|
||||
|
||||
public static File tildeExpand(String path) {
|
||||
if (path.startsWith("~"))
|
||||
path = path.replaceFirst("~", System.getProperty("user.home"));
|
||||
return new File(path);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,166 @@
|
|||
package org.jcodec.common.tools;
|
||||
|
||||
public class MathUtil {
|
||||
private static final int[] logTab = new int[] {
|
||||
0, 0, 1, 1, 2, 2, 2, 2, 3, 3,
|
||||
3, 3, 3, 3, 3, 3, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7 };
|
||||
|
||||
private static final int[] reverseTab = new int[] {
|
||||
0, 128, 64, 192, 32, 160, 96, 224, 16, 144,
|
||||
80, 208, 48, 176, 112, 240, 8, 136, 72, 200,
|
||||
40, 168, 104, 232, 24, 152, 88, 216, 56, 184,
|
||||
120, 248, 4, 132, 68, 196, 36, 164, 100, 228,
|
||||
20, 148, 84, 212, 52, 180, 116, 244, 12, 140,
|
||||
76, 204, 44, 172, 108, 236, 28, 156, 92, 220,
|
||||
60, 188, 124, 252, 2, 130, 66, 194, 34, 162,
|
||||
98, 226, 18, 146, 82, 210, 50, 178, 114, 242,
|
||||
10, 138, 74, 202, 42, 170, 106, 234, 26, 154,
|
||||
90, 218, 58, 186, 122, 250, 6, 134, 70, 198,
|
||||
38, 166, 102, 230, 22, 150, 86, 214, 54, 182,
|
||||
118, 246, 14, 142, 78, 206, 46, 174, 110, 238,
|
||||
30, 158, 94, 222, 62, 190, 126, 254, 1, 129,
|
||||
65, 193, 33, 161, 97, 225, 17, 145, 81, 209,
|
||||
49, 177, 113, 241, 9, 137, 73, 201, 41, 169,
|
||||
105, 233, 25, 153, 89, 217, 57, 185, 121, 249,
|
||||
5, 133, 69, 197, 37, 165, 101, 229, 21, 149,
|
||||
85, 213, 53, 181, 117, 245, 13, 141, 77, 205,
|
||||
45, 173, 109, 237, 29, 157, 93, 221, 61, 189,
|
||||
125, 253, 3, 131, 67, 195, 35, 163, 99, 227,
|
||||
19, 147, 83, 211, 51, 179, 115, 243, 11, 139,
|
||||
75, 203, 43, 171, 107, 235, 27, 155, 91, 219,
|
||||
59, 187, 123, 251, 7, 135, 71, 199, 39, 167,
|
||||
103, 231, 23, 151, 87, 215, 55, 183, 119, 247,
|
||||
15, 143, 79, 207, 47, 175, 111, 239, 31, 159,
|
||||
95, 223, 63, 191, 127, 255 };
|
||||
|
||||
public static int log2(int v) {
|
||||
int n = 0;
|
||||
if ((v & 0xFFFF0000) != 0) {
|
||||
v >>= 16;
|
||||
n += 16;
|
||||
}
|
||||
if ((v & 0xFF00) != 0) {
|
||||
v >>= 8;
|
||||
n += 8;
|
||||
}
|
||||
n += logTab[v];
|
||||
return n;
|
||||
}
|
||||
|
||||
public static int log2l(long v) {
|
||||
int n = 0;
|
||||
if ((v & 0xFFFFFFFF00000000L) != 0L) {
|
||||
v >>= 32L;
|
||||
n += 32;
|
||||
}
|
||||
if ((v & 0xFFFF0000L) != 0L) {
|
||||
v >>= 16L;
|
||||
n += 16;
|
||||
}
|
||||
if ((v & 0xFF00L) != 0L) {
|
||||
v >>= 8L;
|
||||
n += 8;
|
||||
}
|
||||
n += logTab[(int)v];
|
||||
return n;
|
||||
}
|
||||
|
||||
public static int log2Slow(int val) {
|
||||
int i = 0;
|
||||
while ((val & Integer.MIN_VALUE) == 0) {
|
||||
val <<= 1;
|
||||
i++;
|
||||
}
|
||||
return 31 - i;
|
||||
}
|
||||
|
||||
public static int gcd(int a, int b) {
|
||||
if (b != 0)
|
||||
return gcd(b, a % b);
|
||||
return a;
|
||||
}
|
||||
|
||||
public static long gcdLong(long a, long b) {
|
||||
if (b != 0L)
|
||||
return gcdLong(b, a % b);
|
||||
return a;
|
||||
}
|
||||
|
||||
public static final int clip(int val, int from, int to) {
|
||||
return (val < from) ? from : ((val > to) ? to : val);
|
||||
}
|
||||
|
||||
public static final int clipMax(int val, int max) {
|
||||
return (val < max) ? val : max;
|
||||
}
|
||||
|
||||
public static int cubeRoot(int n) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static final int reverse(int b) {
|
||||
return reverseTab[b & 0xFF];
|
||||
}
|
||||
|
||||
public static int nextPowerOfTwo(int n) {
|
||||
n--;
|
||||
n |= n >> 1;
|
||||
n |= n >> 2;
|
||||
n |= n >> 4;
|
||||
n |= n >> 8;
|
||||
n |= n >> 16;
|
||||
n++;
|
||||
return n;
|
||||
}
|
||||
|
||||
public static final int abs(int val) {
|
||||
int sign = val >> 31;
|
||||
return (val ^ sign) - sign;
|
||||
}
|
||||
|
||||
public static final int golomb(int signedLevel) {
|
||||
if (signedLevel == 0)
|
||||
return 0;
|
||||
return (abs(signedLevel) << 1) - ((signedLevel ^ 0xFFFFFFFF) >>> 31);
|
||||
}
|
||||
|
||||
public static final int toSigned(int val, int sign) {
|
||||
return (val ^ sign) - sign;
|
||||
}
|
||||
|
||||
public static final int sign(int val) {
|
||||
return -(val >> 31);
|
||||
}
|
||||
|
||||
public static int wrap(int picNo, int maxFrames) {
|
||||
return (picNo < 0) ? (picNo + maxFrames) : ((picNo >= maxFrames) ? (picNo - maxFrames) : picNo);
|
||||
}
|
||||
|
||||
public static int max3(int a, int b, int c) {
|
||||
return Math.max(Math.max(a, b), c);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,226 @@
|
|||
package org.jcodec.common.tools;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import org.jcodec.common.IntArrayList;
|
||||
import org.jcodec.common.io.NIOUtils;
|
||||
|
||||
public class ToJSON {
|
||||
private static final Set<Class> primitive = new HashSet<>();
|
||||
|
||||
private static final Set<String> omitMethods = new HashSet<>();
|
||||
|
||||
static {
|
||||
primitive.add(Boolean.class);
|
||||
primitive.add(Byte.class);
|
||||
primitive.add(Short.class);
|
||||
primitive.add(Integer.class);
|
||||
primitive.add(Long.class);
|
||||
primitive.add(Float.class);
|
||||
primitive.add(Double.class);
|
||||
primitive.add(Character.class);
|
||||
omitMethods.add("getClass");
|
||||
omitMethods.add("get");
|
||||
}
|
||||
|
||||
public static String toJSON(Object obj) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
IntArrayList stack = IntArrayList.createIntArrayList();
|
||||
toJSONSub(obj, stack, builder);
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
private static void toJSONSub(Object obj, IntArrayList stack, StringBuilder builder) {
|
||||
if (obj == null) {
|
||||
builder.append("null");
|
||||
return;
|
||||
}
|
||||
String className = obj.getClass().getName();
|
||||
if (className.startsWith("java.lang") && !className.equals("java.lang.String")) {
|
||||
builder.append("null");
|
||||
return;
|
||||
}
|
||||
int id = System.identityHashCode(obj);
|
||||
if (stack.contains(id)) {
|
||||
builder.append("null");
|
||||
return;
|
||||
}
|
||||
stack.push(id);
|
||||
if (obj instanceof ByteBuffer)
|
||||
obj = NIOUtils.toArray((ByteBuffer)obj);
|
||||
if (obj == null) {
|
||||
builder.append("null");
|
||||
} else if (obj instanceof String) {
|
||||
builder.append("\"");
|
||||
escape((String)obj, builder);
|
||||
builder.append("\"");
|
||||
} else if (obj instanceof Map) {
|
||||
Iterator<Map.Entry> it = ((Map)obj).entrySet().iterator();
|
||||
builder.append("{");
|
||||
while (it.hasNext()) {
|
||||
Map.Entry e = it.next();
|
||||
builder.append("\"");
|
||||
builder.append(e.getKey());
|
||||
builder.append("\":");
|
||||
toJSONSub(e.getValue(), stack, builder);
|
||||
if (it.hasNext())
|
||||
builder.append(",");
|
||||
}
|
||||
builder.append("}");
|
||||
} else if (obj instanceof Iterable) {
|
||||
Iterator it = ((Iterable)obj).iterator();
|
||||
builder.append("[");
|
||||
while (it.hasNext()) {
|
||||
toJSONSub(it.next(), stack, builder);
|
||||
if (it.hasNext())
|
||||
builder.append(",");
|
||||
}
|
||||
builder.append("]");
|
||||
} else if (obj instanceof Object[]) {
|
||||
builder.append("[");
|
||||
int len = Array.getLength(obj);
|
||||
for (int i = 0; i < len; i++) {
|
||||
toJSONSub(Array.get(obj, i), stack, builder);
|
||||
if (i < len - 1)
|
||||
builder.append(",");
|
||||
}
|
||||
builder.append("]");
|
||||
} else if (obj instanceof long[]) {
|
||||
long[] a = (long[])obj;
|
||||
builder.append("[");
|
||||
for (int i = 0; i < a.length; i++) {
|
||||
builder.append(String.format("0x%016x", a[i]));
|
||||
if (i < a.length - 1)
|
||||
builder.append(",");
|
||||
}
|
||||
builder.append("]");
|
||||
} else if (obj instanceof int[]) {
|
||||
int[] a = (int[])obj;
|
||||
builder.append("[");
|
||||
for (int i = 0; i < a.length; i++) {
|
||||
builder.append(String.format("0x%08x", a[i]));
|
||||
if (i < a.length - 1)
|
||||
builder.append(",");
|
||||
}
|
||||
builder.append("]");
|
||||
} else if (obj instanceof float[]) {
|
||||
float[] a = (float[])obj;
|
||||
builder.append("[");
|
||||
for (int i = 0; i < a.length; i++) {
|
||||
builder.append(String.format("%.3f", a[i]));
|
||||
if (i < a.length - 1)
|
||||
builder.append(",");
|
||||
}
|
||||
builder.append("]");
|
||||
} else if (obj instanceof double[]) {
|
||||
double[] a = (double[])obj;
|
||||
builder.append("[");
|
||||
for (int i = 0; i < a.length; i++) {
|
||||
builder.append(String.format("%.6f", a[i]));
|
||||
if (i < a.length - 1)
|
||||
builder.append(",");
|
||||
}
|
||||
builder.append("]");
|
||||
} else if (obj instanceof short[]) {
|
||||
short[] a = (short[])obj;
|
||||
builder.append("[");
|
||||
for (int i = 0; i < a.length; i++) {
|
||||
builder.append(String.format("0x%04x", a[i]));
|
||||
if (i < a.length - 1)
|
||||
builder.append(",");
|
||||
}
|
||||
builder.append("]");
|
||||
} else if (obj instanceof byte[]) {
|
||||
byte[] a = (byte[])obj;
|
||||
builder.append("[");
|
||||
for (int i = 0; i < a.length; i++) {
|
||||
builder.append(String.format("0x%02x", a[i]));
|
||||
if (i < a.length - 1)
|
||||
builder.append(",");
|
||||
}
|
||||
builder.append("]");
|
||||
} else if (obj instanceof boolean[]) {
|
||||
boolean[] a = (boolean[])obj;
|
||||
builder.append("[");
|
||||
for (int i = 0; i < a.length; i++) {
|
||||
builder.append(a[i]);
|
||||
if (i < a.length - 1)
|
||||
builder.append(",");
|
||||
}
|
||||
builder.append("]");
|
||||
} else if (obj.getClass().isEnum()) {
|
||||
builder.append(String.valueOf(obj));
|
||||
} else {
|
||||
builder.append("{");
|
||||
Method[] methods = obj.getClass().getMethods();
|
||||
List<Method> filteredMethods = new ArrayList<>();
|
||||
for (Method method : methods) {
|
||||
if (!omitMethods.contains(method.getName()) && isGetter(method))
|
||||
filteredMethods.add(method);
|
||||
}
|
||||
Iterator<Method> iterator = filteredMethods.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
Method method = iterator.next();
|
||||
String name = toName(method);
|
||||
invoke(obj, stack, builder, method, name);
|
||||
if (iterator.hasNext())
|
||||
builder.append(",");
|
||||
}
|
||||
builder.append("}");
|
||||
}
|
||||
stack.pop();
|
||||
}
|
||||
|
||||
private static void invoke(Object obj, IntArrayList stack, StringBuilder builder, Method method, String name) {
|
||||
try {
|
||||
Object invoke = method.invoke(obj);
|
||||
builder.append('"');
|
||||
builder.append(name);
|
||||
builder.append("\":");
|
||||
if (invoke != null && primitive.contains(invoke.getClass())) {
|
||||
builder.append(invoke);
|
||||
} else {
|
||||
toJSONSub(invoke, stack, builder);
|
||||
}
|
||||
} catch (Exception e) {}
|
||||
}
|
||||
|
||||
private static void escape(String invoke, StringBuilder sb) {
|
||||
char[] ch = invoke.toCharArray();
|
||||
for (char c : ch) {
|
||||
if (c < ' ') {
|
||||
sb.append(String.format("\\%02x", Integer.valueOf(c)));
|
||||
} else {
|
||||
sb.append(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static String toName(Method method) {
|
||||
if (!isGetter(method))
|
||||
throw new IllegalArgumentException("Not a getter");
|
||||
char[] name = method.getName().toCharArray();
|
||||
int ind = (name[0] == 'g') ? 3 : 2;
|
||||
name[ind] = Character.toLowerCase(name[ind]);
|
||||
return new String(name, ind, name.length - ind);
|
||||
}
|
||||
|
||||
private static boolean isGetter(Method method) {
|
||||
if (!Modifier.isPublic(method.getModifiers()))
|
||||
return false;
|
||||
if (!method.getName().startsWith("get") && (
|
||||
!method.getName().startsWith("is") || method.getReturnType() != boolean.class))
|
||||
return false;
|
||||
if ((method.getParameterTypes()).length != 0)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
package org.jcodec.common.tools;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.ReadableByteChannel;
|
||||
import java.nio.channels.WritableByteChannel;
|
||||
import org.jcodec.codecs.wav.WavHeader;
|
||||
import org.jcodec.common.AudioUtil;
|
||||
import org.jcodec.common.io.IOUtils;
|
||||
import org.jcodec.common.io.NIOUtils;
|
||||
|
||||
public class WavMerge {
|
||||
public static void main1(String[] args) throws Exception {
|
||||
if (args.length < 3) {
|
||||
System.out.println("wavmerge <output wav> <input wav> .... <input wav>");
|
||||
System.exit(-1);
|
||||
}
|
||||
File out = new File(args[0]);
|
||||
File[] ins = new File[args.length - 1];
|
||||
for (int i = 1; i < args.length; i++)
|
||||
ins[i - 1] = new File(args[i]);
|
||||
merge(out, ins);
|
||||
}
|
||||
|
||||
public static void merge(File result, File[] src) throws IOException {
|
||||
WritableByteChannel out = null;
|
||||
ReadableByteChannel[] inputs = new ReadableByteChannel[src.length];
|
||||
WavHeader[] headers = new WavHeader[src.length];
|
||||
ByteBuffer[] ins = new ByteBuffer[src.length];
|
||||
try {
|
||||
int sampleSize = -1;
|
||||
for (int i = 0; i < src.length; i++) {
|
||||
inputs[i] = NIOUtils.readableChannel(src[i]);
|
||||
WavHeader hdr = WavHeader.readChannel(inputs[i]);
|
||||
if (sampleSize != -1 && sampleSize != hdr.fmt.bitsPerSample)
|
||||
throw new RuntimeException("Input files have different sample sizes");
|
||||
sampleSize = hdr.fmt.bitsPerSample;
|
||||
headers[i] = hdr;
|
||||
ins[i] = ByteBuffer.allocate(hdr.getFormat().framesToBytes(4096));
|
||||
}
|
||||
ByteBuffer outb = ByteBuffer.allocate(headers[0].getFormat().framesToBytes(4096) * src.length);
|
||||
WavHeader newHeader = WavHeader.multiChannelWav(headers);
|
||||
out = NIOUtils.writableChannel(result);
|
||||
newHeader.write(out);
|
||||
boolean readOnce = true;
|
||||
while (true) {
|
||||
readOnce = false;
|
||||
for (int j = 0; j < ins.length; j++) {
|
||||
if (inputs[j] != null) {
|
||||
ins[j].clear();
|
||||
if (inputs[j].read(ins[j]) == -1) {
|
||||
NIOUtils.closeQuietly(inputs[j]);
|
||||
inputs[j] = null;
|
||||
} else {
|
||||
readOnce = true;
|
||||
}
|
||||
ins[j].flip();
|
||||
}
|
||||
}
|
||||
if (!readOnce)
|
||||
break;
|
||||
outb.clear();
|
||||
AudioUtil.interleave(headers[0].getFormat(), ins, outb);
|
||||
outb.flip();
|
||||
out.write(outb);
|
||||
}
|
||||
} finally {
|
||||
IOUtils.closeQuietly(out);
|
||||
for (ReadableByteChannel inputStream : inputs)
|
||||
IOUtils.closeQuietly(inputStream);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
package org.jcodec.common.tools;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.ReadableByteChannel;
|
||||
import java.util.Arrays;
|
||||
import org.jcodec.codecs.wav.WavHeader;
|
||||
import org.jcodec.common.AudioFormat;
|
||||
import org.jcodec.common.AudioUtil;
|
||||
import org.jcodec.common.Preconditions;
|
||||
import org.jcodec.common.io.FileChannelWrapper;
|
||||
import org.jcodec.common.io.NIOUtils;
|
||||
import org.jcodec.common.io.SeekableByteChannel;
|
||||
|
||||
public class WavSplit {
|
||||
public static final MainUtils.Flag FLAG_PATTERN = MainUtils.Flag.flag("pattern", "p", "Output file name pattern, i.e. out%02d.wav");
|
||||
|
||||
private static final MainUtils.Flag[] ALL_FLAGS = new MainUtils.Flag[] { FLAG_PATTERN };
|
||||
|
||||
public static void main1(String[] args) throws Exception {
|
||||
MainUtils.Cmd cmd = MainUtils.parseArguments(args, ALL_FLAGS);
|
||||
if (cmd.argsLength() < 1) {
|
||||
MainUtils.printHelp(ALL_FLAGS, Arrays.asList("filename.wav"));
|
||||
System.exit(-1);
|
||||
}
|
||||
File s = new File(args[0]);
|
||||
String pattern = cmd.getStringFlagD(FLAG_PATTERN, "c%02d.wav");
|
||||
WavHeader wavHeader = WavHeader.read(s);
|
||||
System.out.println("WAV: " + String.valueOf(wavHeader.getFormat()));
|
||||
Preconditions.checkState((2 == wavHeader.fmt.numChannels));
|
||||
int dataOffset = wavHeader.dataOffset;
|
||||
FileChannelWrapper is = NIOUtils.readableChannel(s);
|
||||
is.setPosition((long)dataOffset);
|
||||
int channels = wavHeader.getFormat().getChannels();
|
||||
SeekableByteChannel[] out = new SeekableByteChannel[channels];
|
||||
for (int j = 0; j < channels; j++) {
|
||||
out[j] = NIOUtils.writableChannel(new File(s.getParentFile(), String.format(pattern, j)));
|
||||
WavHeader.copyWithChannels(wavHeader, 1).write(out[j]);
|
||||
}
|
||||
copy(wavHeader.getFormat(), is, out);
|
||||
for (int i = 0; i < channels; i++)
|
||||
out[i].close();
|
||||
}
|
||||
|
||||
private static void copy(AudioFormat format, ReadableByteChannel is, SeekableByteChannel[] out) throws IOException {
|
||||
ByteBuffer[] outs = new ByteBuffer[out.length];
|
||||
for (int i = 0; i < out.length; i++)
|
||||
outs[i] = ByteBuffer.allocate(format.framesToBytes(4096));
|
||||
ByteBuffer inb = ByteBuffer.allocate(format.framesToBytes(4096) * out.length);
|
||||
while (is.read(inb) != -1) {
|
||||
inb.flip();
|
||||
AudioUtil.deinterleave(format, inb, outs);
|
||||
inb.clear();
|
||||
for (int j = 0; j < out.length; j++) {
|
||||
outs[j].flip();
|
||||
out[j].write(outs[j]);
|
||||
outs[j].clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue