183 lines
7.0 KiB
Java
183 lines
7.0 KiB
Java
package com.mojang.blaze3d.platform;
|
|
|
|
import java.io.EOFException;
|
|
import java.nio.channels.ReadableByteChannel;
|
|
import java.nio.ByteBuffer;
|
|
import org.lwjgl.system.MemoryUtil;
|
|
import java.nio.channels.Channels;
|
|
import java.nio.channels.SeekableByteChannel;
|
|
import java.io.FileInputStream;
|
|
import java.nio.IntBuffer;
|
|
import java.io.IOException;
|
|
import org.lwjgl.stb.STBImage;
|
|
import org.lwjgl.stb.STBIEOFCallbackI;
|
|
import org.lwjgl.stb.STBISkipCallbackI;
|
|
import org.lwjgl.stb.STBIReadCallbackI;
|
|
import org.lwjgl.stb.STBIIOCallbacks;
|
|
import org.lwjgl.stb.STBIEOFCallback;
|
|
import org.lwjgl.stb.STBISkipCallback;
|
|
import org.lwjgl.stb.STBIReadCallback;
|
|
import org.lwjgl.system.MemoryStack;
|
|
import java.io.InputStream;
|
|
|
|
public class PngInfo {
|
|
public final int width;
|
|
public final int height;
|
|
|
|
public PngInfo(final String string, final InputStream inputStream) throws IOException {
|
|
try (final MemoryStack memoryStack4 = MemoryStack.stackPush();
|
|
final StbReader a6 = createCallbacks(inputStream);
|
|
final STBIReadCallback sTBIReadCallback8 = STBIReadCallback.create(a6::read);
|
|
final STBISkipCallback sTBISkipCallback10 = STBISkipCallback.create(a6::skip);
|
|
final STBIEOFCallback sTBIEOFCallback12 = STBIEOFCallback.create(a6::eof)) {
|
|
final STBIIOCallbacks sTBIIOCallbacks14 = STBIIOCallbacks.mallocStack(memoryStack4);
|
|
sTBIIOCallbacks14.read((STBIReadCallbackI)sTBIReadCallback8);
|
|
sTBIIOCallbacks14.skip((STBISkipCallbackI)sTBISkipCallback10);
|
|
sTBIIOCallbacks14.eof((STBIEOFCallbackI)sTBIEOFCallback12);
|
|
final IntBuffer intBuffer15 = memoryStack4.mallocInt(1);
|
|
final IntBuffer intBuffer16 = memoryStack4.mallocInt(1);
|
|
final IntBuffer intBuffer17 = memoryStack4.mallocInt(1);
|
|
if (!STBImage.stbi_info_from_callbacks(sTBIIOCallbacks14, 0L, intBuffer15, intBuffer16, intBuffer17)) {
|
|
throw new IOException("Could not read info from the PNG file " + string + " " + STBImage.stbi_failure_reason());
|
|
}
|
|
this.width = intBuffer15.get(0);
|
|
this.height = intBuffer16.get(0);
|
|
}
|
|
}
|
|
|
|
private static StbReader createCallbacks(final InputStream inputStream) {
|
|
if (inputStream instanceof FileInputStream) {
|
|
return new StbReaderSeekableByteChannel((SeekableByteChannel)((FileInputStream)inputStream).getChannel());
|
|
}
|
|
return new StbReaderBufferedChannel(Channels.newChannel(inputStream));
|
|
}
|
|
|
|
abstract static class StbReader implements AutoCloseable {
|
|
protected boolean closed;
|
|
|
|
private StbReader() {
|
|
}
|
|
|
|
int read(final long long1, final long long2, final int integer) {
|
|
try {
|
|
return this.read(long2, integer);
|
|
}
|
|
catch (IOException iOException7) {
|
|
this.closed = true;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
void skip(final long long1, final int integer) {
|
|
try {
|
|
this.skip(integer);
|
|
}
|
|
catch (IOException iOException5) {
|
|
this.closed = true;
|
|
}
|
|
}
|
|
|
|
int eof(final long long1) {
|
|
return this.closed ? 1 : 0;
|
|
}
|
|
|
|
protected abstract int read(final long long1, final int integer) throws IOException;
|
|
|
|
protected abstract void skip(final int integer) throws IOException;
|
|
|
|
@Override
|
|
public abstract void close() throws IOException;
|
|
}
|
|
|
|
static class StbReaderSeekableByteChannel extends StbReader {
|
|
private final SeekableByteChannel channel;
|
|
|
|
private StbReaderSeekableByteChannel(final SeekableByteChannel seekableByteChannel) {
|
|
this.channel = seekableByteChannel;
|
|
}
|
|
|
|
public int read(final long long1, final int integer) throws IOException {
|
|
final ByteBuffer byteBuffer5 = MemoryUtil.memByteBuffer(long1, integer);
|
|
return this.channel.read(byteBuffer5);
|
|
}
|
|
|
|
public void skip(final int integer) throws IOException {
|
|
this.channel.position(this.channel.position() + integer);
|
|
}
|
|
|
|
public int eof(final long long1) {
|
|
return (super.eof(long1) != 0 && this.channel.isOpen()) ? 1 : 0;
|
|
}
|
|
|
|
@Override
|
|
public void close() throws IOException {
|
|
this.channel.close();
|
|
}
|
|
}
|
|
|
|
static class StbReaderBufferedChannel extends StbReader {
|
|
private final ReadableByteChannel channel;
|
|
private long readBufferAddress;
|
|
private int bufferSize;
|
|
private int read;
|
|
private int consumed;
|
|
|
|
private StbReaderBufferedChannel(final ReadableByteChannel readableByteChannel) {
|
|
this.readBufferAddress = MemoryUtil.nmemAlloc(128L);
|
|
this.bufferSize = 128;
|
|
this.channel = readableByteChannel;
|
|
}
|
|
|
|
private void fillReadBuffer(final int integer) throws IOException {
|
|
ByteBuffer byteBuffer3 = MemoryUtil.memByteBuffer(this.readBufferAddress, this.bufferSize);
|
|
if (integer + this.consumed > this.bufferSize) {
|
|
this.bufferSize = integer + this.consumed;
|
|
byteBuffer3 = MemoryUtil.memRealloc(byteBuffer3, this.bufferSize);
|
|
this.readBufferAddress = MemoryUtil.memAddress(byteBuffer3);
|
|
}
|
|
byteBuffer3.position(this.read);
|
|
while (integer + this.consumed > this.read) {
|
|
try {
|
|
final int integer2 = this.channel.read(byteBuffer3);
|
|
if (integer2 == -1) {
|
|
break;
|
|
}
|
|
continue;
|
|
}
|
|
finally {
|
|
this.read = byteBuffer3.position();
|
|
}
|
|
}
|
|
}
|
|
|
|
public int read(final long long1, int integer) throws IOException {
|
|
this.fillReadBuffer(integer);
|
|
if (integer + this.consumed > this.read) {
|
|
integer = this.read - this.consumed;
|
|
}
|
|
MemoryUtil.memCopy(this.readBufferAddress + this.consumed, long1, (long)integer);
|
|
this.consumed += integer;
|
|
return integer;
|
|
}
|
|
|
|
public void skip(final int integer) throws IOException {
|
|
if (integer > 0) {
|
|
this.fillReadBuffer(integer);
|
|
if (integer + this.consumed > this.read) {
|
|
throw new EOFException("Can't skip past the EOF.");
|
|
}
|
|
}
|
|
if (this.consumed + integer < 0) {
|
|
throw new IOException("Can't seek before the beginning: " + (this.consumed + integer));
|
|
}
|
|
this.consumed += integer;
|
|
}
|
|
|
|
@Override
|
|
public void close() throws IOException {
|
|
MemoryUtil.nmemFree(this.readBufferAddress);
|
|
this.channel.close();
|
|
}
|
|
}
|
|
}
|