pax_global_header00006660000000000000000000000064132217430720014513gustar00rootroot0000000000000052 comment=3ed61a4899f37d5e20aecdabd4ba8042b1d6b058 rawkit-0.6.0/000077500000000000000000000000001322174307200130175ustar00rootroot00000000000000rawkit-0.6.0/.coveragerc000066400000000000000000000012001322174307200151310ustar00rootroot00000000000000# Coveragerc file stolen from pre-commit [run] branch = True source = . omit = .tox/* /usr/* */tmp* setup.py # Don't complain if non-runnable code isn't run */__main__.py tests/stress/* [report] exclude_lines = # Have to re-enable the standard pragma \#\s*pragma: no cover # Don't complain if tests don't hit defensive assertion code: ^\s*raise AssertionError\b ^\s*raise NotImplementedError\b ^\s*return NotImplemented\b ^\s*raise$ # Don't complain if non-runnable code isn't run: ^if __name__ == ['"]__main__['"]:$ [html] directory = coverage-html # vim:ft=dosini rawkit-0.6.0/.pre-commit-config.yaml000066400000000000000000000006501322174307200173010ustar00rootroot00000000000000- repo: git://github.com/pre-commit/pre-commit-hooks sha: v0.4.2 hooks: - id: autopep8-wrapper args: ['-i'] exclude: 'docs/source/_themes/' - id: check-json - id: check-yaml - id: name-tests-test - id: debug-statements - id: end-of-file-fixer - id: trailing-whitespace - id: check-case-conflict - id: check-merge-conflict rawkit-0.6.0/LICENSE000066400000000000000000000021051322174307200140220ustar00rootroot00000000000000The MIT License (MIT) Copyright © 2015 Cameron Paul and Sam Whited Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. rawkit-0.6.0/MANIFEST.in000066400000000000000000000002151322174307200145530ustar00rootroot00000000000000include LICENSE include *.rst include *.txt include *.yaml include .coveragerc include Makefile include tox.ini recursive-include tests *.py rawkit-0.6.0/Makefile000066400000000000000000000031411322174307200144560ustar00rootroot00000000000000REBUILD_FLAG = VENV=env BIN=$(VENV)/bin ACTIVATE=. $(BIN)/activate APIDOCS=docs/source/api DOCSRC=$(APIDOCS)/modules.rst docs/source/* docs/source/_static/* .PHONY: all all: test build pre-commit .PHONY: pre-commit pre-commit: .git/hooks/pre-commit .git/hooks/pre-commit: .pre-commit-config.yaml $(VENV) $(ACTIVATE); pre-commit install $(VENV): $(VENV)/bin/activate $(VENV)/bin/activate: requirements-dev.txt test -d $(VENV) || virtualenv -p python3 $(VENV) $(ACTIVATE); pip install -r requirements-dev.txt touch $(BIN)/activate .PHONY: tox tox: $(VENV) $(ACTIVATE); pip install tox .PHONY: test test: $(VENV) tox $(ACTIVATE); tox $(REBUILD_FLAG) .PHONY: stress-test stress-test: $(VENV) $(ACTIVATE); INPUT=$(INPUT) tox -c tox-stress.ini $(REBUILD_FLAG) dist/*.whl: setup.py rawkit/*.py python setup.py bdist_wheel dist/*.tar.gz: setup.py rawkit/*.py python setup.py sdist bdist .PHONY: wheel wheel: dist/*.whl .PHONY: dist dist: dist/*.tar.gz .PHONY: build build: pre-commit wheel dist .PHONY: upload upload: clean $(ACTIVATE) python setup.py sdist bdist bdist_wheel upload .PHONY: clean clean: -$(ACTIVATE) 2>/dev/null; $(MAKE) -C docs $@ find . -iname '*.pyc' | xargs rm -f find . -iname '__pycache__' -type d | xargs rm -rf rm -rf .tox rm -rf build rm -rf dist rm -rf $(VENV) .PHONY: docs docs: epub html $(VENV) .PHONY: html html: $(DOCSRC) $(VENV) $(ACTIVATE); $(MAKE) -C docs $@ .PHONY: epub epub: $(DOCSRC) $(VENV) $(ACTIVATE); $(MAKE) -C docs $@ $(APIDOCS)/modules.rst: rawkit/*.py libraw/*.py $(VENV) $(ACTIVATE); sphinx-apidoc -f -E -M -o $(APIDOCS) -H Contents . docs tests setup.py rawkit-0.6.0/PKG-INFO000066400000000000000000000044401322174307200141160ustar00rootroot00000000000000Metadata-Version: 1.1 Name: rawkit Version: 0.6.0 Summary: CTypes based LibRaw bindings Home-page: https://rawkit.readthedocs.org Author: Cameron Paul, Sam Whited Author-email: sam@samwhited.com License: UNKNOWN Description: rawkit ====== .. image:: https://badge.fury.io/py/rawkit.svg? :alt: Package Status :target: https://pypi.python.org/pypi/rawkit .. image:: https://readthedocs.org/projects/rawkit/badge/?version=latest :alt: Docs Status :target: https://rawkit.readthedocs.org/en/latest/ .. image:: https://secure.travis-ci.org/photoshell/rawkit.svg?branch=master :alt: Build Status :target: https://travis-ci.org/photoshell/rawkit .. image:: https://img.shields.io/coveralls/photoshell/rawkit.svg?style=flat :alt: Test Coverage Status :target: https://coveralls.io/r/photoshell/rawkit ``rawkit`` (pronounced `rocket`) is a ctypes-based LibRaw_ binding for Python inspired by the Wand_ API. .. sourcecode:: python from rawkit.raw import Raw from rawkit.options import WhiteBalance with Raw(filename='some/raw/image.CR2') as raw: raw.options.white_balance = WhiteBalance(camera=False, auto=True) raw.save(filename='some/destination/image.ppm') for more info, see the docs_ .. _LibRaw: http://www.libraw.org/ .. _Wand: http://docs.wand-py.org .. _docs: https://rawkit.readthedocs.org/en/latest/ Keywords: encoding,images,photography,libraw,raw,photos Platform: UNKNOWN Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 2 Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.3 Classifier: Programming Language :: Python :: 3.4 Classifier: Programming Language :: Python :: Implementation :: PyPy Classifier: Development Status :: 3 - Alpha Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: MIT License Classifier: Operating System :: OS Independent Classifier: Topic :: Software Development :: Libraries :: Python Modules rawkit-0.6.0/README.rst000066400000000000000000000021531322174307200145070ustar00rootroot00000000000000rawkit ====== .. image:: https://badge.fury.io/py/rawkit.svg? :alt: Package Status :target: https://pypi.python.org/pypi/rawkit .. image:: https://readthedocs.org/projects/rawkit/badge/?version=latest :alt: Docs Status :target: https://rawkit.readthedocs.org/en/latest/ .. image:: https://secure.travis-ci.org/photoshell/rawkit.svg?branch=master :alt: Build Status :target: https://travis-ci.org/photoshell/rawkit .. image:: https://img.shields.io/coveralls/photoshell/rawkit.svg?style=flat :alt: Test Coverage Status :target: https://coveralls.io/r/photoshell/rawkit ``rawkit`` (pronounced `rocket`) is a ctypes-based LibRaw_ binding for Python inspired by the Wand_ API. .. sourcecode:: python from rawkit.raw import Raw from rawkit.options import WhiteBalance with Raw(filename='some/raw/image.CR2') as raw: raw.options.white_balance = WhiteBalance(camera=False, auto=True) raw.save(filename='some/destination/image.ppm') for more info, see the docs_ .. _LibRaw: http://www.libraw.org/ .. _Wand: http://docs.wand-py.org .. _docs: https://rawkit.readthedocs.org/en/latest/ rawkit-0.6.0/libraw/000077500000000000000000000000001322174307200142775ustar00rootroot00000000000000rawkit-0.6.0/libraw/__init__.py000066400000000000000000000007131322174307200164110ustar00rootroot00000000000000"""Introduction ~~~~~~~~~~~~~~~ The :mod:`libraw` package contains low-level CTYPES_ based APIs for interfacing with LibRaw_ by LibRaw, LLC. While this library can be used on its own to access the full functionality of LibRaw and develop raw photos, we recommend using the higher-level :mod:`rawkit` module, which provides a more pythonic interface to LibRaw. .. _CTYPES: https://docs.python.org/3/library/ctypes.html .. _LibRaw: http://www.libraw.org """ rawkit-0.6.0/libraw/bindings.py000066400000000000000000000154401322174307200164520ustar00rootroot00000000000000""":mod:`libraw.bindings` --- Low-level LibRaw bindings ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The :class:`libraw.bindings` module handles linking against the LibRaw binary. """ from ctypes import * # noqa from ctypes import util from libraw import errors from libraw.callbacks import data_callback from libraw.callbacks import memory_callback from libraw.callbacks import progress_callback from libraw.errors import c_error from libraw import structs_16 from libraw import structs_17 from libraw import structs_18 class LibRaw(CDLL): """ A :class:`ctypes.CDLL` that links against `libraw.so` (or the equivalent on your platform). Raises: ImportError: If LibRaw cannot be found on your system, or linking fails. """ def __init__(self): # pragma: no cover libraw = util.find_library('raw') try: if libraw is not None: super(LibRaw, self).__init__(libraw) else: raise ImportError except (ImportError, AttributeError, OSError, IOError): raise ImportError('Cannot find LibRaw on your system!') try: structs = { 16: structs_16, 17: structs_17, 18: structs_18, }[self.version_number[1]] except KeyError: raise ImportError( 'Unsupported Libraw version: %s.%s.%s.' % self.version_number ) libraw_data_t = structs.libraw_data_t libraw_decoder_info_t = structs.libraw_decoder_info_t libraw_processed_image_t = structs.libraw_processed_image_t # Define arg types self.libraw_init.argtypes = [c_int] # enum LibRaw_progress self.libraw_strprogress.argtypes = [c_int] self.libraw_unpack_function_name.argtypes = [POINTER(libraw_data_t)] self.libraw_subtract_black.argtypes = [POINTER(libraw_data_t)] self.libraw_open_file.argtypes = [POINTER(libraw_data_t), c_char_p] self.libraw_open_file_ex.argtypes = [ POINTER(libraw_data_t), c_char_p, c_int64 ] self.libraw_open_buffer.argtypes = [ POINTER(libraw_data_t), c_void_p, c_int64 ] self.libraw_unpack.argtypes = [POINTER(libraw_data_t)] self.libraw_unpack_thumb.argtypes = [POINTER(libraw_data_t)] self.libraw_recycle_datastream.argtypes = [POINTER(libraw_data_t)] self.libraw_recycle.argtypes = [POINTER(libraw_data_t)] self.libraw_close.argtypes = [POINTER(libraw_data_t)] self.libraw_set_memerror_handler.argtypes = [ POINTER(libraw_data_t), memory_callback, c_void_p, ] self.libraw_set_dataerror_handler.argtypes = [ POINTER(libraw_data_t), data_callback, c_void_p, ] self.libraw_set_progress_handler.argtypes = [ POINTER(libraw_data_t), progress_callback, c_void_p, ] self.libraw_adjust_sizes_info_only.argtypes = [ POINTER(libraw_data_t) ] self.libraw_dcraw_ppm_tiff_writer.argtypes = [ POINTER(libraw_data_t), c_char_p ] self.libraw_dcraw_thumb_writer.argtypes = [ POINTER(libraw_data_t), c_char_p ] self.libraw_dcraw_process.argtypes = [POINTER(libraw_data_t)] self.libraw_dcraw_make_mem_image.argtypes = [ POINTER(libraw_data_t), POINTER(c_int) ] self.libraw_dcraw_make_mem_thumb.argtypes = [ POINTER(libraw_data_t), POINTER(c_int) ] self.libraw_dcraw_clear_mem.argtypes = [ POINTER(libraw_processed_image_t) ] self.libraw_raw2image.argtypes = [POINTER(libraw_data_t)] self.libraw_free_image.argtypes = [POINTER(libraw_data_t)] self.libraw_get_decoder_info.argtypes = [ POINTER(libraw_data_t), POINTER(libraw_decoder_info_t) ] self.libraw_COLOR.argtypes = [ POINTER(libraw_data_t), c_int, c_int ] # Define return types self.libraw_init.restype = POINTER(libraw_data_t) self.libraw_version.restype = c_char_p self.libraw_strprogress.restype = c_char_p self.libraw_versionNumber.restype = c_int self.libraw_cameraCount.restype = c_int self.libraw_cameraList.restype = POINTER( c_char_p * self.libraw_cameraCount() ) self.libraw_unpack_function_name.restype = c_char_p self.libraw_subtract_black.restype = POINTER(libraw_data_t) self.libraw_open_file.restype = c_error self.libraw_open_file_ex.restype = c_error self.libraw_open_buffer.restype = c_error self.libraw_unpack.restype = c_error self.libraw_unpack_thumb.restype = c_error self.libraw_adjust_sizes_info_only.restype = c_error self.libraw_dcraw_ppm_tiff_writer.restype = c_error self.libraw_dcraw_thumb_writer.restype = c_error self.libraw_dcraw_process.restype = c_error self.libraw_dcraw_make_mem_image.restype = POINTER( libraw_processed_image_t) self.libraw_dcraw_make_mem_thumb.restype = POINTER( libraw_processed_image_t) self.libraw_raw2image.restype = c_error self.libraw_get_decoder_info.restype = c_error self.libraw_COLOR.restype = c_int # Some special Windows-only garbage: try: self.libraw_open_wfile.argtypes = [ POINTER(libraw_data_t), c_wchar_p ] self.libraw_open_wfile_ex.argtypes = [ POINTER(libraw_data_t), c_wchar_p, c_int64 ] self.libraw_open_wfile.restype = c_error self.libraw_open_wfile_ex.restype = c_error except AttributeError: pass @property def version_number(self): """ A numeric representation of the version of LibRaw which we have linked against in ``(Major, Minor, Patch)`` form. eg. :: (0, 16, 1) Returns: 3 tuple: The version number """ v = self.libraw_versionNumber() return ((v >> 16) & 0x0000ff, (v >> 8) & 0x0000ff, v & 0x0000ff) @property def version(self): """ A string representation of the version of LibRaw which we have linked against. eg. :: "0.16.1-Release" Returns: str: The version """ return self.libraw_version().decode('utf-8') def __getitem__(self, name): func = super(LibRaw, self).__getitem__(name) func.errcheck = errors.check_call return func rawkit-0.6.0/libraw/callbacks.py000066400000000000000000000044201322174307200165700ustar00rootroot00000000000000""":mod:`libraw.callbacks` --- LibRaw callback definitions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Warning: You will need to keep a reference to your callback functions for as long as you want to call them from C code, otherwise they may be garbage collected and lead to a segmentation fault. """ from ctypes import * # noqa memory_callback = CFUNCTYPE(c_void_p, c_char_p, c_char_p) """ Creates a callback for use when there are memory errors in LibRaw. .. sourcecode:: python def memory_cb(data, file, where): pass cb = memory_callback(memory_cb) libraw.libraw_set_memerror_handler(libraw_data, cb, data) Your callback function should map to the LibRaw C callback definition below: .. sourcecode:: c typedef void (*memory_callback) ( void *data, const char *file, const char *where ); Args: callback (function): The Python function to convert to a C callback. Returns: _ctypes.PyCFuncPtrType: A C callback. """ data_callback = CFUNCTYPE(c_void_p, c_char_p, c_int) """ A callback for use when there are data errors in LibRaw. .. sourcecode:: python def data_cb(data, file, offset): pass cb = data_callback(data_cb) libraw.libraw_set_dataerror_handler(libraw_data, cb, data) Your callback function should map to the LibRaw C callback definition below: .. sourcecode:: c typedef void (*data_callback) ( void *data, const char *file, const int offset ); Args: callback (function): The Python function to convert to a C callback. Returns: _ctypes.PyCFuncPtrType: A C callback. """ progress_callback = CFUNCTYPE(c_void_p, c_int, c_int, c_int) """ A callback that will be called to alert you to the stages of image processing. .. sourcecode:: python def progress_cb(data, stage, iteration, expected): pass cb = progress_callback(progress_cb) libraw.libraw_set_progress_handler(libraw_data, cb, data) Your callback function should map to the LibRaw C callback definition below: .. sourcecode:: c typedef void (*progress_callback) ( void *data, enum LibRaw_progress stage, int iterationa, int expected ); Args: callback (function): The Python function to convert to a C callback. Returns: _ctypes.PyCFuncPtrType: A C callback. """ rawkit-0.6.0/libraw/errors.py000066400000000000000000000106341322174307200161710ustar00rootroot00000000000000""":mod:`libraw.errors` --- Pythonic error handling for LibRaw ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ """ from ctypes import c_int class c_error(c_int): """ An error type for LibRaw (since LibRaw errors are ints and you can't distinguish between functions that return an error and functions that return an int that doesn't code for an error). """ class LibRawError(Exception): """ A base exception class from which all other exceptions that originate in LibRaw inherit. """ class UnspecifiedError(LibRawError): """ Something bad happened, but we don't know what. """ class FileUnsupported(LibRawError): """ The file is not a raw file or is from an unsupported camera. """ class RequestForNonexistentImage(LibRawError): """ The image file directory in the raw file which you are trying to access does not contain an image. """ class OutOfOrderCall(LibRawError): """ A LibRaw function depends on another function being called first and was invoked out of order. """ class NoThumbnail(LibRawError): """ The raw file does not contain a thumbnail. """ class UnsupportedThumbnail(LibRawError): """ The thumbnail format is not supported. """ class InputClosed(LibRawError): """ There is no input stream, or the input stream has been closed. """ class InsufficientMemory(LibRawError): """ Memory allocation failed. """ class DataError(LibRawError): """ Data unpacking failed. """ class CanceledByCallback(LibRawError): """ Image processing was canceled because the progress callback requested it. """ class BadCrop(LibRawError): """ The cropping coordinates specified are invalid (eg. the top left corner of the cropping rectangle is outside the image). """ def check_call(exit_code, func, arguments): """ Throws a Python error which corresponds to the given LibRaw exit code. Args: exit_code (int): An exit code returned by a LibRaw function. Raises: UnspecifiedError: We're not sure what happened. FileUnsupported: The file is not a raw file that we recognize. RequestForNonexistentImage: The given IFD does not contain an image. OutOfOrderCall: Something was called out of order (eg. before data was unpacked) NoThumbnail: The image does not have a thumbnail. UnsupportedThumbnail: The embedded thumbnail format is unsupported. InputClosed: The input stream has been closed. InsufficientMemory: We're out of memory. DataError: The unpacking step failed. IOError: Reading was interrupted (or the file is corrupt). CanceledByCallback: A callback canceled the operation. BadCrop: The crop range was invalid. """ if func.restype is c_error: raise_if_error(exit_code.value) return exit_code def raise_if_error(error_code): """ :func:`raise_if_error` raises a meaningful exception that corresponds to the given LibRaw integer return value. Args: error_code (int): An exit code returned by a LibRaw function. Raises: UnspecifiedError: We're not sure what happened. FileUnsupported: The file is not a raw file that we recognize. RequestForNonexistentImage: The given IFD does not contain an image. OutOfOrderCall: Something was called out of order (eg. before data was unpacked) NoThumbnail: The image does not have a thumbnail. UnsupportedThumbnail: The embedded thumbnail format is unsupported. InputClosed: The input stream has been closed. InsufficientMemory: We're out of memory. DataError: The unpacking step failed. IOError: Reading was interrupted (or the file is corrupt). CanceledByCallback: A callback canceled the operation. BadCrop: The crop range was invalid. """ if error_code != 0: raise { -1: UnspecifiedError, -2: FileUnsupported, -3: RequestForNonexistentImage, -4: OutOfOrderCall, -5: NoThumbnail, -6: UnsupportedThumbnail, -7: InputClosed, -100007: InsufficientMemory, -100008: DataError, -100009: IOError, -100010: CanceledByCallback, -100011: BadCrop }[error_code] rawkit-0.6.0/libraw/structs_16.py000066400000000000000000000153171322174307200166750ustar00rootroot00000000000000""":mod:`libraw.structs` --- LibRaw struct definitions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ """ from ctypes import * # noqa class ph1_t(Structure): """Contains color data read by Phase One cameras.""" _fields_ = [ ('format', c_int), ('key_off', c_int), ('t_black', c_int), ('black_off', c_int), ('split_col', c_int), ('tag_21a', c_int), ('tag_210', c_float), ] class libraw_iparams_t(Structure): """The primary parameters of the image.""" _fields_ = [ ('make', c_char * 64), ('model', c_char * 64), ('raw_count', c_uint), ('dng_version', c_uint), ('is_foveon', c_uint), ('colors', c_int), ('filters', c_uint), ('xtrans', c_char * 6 * 6), ('cdesc', c_char * 5), ] class libraw_image_sizes_t(Structure): """Describes the size of the image.""" _fields_ = [ ('raw_height', c_ushort), ('raw_width', c_ushort), ('height', c_ushort), ('width', c_ushort), ('top_margin', c_ushort), ('left_margin', c_ushort), ('iheight', c_ushort), ('iwidth', c_ushort), ('raw_pitch', c_uint), ('pixel_aspect', c_double), ('flip', c_int), ('mask', c_int * 8 * 4), ] class libraw_colordata_t(Structure): """Describes all color data of the image.""" _fields_ = [ ('curve', c_ushort * 0x10000), ('cblack', c_uint * 4), ('black', c_uint), ('data_maximum', c_uint), ('maximum', c_uint), ('white', c_ushort * 8 * 8), ('cam_mul', c_float * 4), ('pre_mul', c_float * 4), ('cmatrix', c_float * 3 * 4), ('rgb_cam', c_float * 3 * 4), ('cam_xyz', c_float * 4 * 3), ('phase_one_data', ph1_t), ('flash_used', c_float), ('canon_ev', c_float), ('model2', c_char * 64), ('profile', c_void_p), ('profile_length', c_uint), ('black_stat', c_uint * 8), ] class libraw_imgother_t(Structure): """ Information read from the raw file that is unnecessary for raw processing. """ _fields_ = [ ('iso_speed', c_float), ('shutter', c_float), ('aperture', c_float), ('focal_len', c_float), ('timestamp', c_uint), # time_t ('shot_order', c_uint), ('gpsdata', c_uint * 32), ('desc', c_char * 512), ('artist', c_char * 64), ] class libraw_thumbnail_t(Structure): """Describes the thumbnail image embedded in the raw file.""" _fields_ = [ ('tformat', c_uint), # LibRaw_thumbnail_formats ('twidth', c_ushort), ('theight', c_ushort), ('tlength', c_uint), ('tcolors', c_int), ('thumb', POINTER(c_char)), ] class libraw_internal_output_params_t(Structure): _fields_ = [ ('mix_green', c_uint), ('raw_color', c_uint), ('zero_is_bad', c_uint), ('shrink', c_ushort), ('fuji_width', c_ushort), ] class libraw_rawdata_t(Structure): """ Raw image data (after it has been unpacked) and a backup copy of color info used during post processing. """ _fields_ = [ ('raw_alloc', c_void_p), ('raw_image', POINTER(c_ushort)), ('color4_image', POINTER(c_ushort * 4)), ('color3_image', POINTER(c_ushort * 3)), ('ph1_black', POINTER(c_short * 2)), ('iparams', libraw_iparams_t), ('sizes', libraw_image_sizes_t), ('ioparams', libraw_internal_output_params_t), ('color', libraw_colordata_t), ] class libraw_output_params_t(Structure): """Output parameters for processing the image with dcraw.""" _fields_ = [ ('greybox', c_uint * 4), ('cropbox', c_uint * 4), ('aber', c_double * 4), ('gamm', c_double * 6), ('user_mul', c_float * 4), ('shot_select', c_uint), ('bright', c_float), ('threshold', c_float), ('half_size', c_int), ('four_color_rgb', c_int), ('highlight', c_int), ('use_auto_wb', c_int), ('use_camera_wb', c_int), ('use_camera_matrix', c_int), ('output_color', c_int), ('output_profile', POINTER(c_char)), ('camera_profile', c_char_p), ('bad_pixels', POINTER(c_char)), ('dark_frame', c_char_p), ('output_bps', c_int), ('output_tiff', c_int), ('user_flip', c_int), ('user_qual', c_int), ('user_black', c_int), ('user_cblack', c_int * 4), ('sony_arw2_hack', c_int), ('user_sat', c_int), ('med_passes', c_int), ('auto_bright_thr', c_float), ('adjust_maximum_thr', c_float), ('no_auto_bright', c_int), ('use_fuji_rotate', c_int), ('green_matching', c_int), ('dcb_iterations', c_int), ('dcb_enhance_fl', c_int), ('fbdd_noiserd', c_int), ('eeci_refine', c_int), ('es_med_passes', c_int), ('ca_correc', c_int), ('cared', c_float), ('cablue', c_float), ('cfaline', c_int), ('linenoise', c_float), ('cfa_clean', c_int), ('lclean', c_float), ('cclean', c_float), ('cfa_green', c_int), ('green_thresh', c_float), ('exp_correc', c_int), ('exp_shift', c_float), ('exp_preser', c_float), ('wf_debanding', c_int), ('wf_deband_treshold', c_float * 4), ('use_rawspeed', c_int), ('no_auto_scale', c_int), ('no_interpolation', c_int), ('straw_ycc', c_int), ('force_foveon_x3f', c_int), ] class libraw_data_t(Structure): """ A container which comprises the data structures that make up libraw's representation of a raw file. """ _fields_ = [ ('image', POINTER(c_ushort * 4)), ('sizes', libraw_image_sizes_t), ('idata', libraw_iparams_t), ('params', libraw_output_params_t), ('progress_flags', c_uint), ('process_warnings', c_uint), ('color', libraw_colordata_t), ('other', libraw_imgother_t), ('thumbnail', libraw_thumbnail_t), ('rawdata', libraw_rawdata_t), ('parent_class', c_void_p), ] class libraw_processed_image_t(Structure): """A container for processed image data.""" _fields_ = [ ('type', c_uint), ('height', c_ushort), ('width', c_ushort), ('colors', c_ushort), ('bits', c_ushort), ('data_size', c_uint), ('data', c_byte * 1), ] class libraw_decoder_info_t(Structure): """Describes a raw format decoder name and format.""" _fields_ = [ ('decoder_name', c_char_p), ('decoder_flags', c_uint), ] rawkit-0.6.0/libraw/structs_17.py000066400000000000000000000243751322174307200167020ustar00rootroot00000000000000""":mod:`libraw.structs` --- LibRaw struct definitions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ """ from ctypes import * # noqa class ph1_t(Structure): """Contains color data read by Phase One cameras.""" _fields_ = [ ('format', c_int), ('key_off', c_int), ('tag_21a', c_int), ('t_black', c_int), ('split_col', c_int), ('black_col', c_int), ('split_row', c_int), ('black_row', c_int), ('tag_210', c_float), ] class libraw_iparams_t(Structure): """The primary parameters of the image.""" _fields_ = [ ('make', c_char * 64), ('model', c_char * 64), ('software', c_char * 64), ('raw_count', c_uint), ('dng_version', c_uint), ('is_foveon', c_uint), ('colors', c_int), ('filters', c_uint), ('xtrans', c_char * 6 * 6), ('xtrans_abs', c_char * 6 * 6), ('cdesc', c_char * 5), ('xmplen', c_uint), ('xmpdata', POINTER(c_char)), ] class libraw_image_sizes_t(Structure): """Describes the size of the image.""" _fields_ = [ ('raw_height', c_ushort), ('raw_width', c_ushort), ('height', c_ushort), ('width', c_ushort), ('top_margin', c_ushort), ('left_margin', c_ushort), ('iheight', c_ushort), ('iwidth', c_ushort), ('raw_pitch', c_uint), ('pixel_aspect', c_double), ('flip', c_int), ('mask', c_int * 8 * 4), ] class libraw_dng_color_t(Structure): _fields_ = [ ('illuminant', c_ushort), ('calibration', c_float * 4 * 4), ('colormatrix', c_float * 4 * 3), ] class libraw_canon_makernotes_t(Structure): _fields_ = [ ('CanonColorDataVer', c_int), ('CanonColorDataSubVer', c_int), ('SpecularWhiteLevel', c_int), ('AverageBlackLevel', c_int), ] class libraw_colordata_t(Structure): """Describes all color data of the image.""" _fields_ = [ ('curve', c_ushort * 0x10000), ('cblack', c_uint * 4102), ('black', c_uint), ('data_maximum', c_uint), ('maximum', c_uint), ('white', c_ushort * 8 * 8), ('cam_mul', c_float * 4), ('pre_mul', c_float * 4), ('cmatrix', c_float * 3 * 4), ('rgb_cam', c_float * 3 * 4), ('cam_xyz', c_float * 4 * 3), ('phase_one_data', ph1_t), ('flash_used', c_float), ('canon_ev', c_float), ('model2', c_char * 64), ('profile', c_void_p), ('profile_length', c_uint), ('black_stat', c_uint * 8), ('dng_color', libraw_dng_color_t * 2), ('canon_makernotes', libraw_canon_makernotes_t), ('baseline_exposure', c_float), ('OlympusSensorCalibration', c_int * 2), ('FujiExpoMidPointShift', c_float), ('digitalBack_color', c_int), ] class libraw_gps_info_t(Structure): """GPS data for the image.""" _fields_ = [ ('latitude', c_float * 3), ('longitude', c_float * 3), ('gpstimestamp', c_float * 3), ('altitude', c_float), ('altref', c_char), ('latref', c_char), ('longref', c_char), ('gpsstatus', c_char), ('gpsparsed', c_char), ] class libraw_imgother_t(Structure): """ Information read from the raw file that is unnecessary for raw processing. """ _fields_ = [ ('iso_speed', c_float), ('shutter', c_float), ('aperture', c_float), ('focal_len', c_float), ('timestamp', c_uint), # time_t ('shot_order', c_uint), ('gpsdata', c_uint * 32), ('parsed_gps', libraw_gps_info_t), ('desc', c_char * 512), ('artist', c_char * 64), ] class libraw_thumbnail_t(Structure): """Describes the thumbnail image embedded in the raw file.""" _fields_ = [ ('tformat', c_uint), # LibRaw_thumbnail_formats ('twidth', c_ushort), ('theight', c_ushort), ('tlength', c_uint), ('tcolors', c_int), ('thumb', POINTER(c_char)), ] class libraw_internal_output_params_t(Structure): _fields_ = [ ('mix_green', c_uint), ('raw_color', c_uint), ('zero_is_bad', c_uint), ('shrink', c_ushort), ('fuji_width', c_ushort), ] class libraw_rawdata_t(Structure): """ Raw image data (after it has been unpacked) and a backup copy of color info used during post processing. """ _fields_ = [ ('raw_alloc', c_void_p), ('raw_image', POINTER(c_ushort)), ('color4_image', POINTER(c_ushort * 4)), ('color3_image', POINTER(c_ushort * 3)), ('ph1_cblack', POINTER(c_short * 2)), ('ph1_rblack', POINTER(c_short * 2)), ('iparams', libraw_iparams_t), ('sizes', libraw_image_sizes_t), ('ioparams', libraw_internal_output_params_t), ('color', libraw_colordata_t), ] class libraw_output_params_t(Structure): """Output parameters for processing the image with dcraw.""" _fields_ = [ ('greybox', c_uint * 4), ('cropbox', c_uint * 4), ('aber', c_double * 4), ('gamm', c_double * 6), ('user_mul', c_float * 4), ('shot_select', c_uint), ('bright', c_float), ('threshold', c_float), ('half_size', c_int), ('four_color_rgb', c_int), ('highlight', c_int), ('use_auto_wb', c_int), ('use_camera_wb', c_int), ('use_camera_matrix', c_int), ('output_color', c_int), ('output_profile', c_char_p), ('camera_profile', c_char_p), ('bad_pixels', c_char_p), ('dark_frame', c_char_p), ('output_bps', c_int), ('output_tiff', c_int), ('user_flip', c_int), ('user_qual', c_int), ('user_black', c_int), ('user_cblack', c_int * 4), ('user_sat', c_int), ('med_passes', c_int), ('auto_bright_thr', c_float), ('adjust_maximum_thr', c_float), ('no_auto_bright', c_int), ('use_fuji_rotate', c_int), ('green_matching', c_int), ('dcb_iterations', c_int), ('dcb_enhance_fl', c_int), ('fbdd_noiserd', c_int), ('eeci_refine', c_int), ('es_med_passes', c_int), ('ca_correc', c_int), ('cared', c_float), ('cablue', c_float), ('cfaline', c_int), ('linenoise', c_float), ('cfa_clean', c_int), ('lclean', c_float), ('cclean', c_float), ('cfa_green', c_int), ('green_thresh', c_float), ('exp_correc', c_int), ('exp_shift', c_float), ('exp_preser', c_float), ('wf_debanding', c_int), ('wf_deband_treshold', c_float * 4), ('use_rawspeed', c_int), ('no_auto_scale', c_int), ('no_interpolation', c_int), ('straw_ycc', c_int), ('force_foveon_x3f', c_int), ('x3f_flags', c_int), ('sony_arw2_options', c_int), ('sony_arw2_posterization_thr', c_int), ('coolscan_nef_gamma', c_float), ] class libraw_nikonlens_t(Structure): _fields_ = [ ('NikonEffectiveMaxAp', c_float), ('NikonLensIDNumber', c_ubyte), ('NikonLensFStops', c_ubyte), ('NikonMCUVersion', c_ubyte), ('NikonLensType', c_ubyte), ] class libraw_dnglens_t(Structure): _fields_ = [ ('MinFocal', c_float), ('MaxFocal', c_float), ('MaxAp4MinFocal', c_float), ('MaxAp4MaxFocal', c_float), ] class libraw_makernotes_lens_t(Structure): _fields_ = [ ('LensID', c_ulonglong), ('Lens', c_char * 128), ('LensFormat', c_ushort), ('LensMount', c_ushort), ('CamID', c_ulonglong), ('CameraFormat', c_ushort), ('CameraMount', c_ushort), ('body', c_char * 64), ('FocalType', c_short), ('LensFeatures_pre', c_char * 16), ('LensFeatures_suf', c_char * 16), ('MinFocal', c_float), ('MaxFocal', c_float), ('MaxAp4MinFocal', c_float), ('MaxAp4MaxFocal', c_float), ('MinAp4MinFocal', c_float), ('MinAp4MaxFocal', c_float), ('MaxAp', c_float), ('MinAp', c_float), ('CurFocal', c_float), ('CurAp', c_float), ('MaxAp4CurFocal', c_float), ('MinAp4CurFocal', c_float), ('LensFStops', c_float), ('TeleconverterID', c_ulonglong), ('Teleconverter', c_char * 128), ('AdapterID', c_ulonglong), ('Adapter', c_char * 128), ('AttachmentID', c_ulonglong), ('Attachment', c_char * 128), ('CanonFocalUnits', c_short), ('FocalLengthIn35mmFormat', c_float), ] class libraw_lensinfo_t(Structure): _fields_ = [ ('MinFocal', c_float), ('MaxFocal', c_float), ('MaxAp4MinFocal', c_float), ('MaxAp4MaxFocal', c_float), ('EXIF_MaxAp', c_float), ('LensMake', c_char * 128), ('Lens', c_char * 128), ('FocalLengthIn35mmFormat', c_ushort), ('nikon', libraw_nikonlens_t), ('dng', libraw_dnglens_t), ('makernotes', libraw_makernotes_lens_t), ] class libraw_data_t(Structure): """ A container which comprises the data structures that make up libraw's representation of a raw file. """ _fields_ = [ ('image', POINTER(c_ushort * 4)), ('sizes', libraw_image_sizes_t), ('idata', libraw_iparams_t), ('lens', libraw_lensinfo_t), ('params', libraw_output_params_t), ('progress_flags', c_uint), ('process_warnings', c_uint), ('color', libraw_colordata_t), ('other', libraw_imgother_t), ('thumbnail', libraw_thumbnail_t), ('rawdata', libraw_rawdata_t), ('parent_class', c_void_p), ] class libraw_processed_image_t(Structure): """A container for processed image data.""" _fields_ = [ ('type', c_uint), ('height', c_ushort), ('width', c_ushort), ('colors', c_ushort), ('bits', c_ushort), ('data_size', c_uint), ('data', c_byte * 1), ] class libraw_decoder_info_t(Structure): """Describes a raw format decoder name and format.""" _fields_ = [ ('decoder_name', c_char_p), ('decoder_flags', c_uint), ] rawkit-0.6.0/libraw/structs_18.py000066400000000000000000000430751322174307200167010ustar00rootroot00000000000000""":mod:`libraw.structs` --- LibRaw struct definitions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ """ from ctypes import * # noqa class ph1_t(Structure): """Contains color data read by Phase One cameras.""" _fields_ = [ ('format', c_int), ('key_off', c_int), ('tag_21a', c_int), ('t_black', c_int), ('split_col', c_int), ('black_col', c_int), ('split_row', c_int), ('black_row', c_int), ('tag_210', c_float), ] class libraw_iparams_t(Structure): """The primary parameters of the image.""" _fields_ = [ ('guard', c_char * 4), ('make', c_char * 64), ('model', c_char * 64), ('software', c_char * 64), ('raw_count', c_uint), ('dng_version', c_uint), ('is_foveon', c_uint), ('colors', c_int), ('filters', c_uint), ('xtrans', c_char * 6 * 6), ('xtrans_abs', c_char * 6 * 6), ('cdesc', c_char * 5), ('xmplen', c_uint), ('xmpdata', POINTER(c_char)), ] class libraw_image_sizes_t(Structure): """Describes the size of the image.""" _fields_ = [ ('raw_height', c_ushort), ('raw_width', c_ushort), ('height', c_ushort), ('width', c_ushort), ('top_margin', c_ushort), ('left_margin', c_ushort), ('iheight', c_ushort), ('iwidth', c_ushort), ('raw_pitch', c_uint), ('pixel_aspect', c_double), ('flip', c_int), ('mask', c_int * 8 * 4), ] class libraw_dng_color_t(Structure): _fields_ = [ ('illuminant', c_ushort), ('calibration', c_float * 4 * 4), ('colormatrix', c_float * 4 * 3), ('forwardmatrix', c_float * 3 * 4), ] class libraw_canon_makernotes_t(Structure): _fields_ = [ ('CanonColorDataVer', c_int), ('CanonColorDataSubVer', c_int), ('SpecularWhiteLevel', c_int), ('ChannelBlackLevel', c_int * 4), ('AverageBlackLevel', c_int), ('MeteringMode', c_short), ('SpotMeteringMode', c_short), ('FlashMeteringMode', c_char), ('FlashExposureLock', c_short), ('ExposureMode', c_short), ('AESetting', c_short), ('HighlightTonePriority', c_char), ('ImageStabilization', c_short), ('FocusMode', c_short), ('AFPoint', c_short), ('FocusContinuous', c_short), ('AFPointsInFocus30D', c_short), ('AFPointsInFocus1D', c_char * 8), ('AFPointsInFocus5D', c_ushort), ('AFAreaMode', c_ushort), ('NumAFPoints', c_ushort), ('ValidAFPoints', c_ushort), ('AFImageWidth', c_ushort), ('AFImageHeight', c_ushort), ('AFAreaWidths', c_short * 61), ('AFAreaHeights', c_short * 61), ('AFAreaXPositions', c_short * 61), ('AFAreaYPositions', c_short * 61), ('AFPointsInFocus', c_short * 4), ('AFPointsSelected', c_short * 4), ('PrimaryAFPoint', c_ushort), ('FlashMode', c_short), ('FlashActivity', c_short), ('FlashBits', c_short), ('ManualFlashOutput', c_short), ('FlashOutput', c_short), ('FlashGuideNumber', c_short), ('ContinuousDrive', c_short), ('SensorWidth', c_short), ('SensorHeight', c_short), ('SensorLeftBorder', c_short), ('SensorTopBorder', c_short), ('SensorRightBorder', c_short), ('SensorBottomBorder', c_short), ('BlackMaskLeftBorder', c_short), ('BlackMaskTopBorder', c_short), ('BlackMaskRightBorder', c_short), ('BlackMaskBottomBorder', c_short), ] class libraw_dng_levels_t(Structure): _fields_ = [ ('dng_cblack', c_uint * 4102), ('dng_black', c_uint), ('dng_whitelevel', c_uint * 4), ('dng_blacklevel', c_float * 4), ('analogbalance', c_float * 4), ] class libraw_P1_color_t(Structure): _fields_ = [ ('romm_cam', c_float * 9), ] class libraw_colordata_t(Structure): """Describes all color data of the image.""" _fields_ = [ ('curve', c_ushort * 0x10000), ('cblack', c_uint * 4102), ('black', c_uint), ('data_maximum', c_uint), ('maximum', c_uint), ('linear_max', c_long * 4), ('fmaximum', c_float), ('fnorm', c_float), ('white', c_ushort * 8 * 8), ('cam_mul', c_float * 4), ('pre_mul', c_float * 4), ('cmatrix', c_float * 3 * 4), ('ccm', c_float * 3 * 4), ('rgb_cam', c_float * 3 * 4), ('cam_xyz', c_float * 4 * 3), ('phase_one_data', ph1_t), ('flash_used', c_float), ('canon_ev', c_float), ('model2', c_char * 64), ('UniqueCameraModel', c_char * 64), ('LocalizedCameraModel', c_char * 64), ('profile', c_void_p), ('profile_length', c_uint), ('black_stat', c_uint * 8), ('dng_color', libraw_dng_color_t * 2), ('dng_levels', libraw_dng_levels_t), ('baseline_exposure', c_float), ('WB_Coeffs', c_int * 256 * 4), ('WBCT_Coeffs', c_float * 64 * 5), ('P1_color', libraw_P1_color_t * 2), ] class libraw_gps_info_t(Structure): """GPS data for the image.""" _fields_ = [ ('latitude', c_float * 3), ('longitude', c_float * 3), ('gpstimestamp', c_float * 3), ('altitude', c_float), ('altref', c_char), ('latref', c_char), ('longref', c_char), ('gpsstatus', c_char), ('gpsparsed', c_char), ] class libraw_imgother_t(Structure): """ Information read from the raw file that is unnecessary for raw processing. """ _fields_ = [ ('iso_speed', c_float), ('shutter', c_float), ('aperture', c_float), ('focal_len', c_float), ('timestamp', c_uint), # time_t ('shot_order', c_uint), ('gpsdata', c_uint * 32), ('parsed_gps', libraw_gps_info_t), ('desc', c_char * 512), ('artist', c_char * 64), ('FlashEC', c_float), ] class libraw_thumbnail_t(Structure): """Describes the thumbnail image embedded in the raw file.""" _fields_ = [ ('tformat', c_uint), # LibRaw_thumbnail_formats ('twidth', c_ushort), ('theight', c_ushort), ('tlength', c_uint), ('tcolors', c_int), ('thumb', POINTER(c_char)), ] class libraw_internal_output_params_t(Structure): _fields_ = [ ('mix_green', c_uint), ('raw_color', c_uint), ('zero_is_bad', c_uint), ('shrink', c_ushort), ('fuji_width', c_ushort), ] class libraw_rawdata_t(Structure): """ Raw image data (after it has been unpacked) and a backup copy of color info used during post processing. """ _fields_ = [ ('raw_alloc', c_void_p), ('raw_image', POINTER(c_ushort)), ('color4_image', POINTER(c_ushort * 4)), ('color3_image', POINTER(c_ushort * 3)), ('float_image', POINTER(c_float)), ('float3_image', POINTER(c_float * 3)), ('float4_image', POINTER(c_float * 4)), ('ph1_cblack', POINTER(c_short * 2)), ('ph1_rblack', POINTER(c_short * 2)), ('iparams', libraw_iparams_t), ('sizes', libraw_image_sizes_t), ('ioparams', libraw_internal_output_params_t), ('color', libraw_colordata_t), ] class libraw_output_params_t(Structure): """Output parameters for processing the image with dcraw.""" _fields_ = [ ('greybox', c_uint * 4), ('cropbox', c_uint * 4), ('aber', c_double * 4), ('gamm', c_double * 6), ('user_mul', c_float * 4), ('shot_select', c_uint), ('bright', c_float), ('threshold', c_float), ('half_size', c_int), ('four_color_rgb', c_int), ('highlight', c_int), ('use_auto_wb', c_int), ('use_camera_wb', c_int), ('use_camera_matrix', c_int), ('output_color', c_int), ('output_profile', c_char_p), ('camera_profile', c_char_p), ('bad_pixels', c_char_p), ('dark_frame', c_char_p), ('output_bps', c_int), ('output_tiff', c_int), ('user_flip', c_int), ('user_qual', c_int), ('user_black', c_int), ('user_cblack', c_int * 4), ('user_sat', c_int), ('med_passes', c_int), ('auto_bright_thr', c_float), ('adjust_maximum_thr', c_float), ('no_auto_bright', c_int), ('use_fuji_rotate', c_int), ('green_matching', c_int), ('dcb_iterations', c_int), ('dcb_enhance_fl', c_int), ('fbdd_noiserd', c_int), ('eeci_refine', c_int), ('es_med_passes', c_int), ('ca_correc', c_int), ('cared', c_float), ('cablue', c_float), ('cfaline', c_int), ('linenoise', c_float), ('cfa_clean', c_int), ('lclean', c_float), ('cclean', c_float), ('cfa_green', c_int), ('green_thresh', c_float), ('exp_correc', c_int), ('exp_shift', c_float), ('exp_preser', c_float), ('wf_debanding', c_int), ('wf_deband_treshold', c_float * 4), ('use_rawspeed', c_int), ('use_dngsdk', c_int), ('no_auto_scale', c_int), ('no_interpolation', c_int), ('raw_processing_options', c_uint), ('sony_arw2_posterization_thr', c_int), ('coolscan_nef_gamma', c_float), ('p4shot_order', c_char * 5), ('custom_camera_strings', POINTER(c_char_p)), ] class libraw_nikonlens_t(Structure): _fields_ = [ ('NikonEffectiveMaxAp', c_float), ('NikonLensIDNumber', c_ubyte), ('NikonLensFStops', c_ubyte), ('NikonMCUVersion', c_ubyte), ('NikonLensType', c_ubyte), ] class libraw_dnglens_t(Structure): _fields_ = [ ('MinFocal', c_float), ('MaxFocal', c_float), ('MaxAp4MinFocal', c_float), ('MaxAp4MaxFocal', c_float), ] class libraw_makernotes_lens_t(Structure): _fields_ = [ ('LensID', c_ulonglong), ('Lens', c_char * 128), ('LensFormat', c_ushort), ('LensMount', c_ushort), ('CamID', c_ulonglong), ('CameraFormat', c_ushort), ('CameraMount', c_ushort), ('body', c_char * 64), ('FocalType', c_short), ('LensFeatures_pre', c_char * 16), ('LensFeatures_suf', c_char * 16), ('MinFocal', c_float), ('MaxFocal', c_float), ('MaxAp4MinFocal', c_float), ('MaxAp4MaxFocal', c_float), ('MinAp4MinFocal', c_float), ('MinAp4MaxFocal', c_float), ('MaxAp', c_float), ('MinAp', c_float), ('CurFocal', c_float), ('CurAp', c_float), ('MaxAp4CurFocal', c_float), ('MinAp4CurFocal', c_float), ('MinFocusDistance', c_float), ('FocusRangeIndex', c_float), ('LensFStops', c_float), ('TeleconverterID', c_ulonglong), ('Teleconverter', c_char * 128), ('AdapterID', c_ulonglong), ('Adapter', c_char * 128), ('AttachmentID', c_ulonglong), ('Attachment', c_char * 128), ('CanonFocalUnits', c_short), ('FocalLengthIn35mmFormat', c_float), ] class libraw_lensinfo_t(Structure): _fields_ = [ ('MinFocal', c_float), ('MaxFocal', c_float), ('MaxAp4MinFocal', c_float), ('MaxAp4MaxFocal', c_float), ('EXIF_MaxAp', c_float), ('LensMake', c_char * 128), ('Lens', c_char * 128), ('LensSerial', c_char * 128), ('InternalLensSerial', c_char * 128), ('FocalLengthIn35mmFormat', c_ushort), ('nikon', libraw_nikonlens_t), ('dng', libraw_dnglens_t), ('makernotes', libraw_makernotes_lens_t), ] class libraw_processed_image_t(Structure): """A container for processed image data.""" _fields_ = [ ('type', c_uint), ('height', c_ushort), ('width', c_ushort), ('colors', c_ushort), ('bits', c_ushort), ('data_size', c_uint), ('data', c_ubyte * 1), ] class libraw_decoder_info_t(Structure): """Describes a raw format decoder name and format.""" _fields_ = [ ('decoder_name', c_char_p), ('decoder_flags', c_uint), ] class libraw_fuji_info_t(Structure): _fields_ = [ ('FujiExpoMidPointShift', c_float), ('FujiDynamicRange', c_ushort), ('FujiFilmMode', c_ushort), ('FujiDynamicRangeSetting', c_ushort), ('FujiDevelopmentDynamicRange', c_ushort), ('FujiAutoDynamicRange', c_ushort), ('FocusMode', c_ushort), ('AFMode', c_ushort), ('FocusPixel', c_ushort * 2), ('ImageStabilization', c_ushort * 3), ('FlashMode', c_ushort), ('WB_Preset', c_ushort), ('ShutterType', c_ushort), ('ExrMode', c_ushort), ('Macro', c_ushort), ('Rating', c_uint), ('FrameRate', c_ushort), ('FrameWidth', c_ushort), ('FrameHeight', c_ushort), ] class libraw_nikon_makernotes_t(Structure): _fields_ = [ ('ExposureBracketValue', c_double), ('ActiveDLighting', c_ushort), ('ShootingMode', c_ushort), ('ImageStabilization', c_ubyte * 7), ('VibrationReduction', c_ubyte), ('VRMode', c_ubyte), ('FocusMode', c_char * 7), ('AFPoint', c_ubyte), ('AFPointsInFocus', c_ushort), ('ContrastDetectAF', c_ubyte), ('AFAreaMode', c_ubyte), ('PhaseDetectAF', c_ubyte), ('PrimaryAFPoint', c_ubyte), ('AFPointsUsed', c_ubyte * 29), ('AFImageWidth', c_ushort), ('AFImageHeight', c_ushort), ('AFAreaXPposition', c_ushort), ('AFAreaYPosition', c_ushort), ('AFAreaWidth', c_ushort), ('AFAreaHeight', c_ushort), ('ContrastDetectAFInFocus', c_ubyte), ('FlashSetting', c_char * 13), ('FlashType', c_char * 20), ('FlashExposureCompensation', c_ubyte * 4), ('ExternalFlashExposureComp', c_ubyte * 4), ('FlashExposureBracketValue', c_ubyte * 4), ('FlashMode', c_ubyte), ('FlashExposureCompensation2', c_char), ('FlashExposureCompensation3', c_char), ('FlashExposureCompensation4', c_char), ('FlashSource', c_ubyte), ('FlashFirmware', c_ubyte * 2), ('ExternalFlashFlags', c_ubyte), ('FlashControlCommanderMode', c_ubyte), ('FlashOutputAndCompensation', c_ubyte), ('FlashFocalLength', c_ubyte), ('FlashGNDistance', c_ubyte), ('FlashGroupControlMode', c_ubyte * 4), ('FlashGroupOutputAndCompensation', c_ubyte * 4), ('FlashColorFilter', c_ubyte), ] class libraw_olympus_makernotes_t(Structure): _fields_ = [ ('OlympusCropID', c_int), ('OlympusFrame', c_ushort * 4), ('OlympusSensorCalibration', c_int * 2), ('FocusMode', c_ushort * 2), ('AutoFocus', c_ushort), ('AFPoint', c_ushort), ('AFAreas', c_uint * 64), ('AFPointSelected', c_double * 5), ('AFResult', c_ushort), ('ImageStabilization', c_uint), ('ColorSpace', c_ushort), ] class libraw_pentax_makernotes_t(Structure): _fields_ = [ ('FocusMode', c_ushort), ('AFPointMode', c_ubyte), ('AFPointSelected', c_ushort), ('AFPointsInFocus', c_uint), ('DriveMode', c_ubyte * 4), ('SRResult', c_ubyte), ('ShakeReduction', c_ubyte), ] class libraw_sony_info_t(Structure): _fields_ = [ ('SonyCameraType', c_ushort), ] class libraw_makernotes_t(Structure): _fields_ = [ ('canon', libraw_canon_makernotes_t), ('fuji', libraw_fuji_info_t), ('olympus', libraw_olympus_makernotes_t), ('sony', libraw_sony_info_t), ] class libraw_shootinginfo_t(Structure): _fields_ = [ ('DriveMode', c_short), ('FocusMode', c_short), ('MeteringMode', c_short), ('AFPoint', c_short), ('ExposureMode', c_short), ('ImageStabilization', c_short), ('BodySerial', c_char * 64), ('InternalBodySerial', c_char * 64), ] class libraw_custom_camera_t(Structure): _fields_ = [ ('fsize', c_uint), ('rw', c_ushort), ('rh', c_ushort), ('lm', c_ubyte), ('tm', c_ubyte), ('rm', c_ubyte), ('bm', c_ubyte), ('lf', c_ubyte), ('cf', c_ubyte), ('max', c_ubyte), ('flags', c_ubyte), ('t_make', c_char * 10), ('t_model', c_char * 20), ('offset', c_ushort) ] class libraw_data_t(Structure): """ A container which comprises the data structures that make up libraw's representation of a raw file. """ _fields_ = [ ('image', POINTER(c_ushort * 4)), ('sizes', libraw_image_sizes_t), ('idata', libraw_iparams_t), ('lens', libraw_lensinfo_t), ('makernotes', libraw_makernotes_t), ('shootinginfo', libraw_shootinginfo_t), ('params', libraw_output_params_t), ('progress_flags', c_uint), ('process_warnings', c_uint), ('color', libraw_colordata_t), ('other', libraw_imgother_t), ('thumbnail', libraw_thumbnail_t), ('rawdata', libraw_rawdata_t), ('parent_class', c_void_p), ] class xtrans_params(Structure): _fields_ = [ ('q_table', POINTER(c_char)), ('q_points', c_int * 5), ('max_bits', c_int), ('min_value', c_int), ('raw_bits', c_int), ('total_values', c_int), ('maxDiff', c_int), ('line_width', c_ushort), ] rawkit-0.6.0/rawkit.egg-info/000077500000000000000000000000001322174307200160125ustar00rootroot00000000000000rawkit-0.6.0/rawkit.egg-info/PKG-INFO000066400000000000000000000044401322174307200171110ustar00rootroot00000000000000Metadata-Version: 1.1 Name: rawkit Version: 0.6.0 Summary: CTypes based LibRaw bindings Home-page: https://rawkit.readthedocs.org Author: Cameron Paul, Sam Whited Author-email: sam@samwhited.com License: UNKNOWN Description: rawkit ====== .. image:: https://badge.fury.io/py/rawkit.svg? :alt: Package Status :target: https://pypi.python.org/pypi/rawkit .. image:: https://readthedocs.org/projects/rawkit/badge/?version=latest :alt: Docs Status :target: https://rawkit.readthedocs.org/en/latest/ .. image:: https://secure.travis-ci.org/photoshell/rawkit.svg?branch=master :alt: Build Status :target: https://travis-ci.org/photoshell/rawkit .. image:: https://img.shields.io/coveralls/photoshell/rawkit.svg?style=flat :alt: Test Coverage Status :target: https://coveralls.io/r/photoshell/rawkit ``rawkit`` (pronounced `rocket`) is a ctypes-based LibRaw_ binding for Python inspired by the Wand_ API. .. sourcecode:: python from rawkit.raw import Raw from rawkit.options import WhiteBalance with Raw(filename='some/raw/image.CR2') as raw: raw.options.white_balance = WhiteBalance(camera=False, auto=True) raw.save(filename='some/destination/image.ppm') for more info, see the docs_ .. _LibRaw: http://www.libraw.org/ .. _Wand: http://docs.wand-py.org .. _docs: https://rawkit.readthedocs.org/en/latest/ Keywords: encoding,images,photography,libraw,raw,photos Platform: UNKNOWN Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 2 Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.3 Classifier: Programming Language :: Python :: 3.4 Classifier: Programming Language :: Python :: Implementation :: PyPy Classifier: Development Status :: 3 - Alpha Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: MIT License Classifier: Operating System :: OS Independent Classifier: Topic :: Software Development :: Libraries :: Python Modules rawkit-0.6.0/rawkit.egg-info/SOURCES.txt000066400000000000000000000012171322174307200176770ustar00rootroot00000000000000.coveragerc .pre-commit-config.yaml LICENSE MANIFEST.in Makefile README.rst requirements-dev.txt setup.cfg setup.py tox.ini libraw/__init__.py libraw/bindings.py libraw/callbacks.py libraw/errors.py libraw/structs_16.py libraw/structs_17.py libraw/structs_18.py rawkit/__init__.py rawkit/errors.py rawkit/metadata.py rawkit/options.py rawkit/raw.py rawkit/util.py rawkit.egg-info/PKG-INFO rawkit.egg-info/SOURCES.txt rawkit.egg-info/dependency_links.txt rawkit.egg-info/requires.txt rawkit.egg-info/top_level.txt tests/__init__.py tests/unit/__init__.py tests/unit/bindings_test.py tests/unit/options_test.py tests/unit/raw_test.py tests/unit/util_test.pyrawkit-0.6.0/rawkit.egg-info/dependency_links.txt000066400000000000000000000000011322174307200220600ustar00rootroot00000000000000 rawkit-0.6.0/rawkit.egg-info/requires.txt000066400000000000000000000000251322174307200204070ustar00rootroot00000000000000 [doc] sphinx >= 1.3 rawkit-0.6.0/rawkit.egg-info/top_level.txt000066400000000000000000000000161322174307200205410ustar00rootroot00000000000000libraw rawkit rawkit-0.6.0/rawkit/000077500000000000000000000000001322174307200143205ustar00rootroot00000000000000rawkit-0.6.0/rawkit/__init__.py000066400000000000000000000012761322174307200164370ustar00rootroot00000000000000"""Introduction ~~~~~~~~~~~~~~~ The :mod:`rawkit` module contains high-level APIs for manipulating raw photos using the low-level :mod:`libraw` module (which in turn uses the even lower-level LibRaw C library). Eg. quickly processing a raw Canon CR2 file without using the camera white balance and saving it as a PPM image might look like this: .. sourcecode:: python from rawkit.raw import Raw from rawkit.options import WhiteBalance with Raw(filename='some/raw/image.CR2') as raw: raw.options.white_balance = WhiteBalance(camera=False, auto=True) raw.save(filename='some/destination/image.ppm') """ VERSION = '0.6.0' """ The current version of the `rawkit` package. """ rawkit-0.6.0/rawkit/errors.py000066400000000000000000000012131322174307200162030ustar00rootroot00000000000000""":mod:`rawkit.errors` --- Errors thrown by rawkit ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ These errors are thrown by various rawkit functions and methods when things go wrong. They will only be raised by rawkit; for lower level errors raised by the underlying libraw bindings, see :class:`libraw.errors`. """ class InvalidFileType(ValueError): """ Raised when an invalid file type or file extension is passed to a rawkit method. """ class NoFileSpecified(ValueError): """ Raised when the method or function excpects a `filename` argument, but no file name (or a value of `None`) was specified. """ rawkit-0.6.0/rawkit/metadata.py000066400000000000000000000010451322174307200164520ustar00rootroot00000000000000""":mod:`rawkit.metadata` --- Metadata structures ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ """ from collections import namedtuple Orientation = namedtuple('Orientation', [ 'landscape', 'portrait', ])(0, 1) """ Represents the orientation of an image. Either `landscape` or `portrait`. """ Metadata = namedtuple('Metadata', [ 'aperture', 'timestamp', 'shutter', 'flash', 'focal_length', 'height', 'iso', 'make', 'model', 'orientation', 'width', ]) """ Common metadata for a photo. """ rawkit-0.6.0/rawkit/options.py000066400000000000000000000603551322174307200163760ustar00rootroot00000000000000""":mod:`rawkit.options` --- High level options for processing raw files ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ """ import ctypes from collections import namedtuple class option(object): """ The :class:`option` decorator is an internal decorator which allows you to define an option in a clean manner (specifying its name and how it maps to the libraw params). """ def __init__(self, param=None, ctype=None): if callable(param): func = param param = None else: func = None self._prepare_func(func) self.param = param self.ctype = ctype self.setter_func = None self.param_func = None def _prepare_func(self, func): self.func = func if func is not None: self.__doc__ = getattr(func, '__doc__') self.__name__ = getattr(func, '__name__') self.internal_name = '_{name}'.format(name=self.__name__) self.__module__ = getattr(func, '__module__') def __call__(self, func=None): self._prepare_func(func) if func is None: raise TypeError("option should not be called except as a property") self.func = func return self def setter(self, func): self.setter_func = func return self def param_writer(self, func): self.param_func = func return self def write_param(self, obj, params): if self.param_func is None: val = self.__get__(obj, None) try: setattr(params, self.param, self.ctype(*val)) except TypeError: setattr(params, self.param, self.ctype(val)) else: self.param_func(obj, params) def __set__(self, obj, value): if self.setter_func is None: setattr(obj, self.internal_name, value) else: self.setter_func(obj, value) def __get__(self, obj, cls): try: val = getattr(obj, self.internal_name) if val is None: return self.func(obj) else: return val except AttributeError: # We're probably generating the documentation... return self highlight_modes = namedtuple( 'HighlightMode', ['clip', 'ignore', 'blend', 'reconstruct'] )(0, 1, 2, 5) """ Constants for setting the highlight mode. - ``clip`` --- Clip all highlights to white (default). - ``ignore`` --- Leave highlights unclipped. - ``blend`` --- Blend clipped and unclipped highlights. - ``reconstruct`` --- A good average value for reconstruction of clipped highlights which compromises between favoring whites and favoring colors. """ gamma_curves = namedtuple( 'GammaCurves', ['linear', 'bt709', 'srgb', 'adobe_rgb'] )([1, 1], [1 / 2.222, 4.5], [1 / 2.4, 12.92], [256 / float(563)]) """ Gamma curves for a few common color profiles. - ``linear`` --- A basic linear transfer function. - ``bt709`` --- The BT.709 (Rec. 709) curve used by HDTVs (uses the median power of sRGB, and a similar but shifted transfer function). - ``srgb`` --- The sRGB gamma curve (uses the max power to account for linear discontinuity and to attain the standard `IEC 61966-2-1` solution $K_0 \\\\approx 0.04045 $). - ``adobe_rgb`` --- The correction function power for the Adobe RGB colorspace. The toe-slope is left off. """ colorspaces = namedtuple( 'ColorSpaces', ['raw', 'srgb', 'adobe_rgb', 'wide_gammut_rgb', 'kodak_prophoto_rgb', 'xyz'] )(0, 1, 2, 3, 4, 5) """ Constants for setting the colorspace. - ``raw_color`` --- Raw colorspace (unique to each camera) - ``srgb`` --- sRGB D65 (default colorspace) - ``adobe_rgb`` --- Adobe RGB (1998) D65 - ``wide_gammut_rgb`` --- Wide Gamut RGB D65 - ``kodak_prophoto_rgb`` --- Kodak ProPhoto RGB D65 - ``xyz`` --- XYZ colorspace """ interpolation = namedtuple( 'InterpolationAlgo', ['linear', 'vng', 'ppg', 'ahd', 'dcb', 'modified_ahd', 'afd', 'vcd', 'mixed_vcd_modified_ahd', 'lmmse', 'amaze'] )(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10) """ Constants for setting the interpolation algorithm: 0. Linear 1. VNG 2. PPG 3. AHD 4. DCB 5. Modified AHD 6. AFD 7. VCD 8. Mixed VCD and Modified AHD 9. LMMSE 10. AMaZE Modified AHD (5) through LMMSE (9) are only useful if you're using a version of LibRaw with the "`LibRaw Demosaic Pack GPL2`_" built in and AMaZE (10) is only useful if LibRaw was built with the "`LibRaw Demosaic Pack GPL3`_". If you attepmt to use an interpolation method that's not built into your version of LibRaw, it will silently fallback to AHD. Usage example: .. sourcecode:: python from rawkit.raw import Raw from rawkit.options import interpolation with Raw(filename="RawFile.CR2") as raw: raw.options.interpolation = interpolation.ahd raw.save("RawFile.ppm") .. _LibRaw Demosaic Pack GPL2: https://github.com/LibRaw/LibRaw-demosaic-pack-GPL2 .. _LibRaw Demosaic Pack GPL3: https://github.com/LibRaw/LibRaw-demosaic-pack-GPL3 """ class WhiteBalance(namedtuple('WhiteBalance', ['auto', 'camera', 'greybox', 'rgbg'])): """ Represents the white balance of a photo. If the camera white balance is used, but not present, we fallback to the other options. Other options white balance multipliers stack (eg. you can use auto white balance, and then specify a manual ``rgbg`` multiplier on top of that). Args: auto (boolean): Determines if we should automatically set the WB. camera (boolean): Causes us to use the camera defined WB if present. greybox (4 int tuple): Set the WB based on a neutral grey region of the image. rgbg (4 float tuple): Set the WB manually based on an RGBG channel multiplier. Returns: WhiteBalance: A white balance object. """ __slots__ = () def __new__(cls, auto=False, camera=False, greybox=None, rgbg=None): return super(WhiteBalance, cls).__new__( cls, auto, camera, greybox, rgbg) class Options(object): """ Represents a set of options which can be used when processing raw data. Args: attrs (dict): A subscriptable object from which to take the initial state of the options object. """ __slots__ = [ '_bps', '_brightness', '_auto_brightness', '_auto_brightness_threshold', '_chromatic_aberration', '_darkness', '_half_size', '_noise_threshold', '_rgbg_interpolation', '_saturation', '_shot', '_use_camera_matrix', '_white_balance', '_highlight_mode', '_colorspace', '_output_profile', '_input_profile', '_use_camera_profile', '_cropbox', '_gamma', '_interpolation', '_auto_stretch', '_rotation', '_dark_frame', '_green_matching', '_bad_pixels_file', '_median_filter_passes', '_adjust_maximum_threshold', ] def __init__(self, attrs=None): """ Create the options object, initializing values to ``None`` or their corresponding value from `attrs`. """ for i in self.__slots__: try: param = i[1:] setattr(self, param, attrs[param]) except (KeyError, TypeError): setattr(self, i, None) def __iter__(self): """Allow iterating over the options.""" idx = 0 while True: idx += 1 try: yield self.keys()[idx - 1] except IndexError: raise StopIteration def __repr__(self): """Represents the options as a dict.""" return repr(dict(self)) def keys(self): """ A list of keys which have a value other than ``None`` and which have been set by the user (even if those options are set to the default value). Returns: tuple: List of option keys which have been set. """ return [slot[1:] for slot in self.__slots__ if getattr(self, slot) is not None] def values(self): """ The values of all options which appear in :func:`keys`. Returns: tuple: List of options values. """ return [self.__getitem__(k) for k in self.keys()] def __getitem__(self, k): """ Allow accessing options with dictionary syntax eg. :: opts['half_size']. """ return getattr(self, k) @option(param='output_color', ctype=ctypes.c_int) def colorspace(self): """ Sets the colorspace used for the output image. Supported colorspaces are defined as constants in :class:`rawkit.options.colorspaces`. :type: :class:`int` :default: :class:`rawkit.options.colorspaces.srgb` :dcraw: ``-o`` :libraw: :class:`libraw.structs.libraw_output_params_t.output_color` """ return colorspaces.srgb @option(param='highlight', ctype=ctypes.c_int) def highlight_mode(self): """ The mode for dealing with highlights in the image. Some constants have been defined in :class:`rawkit.options.highlight_modes` to make things easier, or you can set an integer directly. Integers that are greater than or equal to 3 will attempt to reconstruct highlights. Lower numbers favor whites, and higher colors favor colors. :class:`rawkit.options.RECONSTRUCT` (5) is a good compromise. :type: :class:`int` :default: :class:`rawkit.options.highlight_modes.clip` :dcraw: ``-H`` :libraw: :class:`libraw.structs.libraw_output_params_t.highlight` """ return highlight_modes.clip @option def white_balance(self): """ The white balance of the image. :type: :class:`rawkit.options.WhiteBalance` :default: WhiteBalance(auto=True, camera=True) :dcraw: ``-a`` ``-w`` ``-A`` ``-r`` :libraw: :class:`libraw.structs.libraw_output_params_t.use_auto_wb` :class:`libraw.structs.libraw_output_params_t.use_camera_wb` :class:`libraw.structs.libraw_output_params_t.greybox` :class:`libraw.structs.libraw_output_params_t.user_mul` """ return WhiteBalance(auto=True, camera=True) @white_balance.param_writer def white_balance(self, params): if self.white_balance.greybox is not None: params.greybox = (ctypes.c_uint * 4)(*self.white_balance.greybox) if self.white_balance.rgbg is not None: params.user_mul = (ctypes.c_float * 4)(*self.white_balance.rgbg) params.use_camera_wb = ctypes.c_int(self.white_balance.camera) params.use_auto_wb = ctypes.c_int(self.white_balance.auto) @option(param='use_camera_matrix', ctype=ctypes.c_int) def use_camera_matrix(self): """ Use the color matrix from the raw's metadata. Only affects Olympus, Leaf, and Phase One cameras (and DNG files). Note that we differ from the LibRaw defaults on this option. LibRaw defaults to true if the photo is in DNG format or the camera white balance is being used, and false otherwise. rawkit always defaults to true. :type: :class:`boolean` :default: True :dcraw: ``+M`` ``-M`` :libraw: :class:`libraw.libraw_output_params_t.use_camera_matrix` """ return True @option(param='shot_select', ctype=ctypes.c_uint) def shot(self): """ Selects the shot to process for raw images that contain multiple images. :type: :class:`int` :default: 0 :dcraw: ``-s`` :libraw: :class:`libraw.structs.libraw_output_params_t.shot_select` """ return None @option(param='user_sat', ctype=ctypes.c_int) def saturation(self): """ Determines the saturation level of the output image. :type: :class:`int` :default: None :dcraw: ``-S`` :libraw: :class:`libraw.structs.libraw_output_params_t.user_sat` """ return None @option(param='four_color_rgb', ctype=ctypes.c_int) def rgbg_interpolation(self): """ Determines if we should use four channel RGB interpolation. :type: :class:`boolean` :default: False :dcraw: ``-f`` :libraw: :class:`libraw.structs.libraw_output_params_t.four_color_rgb` """ return False @option(param='threshold', ctype=ctypes.c_float) def noise_threshold(self): """ Sets the threshold for noise reduction using wavelet denoising. :type: :class:`float` :default: None :dcraw: ``-n`` :libraw: :class:`libraw.structs.libraw_output_params_t.threshold` """ return None @option(param='half_size', ctype=ctypes.c_int) def half_size(self): """ When developing the image, output it at 50% size. This makes developing preview images much faster. :type: :class:`boolean` :default: False :dcraw: ``-h`` :libraw: :class:`libraw.structs.libraw_output_params_t.half_size` """ return False @option(param='user_black', ctype=ctypes.c_int) def darkness(self): """ Raise the black level of a photo. :type: :class:`int` :default: None :dcraw: ``-k`` :libraw: :class:`libraw.structs.libraw_output_params_t.user_black` """ return None @option def chromatic_aberration(self): """ A Red-Blue scale factor that's used to correct for chromatic aberration by scaling the respective channels. eg. :: # (red_scale, blue_scale) raw.options.chromatic_aberration = (0.999, 1.001) :type: :class:`double tuple` :default: (1, 1) :dcraw: ``-C`` :libraw: :class:`libraw.structs.libraw_output_params_t.aber` """ return (1, 1) @chromatic_aberration.param_writer def chromatic_aberration(self, params): params.aber = (ctypes.c_double * 4)(*( self.chromatic_aberration[0], 0, # TODO: What is this index used for? self.chromatic_aberration[1], 0 # TODO: What is this index used for? )) @option(param='output_bps', ctype=ctypes.c_int) def bps(self): """ Set the bits per sample used for the photo (8 or 16). Setting this to 16 is effectively the same as running dcraw with the ``-4`` option. :type: :class:`int` :default: 8 :dcraw: ``-4`` :libraw: :class:`libraw.structs.libraw_output_params_t.output_bps` """ return 8 @bps.setter def bps(self, value): if value in (8, 16): self._bps = value else: raise ValueError("BPS must be 8 or 16") @option(param='cropbox', ctype=(ctypes.c_uint * 4)) def cropbox(self): """ Crops the image. :type: :class:`4 float tuple` :default: None :dcraw: None :libraw: :class:`libraw.structs.libraw_output_params_t.cropbox` """ return None @option(param='gamm', ctype=(ctypes.c_double * 6)) def gamma(self): """ Sets the gamma-curve of the photo. The two values in the tuple correspond to: - gamma[0] --- Correction function power (inverted Gamma power, $\\\\gamma^{-1}$) - gamma[1] --- toe-slope ($\\\\phi$) For a simple power curve, set the toe-slope to zero. :type: :class:`2 double tuple` :default: None :dcraw: ``-g`` :libraw: :class:`libraw.structs.libraw_output_params_t.gamm` """ return None @option(param='interpolation', ctype=ctypes.c_uint) def interpolation(self): """ Sets the interpolation algorithm. :type: :class:`rawkit.options.interpolation` :default: `ahd` :dcraw: ``-q`` :libraw: :class:`libraw.structs.libraw_output_params_t.user_qual` """ return interpolation.ahd @option(param='bright', ctype=ctypes.c_float) def brightness(self): """ Sets the brightness level by dividing the white level by this value. This is ignored if :class:`~auto_brightness` is ``True``. :type: :class:`float` :default: 1.0 :dcraw: ``-b`` :libraw: :class:`libraw.structs.libraw_output_params_t.bright` """ return None @option(param='auto_bright_thr', ctype=ctypes.c_float) def auto_brightness_threshold(self): """ The allowable percentage of clipped pixels when :class:`~auto_brightness` is used. :type: :class:`float` :default: 0.001 (0.1%) :dcraw: None :libraw: :class:`libraw.structs.libraw_output_params_t.auto_bright_thr` """ return 0.001 @option def auto_brightness(self): """ Set the brightness automatically based on the image histogram and the :class:`~auto_brightness_threshold`. :type: :class:`boolean` :default: True :dcraw: ``-W`` :libraw: :class:`libraw.structs.libraw_output_params_t.no_auto_bright` """ return True @auto_brightness.param_writer def auto_brightness(self, param): param.no_auto_bright = ctypes.c_int(not self.auto_brightness) @option(param='use_fuji_rotate', ctype=ctypes.c_int) def auto_stretch(self): """ Stretches images taken on cameras with non-square pixels to the correct aspect ratio. For Fuji Super CCD cameras, rotates the image 45 degrees. This guarantees that the output pixels share a 1:1 correspondence with the raw pixels. :type: :class:`boolean` :default: True :dcraw: ``-j`` :libraw: :class:`libraw.structs.libraw_output_params_t.use_fuji_rotate` """ return True @option def rotation(self): """ Rotates the image by the given number of degrees. Must be a multiple of 90 (0, 90, 180, 270, etc). The default (None) is to use the rotation provided by the camera. :type: :class:`int` :default: None :dcraw: ``-t`` :libraw: :class:`libraw.structs.libraw_output_params_t.user_flip` """ return None @rotation.setter def rotation(self, value): if value is not None and value > 0: value = ((value + 3600) % 360) if value in (None, 0, 90, 180, 270): self._rotation = value else: raise ValueError('Rotation must be None (use camera rotation) or ' 'a multiple of 90') @rotation.param_writer def rotation(self, params): params.user_flip = ctypes.c_int({ 270: 5, 180: 3, 90: 6, 0: 0 }[self.rotation]) @option def dark_frame(self): """ A dark frame in 16-bit PGM format. This may either be a path to an existing file, or an instance of :class:`rawkit.raw.DarkFrame`. :type: :class:`rawkit.raw.DarkFrame` :class:`str` :default: None :dcraw: ``-K`` :libraw: :class:`libraw.structs.libraw_output_params_t.dark_frame` """ return None @dark_frame.setter def dark_frame(self, value): self._dark_frame = value @dark_frame.param_writer def dark_frame(self, params): try: self.dark_frame.save() params.dark_frame = ctypes.c_char_p( self.dark_frame.name.encode('utf-8') ) except AttributeError: params.dark_frame = ctypes.c_char_p( self.dark_frame.encode('utf-8') ) @option(param='green_matching', ctype=ctypes.c_int) def green_matching(self): """ Performs a second post-processing pass to correct for green channel imbalance. :type: :class:`boolean` :default: False :dcraw: None :libraw: :class:`libraw.structs.libraw_output_params_t.green_matching` """ return False @option(param='output_profile', ctype=ctypes.c_char_p) def output_profile(self): """ Path to an ICC color profile file containing the output profile. Only used if the version of LibRaw that you're linking against was compiled with LCMS support. :type: :class:`string` :default: None :dcraw: ``-o`` ``-p`` :libraw: :class:`libraw.structs.libraw_output_params_t.output_profile` """ return None @option(param='camera_profile', ctype=ctypes.c_char_p) def input_profile(self): """ Path to an ICC color profile file containing the input profile. Only used if the version of LibRaw that you're linking against was compiled with LCMS support. Note that LibRaw defines a magic string, 'embed', which causes it to use the profile embedded in the raw image if present. This is the same as setting the :class:`~use_camera_profile` option. :type: :class:`string` :default: None :dcraw: ``-o`` ``-p`` :libraw: :class:`libraw.structs.libraw_output_params_t.camera_profile` """ return None @option def use_camera_profile(self): """ True if we should use the embedded camera profile (if present in the raw file and we're linking against a version of LibRaw with LCMS support). :type: :class:`boolean` :default: True :dcraw: ``-o`` ``-p`` :libraw: :class:`libraw.structs.libraw_output_params_t.camera_profile` """ return True @use_camera_profile.setter def use_camera_profile(self, value): self._use_camera_profile = value @use_camera_profile.param_writer def use_camera_profile(self, params): if self.use_camera_profile: params.camera_profile = ctypes.c_char_p(b'embed') else: params.camera_profile = None @option(param='bad_pixels', ctype=ctypes.c_char_p) def bad_pixels_file(self): """ Points to a bad pixels map in dcraw format: :: column row unix-timestamp\\n :type: :class:`str` :default: None :dcraw: ``-P`` :libraw: :class:`libraw.structs.libraw_output_params_t.bad_pixels` """ return None @option(param='med_passes', ctype=ctypes.c_int) def median_filter_passes(self): """ Useful for cleaning up color artifacts by running a 3x3 median filter over the R-G and B-G channels. :type: :class:`int` :default: 0 :dcraw: ``-m`` :libraw: :class:`libraw.structs.libraw_output_params_t.med_passes` """ return 0 @option(param='adjust_maximum_thr', ctype=ctypes.c_float) def adjust_maximum_threshold(self): """ Automatically adjusts the maximum pixel value based on per channel maximum data. Note: If this value is set above 0.99999, the default value will be used instead. If it is set below 0.00001, no adjustment will happen. :type: :class:`float` :default: 0.75 :dcraw: None :libraw: :class:`libraw.structs.libraw_output_params_t.adjust_maximum_thr` """ return 0 def _map_to_libraw_params(self, params): """ Internal method that writes rawkit options into the libraw options struct with the proper C data types. Args: params (libraw.structs.libraw_output_params_t): The output params struct to set. """ for slot in self.__slots__: prop = slot[1:] opt = getattr(Options, prop) if type(opt) is option and getattr(self, prop) is not None: opt.write_param(self, params) # This generally isn't needed, except for testing. return params rawkit-0.6.0/rawkit/raw.py000066400000000000000000000332421322174307200154670ustar00rootroot00000000000000""":mod:`rawkit.raw` --- High-level raw file API ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ """ import ctypes import os import random import string import tempfile import warnings from collections import namedtuple from libraw.bindings import LibRaw from libraw.errors import raise_if_error from rawkit.errors import InvalidFileType from rawkit.errors import NoFileSpecified from rawkit.metadata import Metadata from rawkit.options import Options output_file_types = namedtuple( 'OutputFileType', ['ppm', 'tiff'] )('ppm', 'tiff') """ Constants for setting the output filetype. - ``ppm`` --- PGM data file. - ``tiff`` --- TIFF file. """ class Raw(object): """ Represents a raw file (of any format) and exposes development options to the user. For example, the basic workflow (open a file, process the file, save the file) looks like this:: from rawkit.raw import Raw from rawkit.options import WhiteBalance with Raw(filename='some/raw/image.CR2') as raw: raw.options.white_balance = WhiteBalance(camera=False, auto=True) raw.save(filename='some/destination/image.ppm') Args: filename (str): The name of a raw file to load. Returns: Raw: A raw object. Raises: rawkit.errors.NoFileSpecified: If `filename` is ``None``. libraw.errors.FileUnsupported: If the specified file is not a supported raw type. libraw.errors.InsufficientMemory: If we run out of memory while loading the raw file. IOError: If the file does not exist, or cannot be opened (eg. incorrect permissions). """ def __init__(self, filename=None): """Initializes a new Raw object.""" if filename is None: raise NoFileSpecified() self.libraw = LibRaw() self.data = self.libraw.libraw_init(0) self.libraw.libraw_open_file(self.data, filename.encode('ascii')) self.options = Options() self.image_unpacked = False self.thumb_unpacked = False def __enter__(self): """Return a Raw object for use in context managers.""" return self def __exit__(self, exc_type, exc_value, traceback): """Clean up after ourselves when leaving the context manager.""" self.close() def close(self): """Free the underlying raw representation.""" self.libraw.libraw_close(self.data) def unpack(self): """Unpack the raw data.""" if not self.image_unpacked: self.libraw.libraw_unpack(self.data) self.image_unpacked = True def unpack_thumb(self): """ Unpack the thumbnail data. Raises: libraw.errors.NoThumbnail: If the raw file does not contain a thumbnail. libraw.errors.UnsupportedThumbnail: If the thumbnail format is unsupported. """ if not self.thumb_unpacked: self.libraw.libraw_unpack_thumb(self.data) self.thumb_unpacked = True def process(self): """ Process the raw data based on ``self.options``. Raises: libraw.errors.DataError: If invalid or corrupt data is encountered in the data struct. libraw.errors.BadCrop: If the image has been cropped poorly (eg. the edges are outside of the image bounds, or the crop box coordinates don't make sense). """ self.options._map_to_libraw_params(self.data.contents.params) self.libraw.libraw_dcraw_process(self.data) def save(self, filename=None, filetype=None): """ Save the image data as a new PPM or TIFF image. Args: filename (str): The name of an image file to save. filetype (output_file_types): The type of file to output. By default, guess based on the filename, falling back to PPM. Raises: rawkit.errors.NoFileSpecified: If `filename` is ``None``. rawkit.errors.InvalidFileType: If `filetype` is not None or in :class:`output_file_types`. """ if filename is None: raise NoFileSpecified() if filetype is None: ext = os.path.splitext(filename)[-1].lower()[1:] filetype = ext or output_file_types.ppm if filetype not in output_file_types: raise InvalidFileType( "Output filetype must be in raw.output_file_types") self.data.contents.params.output_tiff = ( filetype == output_file_types.tiff ) self.unpack() self.process() self.libraw.libraw_dcraw_ppm_tiff_writer( self.data, filename.encode('ascii')) def save_thumb(self, filename=None): """ Save the thumbnail data. Args: filename (str): The name of an image file to save. Raises: rawkit.errors.NoFileSpecified: If `filename` is ``None``. """ if filename is None: raise NoFileSpecified() self.unpack_thumb() self.libraw.libraw_dcraw_thumb_writer( self.data, filename.encode('ascii')) @property def color_description(self): """ Get the color_description of an image. Returns: str: 4 character string representing color format, such as 'RGGB'. """ # TODO: remove the pragma once there is integration testing, # but until then testing this is entirely pointless. return self.data.contents.idata.cdesc # pragma: no cover def color(self, y, x): """ Get the active color of a pixel of bayer data. Args: y (int): the y coordinate (or row) of the pixel x (int): the x coordinate (or column) of the pixel Returns: str: Character representing the color, such as 'R' for red. """ color_index = self.libraw.libraw_COLOR(self.data, y, x) return chr(self.color_description[color_index]) @property def color_filter_array(self): """ EXPERIMENTAL: This method only supports bayer filters for the time being. It will be incorrect when used with other types of sensors. Get the color filter array for the camera sensor. Returns: list: 2D array representing the color format array pattern. For example, the typical 'RGGB' pattern of abayer sensor would be of the format:: [ ['R', 'G'], ['G', 'B'], ] """ # TODO: don't assume 2x2 bayer sensor return [[self.color(0, 0), self.color(0, 1)], [self.color(1, 0), self.color(1, 1)]] def raw_image(self, include_margin=False): """ Get the bayer data for an image if it exists. Args: include_margin (bool): Include margin with calibration pixels. Returns: list: 2D array of bayer pixel data structured as a list of rows, or None if there is no bayer data. For example, if the color format is `RGGB`, the array would be of the format:: [ [R, G, R, G, ...], [G, B, G, B, ...], [R, G, R, G, ...], ... ] """ self.unpack() image = self.data.contents.rawdata.raw_image if not bool(image): return [] sizes = self.data.contents.sizes # TODO: handle this if sizes.pixel_aspect != 1: warnings.warn( "The pixel aspect is not unity, it is: " + str(sizes.pixel_aspect) ) # TODO: handle this if sizes.flip != 0: warnings.warn( "The image is flipped." ) pitch = sizes.raw_width if include_margin: first = 0 width = sizes.raw_width height = sizes.raw_height else: first = sizes.raw_width * sizes.top_margin + sizes.left_margin width = sizes.width height = sizes.height data_pointer = ctypes.cast( image, ctypes.POINTER(ctypes.c_ushort) ) data = [] for y in range(height): row = [] for x in range(width): row.append(data_pointer[first + y * pitch + x]) data.append(row) return data def bayer_data(self, include_margin=False): """ Get the bayer data and color_description for an image. Returns: tuple: Tuple of bayer data and color filter array. This is a convenience method to return `rawkit.raw.Raw.raw_image` and `rawkit.raw.Raw.color_filter_array` as a single tuple. """ return self.raw_image(include_margin), self.color_filter_array def to_buffer(self): """ Convert the image to an RGB buffer. Returns: bytearray: RGB data of the image. """ self.unpack() self.process() status = ctypes.c_int(0) processed_image = self.libraw.libraw_dcraw_make_mem_image( self.data, ctypes.cast( ctypes.addressof(status), ctypes.POINTER(ctypes.c_int), ), ) raise_if_error(status.value) data_pointer = ctypes.cast( processed_image.contents.data, ctypes.POINTER(ctypes.c_byte * processed_image.contents.data_size) ) data = bytearray(data_pointer.contents) self.libraw.libraw_dcraw_clear_mem(processed_image) return data def thumbnail_to_buffer(self): """ Convert the thumbnail data as an RGB buffer. Returns: bytearray: RGB data of the thumbnail. """ self.unpack_thumb() status = ctypes.c_int(0) processed_image = self.libraw.libraw_dcraw_make_mem_thumb( self.data, ctypes.cast( ctypes.addressof(status), ctypes.POINTER(ctypes.c_int), ), ) raise_if_error(status.value) data_pointer = ctypes.cast( processed_image.contents.data, ctypes.POINTER(ctypes.c_byte * processed_image.contents.data_size) ) data = bytearray(data_pointer.contents) self.libraw.libraw_dcraw_clear_mem(processed_image) return data @property def metadata(self): """ Common metadata for the photo Returns: rawkit.metadata.Metadata: A metadata object. """ return Metadata( aperture=self.data.contents.other.aperture, timestamp=self.data.contents.other.timestamp, shutter=self.data.contents.other.shutter, flash=bool(self.data.contents.color.flash_used), focal_length=self.data.contents.other.focal_len, height=self.data.contents.sizes.height, iso=self.data.contents.other.iso_speed, make=self.data.contents.idata.make, model=self.data.contents.idata.model, orientation=self.data.contents.sizes.flip, width=self.data.contents.sizes.width, ) class DarkFrame(Raw): """ Represents a dark frame---a raw photo taken in low light which can be subtracted from another photos raw data. Creates a temporary file which is not cleaned up until the dark frame is closed. """ def __init__(self, filename=None): """Initializes a new DarkFrame object.""" super(DarkFrame, self).__init__(filename=filename) self.options = Options({ 'auto_brightness': False, 'brightness': 1.0, 'auto_stretch': True, 'bps': 16, 'gamma': (1, 1), 'rotation': 0, }) self._tmp = os.path.join( tempfile.gettempdir(), '{prefix}{rand}'.format( prefix=tempfile.gettempprefix(), rand=''.join(random.SystemRandom().choice( string.ascii_uppercase + string.digits) for _ in range(8) ) ) ) self._filetype = None def save(self, filename=None, filetype=output_file_types.ppm): """ Save the image data, defaults to using a temp file. Args: filename (str): The name of an image file to save. filetype (output_file_types): The type of file to output. Raises: rawkit.errors.InvalidFileType: If `filetype` is not of type :class:`output_file_types`. """ if filename is None: filename = self._tmp if not os.path.isfile(filename): super(DarkFrame, self).save(filename=filename, filetype=filetype) @property def name(self): """ A tempfile in a unique directory. Returns: str: The name of a temp file. """ return self._tmp def cleanup(self): """Cleanup temp files.""" try: os.unlink(self._tmp) except OSError: pass def close(self): """Free the underlying raw representation and cleanup temp files.""" super(DarkFrame, self).close() self.cleanup() rawkit-0.6.0/rawkit/util.py000066400000000000000000000026771322174307200156630ustar00rootroot00000000000000""":mod:`rawkit.util` --- Utility functions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ These functions perform helpful tasks which don't really fit anywhere else such as searching for Raw files on the disk, or checking what cameras are supported by LibRaw. """ import ctypes import os from libraw.bindings import LibRaw from libraw.errors import FileUnsupported def discover(path): """ Recursively search for raw files in a given directory. Args: path (str): A tree to recursively search. """ file_list = [] libraw = LibRaw() raw = libraw.libraw_init(0) for root, _, files in os.walk(path): for file_name in files: file_path = os.path.join(root, file_name).encode('ascii') try: libraw.libraw_open_file(raw, file_path) except FileUnsupported: continue finally: libraw.libraw_recycle(raw) file_list.append(file_path) libraw.libraw_close(raw) return file_list def camera_list(): """ Return a list of cameras which are supported by the currently linked version of LibRaw. Returns: str array: A list of supported cameras. """ libraw = LibRaw() libraw.libraw_cameraList.restype = ctypes.POINTER( ctypes.c_char_p * libraw.libraw_cameraCount() ) data_pointer = libraw.libraw_cameraList() return [x.decode('ascii') for x in data_pointer.contents] rawkit-0.6.0/requirements-dev.txt000066400000000000000000000000571322174307200170610ustar00rootroot00000000000000-e . coverage flake8 mock sphinx pytest wheel rawkit-0.6.0/setup.cfg000066400000000000000000000001031322174307200146320ustar00rootroot00000000000000[bdist_wheel] universal = 1 [egg_info] tag_build = tag_date = 0 rawkit-0.6.0/setup.py000066400000000000000000000024331322174307200145330ustar00rootroot00000000000000import os from setuptools import setup from rawkit import VERSION def readme(): with open(os.path.join(os.path.dirname(__file__), 'README.rst')) as f: return f.read() setup( name='rawkit', version=VERSION, description='CTypes based LibRaw bindings', author='Cameron Paul, Sam Whited', author_email='cpaul37@gmail.com', maintainer='Cameron Paul, Sam Whited', maintainer_email='sam@samwhited.com', url='https://rawkit.readthedocs.org', packages=['rawkit', 'libraw'], keywords=['encoding', 'images', 'photography', 'libraw', 'raw', 'photos'], classifiers=[ "Programming Language :: Python", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: Implementation :: PyPy", "Development Status :: 3 - Alpha", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Topic :: Software Development :: Libraries :: Python Modules", ], long_description=readme(), extras_require={'doc': ['sphinx >= 1.3']}, ) rawkit-0.6.0/tests/000077500000000000000000000000001322174307200141615ustar00rootroot00000000000000rawkit-0.6.0/tests/__init__.py000066400000000000000000000000001322174307200162600ustar00rootroot00000000000000rawkit-0.6.0/tests/unit/000077500000000000000000000000001322174307200151405ustar00rootroot00000000000000rawkit-0.6.0/tests/unit/__init__.py000066400000000000000000000000001322174307200172370ustar00rootroot00000000000000rawkit-0.6.0/tests/unit/bindings_test.py000066400000000000000000000043561322174307200203560ustar00rootroot00000000000000import ctypes import mock import pytest from libraw.bindings import LibRaw from libraw.errors import c_error, check_call, UnspecifiedError @pytest.yield_fixture def libraw(): with mock.patch.object(LibRaw, '__init__', mock.Mock(return_value=None)): yield LibRaw() @pytest.fixture def error_func(): m = mock.Mock() m.restype = c_error return m @pytest.fixture def int_func(): m = mock.Mock() m.restype = ctypes.c_int return m @pytest.fixture def success_exit_code(): m = mock.Mock() m.value = 0 return m @pytest.fixture def undefined_exit_code(): m = mock.Mock() m.value = -1 return m def test_libraw_sets_method_name(libraw): """ Ensure that the method name is set when calling a LibRaw function. """ libraw._FuncPtr = mock.Mock() libraw.libraw_init() assert libraw.libraw_init.__name__ == 'libraw_init' def test_error_checking(libraw): """ Check that libraw methods are assigned an error checker. """ libraw._FuncPtr = mock.Mock() libraw.libraw_something() assert libraw.libraw_something.errcheck == check_call def test_version_number_calculation(libraw): """ Check that the version tuple is calculated correctly. """ libraw.libraw_versionNumber = lambda: 4097 assert libraw.version_number == (0, 16, 1) def test_version(libraw): """ Check that the version method actually calls `LibRaw::version()`. """ libraw.libraw_version = mock.Mock() libraw.version libraw.libraw_version.assert_called_once_with() def test_check_call_success(error_func, success_exit_code): """ An error check with a return value of 0 should not raise. """ check_call(success_exit_code, error_func, None) def test_check_call_error(error_func, undefined_exit_code): """ An error check with a negative error code should raise. """ with pytest.raises(UnspecifiedError): check_call(undefined_exit_code, error_func, None) def test_check_non_error_code_int(int_func, undefined_exit_code): """ An error check to a method which does not return an error should not raise (even if the return value looks like an error code). """ check_call(undefined_exit_code, int_func, None) rawkit-0.6.0/tests/unit/options_test.py000066400000000000000000000067251322174307200202560ustar00rootroot00000000000000import pytest from mock import Mock from rawkit.options import option, Options, WhiteBalance @pytest.fixture def options(): return Options() @pytest.fixture def opt_method(): @option() def method(): raise NotImplementedError return method def test_calling_an_option_method_directly_should_error(opt_method): with pytest.raises(TypeError): opt_method() def test_setting_a_value(options): # TODO: It would probably be better for these to operate on a Mock and # check if __set__ was called. # Uses normal set options.darkness = 1 assert options.darkness is 1 # Uses a special setter options.bps = 16 assert options.bps == 16 def test_option_from_class_should_return_decorator(): assert type(Options.bps) is option def test_custom_wb_param_writer_writes_rgbg_and_greybox(options): options.white_balance = WhiteBalance(greybox=(7, 7, 7, 7), rgbg=(42, 42, 42, 42)) params = options._map_to_libraw_params(Mock()) for v in params.greybox: assert v == 7 for v in params.user_mul: assert v == 42 def test_bps_must_be_8_or_16(options): with pytest.raises(ValueError): options.bps = 5 def test_options_are_iterable(options): options.half_size = True assert 'half_size' in options assert 'bps' not in options def test_options_repr(options): options.half_size = True assert repr(options) == repr({'half_size': True}) def test_options_keys(options): options.half_size = True assert options.keys() == ['half_size'] def test_options_values(options): options.half_size = True assert options.values() == [True] def test_set_rotation_invalid_type(options): with pytest.raises(TypeError): options.rotation = 'fish' def test_set_rotation_value_is_reduced(options): options.rotation = 270 + 90 assert options.rotation == 0 options.rotation = 270 + 180 assert options.rotation == 90 options.rotation = None assert options.rotation is None def test_set_rotation_invalid_value(options): with pytest.raises(ValueError): options.rotation = 93.5 def test_rotation_param_writer_values(options): values = { 270: 5, 180: 3, 90: 6, 0: 0 } for value in values.keys(): options.rotation = value params = options._map_to_libraw_params(Mock()) assert params.user_flip.value == values[value] def test_dark_frame_setter(options): options.dark_frame = 'Some String' assert options._dark_frame == 'Some String' def test_dark_frame_writer(options): options.dark_frame = 'Some String' params = options._map_to_libraw_params(Mock()) assert params.dark_frame.value == b'Some String' df = Mock() df._tmp = 'fakefile' df.name = df._tmp options.dark_frame = df params = options._map_to_libraw_params(Mock()) assert params.dark_frame.value == b'fakefile' def test_use_camera_profile_setter(options): options.use_camera_profile = False assert options.use_camera_profile is False options.use_camera_profile = True assert options.use_camera_profile is True def test_use_camera_profile_writer(options): options.use_camera_profile = True params = options._map_to_libraw_params(Mock()) assert params.camera_profile.value == b'embed' options.use_camera_profile = False params = options._map_to_libraw_params(Mock()) assert params.camera_profile is None rawkit-0.6.0/tests/unit/raw_test.py000066400000000000000000000145601322174307200173500ustar00rootroot00000000000000import mock import os import pytest import warnings from rawkit.errors import InvalidFileType, NoFileSpecified from rawkit.metadata import Metadata from rawkit.raw import Raw, DarkFrame from rawkit.raw import output_file_types @pytest.fixture def input_file(): return 'potato_salad.CR2' @pytest.fixture def output_file(): return 'potato_salad.out' @pytest.yield_fixture def raw(input_file): with mock.patch('rawkit.raw.LibRaw'): with Raw(filename=input_file) as raw_obj: yield raw_obj raw_obj.libraw.libraw_close.assert_called_once_with(raw_obj.data) @pytest.yield_fixture def dark_frame(input_file): with mock.patch('rawkit.raw.LibRaw'): with DarkFrame(filename=input_file) as raw_obj: yield raw_obj raw_obj.libraw.libraw_close.assert_called_once_with(raw_obj.data) @pytest.yield_fixture def mock_warning(): with mock.patch.object(warnings, 'warn') as mock_warning: yield mock_warning @pytest.yield_fixture def mock_ctypes(): with mock.patch('rawkit.raw.ctypes') as mock_ctypes: yield mock_ctypes def test_create(raw, input_file): raw.libraw.libraw_init.assert_called_once_with(0) raw.libraw.libraw_open_file.assert_called_once_with( raw.data, input_file.encode('ascii'), ) def test_create_no_filename(): with pytest.raises(NoFileSpecified): Raw() def test_dark_frame_is_raw(dark_frame): assert isinstance(dark_frame, Raw) def test_unpack(raw): raw.unpack() raw.libraw.libraw_unpack.assert_called_once_with(raw.data) def test_unpack_twice(raw): raw.unpack() raw.unpack() raw.libraw.libraw_unpack.assert_called_once_with(raw.data) def test_unpack_thumb(raw): raw.unpack_thumb() raw.libraw.libraw_unpack_thumb.assert_called_once_with(raw.data) def test_unpack_thumb_twice(raw): raw.unpack_thumb() raw.unpack_thumb() raw.libraw.libraw_unpack_thumb.assert_called_once_with(raw.data) def test_save_dark_frame_cached(dark_frame, tmpdir): dark_frame.save() # Touch the file (as if LibRaw were installed and saved a file) with open(dark_frame.name, 'a'): pass dark_frame.save() dark_frame.libraw.libraw_dcraw_ppm_tiff_writer.assert_called_once_with( dark_frame.data, dark_frame.name.encode('ascii'), ) def test_save_dark_frame_with_filename_cached(dark_frame, tmpdir): tmpdir.join('somefile').write('') fn = os.path.join(str(tmpdir), 'somefile') dark_frame.save(filename=fn) dark_frame.save(filename=fn, filetype=output_file_types.tiff) assert not dark_frame.libraw.libraw_dcraw_ppm_tiff_writer.called def _test_save(raw, output_file, filetype): raw.save(filename=output_file, filetype=filetype) raw.libraw.libraw_dcraw_ppm_tiff_writer.assert_called_once_with( raw.data, output_file.encode('ascii'), ) def test_save_no_filename(raw): with pytest.raises(NoFileSpecified): raw.save(filetype=output_file_types.ppm) def test_save_ppm(raw, output_file): _test_save(raw, output_file, output_file_types.ppm) assert raw.data.contents.params.output_tiff is False def test_save_tiff(raw, output_file): _test_save(raw, output_file, output_file_types.tiff) assert raw.data.contents.params.output_tiff is True def test_save_invalid_extension(raw, output_file): with pytest.raises(InvalidFileType): _test_save(raw, output_file, None) def test_save_infer_type_tiff(raw, output_file): _test_save(raw, output_file + '.tiff', None) assert raw.data.contents.params.output_tiff is True def test_save_infer_type_no_ext(raw, output_file): _test_save(raw, 'noext', None) assert raw.data.contents.params.output_tiff is False def test_save_infer_type_ppm(raw, output_file): _test_save(raw, output_file + '.ppm', None) assert raw.data.contents.params.output_tiff is False def test_save_invalid(raw, output_file): with pytest.raises(InvalidFileType): _test_save(raw, output_file, 'jpg') def test_save_thumb(raw, output_file): raw.save_thumb(filename=output_file) raw.libraw.libraw_dcraw_thumb_writer.assert_called_once_with( raw.data, output_file.encode('ascii'), ) def test_save_thumb_no_filename(raw): with pytest.raises(NoFileSpecified): raw.save_thumb() def test_to_buffer(raw, mock_ctypes): with mock.patch('rawkit.raw.raise_if_error'): raw.to_buffer() raw.libraw.libraw_dcraw_make_mem_image.assert_called_once_with( raw.data, mock.ANY, ) raw.libraw.libraw_dcraw_clear_mem.assert_called_once_with( raw.libraw.libraw_dcraw_make_mem_image(raw.data), ) def test_thumbnail_to_buffer(raw, mock_ctypes): with mock.patch('rawkit.raw.raise_if_error'): raw.thumbnail_to_buffer() raw.libraw.libraw_dcraw_make_mem_thumb.assert_called_once_with( raw.data, mock.ANY, ) raw.libraw.libraw_dcraw_clear_mem.assert_called_once_with( raw.libraw.libraw_dcraw_make_mem_thumb(raw.data), ) def test_metadata(raw): metadata = raw.metadata assert type(metadata) is Metadata def test_get_bayer_data(raw, mock_ctypes): raw.data.contents.sizes.pixel_aspect = 1 raw.data.contents.sizes.flip = 0 result, _ = raw.bayer_data() assert result is not None def test_get_bayer_data_bad_aspect(raw, mock_ctypes, mock_warning): raw.data.contents.sizes.pixel_aspect = 2 raw.data.contents.sizes.flip = 0 raw.bayer_data() mock_warning.assert_called_with( 'The pixel aspect is not unity, it is: 2' ) def test_get_bayer_data_flip(raw, mock_ctypes, mock_warning): raw.data.contents.sizes.pixel_aspect = 1 raw.data.contents.sizes.flip = 1 raw.bayer_data() mock_warning.assert_called_with( 'The image is flipped.' ) def test_bayer_data_non_bayer_image(raw, mock_ctypes): raw.data.contents.sizes.pixel_aspect = 1 raw.data.contents.sizes.flip = 0 # The falsiness of this value is what is tested to see if bayer data # exists, so we set this to False even though it's supposed to be a # pointer. raw.data.contents.rawdata.raw_image = False result, _ = raw.bayer_data() assert result == [] def test_bayer_data_with_margin(raw, mock_ctypes): raw.data.contents.sizes.pixel_aspect = 1 raw.data.contents.sizes.flip = 0 result, _ = raw.bayer_data(include_margin=True) assert result rawkit-0.6.0/tests/unit/util_test.py000066400000000000000000000013701322174307200175270ustar00rootroot00000000000000import mock import pytest from rawkit import util from libraw.errors import FileUnsupported @pytest.yield_fixture def libraw(): with mock.patch('rawkit.util.LibRaw') as libraw: # TODO: There must be a better way... libraw.return_value = libraw yield libraw def test_discover(libraw): with mock.patch( 'rawkit.util.os.walk', return_value=(('', None, ('foo.CR2', 'foo.jpg')),) ): libraw.libraw_open_file.side_effect = [0, FileUnsupported()] files = util.discover('') assert files == ['foo.CR2'.encode('ascii')] def test_camera_list(libraw): libraw.libraw_cameraCount.return_value = 0 assert util.camera_list() == [] libraw.libraw_cameraList.assert_called_once_with() rawkit-0.6.0/tox.ini000066400000000000000000000004431322174307200143330ustar00rootroot00000000000000[tox] project = rawkit # Keep up to date with the .travis.yml list envlist = py{27,36,py} [testenv] deps = -rrequirements-dev.txt commands = coverage erase coverage run -m pytest tests coverage report --show-missing --fail-under 100 flake8 {[tox]project} tests setup.py