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