Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -45,5 +45,9 @@ docs/_build
docs/modules.rst
docs/planetaryimage.rst

# Pycharm
.idea/

# Sample Data
tests/mission_data
.pytest_cache/
3 changes: 2 additions & 1 deletion AUTHORS.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,5 @@ Contributors
* Trevor Olson <[email protected]>
* Nikhil Kalige <[email protected]>
* Austin Godber <[email protected]>
* Bhavin Nayak <[email protected]>
* Bhavin Nayak <[email protected]>
* Andrew Annex <[email protected]>
31 changes: 31 additions & 0 deletions planetaryimage/decoders.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@


class BandSequentialDecoder(object):
"""
BSQ
"""
def __init__(self, dtype, shape, compression=None):
self.dtype = dtype
self.shape = shape
Expand All @@ -21,6 +24,34 @@ def decode(self, stream):
return data.reshape(self.shape)


class LineInterleavedDecoder(object):
"""
BIL
"""
def __init__(self, dtype, shape, compression=None):
self.dtype = dtype
self.shape = shape
self.sample_bytes = dtype.itemsize
self.compression = compression

@property
def size(self):
return numpy.product(self.shape)

def decode(self, stream):
bands, lines, samples = self.shape
bs = bands*samples
data = numpy.empty(self.shape, self.dtype)
for line in range(lines):
if self.compression:
chunk = numpy.fromstring(stream.read(bs * self.sample_bytes), self.dtype)
else:
chunk = numpy.fromfile(stream, self.dtype, bs)
data[:, line, :] = chunk.reshape((bands, samples))

return data


class TileDecoder(object):
def __init__(self, dtype, shape, tile_shape):
self.dtype = dtype
Expand Down
5 changes: 3 additions & 2 deletions planetaryimage/image.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,9 +142,10 @@ def image(self):
"""
if self.bands == 1:
return self.data.squeeze()
elif self.bands == 3:
elif self.bands > 1:
return numpy.dstack(self.data)
# TODO: what about multiband images with 2, and 4+ bands?
else:
raise NotImplementedError('Have no impl for {} bands'.format(self.bands))

@property
def bands(self):
Expand Down
15 changes: 13 additions & 2 deletions planetaryimage/pds3image.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import collections

from .image import PlanetaryImage
from .decoders import BandSequentialDecoder
from . import decoders


class Pointer(collections.namedtuple('Pointer', ['filename', 'bytes'])):
Expand Down Expand Up @@ -311,6 +311,12 @@ def record_bytes(self):

@property
def _image_pointer(self):
# If we have a File object containing an Image within it
if '^IMAGE' not in self.label and 'FILE' in self.label:
new_label = self.label['FILE']
if '^IMAGE' in new_label:
self.label = new_label
return Pointer.parse(new_label['^IMAGE'], self.record_bytes)
return Pointer.parse(self.label['^IMAGE'], self.record_bytes)

@property
Expand Down Expand Up @@ -343,7 +349,12 @@ def dtype(self):
@property
def _decoder(self):
if self.format == 'BAND_SEQUENTIAL':
return BandSequentialDecoder(
return decoders.BandSequentialDecoder(
self.dtype, self.shape, self.compression
)
elif self.format == 'LINE_INTERLEAVED':
return decoders.LineInterleavedDecoder(
self.dtype, self.shape, self.compression
)

raise ValueError('Unkown format (%s)' % self.format)
1 change: 0 additions & 1 deletion tests/test_pds3file.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
gzipped_filename = os.path.join(DATA_DIR, 'pds3_1band.IMG.gz')
bz2_filename = os.path.join(DATA_DIR, 'pds3_1band.IMG.bz2')


@pytest.fixture
def expected():
return numpy.loadtxt(os.path.join(DATA_DIR, 'pds3_1band.txt')).reshape(
Expand Down