ffi-gphoto2 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/.rspec +2 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +90 -0
  7. data/Rakefile +6 -0
  8. data/examples/intervalometer.rb +12 -0
  9. data/examples/live_view.rb +21 -0
  10. data/ffi-gphoto2.gemspec +30 -0
  11. data/lib/ffi/gphoto2.rb +85 -0
  12. data/lib/ffi/gphoto2/camera.rb +12 -0
  13. data/lib/ffi/gphoto2/camera_abilities.rb +37 -0
  14. data/lib/ffi/gphoto2/camera_abilities_list.rb +15 -0
  15. data/lib/ffi/gphoto2/camera_capture_type.rb +8 -0
  16. data/lib/ffi/gphoto2/camera_driver_status.rb +9 -0
  17. data/lib/ffi/gphoto2/camera_event_type.rb +10 -0
  18. data/lib/ffi/gphoto2/camera_file.rb +28 -0
  19. data/lib/ffi/gphoto2/camera_file_access_type.rb +8 -0
  20. data/lib/ffi/gphoto2/camera_file_operation.rb +11 -0
  21. data/lib/ffi/gphoto2/camera_file_path.rb +9 -0
  22. data/lib/ffi/gphoto2/camera_file_type.rb +11 -0
  23. data/lib/ffi/gphoto2/camera_folder_operation.rb +10 -0
  24. data/lib/ffi/gphoto2/camera_list.rb +15 -0
  25. data/lib/ffi/gphoto2/camera_operation.rb +12 -0
  26. data/lib/ffi/gphoto2/camera_widget.rb +33 -0
  27. data/lib/ffi/gphoto2/camera_widget_type.rb +14 -0
  28. data/lib/ffi/gphoto2/entry.rb +9 -0
  29. data/lib/ffi/gphoto2/gp_context.rb +31 -0
  30. data/lib/ffi/gphoto2/gphoto_device_type.rb +7 -0
  31. data/lib/ffi/gphoto2_port.rb +31 -0
  32. data/lib/ffi/gphoto2_port/gp_port_info.rb +11 -0
  33. data/lib/ffi/gphoto2_port/gp_port_info_list.rb +14 -0
  34. data/lib/ffi/gphoto2_port/gp_port_result.rb +35 -0
  35. data/lib/ffi/gphoto2_port/gp_port_type.rb +12 -0
  36. data/lib/gphoto2.rb +41 -0
  37. data/lib/gphoto2/camera.rb +219 -0
  38. data/lib/gphoto2/camera_abilities.rb +44 -0
  39. data/lib/gphoto2/camera_abilities_list.rb +64 -0
  40. data/lib/gphoto2/camera_file.rb +69 -0
  41. data/lib/gphoto2/camera_file_path.rb +21 -0
  42. data/lib/gphoto2/camera_folder.rb +82 -0
  43. data/lib/gphoto2/camera_list.rb +43 -0
  44. data/lib/gphoto2/camera_widgets/camera_widget.rb +112 -0
  45. data/lib/gphoto2/camera_widgets/date_camera_widget.rb +19 -0
  46. data/lib/gphoto2/camera_widgets/menu_camera_widget.rb +4 -0
  47. data/lib/gphoto2/camera_widgets/radio_camera_widget.rb +41 -0
  48. data/lib/gphoto2/camera_widgets/range_camera_widget.rb +37 -0
  49. data/lib/gphoto2/camera_widgets/section_camera_widget.rb +4 -0
  50. data/lib/gphoto2/camera_widgets/text_camera_widget.rb +14 -0
  51. data/lib/gphoto2/camera_widgets/toggle_camera_widget.rb +18 -0
  52. data/lib/gphoto2/camera_widgets/window_camera_widget.rb +4 -0
  53. data/lib/gphoto2/context.rb +31 -0
  54. data/lib/gphoto2/entry.rb +38 -0
  55. data/lib/gphoto2/port_info.rb +70 -0
  56. data/lib/gphoto2/port_info_list.rb +46 -0
  57. data/lib/gphoto2/port_result.rb +7 -0
  58. data/lib/gphoto2/version.rb +3 -0
  59. data/spec/gphoto2/camera_abilities_list_spec.rb +45 -0
  60. data/spec/gphoto2/camera_abilities_spec.rb +38 -0
  61. data/spec/gphoto2/camera_file_path_spec.rb +27 -0
  62. data/spec/gphoto2/camera_file_spec.rb +71 -0
  63. data/spec/gphoto2/camera_folder_spec.rb +110 -0
  64. data/spec/gphoto2/camera_list_spec.rb +35 -0
  65. data/spec/gphoto2/camera_spec.rb +292 -0
  66. data/spec/gphoto2/camera_widgets/date_camera_widget_spec.rb +15 -0
  67. data/spec/gphoto2/camera_widgets/radio_camera_widget_spec.rb +31 -0
  68. data/spec/gphoto2/camera_widgets/range_camera_widget_spec.rb +27 -0
  69. data/spec/gphoto2/camera_widgets/text_camera_widget_spec.rb +15 -0
  70. data/spec/gphoto2/camera_widgets/toggle_camera_widget_spec.rb +21 -0
  71. data/spec/gphoto2/context_spec.rb +17 -0
  72. data/spec/gphoto2/entry_spec.rb +27 -0
  73. data/spec/gphoto2/port_info_list_spec.rb +33 -0
  74. data/spec/gphoto2/port_info_spec.rb +53 -0
  75. data/spec/spec_helper.rb +12 -0
  76. data/spec/support/shared_examples/camera_widget_examples.rb +89 -0
  77. metadata +194 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 4fb2cb331909ca8e1522318738dfbfe6675c6aba
