Skip to content

Commit

Permalink
windows: support filenames with special characters
Browse files Browse the repository at this point in the history
fixes #85
  • Loading branch information
letmaik committed Aug 8, 2020
1 parent 7485b3e commit ac7cfc5
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 18 deletions.
69 changes: 52 additions & 17 deletions rawpy/_rawpy.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ from __future__ import print_function

from cpython.ref cimport PyObject, Py_INCREF
from cpython.bytes cimport PyBytes_FromStringAndSize
from cpython.mem cimport PyMem_Free
from cython.operator cimport dereference as deref
from libc.stddef cimport wchar_t

import numpy as np
from collections import namedtuple
Expand All @@ -18,6 +20,9 @@ import sys
import warnings
from enum import Enum

cdef extern from "Python.h":
wchar_t* PyUnicode_AsWideCharString(object, Py_ssize_t *)

cdef extern from "def_helper.h":
cdef int LIBRAW_XTRANS

Expand Down Expand Up @@ -181,22 +186,42 @@ cdef extern from "libraw.h":
unsigned int data_size
unsigned char data[1] # this is the image data, no idea why [1]

cdef cppclass LibRaw:
libraw_data_t imgdata
LibRaw()
int open_file(const char *fname)
int open_buffer(void *buffer, size_t bufsize)
int unpack()
int unpack_thumb()
int COLOR(int row, int col)
# int raw2image()
int dcraw_process()
libraw_processed_image_t* dcraw_make_mem_image(int *errcode)
libraw_processed_image_t* dcraw_make_mem_thumb(int *errcode)
void dcraw_clear_mem(libraw_processed_image_t* img)
void free_image()
const char* strerror(int p)
void recycle()
# The open_file method is overloaded on Windows and unfortunately
# there is no better way to deal with this in Cython.
IF UNAME_SYSNAME == "Windows":
cdef extern from "libraw.h":
cdef cppclass LibRaw:
libraw_data_t imgdata
LibRaw()
int open_buffer(void *buffer, size_t bufsize)
int open_file(const wchar_t *fname)
int unpack()
int unpack_thumb()
int COLOR(int row, int col)
int dcraw_process()
libraw_processed_image_t* dcraw_make_mem_image(int *errcode)
libraw_processed_image_t* dcraw_make_mem_thumb(int *errcode)
void dcraw_clear_mem(libraw_processed_image_t* img)
void free_image()
const char* strerror(int p)
void recycle()
ELSE:
cdef extern from "libraw.h":
cdef cppclass LibRaw:
libraw_data_t imgdata
LibRaw()
int open_buffer(void *buffer, size_t bufsize)
int open_file(const char *fname)
int unpack()
int unpack_thumb()
int COLOR(int row, int col)
int dcraw_process()
libraw_processed_image_t* dcraw_make_mem_image(int *errcode)
libraw_processed_image_t* dcraw_make_mem_thumb(int *errcode)
void dcraw_clear_mem(libraw_processed_image_t* img)
void free_image()
const char* strerror(int p)
void recycle()

libraw_version = (LIBRAW_MAJOR_VERSION, LIBRAW_MINOR_VERSION, LIBRAW_PATCH_VERSION)

Expand Down Expand Up @@ -364,9 +389,19 @@ cdef class RawPy:
:param str path: The path to the RAW image.
"""
cdef wchar_t *wchars
cdef Py_ssize_t wchars_len
self.unpack_called = False
self.unpack_thumb_called = False
self.handle_error(self.p.open_file(_chars(path)))
IF UNAME_SYSNAME == "Windows":
wchars = PyUnicode_AsWideCharString(path, &wchars_len)
if wchars == NULL:
raise RuntimeError('cannot convert unicode path to wide chars')
res = self.p.open_file(wchars)
PyMem_Free(wchars)
ELSE:
res = self.p.open_file(path.encode('UTF-8'))
self.handle_error(res)

def open_buffer(self, fileobj):
"""
Expand Down
Binary file added test/RAW_KODAK_DC50_é.KDC
Binary file not shown.
2 changes: 1 addition & 1 deletion test/README.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
RAW_CANON_5DMARK2_PREPROD.CR2, RAW_CANON_40D_SRAW_V103.CR2, and RAW_SIGMA_SD9_SRGB.X3F were downloaded
RAW_CANON_5DMARK2_PREPROD.CR2, RAW_CANON_40D_SRAW_V103.CR2, RAW_SIGMA_SD9_SRGB.X3F, RAW_KODAK_DC50.KDC were downloaded
from https://www.rawsamples.ch and are licensed under CC BY-NC-SA 4.0
(https://creativecommons.org/licenses/by-nc-sa/4.0/).
6 changes: 6 additions & 0 deletions test/basic_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@
# Canon 40D in sRAW format with 4 channels
raw5TestPath = os.path.join(thisDir, 'RAW_CANON_40D_SRAW_V103.CR2')

# Kodak DC50 with special characters in filename
raw6TestPath = os.path.join(thisDir, 'RAW_KODAK_DC50_é.KDC')

def testVersion():
print('using libraw', rawpy.libraw_version)
pprint(rawpy.flags)
Expand Down Expand Up @@ -89,6 +92,9 @@ def testSRawFileOpenAndPostProcess():
print_stats(rgb)
save('test_sraw.tiff', rgb)

def testFileOpenWithNonAsciiCharacters():
raw = rawpy.imread(raw6TestPath)

def testBufferOpen():
with open(rawTestPath, 'rb') as rawfile:
with rawpy.imread(rawfile) as raw:
Expand Down

0 comments on commit ac7cfc5

Please sign in to comment.