text: /* This Source Code Form is subject to the terms of the Mozilla Public
   * License, v. 2.0. If a copy of the MPL was not distributed with this
   * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
  
  import Types from './types.js';
  
  export default {
      read
  };
  
  function read(dataView, fileDataOffset) {
      const length = getLength(dataView, fileDataOffset);
      const numberOfColorComponents = getNumberOfColorComponents(dataView, fileDataOffset, length);
      return {
          'Bits Per Sample': getDataPrecision(dataView, fileDataOffset, length),
          'Image Height': getImageHeight(dataView, fileDataOffset, length),
          'Image Width': getImageWidth(dataView, fileDataOffset, length),
          'Color Components': numberOfColorComponents,
          'Subsampling': numberOfColorComponents && getSubsampling(dataView, fileDataOffset, numberOfColorComponents.value, length)
      };
  }
  
  function getLength(dataView, fileDataOffset) {
      return Types.getShortAt(dataView, fileDataOffset);
  }
  
  function getDataPrecision(dataView, fileDataOffset, length) {
      const OFFSET = 2;
      const SIZE = 1;
  
      if (OFFSET + SIZE > length) {
          return undefined;
      }
  
      const value = Types.getByteAt(dataView, fileDataOffset + OFFSET);
      return {
          value,
          description: '' + value
      };
  }
  
  function getImageHeight(dataView, fileDataOffset, length) {
      const OFFSET = 3;
      const SIZE = 2;
  
      if (OFFSET + SIZE > length) {
          return undefined;
      }
  
      const value = Types.getShortAt(dataView, fileDataOffset + OFFSET);
      return {
          value,
          description: `${value}px`
      };
  }
  
  function getImageWidth(dataView, fileDataOffset, length) {
      const OFFSET = 5;
      const SIZE = 2;
  
      if (OFFSET + SIZE > length) {
          return undefined;
      }
  
      const value = Types.getShortAt(dataView, fileDataOffset + OFFSET);
      return {
          value,
          description: `${value}px`
      };
  }
  
  function getNumberOfColorComponents(dataView, fileDataOffset, length) {
      const OFFSET = 7;
      const SIZE = 1;
  
      if (OFFSET + SIZE > length) {
          return undefined;
      }
  
      const value = Types.getByteAt(dataView, fileDataOffset + OFFSET);
      return {
          value,
          description: '' + value
      };
  }
  
  function getSubsampling(dataView, fileDataOffset, numberOfColorComponents, length) {
      const OFFSET = 8;
      const SIZE = 3 * numberOfColorComponents;
  
      if (OFFSET + SIZE > length) {
          return undefined;
      }
  
      const components = [];
  
      for (let i = 0; i < numberOfColorComponents; i++) {
          const componentOffset = fileDataOffset + OFFSET + i * 3;
          components.push([
              Types.getByteAt(dataView, componentOffset),
              Types.getByteAt(dataView, componentOffset + 1),
              Types.getByteAt(dataView, componentOffset + 2)
          ]);
      }
  
      return {
          value: components,
          description: components.length > 1 ? getComponentIds(components) + getSamplingType(components) : ''
      };
  }
  
  function getComponentIds(components) {
      const ids = {
          0x01: 'Y',
          0x02: 'Cb',
          0x03: 'Cr',
          0x04: 'I',
          0x05: 'Q',
      };
  
      return components.map((compontent) => ids[compontent[0]]).join('');
  }
  
  function getSamplingType(components) {
      const types = {
          0x11: '4:4:4 (1 1)',
          0x12: '4:4:0 (1 2)',
          0x14: '4:4:1 (1 4)',
          0x21: '4:2:2 (2 1)',
          0x22: '4:2:0 (2 2)',
          0x24: '4:2:1 (2 4)',
          0x41: '4:1:1 (4 1)',
          0x42: '4:1:0 (4 2)'
      };
  
      if (components.length === 0 || components[0][1] === undefined || types[components[0][1]] === undefined) {
          return '';
      }
  
      return types[components[0][1]];
  }
  