@@ -8,6 +8,7 @@ from pathlib import Path
88
99np.import_array()
1010
11+ ctypedef np.uint8_t DTYPE_t
1112
1213class QOIColorSpace (enum .Enum ):
1314 SRGB = qoi.QOI_SRGB
@@ -16,9 +17,9 @@ class QOIColorSpace(enum.Enum):
1617cdef class PixelWrapper:
1718 cdef void * pixels
1819
19- cdef np.ndarray as_ndarray(self , int height, int width, int channels, char * pixels):
20+ cdef np.ndarray[DTYPE_t, ndim = 3 ] as_ndarray(self , int height, int width, int channels, char * pixels):
2021 cdef np.npy_intp shape[3 ]
21- cdef np.ndarray ndarray
22+ cdef np.ndarray[DTYPE_t, ndim = 3 ] ndarray
2223 self .pixels = pixels
2324 shape[:] = (height, width, channels)
2425 ndarray = np.PyArray_SimpleNewFromData(3 , shape, np.NPY_UINT8, self .pixels)
@@ -52,12 +53,14 @@ cpdef int write(filename, unsigned char[:,:,::1] rgb, colorspace: QOIColorSpace
5253 # Makes a contiguous copy of the numpy array so we can process bytes directly:
5354 # rgb = np.ascontiguousarray(rgb)
5455
55- cdef int bytes_written = qoi.qoi_write(_filename, & rgb[0 ][0 ][0 ], & desc)
56+ cdef int bytes_written
57+ with nogil:
58+ bytes_written = qoi.qoi_write(_filename, & rgb[0 ][0 ][0 ], & desc)
5659 if bytes_written == 0 :
5760 raise RuntimeError (" Failed to write!" )
5861 return bytes_written
5962
60- cpdef np.ndarray read(filename, int channels = 0 , unsigned char [::1 ] colorspace = bytearray(1 )):
63+ cpdef np.ndarray[DTYPE_t, ndim = 3 ] read(filename, int channels = 0 , unsigned char [::1 ] colorspace = bytearray(1 )):
6164 # TODO: how to return desc.colorspace? A: How about return a tuple of ndarray and a wrapper around struct qoi_desc? or we can add another param like char[:] to simulate pointer
6265 cdef bytes filename_bytes
6366 cdef char * _filename
@@ -71,8 +74,8 @@ cpdef np.ndarray read(filename, int channels = 0, unsigned char[::1] colorspace
7174 filename_bytes = str (filename).encode(' utf8' )
7275 _filename = filename_bytes
7376
74-
75- pixels = < char * > qoi.qoi_read(_filename, & desc, channels)
77+ with nogil:
78+ pixels = < char * > qoi.qoi_read(_filename, & desc, channels)
7679 if pixels is NULL :
7780 raise RuntimeError (" Failed to read!" )
7881 try :
@@ -97,7 +100,8 @@ cpdef bytes encode(unsigned char[:,:,::1] rgb, colorspace: QOIColorSpace = QOICo
97100
98101 # if not rgb.flags['C_CONTIGUOUS']:
99102 # rgb = np.ascontiguousarray(rgb) # makes a contiguous copy of the numpy array so we can read memory directly
100- encoded = < char * > qoi.qoi_encode(& rgb[0 ][0 ][0 ], & desc, & size)
103+ with nogil:
104+ encoded = < char * > qoi.qoi_encode(& rgb[0 ][0 ][0 ], & desc, & size)
101105 if encoded is NULL or size <= 0 :
102106 raise RuntimeError (" Failed to encode!" )
103107 try :
@@ -106,12 +110,13 @@ cpdef bytes encode(unsigned char[:,:,::1] rgb, colorspace: QOIColorSpace = QOICo
106110 finally :
107111 PyMem_Free(encoded)
108112
109- cpdef np.ndarray decode(const unsigned char [::1 ] data, int channels = 0 , unsigned char [::1 ] colorspace = bytearray(1 )):
113+ cpdef np.ndarray[DTYPE_t, ndim = 3 ] decode(const unsigned char [::1 ] data, int channels = 0 , unsigned char [::1 ] colorspace = bytearray(1 )):
110114 # TODO: what to do about desc.colorspace? A: How about return a tuple of ndarray and a wrapper around struct qoi_desc? or we can add another param like char[:] to simulate pointer
111115 cdef qoi.qoi_desc desc
112116 cdef int ret
113117 cdef char * pixels
114- pixels = < char * > qoi.qoi_decode(& data[0 ], < int > data.shape[0 ], & desc, channels)
118+ with nogil:
119+ pixels = < char * > qoi.qoi_decode(& data[0 ], < int > data.shape[0 ], & desc, channels)
115120 if pixels is NULL :
116121 raise RuntimeError (" Failed to decode!" )
117122 try :
0 commit comments