4
+ data.tar.gz: d895c48398334dc8c60565b7302673244402f06d
5
+ SHA512:
6
+ metadata.gz: 6dbbfd432cd4ad2516ba6ebfbeda293debd0a02587b41b5bf2d21f6c2d35c7bee9b70ed06265958158cec9a66b9b7d12c237bb636b668b289947c08c152971a8
7
+ data.tar.gz: c9c4ae048625002e761f87390d7a57d664c8e471344e88395d5581910efba2ca16edc0910c3cbbbc54dbd0432ea6a766b713ee0f6add001b999fb130cc11fc10
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format progress
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in ffi-gphoto2.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Michael Macias
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,90 @@
1
+ # ffi-gphoto2
2
+
3
+ **ffi-gphoto2** provides an FFI for common functions in [libgphoto2][1].
4
+ It also includes a facade to interact with the library in a more
5
+ canonical Ruby way.
6
+
7
+ ## Installation
8
+
9
+ ### Prerequisites
10
+
11
+ * Ruby >= 1.9
12
+ * libgphoto2 >= 2.5.0 (`brew install libgphoto2`)
13
+
14
+ ### Gem
15
+
16
+ $ gem install ffi-gphoto2
17
+
18
+ ## Usage
19
+
20
+ require 'gphoto2'
21
+
22
+ # list available cameras
23
+ cameras = GPhoto2::Camera.all
24
+ # => [#<GPhoto2::Camera>, ...]
25
+
26
+ # list found cameras by model and port path
27
+ cameras.map { |c| [c.model, c.port] }
28
+ # => [['Nikon DSC D5100 (PTP mode)', 'usb:250,006'], ...]
29
+
30
+ # use the first camera
31
+ camera = cameras.first
32
+
33
+ # ...or more conveniently
34
+ camera = GPhoto2::Camera.first
35
+
36
+ # ...or even search by model name
37
+ camera = GPhoto2::Camera.where(/nikon/i).first
38
+
39
+ # list camera configuration names
40
+ camera.config.keys
41
+ # => ['autofocusdrive', 'manualfocusdrive', 'controlmode', ...]
42
+
43
+ # read the current configuration value of an option
44
+ camera['whitebalance']
45
+ # => "Automatic"
46
+
47
+ # list valid choices of a configuration option
48
+ camera['whitebalance'].choices
49
+ # => ['Automatic', 'Daylight', 'Fluorescent', 'Tungsten', ...]
50
+
51
+ # check if the configuration has changed
52
+ camera.dirty?
53
+ # => false
54
+
55
+ # change camera configuration
56
+ camera['iso'] = 800
57
+ camera['f-number'] = 'f/4.5'
58
+ camera['shutterspeed2'] = '1/30'
59
+
60
+ # check if the configuration has changed
61
+ camera.dirty?
62
+ # => true
63
+
64
+ # apply the new configuration on the device
65
+ camera.save
66
+
67
+ # take a photo
68
+ file = camera.capture
69
+
70
+ # ...and save it to the current working directory
71
+ file.save
72
+
73
+ # traverse the camera filesystem
74
+ folder = camera/'store_00010001/DCIM/100D5100'
75
+
76
+ # list files
77
+ files = folder.files
78
+ folder.files.map(&:name)
79
+ => ["DSC_0001.JPG", "DSC_0002.JPG", ...]
80
+
81
+ # save a file
82
+ files.first.save
83
+
84
+ # close the camera
85
+ camera.finalize
86
+
87
+ More examples can be found in [`examples/`][2].
88
+
89
+ [1]: http://www.gphoto.org/
90
+ [2]: https://github.com/zaeleus/ffi-gphoto2/tree/master/examples
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new('spec')
5
+
6
+ task default: :spec
@@ -0,0 +1,12 @@
1
+ require 'gphoto2'
2
+
3
+ camera = GPhoto2::Camera.first
4
+
5
+ six_hours = 60 * 60 * 6
6
+ stop_time = Time.now + six_hours
7
+
8
+ # take a photo every 30 seconds for 6 hours
9
+ until Time.now >= stop_time
10
+ camera.capture.save
11
+ sleep 30
12
+ end
@@ -0,0 +1,21 @@
1
+ # Run and pipe to a video player that can demux raw mjpeg. For example,
2
+ #
3
+ # ruby live_view.rb | mpv --demuxer=+lavf --demuxer-lavf-format=mjpeg --demuxer-lavf-analyzeduration=0.1 -
4
+
5
+ require 'gphoto2'
6
+
7
+ # automatically flush the io buffer
8
+ STDOUT.sync = true
9
+
10
+ camera = GPhoto2::Camera.first
11
+
12
+ begin
13
+ loop do
14
+ # write the preview image to stdout
15
+ print camera.preview.data
16
+ end
17
+ ensure
18
+ # make sure to close (or #exit) the camera
19
+ # otherwise, the mirror will stay up
20
+ camera.finalize
21
+ end
@@ -0,0 +1,30 @@
1
+ lib = File.expand_path('../lib', __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+
4
+ require 'gphoto2/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'ffi-gphoto2'
8
+ spec.summary = 'A Ruby FFI for common functions in libgphoto2'
9
+ spec.homepage = 'https://github.com/zaeleus/ffi-gphoto2'
10
+
11
+ spec.authors = ['Michael Macias']
12
+ spec.email = ['mamacias@go.olemiss.edu']
13
+
14
+ spec.version = GPhoto2::VERSION
15
+ spec.license = 'MIT'
16
+
17
+ spec.files = `git ls-files`.split($/)
18
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
19
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
20
+ spec.require_paths = ['lib']
21
+
22
+ spec.requirements << 'libgphoto2 >= 2.5.0'
23
+ spec.required_ruby_version = '>= 1.9'
24
+
25
+ spec.add_development_dependency 'bundler', '~> 1.3'
26
+ spec.add_development_dependency 'rake'
27
+ spec.add_development_dependency 'rspec', '~> 2.14.1'
28
+
29
+ spec.add_dependency 'ffi', '~> 1.9.0'
30
+ end
@@ -0,0 +1,85 @@
1
+ require 'ffi/gphoto2_port'
2
+
3
+ module FFI
4
+ module GPhoto2
5
+ extend FFI::Library
6
+
7
+ ffi_lib 'libgphoto2'
8
+
9
+ # enums
10
+ require 'ffi/gphoto2/camera_capture_type'
11
+ require 'ffi/gphoto2/camera_driver_status'
12
+ require 'ffi/gphoto2/camera_event_type'
13
+ require 'ffi/gphoto2/camera_file_access_type'
14
+ require 'ffi/gphoto2/camera_file_operation'
15
+ require 'ffi/gphoto2/camera_file_type'
16
+ require 'ffi/gphoto2/camera_folder_operation'
17
+ require 'ffi/gphoto2/camera_operation'
18
+ require 'ffi/gphoto2/camera_widget_type'
19
+ require 'ffi/gphoto2/gphoto_device_type'
20
+
21
+ # structs
22
+ require 'ffi/gphoto2/camera'
23
+ require 'ffi/gphoto2/camera_abilities'
24
+ require 'ffi/gphoto2/camera_abilities_list'
25
+ require 'ffi/gphoto2/camera_file'
26
+ require 'ffi/gphoto2/camera_file_path'
27
+ require 'ffi/gphoto2/camera_list'
28
+ require 'ffi/gphoto2/camera_widget'
29
+ require 'ffi/gphoto2/entry'
30
+ require 'ffi/gphoto2/gp_context'
31
+
32
+ # gphoto2/gphoto2-abilities-list.h
33
+ attach_function :gp_abilities_list_new, [:pointer], :int
34
+ attach_function :gp_abilities_list_free, [CameraAbilitiesList.by_ref], :int
35
+ attach_function :gp_abilities_list_load, [CameraAbilitiesList.by_ref, GPContext.by_ref], :int
36
+ attach_function :gp_abilities_list_detect, [CameraAbilitiesList.by_ref, GPhoto2Port::GPPortInfoList.by_ref, CameraList.by_ref, GPContext.by_ref], :int
37
+ attach_function :gp_abilities_list_lookup_model, [CameraAbilitiesList.by_ref, :string], :int
38
+ attach_function :gp_abilities_list_get_abilities, [CameraAbilitiesList.by_ref, :int, CameraAbilities.by_ref], :int
39
+
40
+ # gphoto2/gphoto2-camera.h
41
+ attach_function :gp_camera_new, [:pointer], :int
42
+ attach_function :gp_camera_set_abilities, [Camera.by_ref, CameraAbilities.by_value], :int
43
+ attach_function :gp_camera_set_port_info, [Camera.by_ref, GPhoto2Port::GPPortInfo], :int
44
+ attach_function :gp_camera_exit, [Camera.by_ref, GPContext.by_ref], :int
45
+ attach_function :gp_camera_ref, [Camera.by_ref], :int
46
+ attach_function :gp_camera_unref, [Camera.by_ref], :int
47
+ attach_function :gp_camera_get_config, [Camera.by_ref, :pointer, GPContext.by_ref], :int
48
+ attach_function :gp_camera_set_config, [Camera.by_ref, CameraWidget.by_ref, GPContext.by_ref], :int
49
+ attach_function :gp_camera_capture, [Camera.by_ref, CameraCaptureType, CameraFilePath.by_ref, GPContext.by_ref], :int
50
+ attach_function :gp_camera_capture_preview, [Camera.by_ref, CameraFile.by_ref, GPContext.by_ref], :int
51
+ attach_function :gp_camera_wait_for_event, [Camera.by_ref, :int, :pointer, :pointer, GPContext.by_ref], :int
52
+ attach_function :gp_camera_folder_list_files, [Camera.by_ref, :string, CameraList.by_ref, GPContext.by_ref], :int
53
+ attach_function :gp_camera_folder_list_folders, [Camera.by_ref, :string, CameraList.by_ref, GPContext.by_ref], :int
54
+ attach_function :gp_camera_file_get, [Camera.by_ref, :string, :string, CameraFileType, CameraFile.by_ref, GPContext.by_ref], :int
55
+
56
+ # gphoto2/gphoto2-context.h
57
+ attach_function :gp_context_new, [], :pointer
58
+ attach_function :gp_context_ref, [GPContext.by_ref], :void
59
+ attach_function :gp_context_unref, [GPContext.by_ref], :void
60
+
61
+ # gphoto2/gphoto2-file.h
62
+ attach_function :gp_file_new, [:pointer], :int
63
+ attach_function :gp_file_free, [CameraFile.by_ref], :int
64
+ attach_function :gp_file_get_data_and_size, [CameraFile.by_ref, :pointer, :pointer], :int
65
+
66
+ # gphoto2/gphoto2-list.h
67
+ attach_function :gp_list_new, [:pointer], :int
68
+ attach_function :gp_list_free, [CameraList.by_ref], :int
69
+ attach_function :gp_list_count, [CameraList.by_ref], :int
70
+ attach_function :gp_list_get_name, [CameraList.by_ref, :int, :pointer], :int
71
+ attach_function :gp_list_get_value, [CameraList.by_ref, :int, :pointer], :int
72
+
73
+ # gphoto2/gphoto2-widget.h
74
+ attach_function :gp_widget_free, [CameraWidget.by_ref], :int
75
+ attach_function :gp_widget_count_children, [CameraWidget.by_ref], :int
76
+ attach_function :gp_widget_get_child, [CameraWidget.by_ref, :int, :pointer], :int
77
+ attach_function :gp_widget_set_value, [CameraWidget.by_ref, :pointer], :int
78
+ attach_function :gp_widget_get_value, [CameraWidget.by_ref, :pointer], :int
79
+ attach_function :gp_widget_get_name, [CameraWidget.by_ref, :pointer], :int
80
+ attach_function :gp_widget_get_type, [CameraWidget.by_ref, :pointer], :int
81
+ attach_function :gp_widget_get_range, [CameraWidget.by_ref, :pointer, :pointer, :pointer], :int
82
+ attach_function :gp_widget_count_choices, [CameraWidget.by_ref], :int
83
+ attach_function :gp_widget_get_choice, [CameraWidget.by_ref, :int, :pointer], :int
84
+ end
85
+ end
@@ -0,0 +1,12 @@
1
+ module FFI
2
+ module GPhoto2
3
+ class Camera < FFI::Struct
4
+ # gphoto2/gphoto2-camera.h
5
+ layout :port, :pointer, # GPPort
6
+ :fs, :pointer, # CameraFilesystem
7
+ :functions, :pointer, # CameraFunctions
8
+ :pl, :pointer, # CameraPrivateLibrary
9
+ :pc, :pointer # CameraPrivateCore
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,37 @@
1
+ require 'ffi/gphoto2_port/gp_port_type'
2
+
3
+ module FFI
4
+ module GPhoto2
5
+ class CameraAbilities < FFI::Struct
6
+ # gphoto2/gphoto2-abilities-list.h
7
+ layout :model, [:char, 128],
8
+ :status, CameraDriverStatus,
9
+
10
+ :port, GPhoto2Port::GPPortType,
11
+ :speed, [:int, 64],
12
+
13
+ :operations, CameraOperation,
14
+ :file_operations, CameraFileOperation,
15
+ :folder_operations, CameraFolderOperation,
16
+
17
+ :usb_vendor, :int,
18
+ :usb_product, :int,
19
+ :usb_class, :int,
20
+ :usb_subclass, :int,
21
+ :usb_protocol, :int,
22
+
23
+ :library, [:char, 1024],
24
+ :id, [:char, 1024],
25
+
26
+ :device_type, GphotoDeviceType,
27
+
28
+ :reserved2, :int,
29
+ :reserved3, :int,
30
+ :reserved4, :int,
31
+ :reserved5, :int,
32
+ :reserved6, :int,
33
+ :reserved7, :int,
34
+ :reserved8, :int
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,15 @@
1
+ require 'ffi/gphoto2/camera_abilities'
2
+
3
+ module FFI
4
+ module GPhoto2
5
+ class CameraAbilitiesList < FFI::ManagedStruct
6
+ # libgphoto2/gphoto2-abilities-list.c
7
+ layout :count, :int,
8
+ :abilities, :pointer # CameraAbilities*
9
+
10
+ def self.release(ptr)
11
+ FFI::GPhoto2.gp_abilities_list_free(ptr)
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,8 @@
1
+ module FFI
2
+ module GPhoto2
3
+ # gphoto2/gphoto2-camera.h
4
+ CameraCaptureType = enum :image,
5
+ :movie,
6
+ :sound
7
+ end
8
+ end
@@ -0,0 +1,9 @@
1
+ module FFI
2
+ module GPhoto2
3
+ # gphoto2/gphoto2-abilities-list.h
4
+ CameraDriverStatus = enum :production,
5
+ :testing,
6
+ :experimental,
7
+ :deprecated
8
+ end
9
+ end
@@ -0,0 +1,10 @@
1
+ module FFI
2
+ module GPhoto2
3
+ # gphoto2/gphoto2-camera.h
4
+ CameraEventType = enum :unknown,
5
+ :timeout,
6
+ :file_added,
7
+ :folder_added,
8
+ :capture_complete
9
+ end
10
+ end
@@ -0,0 +1,28 @@
1
+ module FFI
2
+ module GPhoto2
3
+ class CameraFile < FFI::ManagedStruct
4
+ MAX_PATH = 256
5
+
6
+ # libgphoto2/gphoto2-file.c
7
+ layout :mime_type, [:char, 64],
8
+ :name, [:char, MAX_PATH],
9
+ :ref_count, :int,
10
+ :mtime, :time_t,
11
+
12
+ :accesstype, CameraFileAccessType,
13
+
14
+ :size, :ulong,
15
+ :data, :pointer, # unsigned char*
16
+ :offset, :ulong,
17
+
18
+ :fd, :int,
19
+
20
+ :handler, :pointer, # CameraFileHandler
21
+ :private, :pointer # void*
22
+
23
+ def self.release(ptr)
24
+ FFI::GPhoto2.gp_file_free(ptr)
25
+ end
26
+ end
27
+ end
28
+ end