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 # Byte-compiled / optimized / DLL files
__pycache__/ __pycache__/
*.py[cod] *.py[cod]


+ 43
- 7
nd2reader/__init__.py View File

@ -1,8 +1,6 @@
import array import array
import numpy as np import numpy as np
import re
import struct import struct
from pprint import pprint
class Nd2Reader(object): class Nd2Reader(object):
@ -14,7 +12,7 @@ class Nd2Reader(object):
self._filename = filename self._filename = filename
self._file_handler = None self._file_handler = None
self._chunk_map_start_location = None self._chunk_map_start_location = None
self._map_keys = {}
self._label_map = {}
self._read_map() self._read_map()
@property @property
@ -30,7 +28,7 @@ class Nd2Reader(object):
grab the subsequent data (always 16 bytes long), advance to the next label and repeat. 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) label_start = self._find_first_label_offset(raw_text)
while True: while True:
data_start = self._get_data_start(label_start, raw_text) data_start = self._get_data_start(label_start, raw_text)
@ -38,7 +36,7 @@ class Nd2Reader(object):
if label == "ND2 CHUNK MAP SIGNATURE 0000001!": if label == "ND2 CHUNK MAP SIGNATURE 0000001!":
# We've reached the end of the chunk map # We've reached the end of the chunk map
break break
self._map_keys[label] = value
self._label_map[label] = value
label_start = data_start + 16 label_start = data_start + 16
@staticmethod @staticmethod
@ -84,8 +82,46 @@ class Nd2Reader(object):
self._chunk_map_start_location = struct.unpack("Q", self.fh.read(8))[0] self._chunk_map_start_location = struct.unpack("Q", self.fh.read(8))[0]
return self._chunk_map_start_location 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. Reads the entire chunk map and returns it as a string.


Loading…
Cancel
Save