Skip to content
This repository has been archived by the owner on Oct 4, 2020. It is now read-only.

Commit

Permalink
Merge pull request #21 from photoshell/support_thumbnails
Browse files Browse the repository at this point in the history
Support thumbnails and update API
  • Loading branch information
campaul committed May 21, 2015
2 parents cae43c8 + 3aec84f commit 18c1774
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 38 deletions.
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,5 @@
from rawkit.raw import Raw

with Raw(filename='some/raw/image.CR2') as raw:
raw.process()
raw.save(filename='some/destination/image.ppm')
```
59 changes: 50 additions & 9 deletions rawkit/raw.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ class Raw(object):
from rawkit.raw import Raw
with Raw(filename='some/raw/image.CR2') as raw:
raw.process()
raw.save(filename='some/destination/image.ppm')
:param filename: the name of a raw file to load
Expand All @@ -32,6 +31,11 @@ def __init__(self, filename=None):
self.data = libraw.libraw_init(0)
libraw.libraw_open_file(self.data, filename.encode('ascii'))

self.options = {}

self.image_unpacked = False
self.thumb_unpacked = False

def __enter__(self):
"""Return a Raw object for use in context managers."""
return self
Expand All @@ -44,20 +48,25 @@ def close(self):
"""Free the underlying raw representation."""
libraw.libraw_close(self.data)

def process(self, options=None):
"""
Unpack and process the raw data into something more usable.
def unpack(self):
"""Unpack and the raw data."""
if not self.image_unpacked:
libraw.libraw_unpack(self.data)
self.image_unpacked = True

"""
def unpack_thumb(self):
"""Unpack the thumbnail data."""
if not self.thumb_unpacked:
libraw.libraw_unpack_thumb(self.data)
self.thumb_unpacked = True

libraw.libraw_unpack(self.data)
def process(self):
"""Process the raw data based on self.options"""
libraw.libraw_dcraw_process(self.data)

def save(self, filename=None, filetype='ppm'):
"""
Save the image data as a new PPM or TIFF image. This method is provided
for convenience, but in general export should actually be handled by
another library (such as Wand).
Save the image data as a new PPM or TIFF image.
Keyword arguments:
filename -- A filename to save.
Expand All @@ -66,11 +75,29 @@ def save(self, filename=None, filetype='ppm'):
assert filetype in ('ppm', 'tiff')
self.data.contents.params.output_tiff = 0 if filetype is 'ppm' else 1

self.unpack()
self.process()

libraw.libraw_dcraw_ppm_tiff_writer(
self.data, filename.encode('ascii'))

def save_thumb(self, filename=None):
"""
Save the thumbnail data.
Keyword arguments:
filename -- A filename to save.
"""
self.unpack_thumb()

libraw.libraw_dcraw_thumb_writer(
self.data, filename.encode('ascii'))

def to_buffer(self):
"""Return the image data as an RGB buffer."""
self.unpack()
self.process()

processed_image = libraw.libraw_dcraw_make_mem_image(self.data)
data_pointer = ctypes.cast(
processed_image.contents.data,
Expand All @@ -80,3 +107,17 @@ def to_buffer(self):
libraw.libraw_dcraw_clear_mem(processed_image)

return data

def thumbnail_to_buffer(self):
"""Return the thumbnail data as an RGB buffer."""
self.unpack_thumb()

processed_image = libraw.libraw_dcraw_make_mem_thumb(self.data)
data_pointer = ctypes.cast(
processed_image.contents.data,
ctypes.POINTER(ctypes.c_byte * processed_image.contents.data_size)
)
data = bytearray(data_pointer.contents)
libraw.libraw_dcraw_clear_mem(processed_image)

return data
93 changes: 65 additions & 28 deletions tests/unit/raw_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,55 +19,78 @@ def output_file():
return 'potato_salad.out'


def test_create(mock_libraw, input_file):
with Raw(filename=input_file) as raw:
mock_libraw.libraw_init.assert_called_once()
mock_libraw.libraw_open_file.assert_called_once_with(
raw.data,
input_file.encode('ascii'),
)
@pytest.yield_fixture
def raw(mock_libraw, input_file):
with Raw(filename=input_file) as raw_obj:
yield raw_obj
mock_libraw.libraw_close.assert_called_once_with(raw_obj.data)


def test_create(mock_libraw, raw, input_file):
mock_libraw.libraw_init.assert_called_once()
mock_libraw.libraw_open_file.assert_called_once_with(
raw.data,
input_file.encode('ascii'),
)

mock_libraw.libraw_close.assert_called_once_with(raw.data)

def test_unpack(mock_libraw, raw):
raw.unpack()
mock_libraw.libraw_unpack.assert_called_once_with(raw.data)

def test_process(mock_libraw, input_file):
with Raw(filename=input_file) as raw:
raw.process()

def test_unpack_twice(mock_libraw, raw):
raw.unpack()
raw.unpack()
mock_libraw.libraw_unpack.assert_called_once_with(raw.data)
mock_libraw.libraw_dcraw_process.assert_called_once_with(raw.data)


def _test_save(mock_libraw, input_file, output_file, filetype):
with Raw(filename=input_file) as raw:
raw.process()
raw.save(filename=output_file, filetype=filetype)
def test_unpack_thumb(mock_libraw, raw):
raw.unpack_thumb()
mock_libraw.libraw_unpack_thumb.assert_called_once_with(raw.data)


def test_unpack_thumb_twice(mock_libraw, raw):
raw.unpack_thumb()
raw.unpack_thumb()
mock_libraw.libraw_unpack_thumb.assert_called_once_with(raw.data)


def _test_save(mock_libraw, raw, output_file, filetype):
raw.save(filename=output_file, filetype=filetype)

mock_libraw.libraw_dcraw_ppm_tiff_writer.assert_called_once_with(
raw.data,
output_file.encode('ascii'),
)


def test_save_ppm(mock_libraw, input_file, output_file):
_test_save(mock_libraw, input_file, output_file, 'ppm')
def test_save_ppm(mock_libraw, raw, output_file):
_test_save(mock_libraw, raw, output_file, 'ppm')


def test_save_tiff(mock_libraw, input_file, output_file):
_test_save(mock_libraw, input_file, output_file, 'tiff')
def test_save_tiff(mock_libraw, raw, output_file):
_test_save(mock_libraw, raw, output_file, 'tiff')


def test_save_invalid(mock_libraw, input_file, output_file):
def test_save_invalid(mock_libraw, raw, output_file):
with pytest.raises(AssertionError):
_test_save(mock_libraw, input_file, output_file, 'jpg')
_test_save(mock_libraw, raw, output_file, 'jpg')


def test_save_thumb(mock_libraw, raw, output_file):
raw.save_thumb(filename=output_file)

mock_libraw.libraw_dcraw_thumb_writer.assert_called_once_with(
raw.data,
output_file.encode('ascii'),
)

def test_to_buffer(mock_libraw, input_file):
with Raw(filename=input_file) as raw:
raw.process()
# Quick hack because to_buffer does some ctypes acrobatics
with mock.patch('rawkit.raw.ctypes'):
raw.to_buffer()

def test_to_buffer(mock_libraw, raw):
# Quick hack because to_buffer does some ctypes acrobatics
with mock.patch('rawkit.raw.ctypes'):
raw.to_buffer()

mock_libraw.libraw_dcraw_make_mem_image.assert_called_once_with(
raw.data,
Expand All @@ -76,3 +99,17 @@ def test_to_buffer(mock_libraw, input_file):
mock_libraw.libraw_dcraw_clear_mem.assert_called_once_with(
mock_libraw.libraw_dcraw_make_mem_image(raw.data),
)


def test_thumbnail_to_buffer(mock_libraw, raw):
# Quick hack because thumbnail_to_buffer does some ctypes acrobatics
with mock.patch('rawkit.raw.ctypes'):
raw.thumbnail_to_buffer()

mock_libraw.libraw_dcraw_make_mem_thumb.assert_called_once_with(
raw.data,
)

mock_libraw.libraw_dcraw_clear_mem.assert_called_once_with(
mock_libraw.libraw_dcraw_make_mem_thumb(raw.data),
)

0 comments on commit 18c1774

Please sign in to comment.