diff --git a/src/core/jpx.js b/src/core/jpx.js index cb79d273a..b31610266 100644 --- a/src/core/jpx.js +++ b/src/core/jpx.js @@ -15,7 +15,7 @@ * limitations under the License. */ /* globals ArithmeticDecoder, globalScope, log2, readUint16, readUint32, - warn */ + info, warn */ 'use strict'; @@ -63,18 +63,52 @@ var JpxImage = (function JpxImageClosure() { var dataLength = lbox - headerSize; var jumpDataLength = true; switch (tbox) { - case 0x6A501A1A: // 'jP\032\032' - // TODO - break; case 0x6A703268: // 'jp2h' jumpDataLength = false; // parsing child boxes break; case 0x636F6C72: // 'colr' - // TODO + // Colorspaces are not used, the CS from the PDF is used. + var method = data[position]; + var precedence = data[position + 1]; + var approximation = data[position + 2]; + if (method === 1) { + // enumerated colorspace + var colorspace = readUint32(data, position + 3); + switch (colorspace) { + case 16: // this indicates a sRGB colorspace + case 17: // this indicates a grayscale colorspace + case 18: // this indicates a YUV colorspace + break; + default: + warn('Unknown colorspace ' + colorspace); + break; + } + } else if (method === 2) { + info('ICC profile not supported'); + } break; case 0x6A703263: // 'jp2c' this.parseCodestream(data, position, position + dataLength); break; + case 0x6A502020: // 'jP\024\024' + if (0x0d0a870a !== readUint32(data, position)) { + warn('Invalid JP2 signature'); + } + break; + // The following header types are valid but currently not used: + case 0x6A501A1A: // 'jP\032\032' + case 0x66747970: // 'ftyp' + case 0x72726571: // 'rreq' + case 0x72657320: // 'res ' + case 0x69686472: // 'ihdr' + break; + default: + var headerType = String.fromCharCode((tbox >> 24) & 0xFF, + (tbox >> 16) & 0xFF, + (tbox >> 8) & 0xFF, + tbox & 0xFF); + warn('Unsupported header type ' + tbox + ' (' + headerType + ')'); + break; } if (jumpDataLength) { position += dataLength; @@ -788,11 +822,11 @@ var JpxImage = (function JpxImageClosure() { var tile = context.tiles[tileIndex]; var packetsIterator = tile.packetsIterator; while (position < dataLength) { - var packet = packetsIterator.nextPacket(); + alignToByte(); if (!readBits(1)) { - alignToByte(); continue; } + var packet = packetsIterator.nextPacket(); var layerNumber = packet.layerNumber; var queue = [], codeblock; for (var i = 0, ii = packet.codeblocks.length; i < ii; i++) { @@ -803,13 +837,13 @@ var JpxImage = (function JpxImageClosure() { var codeblockIncluded = false; var firstTimeInclusion = false; var valueReady; - if ('included' in codeblock) { + if (codeblock['included'] !== undefined) { codeblockIncluded = !!readBits(1); } else { // reading inclusion tree precinct = codeblock.precinct; var inclusionTree, zeroBitPlanesTree; - if ('inclusionTree' in precinct) { + if (precinct['inclusionTree'] !== undefined) { inclusionTree = precinct.inclusionTree; } else { // building inclusion and zero bit-planes trees @@ -874,7 +908,7 @@ var JpxImage = (function JpxImageClosure() { while (queue.length > 0) { var packetItem = queue.shift(); codeblock = packetItem.codeblock; - if (!('data' in codeblock)) { + if (codeblock['data'] === undefined) { codeblock.data = []; } codeblock.data.push({ @@ -904,7 +938,7 @@ var JpxImage = (function JpxImageClosure() { if (blockWidth === 0 || blockHeight === 0) { continue; } - if (!('data' in codeblock)) { + if (codeblock['data'] === undefined) { continue; } @@ -1159,10 +1193,10 @@ var JpxImage = (function JpxImageClosure() { var tile = context.tiles[tileIndex]; for (var c = 0; c < componentsCount; c++) { var component = tile.components[c]; - var qcdOrQcc = (c in context.currentTile.QCC ? + var qcdOrQcc = (context.currentTile.QCC[c] !== undefined ? context.currentTile.QCC[c] : context.currentTile.QCD); component.quantizationParameters = qcdOrQcc; - var codOrCoc = (c in context.currentTile.COC ? + var codOrCoc = (context.currentTile.COC[c] !== undefined ? context.currentTile.COC[c] : context.currentTile.COD); component.codingStyleParameters = codOrCoc; } @@ -1191,7 +1225,7 @@ var JpxImage = (function JpxImageClosure() { while (currentLevel < this.levels.length) { level = this.levels[currentLevel]; var index = i + j * level.width; - if (index in level.items) { + if (level.items[index] !== undefined) { value = level.items[index]; break; }