219 lines
		
	
	
		
			5.3 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			219 lines
		
	
	
		
			5.3 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
"use strict";
 | 
						|
 | 
						|
Object.defineProperty(exports, "__esModule", {
 | 
						|
  value: true
 | 
						|
});
 | 
						|
exports["default"] = void 0;
 | 
						|
 | 
						|
var _ = require("../");
 | 
						|
 | 
						|
var _uint = require("../parsers/uint8");
 | 
						|
 | 
						|
// a set of 0x00 terminated subblocks
 | 
						|
var subBlocksSchema = {
 | 
						|
  blocks: function blocks(stream) {
 | 
						|
    var terminator = 0x00;
 | 
						|
    var chunks = [];
 | 
						|
    var streamSize = stream.data.length;
 | 
						|
    var total = 0;
 | 
						|
 | 
						|
    for (var size = (0, _uint.readByte)()(stream); size !== terminator; size = (0, _uint.readByte)()(stream)) {
 | 
						|
      // size becomes undefined for some case when file is corrupted and  terminator is not proper 
 | 
						|
      // null check to avoid recursion
 | 
						|
      if (!size) break; // catch corrupted files with no terminator
 | 
						|
 | 
						|
      if (stream.pos + size >= streamSize) {
 | 
						|
        var availableSize = streamSize - stream.pos;
 | 
						|
        chunks.push((0, _uint.readBytes)(availableSize)(stream));
 | 
						|
        total += availableSize;
 | 
						|
        break;
 | 
						|
      }
 | 
						|
 | 
						|
      chunks.push((0, _uint.readBytes)(size)(stream));
 | 
						|
      total += size;
 | 
						|
    }
 | 
						|
 | 
						|
    var result = new Uint8Array(total);
 | 
						|
    var offset = 0;
 | 
						|
 | 
						|
    for (var i = 0; i < chunks.length; i++) {
 | 
						|
      result.set(chunks[i], offset);
 | 
						|
      offset += chunks[i].length;
 | 
						|
    }
 | 
						|
 | 
						|
    return result;
 | 
						|
  }
 | 
						|
}; // global control extension
 | 
						|
 | 
						|
var gceSchema = (0, _.conditional)({
 | 
						|
  gce: [{
 | 
						|
    codes: (0, _uint.readBytes)(2)
 | 
						|
  }, {
 | 
						|
    byteSize: (0, _uint.readByte)()
 | 
						|
  }, {
 | 
						|
    extras: (0, _uint.readBits)({
 | 
						|
      future: {
 | 
						|
        index: 0,
 | 
						|
        length: 3
 | 
						|
      },
 | 
						|
      disposal: {
 | 
						|
        index: 3,
 | 
						|
        length: 3
 | 
						|
      },
 | 
						|
      userInput: {
 | 
						|
        index: 6
 | 
						|
      },
 | 
						|
      transparentColorGiven: {
 | 
						|
        index: 7
 | 
						|
      }
 | 
						|
    })
 | 
						|
  }, {
 | 
						|
    delay: (0, _uint.readUnsigned)(true)
 | 
						|
  }, {
 | 
						|
    transparentColorIndex: (0, _uint.readByte)()
 | 
						|
  }, {
 | 
						|
    terminator: (0, _uint.readByte)()
 | 
						|
  }]
 | 
						|
}, function (stream) {
 | 
						|
  var codes = (0, _uint.peekBytes)(2)(stream);
 | 
						|
  return codes[0] === 0x21 && codes[1] === 0xf9;
 | 
						|
}); // image pipeline block
 | 
						|
 | 
						|
var imageSchema = (0, _.conditional)({
 | 
						|
  image: [{
 | 
						|
    code: (0, _uint.readByte)()
 | 
						|
  }, {
 | 
						|
    descriptor: [{
 | 
						|
      left: (0, _uint.readUnsigned)(true)
 | 
						|
    }, {
 | 
						|
      top: (0, _uint.readUnsigned)(true)
 | 
						|
    }, {
 | 
						|
      width: (0, _uint.readUnsigned)(true)
 | 
						|
    }, {
 | 
						|
      height: (0, _uint.readUnsigned)(true)
 | 
						|
    }, {
 | 
						|
      lct: (0, _uint.readBits)({
 | 
						|
        exists: {
 | 
						|
          index: 0
 | 
						|
        },
 | 
						|
        interlaced: {
 | 
						|
          index: 1
 | 
						|
        },
 | 
						|
        sort: {
 | 
						|
          index: 2
 | 
						|
        },
 | 
						|
        future: {
 | 
						|
          index: 3,
 | 
						|
          length: 2
 | 
						|
        },
 | 
						|
        size: {
 | 
						|
          index: 5,
 | 
						|
          length: 3
 | 
						|
        }
 | 
						|
      })
 | 
						|
    }]
 | 
						|
  }, (0, _.conditional)({
 | 
						|
    lct: (0, _uint.readArray)(3, function (stream, result, parent) {
 | 
						|
      return Math.pow(2, parent.descriptor.lct.size + 1);
 | 
						|
    })
 | 
						|
  }, function (stream, result, parent) {
 | 
						|
    return parent.descriptor.lct.exists;
 | 
						|
  }), {
 | 
						|
    data: [{
 | 
						|
      minCodeSize: (0, _uint.readByte)()
 | 
						|
    }, subBlocksSchema]
 | 
						|
  }]
 | 
						|
}, function (stream) {
 | 
						|
  return (0, _uint.peekByte)()(stream) === 0x2c;
 | 
						|
}); // plain text block
 | 
						|
 | 
						|
