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