read method

bool read(
  1. InputBuffer block
)

Implementation

bool read(InputBuffer block) {
  final saveEndian = block.bigEndian;
  block.bigEndian = true;

  int blockOffset = block.offset;

  // Tiff header
  int endian = block.readUint16();
  if (endian == 0x4949) { // II
    block.bigEndian = false;
    if (block.readUint16() != 0x2a00) {
      block.bigEndian = saveEndian;
      return false;
    }
  } else if (endian == 0x4d4d) { // MM
    block.bigEndian = true;
    if (block.readUint16() != 0x002a) {
      block.bigEndian = saveEndian;
      return false;
    }
  } else {
    return false;
  }

  int ifdOffset = block.readUint32();

  // IFD blocks
  var index = 0;
  while (ifdOffset > 0) {
    block.offset = blockOffset + ifdOffset;

    final directory = ExifIFD();
    final numEntries = block.readUint16();
    final dir = List<ExifEntry>.generate(numEntries, (i) =>
        _readEntry(block, blockOffset));

    for (var entry in dir) {
      if (entry.value != null) {
        directory[entry.tag] = entry.value!;
      }
    }
    directories['ifd$index'] = directory;
    index++;

    ifdOffset = block.readUint32();
  }

  const subTags = {
    0x8769: 'exif',
    0xA005: 'interop',
    0x8825: 'gps',
  };

  for (var d in directories.values) {
    for (var dt in subTags.keys) {
      if (d.containsKey(dt)) { // ExifOffset
        int ifdOffset = d[dt]!.toInt();
        block.offset = blockOffset + ifdOffset;
        final directory = ExifIFD();
        final numEntries = block.readUint16();
        final dir = List<ExifEntry>.generate(numEntries, (i) =>
            _readEntry(block, blockOffset));

        for (var entry in dir) {
          if (entry.value != null) {
            directory[entry.tag] = entry.value!;
          }
        }
        d.sub[subTags[dt]!] = directory;
      }
    }
  }

  block.bigEndian = saveEndian;
  return false;
}