mirror of
https://github.com/haraldk/TwelveMonkeys.git
synced 2025-08-03 19:45:28 -04:00
JPEGLosslessDecoder: Support for various component count.
This commit is contained in:
parent
ce7fb1cb94
commit
c924f284a0
@ -66,10 +66,7 @@ final class JPEGLosslessDecoder {
|
||||
private int xLoc;
|
||||
private int yLoc;
|
||||
private int mask;
|
||||
private int[] outputData;
|
||||
private int[] outputRedData;
|
||||
private int[] outputGreenData;
|
||||
private int[] outputBlueData;
|
||||
private int[][] outputData;
|
||||
|
||||
private static final int IDCT_P[] = {
|
||||
0, 5, 40, 16, 45, 2, 7, 42,
|
||||
@ -146,8 +143,6 @@ final class JPEGLosslessDecoder {
|
||||
|
||||
int[][] decode() throws IOException {
|
||||
int current, scanNum = 0;
|
||||
final int pred[] = new int[10];
|
||||
int[][] outputRef;
|
||||
|
||||
xLoc = 0;
|
||||
yLoc = 0;
|
||||
@ -216,32 +211,27 @@ final class JPEGLosslessDecoder {
|
||||
xDim = frame.samplesPerLine;
|
||||
yDim = frame.lines;
|
||||
|
||||
outputRef = new int[numComp][];
|
||||
outputData = new int[numComp][];
|
||||
|
||||
// TODO: Support 4 components (RGBA/YCCA/CMYK/YCCK), others?
|
||||
if (numComp == 1) {
|
||||
outputData = new int[xDim * yDim];
|
||||
outputRef[0] = outputData;
|
||||
for (int componentIndex = 0; componentIndex < numComp; ++componentIndex) {
|
||||
// not a good use of memory, but I had trouble packing bytes into int. some values exceeded 255.
|
||||
outputData[componentIndex] = new int[xDim * yDim];
|
||||
}
|
||||
else {
|
||||
outputRedData = new int[xDim * yDim]; // not a good use of memory, but I had trouble packing bytes into int. some values exceeded 255.
|
||||
outputGreenData = new int[xDim * yDim];
|
||||
outputBlueData = new int[xDim * yDim];
|
||||
|
||||
outputRef[0] = outputRedData;
|
||||
outputRef[1] = outputGreenData;
|
||||
outputRef[2] = outputBlueData;
|
||||
final int firstValue[] = new int[numComp];
|
||||
for (int i = 0; i < numComp; i++) {
|
||||
firstValue[i] = (1 << (precision - 1));
|
||||
}
|
||||
|
||||
final int pred[] = new int[numComp];
|
||||
|
||||
scanNum++;
|
||||
|
||||
while (true) { // Decode one scan
|
||||
int temp[] = new int[1]; // to store remainder bits
|
||||
int index[] = new int[1];
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
pred[i] = (1 << (precision - 1));
|
||||
}
|
||||
System.arraycopy(firstValue, 0, pred, 0, numComp);
|
||||
|
||||
if (restartInterval == 0) {
|
||||
current = decode(pred, temp, index);
|
||||
@ -283,9 +273,10 @@ final class JPEGLosslessDecoder {
|
||||
readNumber();
|
||||
current = input.readUnsignedShort();
|
||||
}
|
||||
// TODO oe: 05.05.2018 Is it correct loop? Content of outputData from previous iteration is always lost.
|
||||
} while ((current != JPEG.EOI) && ((xLoc < xDim) && (yLoc < yDim)) && (scanNum == 0));
|
||||
|
||||
return outputRef;
|
||||
return outputData;
|
||||
}
|
||||
|
||||
private void processWarningOccured(String warning) {
|
||||
@ -339,7 +330,7 @@ final class JPEGLosslessDecoder {
|
||||
return decodeRGB(prev, temp, index);
|
||||
}
|
||||
else {
|
||||
return -1;
|
||||
return decodeAny(prev, temp, index);
|
||||
}
|
||||
}
|
||||
|
||||
@ -351,6 +342,7 @@ final class JPEGLosslessDecoder {
|
||||
prev[0] = (1 << (frame.samplePrecision - 1));
|
||||
}
|
||||
else {
|
||||
final int[] outputData = this.outputData[0];
|
||||
switch (selection) {
|
||||
case 2:
|
||||
prev[0] = getPreviousY(outputData);
|
||||
@ -397,6 +389,9 @@ final class JPEGLosslessDecoder {
|
||||
}
|
||||
|
||||
private int decodeRGB(final int prev[], final int temp[], final int index[]) throws IOException {
|
||||
final int[] outputRedData = outputData[0];
|
||||
final int[] outputGreenData = outputData[1];
|
||||
final int[] outputBlueData = outputData[2];
|
||||
switch (selection) {
|
||||
case 2:
|
||||
prev[0] = getPreviousY(outputRedData);
|
||||
@ -435,6 +430,43 @@ final class JPEGLosslessDecoder {
|
||||
break;
|
||||
}
|
||||
|
||||
return decode0(prev, temp, index);
|
||||
}
|
||||
|
||||
private int decodeAny(final int prev[], final int temp[], final int index[]) throws IOException {
|
||||
for (int componentIndex = 0; componentIndex < outputData.length; ++componentIndex) {
|
||||
final int[] outputData = this.outputData[componentIndex];
|
||||
final int previous;
|
||||
switch (selection) {
|
||||
case 2:
|
||||
previous = getPreviousY(outputData);
|
||||
break;
|
||||
case 3:
|
||||
previous = getPreviousXY(outputData);
|
||||
break;
|
||||
case 4:
|
||||
previous = (getPreviousX(outputData) + getPreviousY(outputData)) - getPreviousXY(outputData);
|
||||
break;
|
||||
case 5:
|
||||
previous = getPreviousX(outputData) + ((getPreviousY(outputData) - getPreviousXY(outputData)) >> 1);
|
||||
break;
|
||||
case 6:
|
||||
previous = getPreviousY(outputData) + ((getPreviousX(outputData) - getPreviousXY(outputData)) >> 1);
|
||||
break;
|
||||
case 7:
|
||||
previous = (int) (((long) getPreviousX(outputData) + getPreviousY(outputData)) / 2);
|
||||
break;
|
||||
default:
|
||||
previous = getPreviousX(outputData);
|
||||
break;
|
||||
}
|
||||
prev[componentIndex] = previous;
|
||||
}
|
||||
|
||||
return decode0(prev, temp, index);
|
||||
}
|
||||
|
||||
private int decode0(int[] prev, int[] temp, int[] index) throws IOException {
|
||||
int value, actab[], dctab[];
|
||||
int qtab[];
|
||||
|
||||
@ -692,14 +724,17 @@ final class JPEGLosslessDecoder {
|
||||
if (numComp == 1) {
|
||||
outputSingle(pred);
|
||||
}
|
||||
else {
|
||||
else if (numComp == 3) {
|
||||
outputRGB(pred);
|
||||
}
|
||||
else {
|
||||
outputAny(pred);
|
||||
}
|
||||
}
|
||||
|
||||
private void outputSingle(final int pred[]) {
|
||||
if ((xLoc < xDim) && (yLoc < yDim)) {
|
||||
outputData[(yLoc * xDim) + xLoc] = mask & pred[0];
|
||||
outputData[0][(yLoc * xDim) + xLoc] = mask & pred[0];
|
||||
xLoc++;
|
||||
|
||||
if (xLoc >= xDim) {
|
||||
@ -711,9 +746,25 @@ final class JPEGLosslessDecoder {
|
||||
|
||||
private void outputRGB(final int pred[]) {
|
||||
if ((xLoc < xDim) && (yLoc < yDim)) {
|
||||
outputRedData[(yLoc * xDim) + xLoc] = pred[0];
|
||||
outputGreenData[(yLoc * xDim) + xLoc] = pred[1];
|
||||
outputBlueData[(yLoc * xDim) + xLoc] = pred[2];
|
||||
final int index = (yLoc * xDim) + xLoc;
|
||||
outputData[0][index] = pred[0];
|
||||
outputData[1][index] = pred[1];
|
||||
outputData[2][index] = pred[2];
|
||||
xLoc++;
|
||||
|
||||
if (xLoc >= xDim) {
|
||||
yLoc++;
|
||||
xLoc = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void outputAny(final int pred[]) {
|
||||
if ((xLoc < xDim) && (yLoc < yDim)) {
|
||||
final int index = (yLoc * xDim) + xLoc;
|
||||
for (int componentIndex = 0; componentIndex < outputData.length; ++componentIndex) {
|
||||
outputData[componentIndex][index] = pred[componentIndex];
|
||||
}
|
||||
xLoc++;
|
||||
|
||||
if (xLoc >= xDim) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user