Skip to content

Commit 6ef164c

Browse files
Copilotletmaik
andauthored
Add shot_select support with set_unpack_params() method (#276)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: letmaik <530988+letmaik@users.noreply.github.com>
1 parent 6c7a142 commit 6ef164c

File tree

3 files changed

+79
-3
lines changed

3 files changed

+79
-3
lines changed

rawpy/__init__.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,20 @@
55
import rawpy._rawpy
66
globals().update({k:v for k,v in rawpy._rawpy.__dict__.items() if not k.startswith('_')})
77

8-
def imread(pathOrFile):
8+
def imread(pathOrFile, shot_select=0):
99
"""
1010
Convenience function that creates a :class:`rawpy.RawPy` instance, opens the given file,
1111
and returns the :class:`rawpy.RawPy` instance for further processing.
1212
1313
:param str|file pathOrFile: path or file object of RAW image that will be read
14+
:param int shot_select: select which image to extract from RAW files that contain multiple images
15+
(e.g., Dual Pixel RAW). Default is 0 for the first/main image.
1416
:rtype: :class:`rawpy.RawPy`
1517
"""
1618
d = RawPy()
1719
if hasattr(pathOrFile, 'read'):
1820
d.open_buffer(pathOrFile)
1921
else:
2022
d.open_file(pathOrFile)
23+
d.set_unpack_params(shot_select=shot_select)
2124
return d

rawpy/_rawpy.pyx

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,6 @@ cdef extern from "libraw.h":
102102
double aber[4] # -C
103103
double gamm[6] # -g
104104
float user_mul[4] # -r mul0 mul1 mul2 mul3
105-
unsigned shot_select # -s
106105
float bright # -b
107106
float threshold # -n
108107
int half_size # -h
@@ -165,6 +164,18 @@ cdef extern from "libraw.h":
165164
# Force use x3f data decoding either if demosaic pack GPL2 enabled
166165
int force_foveon_x3f
167166

167+
ctypedef struct libraw_raw_unpack_params_t:
168+
int use_rawspeed
169+
int use_dngsdk
170+
unsigned options
171+
unsigned shot_select
172+
unsigned specials
173+
unsigned max_raw_memory_mb
174+
int sony_arw2_posterization_thr
175+
float coolscan_nef_gamma
176+
char p4shot_order[5]
177+
char **custom_camera_strings
178+
168179
ctypedef struct libraw_iparams_t:
169180
char make[64]
170181
char model[64]
@@ -183,6 +194,7 @@ cdef extern from "libraw.h":
183194
libraw_image_sizes_t sizes
184195
libraw_iparams_t idata
185196
libraw_output_params_t params
197+
libraw_raw_unpack_params_t rawparams
186198
# unsigned int progress_flags
187199
# unsigned int process_warnings
188200
libraw_colordata_t color
@@ -440,6 +452,21 @@ cdef class RawPy:
440452
e = self.p.open_buffer(buf, buf_len)
441453
self.handle_error(e)
442454

455+
def set_unpack_params(self, shot_select=0):
456+
"""
457+
Set parameters that affect RAW image unpacking.
458+
459+
This should be called after opening a file and before unpacking.
460+
461+
.. NOTE:: This is a low-level method. When using :func:`rawpy.imread`,
462+
unpack parameters can be provided directly.
463+
464+
:param int shot_select: select which image to extract from RAW files that contain multiple images
465+
(e.g., Dual Pixel RAW). Default is 0 for the first/main image.
466+
"""
467+
cdef libraw_raw_unpack_params_t* rp = &self.p.imgdata.rawparams
468+
rp.shot_select = shot_select
469+
443470
def unpack(self):
444471
"""
445472
Unpacks/decodes the opened RAW image.
@@ -1208,7 +1235,7 @@ class Params(object):
12081235
self.aber = (chromatic_aberration[0], chromatic_aberration[1])
12091236
else:
12101237
self.aber = (1, 1)
1211-
self.bad_pixels = bad_pixels_path
1238+
self.bad_pixels = bad_pixels_path
12121239

12131240
cdef class processed_image_wrapper:
12141241
cdef RawPy raw

test/test_shot_select.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
"""
2+
Test for shot_select parameter functionality
3+
"""
4+
import os
5+
import pytest
6+
import rawpy
7+
8+
thisDir = os.path.dirname(__file__)
9+
rawTestPath = os.path.join(thisDir, 'iss030e122639.NEF')
10+
11+
12+
def test_shot_select_parameter_via_imread():
13+
"""Test that shot_select parameter can be passed to imread"""
14+
# Test default shot_select=0
15+
with rawpy.imread(rawTestPath, shot_select=0) as raw:
16+
rgb = raw.postprocess(no_auto_bright=True)
17+
assert rgb is not None
18+
assert rgb.shape[2] == 3 # RGB image
19+
20+
21+
def test_shot_select_nonexistent_image():
22+
"""Test that shot_select=1 raises error for single-image files"""
23+
# Test shot_select=1 on a file with only one image should raise an error
24+
with pytest.raises(rawpy.LibRawRequestForNonexistentImageError):
25+
with rawpy.imread(rawTestPath, shot_select=1) as raw:
26+
rgb = raw.postprocess(no_auto_bright=True)
27+
28+
29+
def test_shot_select_via_open_file():
30+
"""Test that shot_select can be set via set_unpack_params"""
31+
raw = rawpy.RawPy()
32+
raw.open_file(rawTestPath)
33+
raw.set_unpack_params(shot_select=0)
34+
raw.unpack()
35+
rgb = raw.postprocess()
36+
assert rgb is not None
37+
assert rgb.shape[2] == 3
38+
raw.close()
39+
40+
41+
def test_shot_select_default_value():
42+
"""Test that default shot_select value is 0"""
43+
with rawpy.imread(rawTestPath) as raw:
44+
rgb = raw.postprocess()
45+
assert rgb is not None
46+
assert rgb.shape[2] == 3

0 commit comments

Comments
 (0)