|
|
@ -14,7 +14,7 @@ |
|
|
|
* See the License for the specific language governing permissions and |
|
|
|
* See the License for the specific language governing permissions and |
|
|
|
* limitations under the License. |
|
|
|
* limitations under the License. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
/* globals ArithmeticDecoder, error, globalScope, log2, readUint16, readUint32, |
|
|
|
/* globals ArithmeticDecoder, globalScope, log2, readUint16, readUint32, |
|
|
|
warn */ |
|
|
|
warn */ |
|
|
|
|
|
|
|
|
|
|
|
'use strict'; |
|
|
|
'use strict'; |
|
|
@ -58,7 +58,7 @@ var JpxImage = (function JpxImageClosure() { |
|
|
|
lbox = length - position + headerSize; |
|
|
|
lbox = length - position + headerSize; |
|
|
|
} |
|
|
|
} |
|
|
|
if (lbox < headerSize) { |
|
|
|
if (lbox < headerSize) { |
|
|
|
error('JPX error: Invalid box field size'); |
|
|
|
throw new Error('JPX Error: Invalid box field size'); |
|
|
|
} |
|
|
|
} |
|
|
|
var dataLength = lbox - headerSize; |
|
|
|
var dataLength = lbox - headerSize; |
|
|
|
var jumpDataLength = true; |
|
|
|
var jumpDataLength = true; |
|
|
@ -82,7 +82,6 @@ var JpxImage = (function JpxImageClosure() { |
|
|
|
} |
|
|
|
} |
|
|
|
}, |
|
|
|
}, |
|
|
|
parseImageProperties: function JpxImage_parseImageProperties(stream) { |
|
|
|
parseImageProperties: function JpxImage_parseImageProperties(stream) { |
|
|
|
try { |
|
|
|
|
|
|
|
var newByte = stream.getByte(); |
|
|
|
var newByte = stream.getByte(); |
|
|
|
while (newByte >= 0) { |
|
|
|
while (newByte >= 0) { |
|
|
|
var oldByte = newByte; |
|
|
|
var oldByte = newByte; |
|
|
@ -105,18 +104,12 @@ var JpxImage = (function JpxImageClosure() { |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
throw 'No size marker found in JPX stream'; |
|
|
|
throw new Error('JPX Error: No size marker found in JPX stream'); |
|
|
|
} catch (e) { |
|
|
|
|
|
|
|
if (this.failOnCorruptedImage) { |
|
|
|
|
|
|
|
error('JPX error: ' + e); |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
warn('JPX error: ' + e + '. Trying to recover'); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}, |
|
|
|
}, |
|
|
|
parseCodestream: function JpxImage_parseCodestream(data, start, end) { |
|
|
|
parseCodestream: function JpxImage_parseCodestream(data, start, end) { |
|
|
|
var context = {}; |
|
|
|
var context = {}; |
|
|
|
try { |
|
|
|
try { |
|
|
|
|
|
|
|
var doNotRecover = false; |
|
|
|
var position = start; |
|
|
|
var position = start; |
|
|
|
while (position + 1 < end) { |
|
|
|
while (position + 1 < end) { |
|
|
|
var code = readUint16(data, position); |
|
|
|
var code = readUint16(data, position); |
|
|
@ -160,6 +153,11 @@ var JpxImage = (function JpxImageClosure() { |
|
|
|
context.QCC = []; |
|
|
|
context.QCC = []; |
|
|
|
context.COC = []; |
|
|
|
context.COC = []; |
|
|
|
break; |
|
|
|
break; |
|
|
|
|
|
|
|
case 0xFF55: // Tile-part lengths, main header (TLM)
|
|
|
|
|
|
|
|
var Ltlm = readUint16(data, position); // Marker segment length
|
|
|
|
|
|
|
|
// Skip tile length markers
|
|
|
|
|
|
|
|
position += Ltlm; |
|
|
|
|
|
|
|
break; |
|
|
|
case 0xFF5C: // Quantization default (QCD)
|
|
|
|
case 0xFF5C: // Quantization default (QCD)
|
|
|
|
length = readUint16(data, position); |
|
|
|
length = readUint16(data, position); |
|
|
|
var qcd = {}; |
|
|
|
var qcd = {}; |
|
|
@ -179,7 +177,7 @@ var JpxImage = (function JpxImageClosure() { |
|
|
|
scalarExpounded = true; |
|
|
|
scalarExpounded = true; |
|
|
|
break; |
|
|
|
break; |
|
|
|
default: |
|
|
|
default: |
|
|
|
throw 'Invalid SQcd value ' + sqcd; |
|
|
|
throw new Error('JPX Error: Invalid SQcd value ' + sqcd); |
|
|
|
} |
|
|
|
} |
|
|
|
qcd.noQuantization = (spqcdSize == 8); |
|
|
|
qcd.noQuantization = (spqcdSize == 8); |
|
|
|
qcd.scalarExpounded = scalarExpounded; |
|
|
|
qcd.scalarExpounded = scalarExpounded; |
|
|
@ -231,7 +229,7 @@ var JpxImage = (function JpxImageClosure() { |
|
|
|
scalarExpounded = true; |
|
|
|
scalarExpounded = true; |
|
|
|
break; |
|
|
|
break; |
|
|
|
default: |
|
|
|
default: |
|
|
|
throw 'Invalid SQcd value ' + sqcd; |
|
|
|
throw new Error('JPX Error: Invalid SQcd value ' + sqcd); |
|
|
|
} |
|
|
|
} |
|
|
|
qcc.noQuantization = (spqcdSize == 8); |
|
|
|
qcc.noQuantization = (spqcdSize == 8); |
|
|
|
qcc.scalarExpounded = scalarExpounded; |
|
|
|
qcc.scalarExpounded = scalarExpounded; |
|
|
@ -291,16 +289,33 @@ var JpxImage = (function JpxImageClosure() { |
|
|
|
} |
|
|
|
} |
|
|
|
cod.precinctsSizes = precinctsSizes; |
|
|
|
cod.precinctsSizes = precinctsSizes; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
var unsupported = []; |
|
|
|
if (cod.sopMarkerUsed || cod.ephMarkerUsed || |
|
|
|
if (cod.sopMarkerUsed) { |
|
|
|
cod.selectiveArithmeticCodingBypass || |
|
|
|
unsupported.push('sopMarkerUsed'); |
|
|
|
cod.resetContextProbabilities || |
|
|
|
} |
|
|
|
cod.terminationOnEachCodingPass || |
|
|
|
if (cod.ephMarkerUsed) { |
|
|
|
cod.verticalyStripe || cod.predictableTermination) { |
|
|
|
unsupported.push('ephMarkerUsed'); |
|
|
|
throw 'Unsupported COD options: ' + |
|
|
|
} |
|
|
|
globalScope.JSON.stringify(cod); |
|
|
|
if (cod.selectiveArithmeticCodingBypass) { |
|
|
|
|
|
|
|
unsupported.push('selectiveArithmeticCodingBypass'); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (cod.resetContextProbabilities) { |
|
|
|
|
|
|
|
unsupported.push('resetContextProbabilities'); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (cod.terminationOnEachCodingPass) { |
|
|
|
|
|
|
|
unsupported.push('terminationOnEachCodingPass'); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (cod.verticalyStripe) { |
|
|
|
|
|
|
|
unsupported.push('verticalyStripe'); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (cod.predictableTermination) { |
|
|
|
|
|
|
|
unsupported.push('predictableTermination'); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (unsupported.length > 0) { |
|
|
|
|
|
|
|
doNotRecover = true; |
|
|
|
|
|
|
|
throw new Error('JPX Error: Unsupported COD options (' + |
|
|
|
|
|
|
|
unsupported.join(', ') + ')'); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (context.mainHeader) { |
|
|
|
if (context.mainHeader) { |
|
|
|
context.COD = cod; |
|
|
|
context.COD = cod; |
|
|
|
} else { |
|
|
|
} else { |
|
|
@ -343,17 +358,19 @@ var JpxImage = (function JpxImageClosure() { |
|
|
|
// skipping content
|
|
|
|
// skipping content
|
|
|
|
break; |
|
|
|
break; |
|
|
|
case 0xFF53: // Coding style component (COC)
|
|
|
|
case 0xFF53: // Coding style component (COC)
|
|
|
|
throw 'Codestream code 0xFF53 (COC) is not implemented'; |
|
|
|
throw new Error('JPX Error: Codestream code 0xFF53 (COC) is ' + |
|
|
|
|
|
|
|
'not implemented'); |
|
|
|
default: |
|
|
|
default: |
|
|
|
throw 'Unknown codestream code: ' + code.toString(16); |
|
|
|
throw new Error('JPX Error: Unknown codestream code: ' + |
|
|
|
|
|
|
|
code.toString(16)); |
|
|
|
} |
|
|
|
} |
|
|
|
position += length; |
|
|
|
position += length; |
|
|
|
} |
|
|
|
} |
|
|
|
} catch (e) { |
|
|
|
} catch (e) { |
|
|
|
if (this.failOnCorruptedImage) { |
|
|
|
if (doNotRecover || this.failOnCorruptedImage) { |
|
|
|
error('JPX error: ' + e); |
|
|
|
throw e; |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
warn('JPX error: ' + e + '. Trying to recover'); |
|
|
|
warn('Trying to recover from ' + e.message); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
this.tiles = transformComponents(context); |
|
|
|
this.tiles = transformComponents(context); |
|
|
@ -581,7 +598,7 @@ var JpxImage = (function JpxImageClosure() { |
|
|
|
} |
|
|
|
} |
|
|
|
r = 0; |
|
|
|
r = 0; |
|
|
|
} |
|
|
|
} |
|
|
|
throw 'Out of packets'; |
|
|
|
throw new Error('JPX Error: Out of packets'); |
|
|
|
}; |
|
|
|
}; |
|
|
|
} |
|
|
|
} |
|
|
|
function ResolutionLayerComponentPositionIterator(context) { |
|
|
|
function ResolutionLayerComponentPositionIterator(context) { |
|
|
@ -621,7 +638,7 @@ var JpxImage = (function JpxImageClosure() { |
|
|
|
} |
|
|
|
} |
|
|
|
l = 0; |
|
|
|
l = 0; |
|
|
|
} |
|
|
|
} |
|
|
|
throw 'Out of packets'; |
|
|
|
throw new Error('JPX Error: Out of packets'); |
|
|
|
}; |
|
|
|
}; |
|
|
|
} |
|
|
|
} |
|
|
|
function buildPackets(context) { |
|
|
|
function buildPackets(context) { |
|
|
@ -716,7 +733,8 @@ var JpxImage = (function JpxImageClosure() { |
|
|
|
new ResolutionLayerComponentPositionIterator(context); |
|
|
|
new ResolutionLayerComponentPositionIterator(context); |
|
|
|
break; |
|
|
|
break; |
|
|
|
default: |
|
|
|
default: |
|
|
|
throw 'Unsupported progression order ' + progressionOrder; |
|
|
|
throw new Error('JPX Error: Unsupported progression order ' + |
|
|
|
|
|
|
|
progressionOrder); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
function parseTilePackets(context, data, offset, dataLength) { |
|
|
|
function parseTilePackets(context, data, offset, dataLength) { |
|
|
@ -1629,7 +1647,7 @@ var JpxImage = (function JpxImageClosure() { |
|
|
|
(decoder.readBit(contexts, UNIFORM_CONTEXT) << 1) | |
|
|
|
(decoder.readBit(contexts, UNIFORM_CONTEXT) << 1) | |
|
|
|
decoder.readBit(contexts, UNIFORM_CONTEXT); |
|
|
|
decoder.readBit(contexts, UNIFORM_CONTEXT); |
|
|
|
if (symbol != 0xA) { |
|
|
|
if (symbol != 0xA) { |
|
|
|
throw 'Invalid segmentation symbol'; |
|
|
|
throw new Error('JPX Error: Invalid segmentation symbol'); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
}; |
|
|
|
}; |
|
|
|