1import mock 2import os 3import pytest 4import warnings 5 6from rawkit.errors import InvalidFileType, NoFileSpecified 7from rawkit.metadata import Metadata 8from rawkit.raw import Raw, DarkFrame 9from rawkit.raw import output_file_types 10 11 12@pytest.fixture 13def input_file(): 14 return 'potato_salad.CR2' 15 16 17@pytest.fixture 18def output_file(): 19 return 'potato_salad.out' 20 21 22@pytest.yield_fixture 23def raw(input_file): 24 with mock.patch('rawkit.raw.LibRaw'): 25 with Raw(filename=input_file) as raw_obj: 26 yield raw_obj 27 raw_obj.libraw.libraw_close.assert_called_once_with(raw_obj.data) 28 29 30@pytest.yield_fixture 31def dark_frame(input_file): 32 with mock.patch('rawkit.raw.LibRaw'): 33 with DarkFrame(filename=input_file) as raw_obj: 34 yield raw_obj 35 raw_obj.libraw.libraw_close.assert_called_once_with(raw_obj.data) 36 37 38@pytest.yield_fixture 39def mock_warning(): 40 with mock.patch.object(warnings, 'warn') as mock_warning: 41 yield mock_warning 42 43 44@pytest.yield_fixture 45def mock_ctypes(): 46 with mock.patch('rawkit.raw.ctypes') as mock_ctypes: 47 yield mock_ctypes 48 49 50def test_create(raw, input_file): 51 raw.libraw.libraw_init.assert_called_once_with(0) 52 raw.libraw.libraw_open_file.assert_called_once_with( 53 raw.data, 54 input_file.encode('ascii'), 55 ) 56 57 58def test_create_no_filename(): 59 with pytest.raises(NoFileSpecified): 60 Raw() 61 62 63def test_dark_frame_is_raw(dark_frame): 64 assert isinstance(dark_frame, Raw) 65 66 67def test_unpack(raw): 68 raw.unpack() 69 raw.libraw.libraw_unpack.assert_called_once_with(raw.data) 70 71 72def test_unpack_twice(raw): 73 raw.unpack() 74 raw.unpack() 75 raw.libraw.libraw_unpack.assert_called_once_with(raw.data) 76 77 78def test_unpack_thumb(raw): 79 raw.unpack_thumb() 80 raw.libraw.libraw_unpack_thumb.assert_called_once_with(raw.data) 81 82 83def test_unpack_thumb_twice(raw): 84 raw.unpack_thumb() 85 raw.unpack_thumb() 86 raw.libraw.libraw_unpack_thumb.assert_called_once_with(raw.data) 87 88 89def test_save_dark_frame_cached(dark_frame, tmpdir): 90 dark_frame.save() 91 92 # Touch the file (as if LibRaw were installed and saved a file) 93 with open(dark_frame.name, 'a'): 94 pass 95 96 dark_frame.save() 97 dark_frame.libraw.libraw_dcraw_ppm_tiff_writer.assert_called_once_with( 98 dark_frame.data, 99 dark_frame.name.encode('ascii'), 100 ) 101 102 103def test_save_dark_frame_with_filename_cached(dark_frame, tmpdir): 104 tmpdir.join('somefile').write('') 105 fn = os.path.join(str(tmpdir), 'somefile') 106 dark_frame.save(filename=fn) 107 dark_frame.save(filename=fn, filetype=output_file_types.tiff) 108 assert not dark_frame.libraw.libraw_dcraw_ppm_tiff_writer.called 109 110 111def _test_save(raw, output_file, filetype): 112 raw.save(filename=output_file, filetype=filetype) 113 114 raw.libraw.libraw_dcraw_ppm_tiff_writer.assert_called_once_with( 115 raw.data, 116 output_file.encode('ascii'), 117 ) 118 119 120def test_save_no_filename(raw): 121 with pytest.raises(NoFileSpecified): 122 raw.save(filetype=output_file_types.ppm) 123 124 125def test_save_ppm(raw, output_file): 126 _test_save(raw, output_file, output_file_types.ppm) 127 assert raw.data.contents.params.output_tiff is False 128 129 130def test_save_tiff(raw, output_file): 131 _test_save(raw, output_file, output_file_types.tiff) 132 assert raw.data.contents.params.output_tiff is True 133 134 135def test_save_invalid_extension(raw, output_file): 136 with pytest.raises(InvalidFileType): 137 _test_save(raw, output_file, None) 138 139 140def test_save_infer_type_tiff(raw, output_file): 141 _test_save(raw, output_file + '.tiff', None) 142 143 assert raw.data.contents.params.output_tiff is True 144 145 146def test_save_infer_type_no_ext(raw, output_file): 147 _test_save(raw, 'noext', None) 148 149 assert raw.data.contents.params.output_tiff is False 150 151 152def test_save_infer_type_ppm(raw, output_file): 153 _test_save(raw, output_file + '.ppm', None) 154 155 assert raw.data.contents.params.output_tiff is False 156 157 158def test_save_invalid(raw, output_file): 159 with pytest.raises(InvalidFileType): 160 _test_save(raw, output_file, 'jpg') 161 162 163def test_save_thumb(raw, output_file): 164 raw.save_thumb(filename=output_file) 165 166 raw.libraw.libraw_dcraw_thumb_writer.assert_called_once_with( 167 raw.data, 168 output_file.encode('ascii'), 169 ) 170 171 172def test_save_thumb_no_filename(raw): 173 with pytest.raises(NoFileSpecified): 174 raw.save_thumb() 175 176 177def test_to_buffer(raw, mock_ctypes): 178 with mock.patch('rawkit.raw.raise_if_error'): 179 raw.to_buffer() 180 181 raw.libraw.libraw_dcraw_make_mem_image.assert_called_once_with( 182 raw.data, 183 mock.ANY, 184 ) 185 186 raw.libraw.libraw_dcraw_clear_mem.assert_called_once_with( 187 raw.libraw.libraw_dcraw_make_mem_image(raw.data), 188 ) 189 190 191def test_thumbnail_to_buffer(raw, mock_ctypes): 192 with mock.patch('rawkit.raw.raise_if_error'): 193 raw.thumbnail_to_buffer() 194 195 raw.libraw.libraw_dcraw_make_mem_thumb.assert_called_once_with( 196 raw.data, 197 mock.ANY, 198 ) 199 200 raw.libraw.libraw_dcraw_clear_mem.assert_called_once_with( 201 raw.libraw.libraw_dcraw_make_mem_thumb(raw.data), 202 ) 203 204 205def test_metadata(raw): 206 metadata = raw.metadata 207 assert type(metadata) is Metadata 208 209 210def test_get_bayer_data(raw, mock_ctypes): 211 raw.data.contents.sizes.pixel_aspect = 1 212 raw.data.contents.sizes.flip = 0 213 214 result, _ = raw.bayer_data() 215 216 assert result is not None 217 218 219def test_get_bayer_data_bad_aspect(raw, mock_ctypes, mock_warning): 220 raw.data.contents.sizes.pixel_aspect = 2 221 raw.data.contents.sizes.flip = 0 222 223 raw.bayer_data() 224 225 mock_warning.assert_called_with( 226 'The pixel aspect is not unity, it is: 2' 227 ) 228 229 230def test_get_bayer_data_flip(raw, mock_ctypes, mock_warning): 231 raw.data.contents.sizes.pixel_aspect = 1 232 raw.data.contents.sizes.flip = 1 233 234 raw.bayer_data() 235 236 mock_warning.assert_called_with( 237 'The image is flipped.' 238 ) 239 240 241def test_bayer_data_non_bayer_image(raw, mock_ctypes): 242 raw.data.contents.sizes.pixel_aspect = 1 243 raw.data.contents.sizes.flip = 0 244 245 # The falsiness of this value is what is tested to see if bayer data 246 # exists, so we set this to False even though it's supposed to be a 247 # pointer. 248 raw.data.contents.rawdata.raw_image = False 249 250 result, _ = raw.bayer_data() 251 252 assert result == [] 253 254 255def test_bayer_data_with_margin(raw, mock_ctypes): 256 raw.data.contents.sizes.pixel_aspect = 1 257 raw.data.contents.sizes.flip = 0 258 259 result, _ = raw.bayer_data(include_margin=True) 260 261 assert result 262