Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 1 addition & 5 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,6 @@ configurations {
}

repositories {
maven {
name = "JitPack"
url = "https://jitpack.io/"
}
maven {
name = "DaPorkchop_"
url = "https://maven.daporkchop.net/"
Expand All @@ -61,7 +57,7 @@ dependencies {
transitive = false
}

shade "com.github.DaMatrix:commons-imaging:4c6c5dfe6401a884cb4cf53fb838c99e1dfb104c"
shade "org.apache.commons:commons-imaging:1.0.0-alpha5"

shade "com.fasterxml.jackson.core:jackson-databind:2.11.2"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import net.buildtheearth.terraplusplus.config.scalarparse.d.FromIntDSP;
import net.buildtheearth.terraplusplus.config.scalarparse.d.MultiplyDSP;
import net.buildtheearth.terraplusplus.config.scalarparse.d.ParseTiffAutoDSP;
import net.buildtheearth.terraplusplus.config.scalarparse.d.ParseTiffDSP;
import net.buildtheearth.terraplusplus.config.scalarparse.d.ParseTiffFloatingPointDSP;
import net.buildtheearth.terraplusplus.config.scalarparse.d.ParseTerrariumPngDSP;
import net.buildtheearth.terraplusplus.config.scalarparse.d.ParseTiffIntDSP;
Expand Down Expand Up @@ -111,8 +112,9 @@ public class GlobalParseRegistries {
.put("flip_z", FlipZDSP.class)
.put("from_int", FromIntDSP.class)
.put("swap_axes", SwapAxesDSP.class)
//parse operators
//parse operators (including deprecated ParseTiffXXXXDSPs)
.put("parse_png_terrarium", ParseTerrariumPngDSP.class)
.put("parse_tiff", ParseTiffDSP.class)
.put("parse_tiff_auto", ParseTiffAutoDSP.class)
.put("parse_tiff_fp", ParseTiffFloatingPointDSP.class)
.put("parse_tiff_int", ParseTiffIntDSP.class)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,156 +1,22 @@
package net.buildtheearth.terraplusplus.config.scalarparse.d;

import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufInputStream;
import lombok.NonNull;
import lombok.SneakyThrows;
import org.apache.commons.imaging.FormatCompliance;
import org.apache.commons.imaging.ImageReadException;
import org.apache.commons.imaging.common.ImageBuilder;
import org.apache.commons.imaging.common.bytesource.ByteSourceInputStream;
import org.apache.commons.imaging.formats.tiff.TiffContents;
import org.apache.commons.imaging.formats.tiff.TiffDirectory;
import org.apache.commons.imaging.formats.tiff.TiffField;
import org.apache.commons.imaging.formats.tiff.TiffRasterData;
import org.apache.commons.imaging.formats.tiff.TiffReader;
import org.apache.commons.imaging.formats.tiff.constants.GdalLibraryTagConstants;
import org.apache.commons.imaging.formats.tiff.constants.TiffConstants;
import org.apache.commons.imaging.formats.tiff.constants.TiffTagConstants;
import org.apache.commons.imaging.formats.tiff.photometricinterpreters.PhotometricInterpreter;
import sun.awt.image.IntegerComponentRaster;
import net.buildtheearth.terraplusplus.TerraMod;

import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Collections;
import java.util.stream.DoubleStream;

import static net.daporkchop.lib.common.util.PValidation.*;

/**
* @author DaPorkchop_
* Parses scalar data from TIFF files.
*
* @deprecated floating point and integer specific TIFF implementations were made irrelevant
* by Apache Commons imaging supporting them both ina unified way.
* Use {@link ParseTiffDSP} instead, this class may be removed in future releases.
*/
@JsonDeserialize
public class ParseTiffAutoDSP implements DoubleScalarParser {
@Override
@SneakyThrows(ImageReadException.class)
public double[] parse(int resolution, @NonNull ByteBuf buffer) throws IOException {
TiffContents contents = new TiffReader(false)
.readDirectories(new ByteSourceInputStream(new ByteBufInputStream(buffer), ""), true, FormatCompliance.getDefault());

double[] dst = new double[resolution * resolution];
TiffDirectory directory = this.parse(resolution, contents, dst);
this.postProcess(resolution, directory, dst);
return dst;
}

protected void postProcess(int resolution, @NonNull TiffDirectory directory, @NonNull double[] dst) throws ImageReadException, IOException {
TiffField nodataField = directory.findField(GdalLibraryTagConstants.EXIF_TAG_GDAL_NO_DATA);
if (nodataField != null) { //nodata value is set, replace all nodata values
double nodata = Double.parseDouble(nodataField.getStringValue());
for (int i = 0; i < dst.length; i++) {
if (dst[i] == nodata) {
dst[i] = Double.NaN;
}
}
}
}
@Deprecated
public class ParseTiffAutoDSP extends ParseTiffDSP {

protected TiffDirectory parse(int resolution, @NonNull TiffContents contents, @NonNull double[] dst) throws ImageReadException, IOException {
for (TiffDirectory directory : contents.directories) {
if (this.parse(resolution, directory, dst)) {
return directory;
}
}
throw new IllegalArgumentException("no supported TIFF directories could be found!");
public ParseTiffAutoDSP() {
TerraMod.LOGGER.warn("parse_tiff_auto and ParseTiffAutoDSP are deprecated. Use parse_tiff and ParseTiffDSP instead");
}

protected boolean parse(int resolution, @NonNull TiffDirectory directory, @NonNull double[] dst) throws ImageReadException, IOException {
switch (directory.getFieldValue(TiffTagConstants.TIFF_TAG_PHOTOMETRIC_INTERPRETATION)) {
case TiffTagConstants.PHOTOMETRIC_INTERPRETATION_VALUE_WHITE_IS_ZERO:
case TiffTagConstants.PHOTOMETRIC_INTERPRETATION_VALUE_BLACK_IS_ZERO:
break; //grayscale
default:
return false; //colored formats aren't supported lol
}

short[] bitsPerSample = directory.getFieldValue(TiffTagConstants.TIFF_TAG_BITS_PER_SAMPLE, true);
if (bitsPerSample.length != 1) {
return false; //more than one channel
}

switch (directory.findField(TiffTagConstants.TIFF_TAG_SAMPLE_FORMAT, true).getIntValue()) {
case TiffTagConstants.SAMPLE_FORMAT_VALUE_IEEE_FLOATING_POINT:
return this.parseFloatingPoint(resolution, directory, dst);
case TiffTagConstants.SAMPLE_FORMAT_VALUE_UNSIGNED_INTEGER:
case TiffTagConstants.SAMPLE_FORMAT_VALUE_TWOS_COMPLEMENT_SIGNED_INTEGER:
return this.parseInteger(resolution, directory, dst);
default:
return false;
}
}

protected boolean parseFloatingPoint(int resolution, @NonNull TiffDirectory directory, @NonNull double[] dst) throws ImageReadException, IOException {
//extract floating-point raster data
TiffRasterData data = directory.getFloatingPointRasterData(null);
int w = data.getWidth();
int h = data.getHeight();
checkArg(w == resolution && h == resolution, "invalid image resolution: %dx%d (expected: %dx%3$d)", w, h, resolution);

//extend floats to doubles
float[] src = data.getData();
checkArg(src.length == dst.length, "data length invalid?!?");
for (int i = 0; i < resolution * resolution; i++) {
dst[i] = src[i];
}

return true;
}

protected boolean parseInteger(int resolution, @NonNull TiffDirectory directory, @NonNull double[] dst) throws ImageReadException, IOException {
//extract raw integer raster data
BufferedImage img = directory.getTiffImage(Collections.singletonMap(TiffConstants.PARAM_KEY_CUSTOM_PHOTOMETRIC_INTERPRETER,
new PhotometricInterpreter(0, null, 0, 0, 0) {
@Override
public void interpretPixel(ImageBuilder imageBuilder, int[] samples, int x, int y) throws ImageReadException, IOException {
imageBuilder.setRGB(x, y, samples[0]);
}

@Override
public boolean isRaw() {
return true;
}
}));
int w = img.getWidth();
int h = img.getHeight();
checkArg(w == resolution && h == resolution, "invalid image resolution: %dx%d (expected: %dx%3$d)", w, h, resolution);

//compute shift and mask
int bitsPerSample = directory.findField(TiffTagConstants.TIFF_TAG_BITS_PER_SAMPLE, true).getIntValue();
int sampleFormat = directory.findField(TiffTagConstants.TIFF_TAG_SAMPLE_FORMAT, true).getIntValue();

long shift, mask;
switch (sampleFormat) {
case TiffTagConstants.SAMPLE_FORMAT_VALUE_UNSIGNED_INTEGER:
checkArg(positive(bitsPerSample, "bitsPerSample") < Long.SIZE - 1, "bitsPerSample (%d) must be at most %d!", bitsPerSample, Long.SIZE - 1);
mask = Long.MAX_VALUE;
shift = 0L;
break;
case TiffTagConstants.SAMPLE_FORMAT_VALUE_TWOS_COMPLEMENT_SIGNED_INTEGER:
checkArg(positive(bitsPerSample, "bitsPerSample") < Long.SIZE, "bitsPerSample (%d) must be at most %d!", bitsPerSample, Long.SIZE);
mask = 0xFFFFFFFFFFFFFFFFL;
shift = Long.SIZE - bitsPerSample;
break;
default:
throw new IllegalArgumentException("unsupported sample format: " + sampleFormat);
}

int[] src = ((IntegerComponentRaster) img.getRaster()).getDataStorage();
checkArg(src.length == dst.length, "data length invalid?!?");
for (int i = 0; i < dst.length; i++) {
dst[i] = (src[i] & mask) << shift >> shift;
}

return true;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
package net.buildtheearth.terraplusplus.config.scalarparse.d;

import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufInputStream;
import lombok.NonNull;
import org.apache.commons.imaging.FormatCompliance;
import org.apache.commons.imaging.ImagingException;
import org.apache.commons.imaging.bytesource.ByteSource;
import org.apache.commons.imaging.formats.tiff.*;
import org.apache.commons.imaging.formats.tiff.constants.GdalLibraryTagConstants;

import java.io.IOException;

import static net.daporkchop.lib.common.util.PValidation.checkArg;
import static org.apache.commons.imaging.formats.tiff.constants.TiffTagConstants.*;

/**
* Parses integer or floating-point scalar data from single-channel TIFF images, to double arrays.
*
* @author DaPorkchop_
* @author Smyler
*/
@JsonDeserialize
public class ParseTiffDSP implements DoubleScalarParser {

@Override
public double[] parse(int resolution, @NonNull ByteBuf buffer) throws IOException {
ByteSource source = ByteSource.inputStream(new ByteBufInputStream(buffer), "");
TiffContents contents = new TiffReader(false).readDirectories(source, true, FormatCompliance.getDefault());

double[] dst = new double[resolution * resolution];
TiffDirectory directory = this.parse(resolution, contents, dst);
this.postProcess(resolution, directory, dst);
return dst;
}

protected void postProcess(int resolution, @NonNull TiffDirectory directory, double @NonNull [] dst) throws IOException {
TiffField nodataField = directory.findField(GdalLibraryTagConstants.EXIF_TAG_GDAL_NO_DATA);
if (nodataField != null) { //nodata value is set, replace all nodata values
double nodata = Double.parseDouble(nodataField.getStringValue());
for (int i = 0; i < dst.length; i++) {
if (dst[i] == nodata) {
dst[i] = Double.NaN;
}
}
}
}

protected TiffDirectory parse(int resolution, @NonNull TiffContents contents, double @NonNull [] dst) throws IOException {
for (TiffDirectory directory : contents.directories) {
if (this.parse(resolution, directory, dst)) {
return directory;
}
}
throw new IllegalArgumentException("no supported TIFF directories could be found!");
}

protected boolean parse(int resolution, @NonNull TiffDirectory directory, double @NonNull [] dst) throws IOException {
if (!this.isSupportedFormat(directory)) {
return false;
}

TiffRasterData data = directory.getRasterData(null);
int w = data.getWidth();
int h = data.getHeight();
checkArg(w == resolution && h == resolution, "invalid image resolution: %dx%d (expected: %dx%3$d)", w, h, resolution);

//extend floats to doubles
float[] src = data.getData();
checkArg(src.length == dst.length, "data length invalid?!?");
for (int i = 0; i < resolution * resolution; i++) {
dst[i] = src[i];
}

return true;
}

/**
* Verify whether this is a supported format (single-channel grayscale, encoded as IEEE 754, integers, or signed integers).
*
* @param directory the TIFF directory to check
* @return true if the directory can be safely processed, false otherwise
*
* @throws ImagingException if the directory is missing required fields
*/
protected boolean isSupportedFormat(TiffDirectory directory) throws ImagingException {
switch (directory.getFieldValue(TIFF_TAG_PHOTOMETRIC_INTERPRETATION)) {
case PHOTOMETRIC_INTERPRETATION_VALUE_WHITE_IS_ZERO:
case PHOTOMETRIC_INTERPRETATION_VALUE_BLACK_IS_ZERO:
break; //grayscale
default:
return false; //colored formats aren't supported lol
}
short[] bitsPerSample = directory.getFieldValue(TIFF_TAG_BITS_PER_SAMPLE, true);
if (bitsPerSample.length != 1) {
return false; //more than one channel
}
switch (directory.findField(TIFF_TAG_SAMPLE_FORMAT, true).getIntValue()) {
case SAMPLE_FORMAT_VALUE_UNSIGNED_INTEGER:
case SAMPLE_FORMAT_VALUE_TWOS_COMPLEMENT_SIGNED_INTEGER:
case SAMPLE_FORMAT_VALUE_IEEE_FLOATING_POINT:
break;
default:
return false;
}
return true;
}

}
Original file line number Diff line number Diff line change
@@ -1,19 +1,22 @@
package net.buildtheearth.terraplusplus.config.scalarparse.d;

import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import lombok.NonNull;
import org.apache.commons.imaging.ImageReadException;
import org.apache.commons.imaging.formats.tiff.TiffDirectory;
import net.buildtheearth.terraplusplus.TerraMod;

import java.io.IOException;

/**
* @author DaPorkchop_
* Parses floating point scalar data from TIFF files.
*
* @deprecated floating point and integer specific TIFF implementations were made irrelevant
* by Apache Commons imaging supporting them both ina unified way. Use {@link ParseTiffDSP} instead,
* this class may be removed in future releases.
*/
@JsonDeserialize
public class ParseTiffFloatingPointDSP extends ParseTiffAutoDSP {
@Override
protected boolean parseInteger(int resolution, @NonNull TiffDirectory directory, @NonNull double[] dst) throws ImageReadException, IOException {
return false;
@Deprecated
public class ParseTiffFloatingPointDSP extends ParseTiffDSP {

public ParseTiffFloatingPointDSP() {
TerraMod.LOGGER.warn("parse_tiff_fp and ParseTiffFloatingPointDSP are deprecated. Use parse_tiff and ParseTiffDSP instead");
}

}
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
package net.buildtheearth.terraplusplus.config.scalarparse.d;

import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import lombok.NonNull;
import org.apache.commons.imaging.ImageReadException;
import org.apache.commons.imaging.formats.tiff.TiffDirectory;

import java.io.IOException;
import net.buildtheearth.terraplusplus.TerraMod;

/**
* @author DaPorkchop_
* Parses int scalar data from TIFF files.
*
* @deprecated floating point and integer specific TIFF implementations were made irrelevant
* by Apache Commons imaging supporting them both ina unified way.
* Use {@link ParseTiffDSP} instead, this class may be removed in future releases.
*/
@JsonDeserialize
@Deprecated
public class ParseTiffIntDSP extends ParseTiffAutoDSP {
@Override
protected boolean parseFloatingPoint(int resolution, @NonNull TiffDirectory directory, @NonNull double[] dst) throws ImageReadException, IOException {
return false;

public ParseTiffIntDSP() {
TerraMod.LOGGER.warn("parse_tiff_int and ParseTiffIntDSP are deprecated. Use parse_tiff and ParseTiffDSP instead");
}

}
Loading