www in docker support

This commit is contained in:
MaddoScientisto 2026-04-22 18:41:37 +02:00
commit c227fce036
2145 changed files with 399596 additions and 58 deletions

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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;
}

View file

@ -0,0 +1,7 @@
package org.jcodec.common;
import java.nio.ByteBuffer;
public interface AudioEncoder {
ByteBuffer encode(ByteBuffer paramByteBuffer1, ByteBuffer paramByteBuffer2);
}

View file

@ -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);
}
}

View file

@ -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());
}
}
}
}

View file

@ -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);
}
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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();
}

View file

@ -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();
}

View file

@ -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;
}
}

View file

@ -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;
}
}
}

View file

@ -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);
}
}

View file

@ -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");
}

View file

@ -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;
}
}

View file

@ -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;
}
}
}

View file

@ -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];
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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("\\.[^\\.]+$", "");
}
}

View file

@ -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;
}
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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();
}
}

View file

@ -0,0 +1,7 @@
package org.jcodec.common;
import java.util.concurrent.Callable;
public interface PriorityCallable<T> extends Callable<T> {
int getPriority();
}

View file

@ -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;
}
}
}

View file

@ -0,0 +1,7 @@
package org.jcodec.common;
public interface SaveRestore {
void save();
void restore();
}

View file

@ -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;
}

View file

@ -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;
}
}

View file

@ -0,0 +1,5 @@
package org.jcodec.common;
public enum TrackType {
VIDEO, AUDIO, TEXT, OTHER;
}

View file

@ -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);
}
}

View file

@ -0,0 +1,3 @@
package org.jcodec.common;
public @interface UsedViaReflection {}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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() {}
}

View file

@ -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;
}
}
}

View file

@ -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]);
}
}

View file

@ -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);
}
}
}
}

View file

@ -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);
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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);
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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();
}

View file

@ -0,0 +1,5 @@
package org.jcodec.common.io;
public interface AutoResource {
void setCurTime(long paramLong);
}

View file

@ -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);
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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;
}
}

View file

@ -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);
}
}
}

View file

@ -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);
}
}

View file

@ -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;
}

View file

@ -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);
}
}

View file

@ -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;
}
}

View file

@ -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));
}
};
}
}

View file

@ -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;
}
}

View file

@ -0,0 +1,5 @@
package org.jcodec.common.logging;
public enum LogLevel {
DEBUG, INFO, WARN, ERROR;
}

View file

@ -0,0 +1,5 @@
package org.jcodec.common.logging;
public interface LogSink {
void postMessage(Message paramMessage);
}

View file

@ -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);
}
}

View file

@ -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;
}
}

View file

@ -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);
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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;
}

View file

@ -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);
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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);
}
}

View file

@ -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 + "]";
}
}

View file

@ -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;
}
}

View file

@ -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);
}
}

View file

@ -0,0 +1,5 @@
package org.jcodec.common.model;
public enum Unit {
FRAME, SEC;
}

View file

@ -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);
}
}

View file

@ -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]);
}
}

View file

@ -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;
}
}

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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;
}
}

View file

@ -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);
}
}
}

View file

@ -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();
}
}
}
}