var textSchema = (0, _.conditional)({
 | 
						|
  text: [{
 | 
						|
    codes: (0, _uint.readBytes)(2)
 | 
						|
  }, {
 | 
						|
    blockSize: (0, _uint.readByte)()
 | 
						|
  }, {
 | 
						|
    preData: function preData(stream, result, parent) {
 | 
						|
      return (0, _uint.readBytes)(parent.text.blockSize)(stream);
 | 
						|
    }
 | 
						|
  }, subBlocksSchema]
 | 
						|
}, function (stream) {
 | 
						|
  var codes = (0, _uint.peekBytes)(2)(stream);
 | 
						|
  return codes[0] === 0x21 && codes[1] === 0x01;
 | 
						|
}); // application block
 | 
						|
 | 
						|
var applicationSchema = (0, _.conditional)({
 | 
						|
  application: [{
 | 
						|
    codes: (0, _uint.readBytes)(2)
 | 
						|
  }, {
 | 
						|
    blockSize: (0, _uint.readByte)()
 | 
						|
  }, {
 | 
						|
    id: function id(stream, result, parent) {
 | 
						|
      return (0, _uint.readString)(parent.blockSize)(stream);
 | 
						|
    }
 | 
						|
  }, subBlocksSchema]
 | 
						|
}, function (stream) {
 | 
						|
  var codes = (0, _uint.peekBytes)(2)(stream);
 | 
						|
  return codes[0] === 0x21 && codes[1] === 0xff;
 | 
						|
}); // comment block
 | 
						|
 | 
						|
var commentSchema = (0, _.conditional)({
 | 
						|
  comment: [{
 | 
						|
    codes: (0, _uint.readBytes)(2)
 | 
						|
  }, subBlocksSchema]
 | 
						|
}, function (stream) {
 | 
						|
  var codes = (0, _uint.peekBytes)(2)(stream);
 | 
						|
  return codes[0] === 0x21 && codes[1] === 0xfe;
 | 
						|
});
 | 
						|
var schema = [{
 | 
						|
  header: [{
 | 
						|
    signature: (0, _uint.readString)(3)
 | 
						|
  }, {
 | 
						|
    version: (0, _uint.readString)(3)
 | 
						|
  }]
 | 
						|
}, {
 | 
						|
  lsd: [{
 | 
						|
    width: (0, _uint.readUnsigned)(true)
 | 
						|
  }, {
 | 
						|
    height: (0, _uint.readUnsigned)(true)
 | 
						|
  }, {
 | 
						|
    gct: (0, _uint.readBits)({
 | 
						|
      exists: {
 | 
						|
        index: 0
 | 
						|
      },
 | 
						|
      resolution: {
 | 
						|
        index: 1,
 | 
						|
        length: 3
 | 
						|
      },
 | 
						|
      sort: {
 | 
						|
        index: 4
 | 
						|
      },
 | 
						|
      size: {
 | 
						|
        index: 5,
 | 
						|
        length: 3
 | 
						|
      }
 | 
						|
    })
 | 
						|
  }, {
 | 
						|
    backgroundColorIndex: (0, _uint.readByte)()
 | 
						|
  }, {
 | 
						|
    pixelAspectRatio: (0, _uint.readByte)()
 | 
						|
  }]
 | 
						|
}, (0, _.conditional)({
 | 
						|
  gct: (0, _uint.readArray)(3, function (stream, result) {
 | 
						|
    return Math.pow(2, result.lsd.gct.size + 1);
 | 
						|
  })
 | 
						|
}, function (stream, result) {
 | 
						|
  return result.lsd.gct.exists;
 | 
						|
}), // content frames
 | 
						|
{
 | 
						|
  frames: (0, _.loop)([gceSchema, applicationSchema, commentSchema, imageSchema, textSchema], function (stream) {
 | 
						|
    var nextCode = (0, _uint.peekByte)()(stream); // rather than check for a terminator, we should check for the existence
 | 
						|
    // of an ext or image block to avoid infinite loops
 | 
						|
    //var terminator = 0x3B;
 | 
						|
    //return nextCode !== terminator;
 | 
						|
 | 
						|
    return nextCode === 0x21 || nextCode === 0x2c;
 | 
						|
  })
 | 
						|
}];
 | 
						|
var _default = schema;
 | 
						|
exports["default"] = _default; |