commit
af536353d5
372
src/core/jpx.js
372
src/core/jpx.js
@ -108,7 +108,7 @@ var JpxImage = (function JpxImageClosure() {
|
|||||||
// Image and tile size (SIZ)
|
// Image and tile size (SIZ)
|
||||||
if (code == 0xFF51) {
|
if (code == 0xFF51) {
|
||||||
stream.skip(4);
|
stream.skip(4);
|
||||||
var Xsiz = stream.getUint32(); // Byte 4
|
var Xsiz = stream.getUint32(); // Byte 4
|
||||||
var Ysiz = stream.getUint32(); // Byte 8
|
var Ysiz = stream.getUint32(); // Byte 8
|
||||||
var XOsiz = stream.getUint32(); // Byte 12
|
var XOsiz = stream.getUint32(); // Byte 12
|
||||||
var YOsiz = stream.getUint32(); // Byte 16
|
var YOsiz = stream.getUint32(); // Byte 16
|
||||||
@ -117,7 +117,7 @@ var JpxImage = (function JpxImageClosure() {
|
|||||||
this.width = Xsiz - XOsiz;
|
this.width = Xsiz - XOsiz;
|
||||||
this.height = Ysiz - YOsiz;
|
this.height = Ysiz - YOsiz;
|
||||||
this.componentsCount = Csiz;
|
this.componentsCount = Csiz;
|
||||||
// Results are always returned as UInt8Arrays
|
// Results are always returned as UInt8Arrays
|
||||||
this.bitsPerComponent = 8;
|
this.bitsPerComponent = 8;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -491,10 +491,10 @@ var JpxImage = (function JpxImageClosure() {
|
|||||||
var ycb_ = dimensions.ycb_;
|
var ycb_ = dimensions.ycb_;
|
||||||
var codeblockWidth = 1 << xcb_;
|
var codeblockWidth = 1 << xcb_;
|
||||||
var codeblockHeight = 1 << ycb_;
|
var codeblockHeight = 1 << ycb_;
|
||||||
var cbx0 = Math.floor(subband.tbx0 / codeblockWidth);
|
var cbx0 = subband.tbx0 >> xcb_;
|
||||||
var cby0 = Math.floor(subband.tby0 / codeblockHeight);
|
var cby0 = subband.tby0 >> ycb_;
|
||||||
var cbx1 = Math.ceil(subband.tbx1 / codeblockWidth);
|
var cbx1 = (subband.tbx1 + codeblockWidth - 1) >> xcb_;
|
||||||
var cby1 = Math.ceil(subband.tby1 / codeblockHeight);
|
var cby1 = (subband.tby1 + codeblockHeight - 1) >> ycb_;
|
||||||
var precinctParameters = subband.resolution.precinctParameters;
|
var precinctParameters = subband.resolution.precinctParameters;
|
||||||
var codeblocks = [];
|
var codeblocks = [];
|
||||||
var precincts = [];
|
var precincts = [];
|
||||||
@ -528,13 +528,18 @@ var JpxImage = (function JpxImageClosure() {
|
|||||||
codeblock.Lblock = 3;
|
codeblock.Lblock = 3;
|
||||||
codeblocks.push(codeblock);
|
codeblocks.push(codeblock);
|
||||||
// building precinct for the sub-band
|
// building precinct for the sub-band
|
||||||
var precinct;
|
var precinct = precincts[precinctNumber];
|
||||||
if (precinctNumber in precincts) {
|
if (precinct !== undefined) {
|
||||||
precinct = precincts[precinctNumber];
|
if (i < precinct.cbxMin) {
|
||||||
precinct.cbxMin = Math.min(precinct.cbxMin, i);
|
precinct.cbxMin = i;
|
||||||
precinct.cbyMin = Math.min(precinct.cbyMin, j);
|
} else if (i > precinct.cbxMax) {
|
||||||
precinct.cbxMax = Math.max(precinct.cbxMax, i);
|
precinct.cbxMax = i;
|
||||||
precinct.cbyMax = Math.max(precinct.cbyMax, j);
|
}
|
||||||
|
if (j < precinct.cbyMin) {
|
||||||
|
precinct.cbxMin = j;
|
||||||
|
} else if (j > precinct.cbyMax) {
|
||||||
|
precinct.cbyMax = j;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
precincts[precinctNumber] = precinct = {
|
precincts[precinctNumber] = precinct = {
|
||||||
cbxMin: i,
|
cbxMin: i,
|
||||||
@ -553,10 +558,6 @@ var JpxImage = (function JpxImageClosure() {
|
|||||||
numcodeblockhigh: cby1 - cby1 + 1
|
numcodeblockhigh: cby1 - cby1 + 1
|
||||||
};
|
};
|
||||||
subband.codeblocks = codeblocks;
|
subband.codeblocks = codeblocks;
|
||||||
for (var i = 0, ii = codeblocks.length; i < ii; i++) {
|
|
||||||
var codeblock = codeblocks[i];
|
|
||||||
var precinctNumber = codeblock.precinctNumber;
|
|
||||||
}
|
|
||||||
subband.precincts = precincts;
|
subband.precincts = precincts;
|
||||||
}
|
}
|
||||||
function createPacket(resolution, precinctNumber, layerNumber) {
|
function createPacket(resolution, precinctNumber, layerNumber) {
|
||||||
@ -972,13 +973,18 @@ var JpxImage = (function JpxImageClosure() {
|
|||||||
var magnitudeCorrection = reversible ? 0 : 0.5;
|
var magnitudeCorrection = reversible ? 0 : 0.5;
|
||||||
for (var j = 0; j < blockHeight; j++) {
|
for (var j = 0; j < blockHeight; j++) {
|
||||||
for (var k = 0; k < blockWidth; k++) {
|
for (var k = 0; k < blockWidth; k++) {
|
||||||
var mag = magnitude[position];
|
n = magnitude[position];
|
||||||
if (mag !== 0) {
|
if (n !== 0) {
|
||||||
n = sign[position] ? -(mag + magnitudeCorrection) :
|
n = (n + magnitudeCorrection) * delta;
|
||||||
(mag + magnitudeCorrection);
|
if (sign[position] !== 0) {
|
||||||
|
n = -n;
|
||||||
|
}
|
||||||
nb = bitsDecoded[position];
|
nb = bitsDecoded[position];
|
||||||
correction = (irreversible || mb > nb) ? 1 << (mb - nb) : 1;
|
if (irreversible || mb > nb) {
|
||||||
coefficients[offset] = n * correction * delta;
|
coefficients[offset] = n * (1 << (mb - nb));
|
||||||
|
} else {
|
||||||
|
coefficients[offset] = n;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
offset++;
|
offset++;
|
||||||
position++;
|
position++;
|
||||||
@ -1076,10 +1082,10 @@ var JpxImage = (function JpxImageClosure() {
|
|||||||
var y1items = result[1].items;
|
var y1items = result[1].items;
|
||||||
var y2items = result[2].items;
|
var y2items = result[2].items;
|
||||||
for (var j = 0, jj = y0items.length; j < jj; ++j) {
|
for (var j = 0, jj = y0items.length; j < jj; ++j) {
|
||||||
var y0 = y0items[j], y1 = y1items[j], y2 = y2items[j];
|
var y0 = y0items[j] + 0.5, y1 = y1items[j], y2 = y2items[j];
|
||||||
y0items[j] = y0 + 1.402 * y2 + 0.5;
|
y0items[j] = y0 + 1.402 * y2;
|
||||||
y1items[j] = y0 - 0.34413 * y1 - 0.71414 * y2 + 0.5;
|
y1items[j] = y0 - 0.34413 * y1 - 0.71414 * y2;
|
||||||
y2items[j] = y0 + 1.772 * y1 + 0.5;
|
y2items[j] = y0 + 1.772 * y1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// inverse reversible multiple component transform
|
// inverse reversible multiple component transform
|
||||||
@ -1096,32 +1102,18 @@ var JpxImage = (function JpxImageClosure() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Section G.1 DC level shifting to unsigned component values
|
|
||||||
for (var c = 0; c < componentsCount; c++) {
|
|
||||||
var component = components[c];
|
|
||||||
if (component.isSigned) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
var offset = 1 << (component.precision - 1);
|
|
||||||
var tileImage = result[c];
|
|
||||||
var items = tileImage.items;
|
|
||||||
for (var j = 0, jj = items.length; j < jj; j++) {
|
|
||||||
items[j] += offset;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// To simplify things: shift and clamp output to 8 bit unsigned
|
// To simplify things: shift and clamp output to 8 bit unsigned
|
||||||
for (var c = 0; c < componentsCount; c++) {
|
for (var c = 0; c < componentsCount; c++) {
|
||||||
var component = components[c];
|
var component = components[c];
|
||||||
var offset = component.isSigned ? 128 : 0;
|
|
||||||
var shift = component.precision - 8;
|
var shift = component.precision - 8;
|
||||||
var tileImage = result[c];
|
var tileImage = result[c];
|
||||||
var items = tileImage.items;
|
var items = tileImage.items;
|
||||||
var data = new Uint8Array(items.length);
|
var data = new Uint8Array(items.length);
|
||||||
|
var low = -(128 << shift);
|
||||||
|
var high = 127 << shift;
|
||||||
for (var j = 0, jj = items.length; j < jj; j++) {
|
for (var j = 0, jj = items.length; j < jj; j++) {
|
||||||
var value = (items[j] >> shift) + offset;
|
var val = items[j];
|
||||||
data[j] = value < 0 ? 0 : value > 255 ? 255 : value;
|
data[j] = val <= low ? 0 : val >= high ? 255 : (val >> shift) + 128;
|
||||||
}
|
}
|
||||||
result[c].items = data;
|
result[c].items = data;
|
||||||
}
|
}
|
||||||
@ -1311,31 +1303,6 @@ var JpxImage = (function JpxImageClosure() {
|
|||||||
8, 0, 8, 8, 8, 0, 8, 8, 8, 0, 0, 0, 0, 0, 8, 8, 8, 0, 8, 8, 8, 0, 8, 8, 8
|
8, 0, 8, 8, 8, 0, 8, 8, 8, 0, 0, 0, 0, 0, 8, 8, 8, 0, 8, 8, 8, 0, 8, 8, 8
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// Table D-2
|
|
||||||
function calcSignContribution(significance0, sign0, significance1, sign1) {
|
|
||||||
if (significance1) {
|
|
||||||
if (!sign1) {
|
|
||||||
return significance0 ? (!sign0 ? 1 : 0) : 1;
|
|
||||||
} else {
|
|
||||||
return significance0 ? (!sign0 ? 0 : -1) : -1;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return significance0 ? (!sign0 ? 1 : -1) : 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Table D-3
|
|
||||||
var SignContextLabels = [
|
|
||||||
{contextLabel: 13, xorBit: 0},
|
|
||||||
{contextLabel: 12, xorBit: 0},
|
|
||||||
{contextLabel: 11, xorBit: 0},
|
|
||||||
{contextLabel: 10, xorBit: 0},
|
|
||||||
{contextLabel: 9, xorBit: 0},
|
|
||||||
{contextLabel: 10, xorBit: 1},
|
|
||||||
{contextLabel: 11, xorBit: 1},
|
|
||||||
{contextLabel: 12, xorBit: 1},
|
|
||||||
{contextLabel: 13, xorBit: 1}
|
|
||||||
];
|
|
||||||
|
|
||||||
function BitModel(width, height, subband, zeroBitPlanes) {
|
function BitModel(width, height, subband, zeroBitPlanes) {
|
||||||
this.width = width;
|
this.width = width;
|
||||||
this.height = height;
|
this.height = height;
|
||||||
@ -1352,9 +1319,11 @@ var JpxImage = (function JpxImageClosure() {
|
|||||||
this.coefficentsMagnitude = new Uint32Array(coefficientCount);
|
this.coefficentsMagnitude = new Uint32Array(coefficientCount);
|
||||||
this.processingFlags = new Uint8Array(coefficientCount);
|
this.processingFlags = new Uint8Array(coefficientCount);
|
||||||
|
|
||||||
var bitsDecoded = new Uint8Array(this.width * this.height);
|
var bitsDecoded = new Uint8Array(coefficientCount);
|
||||||
for (var i = 0, ii = bitsDecoded.length; i < ii; i++) {
|
if (zeroBitPlanes !== 0) {
|
||||||
bitsDecoded[i] = zeroBitPlanes;
|
for (var i = 0; i < coefficientCount; i++) {
|
||||||
|
bitsDecoded[i] = zeroBitPlanes;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
this.bitsDecoded = bitsDecoded;
|
this.bitsDecoded = bitsDecoded;
|
||||||
|
|
||||||
@ -1366,7 +1335,7 @@ var JpxImage = (function JpxImageClosure() {
|
|||||||
this.decoder = decoder;
|
this.decoder = decoder;
|
||||||
},
|
},
|
||||||
reset: function BitModel_reset() {
|
reset: function BitModel_reset() {
|
||||||
// We have 17 contexts that are accessed via context labels,
|
// We have 17 contexts that are accessed via context labels,
|
||||||
// plus the uniform and runlength context.
|
// plus the uniform and runlength context.
|
||||||
this.contexts = new Int8Array(19);
|
this.contexts = new Int8Array(19);
|
||||||
|
|
||||||
@ -1377,32 +1346,38 @@ var JpxImage = (function JpxImageClosure() {
|
|||||||
this.contexts[RUNLENGTH_CONTEXT] = (3 << 1) | 0;
|
this.contexts[RUNLENGTH_CONTEXT] = (3 << 1) | 0;
|
||||||
},
|
},
|
||||||
setNeighborsSignificance:
|
setNeighborsSignificance:
|
||||||
function BitModel_setNeighborsSignificance(row, column) {
|
function BitModel_setNeighborsSignificance(row, column, index) {
|
||||||
var neighborsSignificance = this.neighborsSignificance;
|
var neighborsSignificance = this.neighborsSignificance;
|
||||||
var width = this.width, height = this.height;
|
var width = this.width, height = this.height;
|
||||||
var index = row * width + column;
|
var left = (column > 0);
|
||||||
|
var right = (column + 1 < width);
|
||||||
|
|
||||||
if (row > 0) {
|
if (row > 0) {
|
||||||
if (column > 0) {
|
var i = index - width;
|
||||||
neighborsSignificance[index - width - 1] += 0x10;
|
if (left) {
|
||||||
|
neighborsSignificance[i - 1] += 0x10;
|
||||||
}
|
}
|
||||||
if (column + 1 < width) {
|
if (right) {
|
||||||
neighborsSignificance[index - width + 1] += 0x10;
|
neighborsSignificance[i + 1] += 0x10;
|
||||||
}
|
}
|
||||||
neighborsSignificance[index - width] += 0x04;
|
neighborsSignificance[i] += 0x04;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (row + 1 < height) {
|
if (row + 1 < height) {
|
||||||
if (column > 0) {
|
var i = index + width;
|
||||||
neighborsSignificance[index + width - 1] += 0x10;
|
if (left) {
|
||||||
|
neighborsSignificance[i - 1] += 0x10;
|
||||||
}
|
}
|
||||||
if (column + 1 < width) {
|
if (right) {
|
||||||
neighborsSignificance[index + width + 1] += 0x10;
|
neighborsSignificance[i + 1] += 0x10;
|
||||||
}
|
}
|
||||||
neighborsSignificance[index + width] += 0x04;
|
neighborsSignificance[i] += 0x04;
|
||||||
}
|
}
|
||||||
if (column > 0) {
|
|
||||||
|
if (left) {
|
||||||
neighborsSignificance[index - 1] += 0x01;
|
neighborsSignificance[index - 1] += 0x01;
|
||||||
}
|
}
|
||||||
if (column + 1 < width) {
|
if (right) {
|
||||||
neighborsSignificance[index + 1] += 0x01;
|
neighborsSignificance[index + 1] += 0x01;
|
||||||
}
|
}
|
||||||
neighborsSignificance[index] |= 0x80;
|
neighborsSignificance[index] |= 0x80;
|
||||||
@ -1419,13 +1394,9 @@ var JpxImage = (function JpxImageClosure() {
|
|||||||
var contexts = this.contexts;
|
var contexts = this.contexts;
|
||||||
var labels = this.contextLabelTable;
|
var labels = this.contextLabelTable;
|
||||||
var bitsDecoded = this.bitsDecoded;
|
var bitsDecoded = this.bitsDecoded;
|
||||||
// clear processed flag
|
|
||||||
var processedInverseMask = ~1;
|
var processedInverseMask = ~1;
|
||||||
var processedMask = 1;
|
var processedMask = 1;
|
||||||
var firstMagnitudeBitMask = 2;
|
var firstMagnitudeBitMask = 2;
|
||||||
for (var q = 0, qq = width * height; q < qq; q++) {
|
|
||||||
processingFlags[q] &= processedInverseMask;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (var i0 = 0; i0 < height; i0 += 4) {
|
for (var i0 = 0; i0 < height; i0 += 4) {
|
||||||
for (var j = 0; j < width; j++) {
|
for (var j = 0; j < width; j++) {
|
||||||
@ -1435,6 +1406,8 @@ var JpxImage = (function JpxImageClosure() {
|
|||||||
if (i >= height) {
|
if (i >= height) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
// clear processed flag first
|
||||||
|
processingFlags[index] &= processedInverseMask;
|
||||||
|
|
||||||
if (coefficentsMagnitude[index] ||
|
if (coefficentsMagnitude[index] ||
|
||||||
!neighborsSignificance[index]) {
|
!neighborsSignificance[index]) {
|
||||||
@ -1444,10 +1417,10 @@ var JpxImage = (function JpxImageClosure() {
|
|||||||
var contextLabel = labels[neighborsSignificance[index]];
|
var contextLabel = labels[neighborsSignificance[index]];
|
||||||
var decision = decoder.readBit(contexts, contextLabel);
|
var decision = decoder.readBit(contexts, contextLabel);
|
||||||
if (decision) {
|
if (decision) {
|
||||||
var sign = this.decodeSignBit(i, j);
|
var sign = this.decodeSignBit(i, j, index);
|
||||||
coefficentsSign[index] = sign;
|
coefficentsSign[index] = sign;
|
||||||
coefficentsMagnitude[index] = 1;
|
coefficentsMagnitude[index] = 1;
|
||||||
this.setNeighborsSignificance(i, j);
|
this.setNeighborsSignificance(i, j, index);
|
||||||
processingFlags[index] |= firstMagnitudeBitMask;
|
processingFlags[index] |= firstMagnitudeBitMask;
|
||||||
}
|
}
|
||||||
bitsDecoded[index]++;
|
bitsDecoded[index]++;
|
||||||
@ -1456,27 +1429,55 @@ var JpxImage = (function JpxImageClosure() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
decodeSignBit: function BitModel_decodeSignBit(row, column) {
|
decodeSignBit: function BitModel_decodeSignBit(row, column, index) {
|
||||||
var width = this.width, height = this.height;
|
var width = this.width, height = this.height;
|
||||||
var index = row * width + column;
|
|
||||||
var coefficentsMagnitude = this.coefficentsMagnitude;
|
var coefficentsMagnitude = this.coefficentsMagnitude;
|
||||||
var coefficentsSign = this.coefficentsSign;
|
var coefficentsSign = this.coefficentsSign;
|
||||||
var horizontalContribution = calcSignContribution(
|
var contribution, sign0, sign1, significance1;
|
||||||
column > 0 && coefficentsMagnitude[index - 1],
|
|
||||||
coefficentsSign[index - 1],
|
|
||||||
column + 1 < width && coefficentsMagnitude[index + 1],
|
|
||||||
coefficentsSign[index + 1]);
|
|
||||||
var verticalContribution = calcSignContribution(
|
|
||||||
row > 0 && coefficentsMagnitude[index - width],
|
|
||||||
coefficentsSign[index - width],
|
|
||||||
row + 1 < height && coefficentsMagnitude[index + width],
|
|
||||||
coefficentsSign[index + width]);
|
|
||||||
|
|
||||||
var contextLabelAndXor = SignContextLabels[
|
// calculate horizontal contribution
|
||||||
3 * (1 - horizontalContribution) + (1 - verticalContribution)];
|
significance1 = (column > 0 && coefficentsMagnitude[index - 1] !== 0);
|
||||||
var contextLabel = contextLabelAndXor.contextLabel;
|
if (column + 1 < width && coefficentsMagnitude[index + 1] !== 0) {
|
||||||
var decoded = this.decoder.readBit(this.contexts, contextLabel);
|
sign1 = coefficentsSign[index + 1];
|
||||||
return decoded ^ contextLabelAndXor.xorBit;
|
if (significance1) {
|
||||||
|
sign0 = coefficentsSign[index - 1];
|
||||||
|
contribution = 1 - sign1 - sign0;
|
||||||
|
} else {
|
||||||
|
contribution = 1 - sign1 - sign1;
|
||||||
|
}
|
||||||
|
} else if (significance1) {
|
||||||
|
sign0 = coefficentsSign[index - 1];
|
||||||
|
contribution = 1 - sign0 - sign0;
|
||||||
|
} else {
|
||||||
|
contribution = 0;
|
||||||
|
}
|
||||||
|
var horizontalContribution = 3 * contribution;
|
||||||
|
|
||||||
|
// calculate vertical contribution and combine with the horizontal
|
||||||
|
significance1 = (row > 0 && coefficentsMagnitude[index - width] !== 0);
|
||||||
|
if (row + 1 < height && coefficentsMagnitude[index + width] !== 0) {
|
||||||
|
sign1 = coefficentsSign[index + width];
|
||||||
|
if (significance1) {
|
||||||
|
sign0 = coefficentsSign[index - width];
|
||||||
|
contribution = 1 - sign1 - sign0 + horizontalContribution;
|
||||||
|
} else {
|
||||||
|
contribution = 1 - sign1 - sign1 + horizontalContribution;
|
||||||
|
}
|
||||||
|
} else if (significance1) {
|
||||||
|
sign0 = coefficentsSign[index - width];
|
||||||
|
contribution = 1 - sign0 - sign0 + horizontalContribution;
|
||||||
|
} else {
|
||||||
|
contribution = horizontalContribution;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (contribution >= 0) {
|
||||||
|
var contextLabel = 9 + contribution;
|
||||||
|
var decoded = this.decoder.readBit(this.contexts, contextLabel);
|
||||||
|
} else {
|
||||||
|
var contextLabel = 9 - contribution;
|
||||||
|
var decoded = this.decoder.readBit(this.contexts, contextLabel) ^ 1;
|
||||||
|
}
|
||||||
|
return decoded;
|
||||||
},
|
},
|
||||||
runMagnitudeRefinementPass:
|
runMagnitudeRefinementPass:
|
||||||
function BitModel_runMagnitudeRefinementPass() {
|
function BitModel_runMagnitudeRefinementPass() {
|
||||||
@ -1489,14 +1490,13 @@ var JpxImage = (function JpxImageClosure() {
|
|||||||
var processingFlags = this.processingFlags;
|
var processingFlags = this.processingFlags;
|
||||||
var processedMask = 1;
|
var processedMask = 1;
|
||||||
var firstMagnitudeBitMask = 2;
|
var firstMagnitudeBitMask = 2;
|
||||||
for (var i0 = 0; i0 < height; i0 += 4) {
|
var length = width * height;
|
||||||
|
var width4 = width * 4;
|
||||||
|
|
||||||
|
for (var index0 = 0, indexNext; index0 < length; index0 = indexNext) {
|
||||||
|
indexNext = Math.min(length, index0 + width4);
|
||||||
for (var j = 0; j < width; j++) {
|
for (var j = 0; j < width; j++) {
|
||||||
for (var i1 = 0; i1 < 4; i1++) {
|
for (var index = index0 + j; index < indexNext; index += width) {
|
||||||
var i = i0 + i1;
|
|
||||||
if (i >= height) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
var index = i * width + j;
|
|
||||||
|
|
||||||
// significant but not those that have just become
|
// significant but not those that have just become
|
||||||
if (!coefficentsMagnitude[index] ||
|
if (!coefficentsMagnitude[index] ||
|
||||||
@ -1506,12 +1506,10 @@ var JpxImage = (function JpxImageClosure() {
|
|||||||
|
|
||||||
var contextLabel = 16;
|
var contextLabel = 16;
|
||||||
if ((processingFlags[index] & firstMagnitudeBitMask) !== 0) {
|
if ((processingFlags[index] & firstMagnitudeBitMask) !== 0) {
|
||||||
processingFlags[i * width + j] ^= firstMagnitudeBitMask;
|
processingFlags[index] ^= firstMagnitudeBitMask;
|
||||||
// first refinement
|
// first refinement
|
||||||
var significance = neighborsSignificance[index];
|
var significance = neighborsSignificance[index] & 127;
|
||||||
var sumOfSignificance = (significance & 3) +
|
contextLabel = significance === 0 ? 15 : 14;
|
||||||
((significance >> 2) & 3) + ((significance >> 4) & 7);
|
|
||||||
contextLabel = sumOfSignificance >= 1 ? 15 : 14;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var bit = decoder.readBit(contexts, contextLabel);
|
var bit = decoder.readBit(contexts, contextLabel);
|
||||||
@ -1570,10 +1568,10 @@ var JpxImage = (function JpxImageClosure() {
|
|||||||
i = i0 + i1;
|
i = i0 + i1;
|
||||||
index += i1 * width;
|
index += i1 * width;
|
||||||
|
|
||||||
var sign = this.decodeSignBit(i, j);
|
var sign = this.decodeSignBit(i, j, index);
|
||||||
coefficentsSign[index] = sign;
|
coefficentsSign[index] = sign;
|
||||||
coefficentsMagnitude[index] = 1;
|
coefficentsMagnitude[index] = 1;
|
||||||
this.setNeighborsSignificance(i, j);
|
this.setNeighborsSignificance(i, j, index);
|
||||||
processingFlags[index] |= firstMagnitudeBitMask;
|
processingFlags[index] |= firstMagnitudeBitMask;
|
||||||
|
|
||||||
index = index0;
|
index = index0;
|
||||||
@ -1597,10 +1595,10 @@ var JpxImage = (function JpxImageClosure() {
|
|||||||
var contextLabel = labels[neighborsSignificance[index]];
|
var contextLabel = labels[neighborsSignificance[index]];
|
||||||
var decision = decoder.readBit(contexts, contextLabel);
|
var decision = decoder.readBit(contexts, contextLabel);
|
||||||
if (decision == 1) {
|
if (decision == 1) {
|
||||||
var sign = this.decodeSignBit(i, j);
|
var sign = this.decodeSignBit(i, j, index);
|
||||||
coefficentsSign[index] = sign;
|
coefficentsSign[index] = sign;
|
||||||
coefficentsMagnitude[index] = 1;
|
coefficentsMagnitude[index] = 1;
|
||||||
this.setNeighborsSignificance(i, j);
|
this.setNeighborsSignificance(i, j, index);
|
||||||
processingFlags[index] |= firstMagnitudeBitMask;
|
processingFlags[index] |= firstMagnitudeBitMask;
|
||||||
}
|
}
|
||||||
bitsDecoded[index]++;
|
bitsDecoded[index]++;
|
||||||
@ -1631,7 +1629,7 @@ var JpxImage = (function JpxImageClosure() {
|
|||||||
Transform.prototype.calculate =
|
Transform.prototype.calculate =
|
||||||
function transformCalculate(subbands, u0, v0) {
|
function transformCalculate(subbands, u0, v0) {
|
||||||
var ll = subbands[0];
|
var ll = subbands[0];
|
||||||
for (var i = 1, ii = subbands.length, j = 1; i < ii; i += 3, j++) {
|
for (var i = 1, ii = subbands.length; i < ii; i += 3) {
|
||||||
ll = this.iterate(ll, subbands[i], subbands[i + 1],
|
ll = this.iterate(ll, subbands[i], subbands[i + 1],
|
||||||
subbands[i + 2], u0, v0);
|
subbands[i + 2], u0, v0);
|
||||||
}
|
}
|
||||||
@ -1692,21 +1690,24 @@ var JpxImage = (function JpxImageClosure() {
|
|||||||
var rowBuffer = new Float32Array(width + 2 * bufferPadding);
|
var rowBuffer = new Float32Array(width + 2 * bufferPadding);
|
||||||
|
|
||||||
// Section F.3.4 HOR_SR
|
// Section F.3.4 HOR_SR
|
||||||
for (var v = 0; v < height; v++) {
|
if (width === 1) {
|
||||||
if (width == 1) {
|
// if width = 1, when u0 even keep items as is, when odd divide by 2
|
||||||
// if width = 1, when u0 even keep items as is, when odd divide by 2
|
if ((u0 & 1) !== 0) {
|
||||||
if ((u0 % 1) !== 0) {
|
for (var v = 0, k = 0; v < height; v++, k += width) {
|
||||||
items[v * width] /= 2;
|
items[k] *= 0.5;
|
||||||
}
|
}
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
k = v * width;
|
} else {
|
||||||
rowBuffer.set(items.subarray(k, k + width), bufferPadding);
|
for (var v = 0, k = 0; v < height; v++, k += width) {
|
||||||
|
rowBuffer.set(items.subarray(k, k + width), bufferPadding);
|
||||||
|
|
||||||
this.extend(rowBuffer, bufferPadding, width);
|
this.extend(rowBuffer, bufferPadding, width);
|
||||||
this.filter(rowBuffer, bufferPadding, width, u0, rowBuffer);
|
this.filter(rowBuffer, bufferPadding, width, u0, rowBuffer);
|
||||||
|
|
||||||
items.set(rowBuffer.subarray(bufferPadding, bufferPadding + width), k);
|
items.set(
|
||||||
|
rowBuffer.subarray(bufferPadding, bufferPadding + width),
|
||||||
|
k);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Accesses to the items array can take long, because it may not fit into
|
// Accesses to the items array can take long, because it may not fit into
|
||||||
@ -1723,37 +1724,38 @@ var JpxImage = (function JpxImageClosure() {
|
|||||||
var b, currentBuffer = 0, ll = bufferPadding + height;
|
var b, currentBuffer = 0, ll = bufferPadding + height;
|
||||||
|
|
||||||
// Section F.3.5 VER_SR
|
// Section F.3.5 VER_SR
|
||||||
for (var u = 0; u < width; u++) {
|
if (height === 1) {
|
||||||
if (height == 1) {
|
|
||||||
// if height = 1, when v0 even keep items as is, when odd divide by 2
|
// if height = 1, when v0 even keep items as is, when odd divide by 2
|
||||||
if ((v0 % 1) !== 0) {
|
if ((v0 & 1) !== 0) {
|
||||||
items[u] /= 2;
|
for (var u = 0; u < width; u++) {
|
||||||
|
items[u] *= 0.5;
|
||||||
}
|
}
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
// if we ran out of buffers, copy several image columns at once
|
for (var u = 0; u < width; u++) {
|
||||||
if (currentBuffer === 0) {
|
// if we ran out of buffers, copy several image columns at once
|
||||||
numBuffers = Math.min(width - u, numBuffers);
|
if (currentBuffer === 0) {
|
||||||
for (k = u, l = bufferPadding; l < ll; k += width, l++) {
|
numBuffers = Math.min(width - u, numBuffers);
|
||||||
for (b = 0; b < numBuffers; b++) {
|
for (k = u, l = bufferPadding; l < ll; k += width, l++) {
|
||||||
colBuffers[b][l] = items[k + b];
|
for (b = 0; b < numBuffers; b++) {
|
||||||
|
colBuffers[b][l] = items[k + b];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
currentBuffer = numBuffers;
|
||||||
}
|
}
|
||||||
currentBuffer = numBuffers;
|
|
||||||
}
|
|
||||||
|
|
||||||
currentBuffer--;
|
currentBuffer--;
|
||||||
var buffer = colBuffers[currentBuffer];
|
var buffer = colBuffers[currentBuffer];
|
||||||
this.extend(buffer, bufferPadding, height);
|
this.extend(buffer, bufferPadding, height);
|
||||||
this.filter(buffer, bufferPadding, height, v0, buffer);
|
this.filter(buffer, bufferPadding, height, v0, buffer);
|
||||||
|
|
||||||
// If this is last buffer in this group of buffers, flush all buffers.
|
// If this is last buffer in this group of buffers, flush all buffers.
|
||||||
if (currentBuffer === 0) {
|
if (currentBuffer === 0) {
|
||||||
k = u - numBuffers + 1;
|
k = u - numBuffers + 1;
|
||||||
for (l = bufferPadding; l < ll; k += width, l++) {
|
for (l = bufferPadding; l < ll; k += width, l++) {
|
||||||
for (b = 0; b < numBuffers; b++) {
|
for (b = 0; b < numBuffers; b++) {
|
||||||
items[k + b] = colBuffers[b][l];
|
items[k + b] = colBuffers[b][l];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1777,9 +1779,8 @@ var JpxImage = (function JpxImageClosure() {
|
|||||||
IrreversibleTransform.prototype = Object.create(Transform.prototype);
|
IrreversibleTransform.prototype = Object.create(Transform.prototype);
|
||||||
IrreversibleTransform.prototype.filter =
|
IrreversibleTransform.prototype.filter =
|
||||||
function irreversibleTransformFilter(y, offset, length, i0, x) {
|
function irreversibleTransformFilter(y, offset, length, i0, x) {
|
||||||
var i0_ = Math.floor(i0 / 2);
|
var len = length >> 1;
|
||||||
var i1_ = Math.floor((i0 + length) / 2);
|
var offset = offset | 0;
|
||||||
var offset_ = offset - (i0 % 1);
|
|
||||||
|
|
||||||
var alpha = -1.586134342059924;
|
var alpha = -1.586134342059924;
|
||||||
var beta = -0.052980118572961;
|
var beta = -0.052980118572961;
|
||||||
@ -1788,39 +1789,31 @@ var JpxImage = (function JpxImageClosure() {
|
|||||||
var K = 1.230174104914001;
|
var K = 1.230174104914001;
|
||||||
var K_ = 1 / K;
|
var K_ = 1 / K;
|
||||||
|
|
||||||
// step 1
|
// step 1 is combined with step 3
|
||||||
var j = offset_ - 2;
|
|
||||||
for (var n = i0_ - 1, nn = i1_ + 2; n < nn; n++, j += 2) {
|
|
||||||
x[j] = K * y[j];
|
|
||||||
}
|
|
||||||
|
|
||||||
// step 2
|
// step 2
|
||||||
var j = offset_ - 3;
|
for (var j = offset - 3, n = len + 4; n--; j += 2) {
|
||||||
for (var n = i0_ - 2, nn = i1_ + 2; n < nn; n++, j += 2) {
|
|
||||||
x[j] = K_ * y[j];
|
x[j] = K_ * y[j];
|
||||||
}
|
}
|
||||||
|
|
||||||
// step 3
|
// step 1 & 3
|
||||||
var j = offset_ - 2;
|
for (var j = offset - 2, n = len + 3; n--; j += 2) {
|
||||||
for (var n = i0_ - 1, nn = i1_ + 2; n < nn; n++, j += 2) {
|
x[j] = K * y[j] -
|
||||||
x[j] -= delta * (x[j - 1] + x[j + 1]);
|
delta * (x[j - 1] + x[j + 1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// step 4
|
// step 4
|
||||||
var j = offset_ - 1;
|
for (var j = offset - 1, n = len + 2; n--; j += 2) {
|
||||||
for (var n = i0_ - 1, nn = i1_ + 1; n < nn; n++, j += 2) {
|
|
||||||
x[j] -= gamma * (x[j - 1] + x[j + 1]);
|
x[j] -= gamma * (x[j - 1] + x[j + 1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// step 5
|
// step 5
|
||||||
var j = offset_;
|
for (var j = offset, n = len + 1; n--; j += 2) {
|
||||||
for (var n = i0_, nn = i1_ + 1; n < nn; n++, j += 2) {
|
|
||||||
x[j] -= beta * (x[j - 1] + x[j + 1]);
|
x[j] -= beta * (x[j - 1] + x[j + 1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// step 6
|
// step 6
|
||||||
var j = offset_ + 1;
|
for (var j = offset + 1, n = len; n--; j += 2) {
|
||||||
for (var n = i0_, nn = i1_; n < nn; n++, j += 2) {
|
|
||||||
x[j] -= alpha * (x[j - 1] + x[j + 1]);
|
x[j] -= alpha * (x[j - 1] + x[j + 1]);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -1837,16 +1830,15 @@ var JpxImage = (function JpxImageClosure() {
|
|||||||
ReversibleTransform.prototype = Object.create(Transform.prototype);
|
ReversibleTransform.prototype = Object.create(Transform.prototype);
|
||||||
ReversibleTransform.prototype.filter =
|
ReversibleTransform.prototype.filter =
|
||||||
function reversibleTransformFilter(y, offset, length, i0, x) {
|
function reversibleTransformFilter(y, offset, length, i0, x) {
|
||||||
var i0_ = Math.floor(i0 / 2);
|
var len = length >> 1;
|
||||||
var i1_ = Math.floor((i0 + length) / 2);
|
var offset = offset | 0;
|
||||||
var offset_ = offset - (i0 % 1);
|
|
||||||
|
|
||||||
for (var n = i0_, nn = i1_ + 1, j = offset_; n < nn; n++, j += 2) {
|
for (var j = offset, n = len + 1; n--; j += 2) {
|
||||||
x[j] = y[j] - Math.floor((y[j - 1] + y[j + 1] + 2) / 4);
|
x[j] = y[j] - ((y[j - 1] + y[j + 1] + 2) >> 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var n = i0_, nn = i1_, j = offset_ + 1; n < nn; n++, j += 2) {
|
for (var j = offset + 1, n = len; n--; j += 2) {
|
||||||
x[j] = y[j] + Math.floor((x[j - 1] + x[j + 1]) / 2);
|
x[j] = y[j] + ((x[j - 1] + x[j + 1]) >> 1);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user