Browse Source

reads chunks

master
Jim Rybarski 10 years ago
parent
commit
5fd09ca2bd
2 changed files with 45 additions and 7 deletions
  1. +2
    -0
      .gitignore
  2. +43
    -7
      nd2reader/__init__.py

+ 2
- 0
.gitignore View File

@ -1,3 +1,5 @@
run.py
.gitignore
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]


+ 43
- 7
nd2reader/__init__.py View File

@ -1,8 +1,6 @@
import array
import numpy as np
import re
import struct
from pprint import pprint
class Nd2Reader(object):
@ -14,7 +12,7 @@ class Nd2Reader(object):
self._filename = filename
self._file_handler = None
self._chunk_map_start_location = None
self._map_keys = {}
self._label_map = {}
self._read_map()
@property
@ -30,7 +28,7 @@ class Nd2Reader(object):
grab the subsequent data (always 16 bytes long), advance to the next label and repeat.
"""
raw_text = self.raw_chunk_map_text
raw_text = self._get_raw_chunk_map_text()
label_start = self._find_first_label_offset(raw_text)
while True:
data_start = self._get_data_start(label_start, raw_text)
@ -38,7 +36,7 @@ class Nd2Reader(object):
if label == "ND2 CHUNK MAP SIGNATURE 0000001!":
# We've reached the end of the chunk map
break
self._map_keys[label] = value
self._label_map[label] = value
label_start = data_start + 16
@staticmethod
@ -84,8 +82,46 @@ class Nd2Reader(object):
self._chunk_map_start_location = struct.unpack("Q", self.fh.read(8))[0]
return self._chunk_map_start_location
@property
def raw_chunk_map_text(self):
def _read_chunk(self, chunk_location):
"""
Gets the data for a given chunk pointer
"""
self.fh.seek(chunk_location)
chunk_data = self._read_chunk_metadata()
header, relative_offset, data_length = self._parse_chunk_metadata(chunk_data)
return self._read_chunk_data(chunk_location, relative_offset, data_length)
def _read_chunk_metadata(self):
"""
Gets the chunks metadata, which is always 16 bytes
"""
return self.fh.read(16)
def _read_chunk_data(self, chunk_location, relative_offset, data_length):
"""
Reads the actual data for a given chunk
"""
# We start at the location of the chunk metadata, skip over the metadata, and then proceed to the
# start of the actual data field, which is at some arbitrary place after the metadata.
self.fh.seek(chunk_location + 16 + relative_offset)
return self.fh.read(data_length)
@staticmethod
def _parse_chunk_metadata(chunk_data):
"""
Finds out everything about a given chunk. Every chunk begins with the same value, so if that's ever
different we can assume the file has suffered some kind of damage.
"""
header, relative_offset, data_length = struct.unpack("IIQ", chunk_data)
if header != 0xabeceda:
raise ValueError("The ND2 file seems to be corrupted.")
return header, relative_offset, data_length
def _get_raw_chunk_map_text(self):
"""
Reads the entire chunk map and returns it as a string.


Loading…
Cancel
Save