format_parser 1.6.0 → 1.7.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 54b56b24c97b2532bc5d7f8521aa38714111a05f2bedd5e15b7391e1005d9795
4
- data.tar.gz: e33a026ab2c611a86d6ba7e35fd413455f7b99c423651fa09dcebf08ad543e0a
3
+ metadata.gz: 8b3cef665ae16efd68e8da952fd4656e2d9403f3899bd58839da3d8026db91f4
4
+ data.tar.gz: 7b0ec88efc2ea62f526699a4041cb3f1b3062994d2a6e0b24c2cfdf247aaf532
5
5
  SHA512:
6
- metadata.gz: e27ec936c4b43cc6c82f896846ef3e8044a0639b18c1c2accf7bbdeffd0fe73d9c03fb2f2e9b4a477ef1f98a1043047042b8521f186e3406ca1c482be9a66abd
7
- data.tar.gz: a7927cfb5fbf0a41980465186809fb830b322e83db56bab15b5a2ad897031f7269eeae85d7e61f489a5cc2e6737348309e4f93c5dee27238d06a3ed0979f0d43
6
+ metadata.gz: 24c6379ef4fd3b5a9f061c6fc40fd8c0498ad33213684d08dd27a8b8994ba40a98bf1fa18a6d6b3b8189aa71436ec9bb394e3b8d41a8dd3ca90a5b93d0f1718a
7
+ data.tar.gz: a2d3df2c17d2559aa99f52f04624032a9243915f2a1b28a6f3626bd3b9112eb8c325b0c9a286864d25c2b4e92a44a8939448a85d1004ac5d48c2f81f747749c1
data/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ ## 1.7.0
2
+ * Add support for `ARW` files.
3
+
4
+ ## 1.6.0
5
+ * Add support for `AAC` files.
6
+
1
7
  ## 1.5.0
2
8
  * Add support for `NEF` files.
3
9
 
data/README.md CHANGED
@@ -194,7 +194,7 @@ Unless specified otherwise in this section the fixture files are MIT licensed an
194
194
  - `IMG_9266_*.tif` and all it's variations were created by the project maintainers
195
195
 
196
196
  ### ARW
197
- - ARW example is downloaded from http://www.rawsamples.ch/ and is Creative Common Licensed.
197
+ - ARW examples are downloaded from http://www.rawsamples.ch/ and are Creative Common Licensed.
198
198
 
199
199
  ### ZIP
200
200
  - The .zip fixture files have been created by the project maintainers
@@ -1,3 +1,3 @@
1
1
  module FormatParser
2
- VERSION = '1.6.0'
2
+ VERSION = '1.7.0'
3
3
  end
@@ -0,0 +1,50 @@
1
+ require_relative 'exif_parser'
2
+
3
+ class FormatParser::ARWParser
4
+ include FormatParser::IOUtils
5
+ include FormatParser::EXIFParser
6
+
7
+ # Standard TIFF headers
8
+ MAGIC_LE = [0x49, 0x49, 0x2A, 0x0].pack('C4')
9
+ MAGIC_BE = [0x4D, 0x4D, 0x0, 0x2A].pack('C4')
10
+ HEADER_BYTES = [MAGIC_LE, MAGIC_BE]
11
+ ARW_MIME_TYPE = 'image/x-sony-arw'
12
+
13
+ def likely_match?(filename)
14
+ filename =~ /\.arw$/i
15
+ end
16
+
17
+ def call(io)
18
+ io = FormatParser::IOConstraint.new(io)
19
+
20
+ return unless HEADER_BYTES.include?(safe_read(io, 4))
21
+ exif_data = exif_from_tiff_io(io)
22
+
23
+ return unless valid?(exif_data)
24
+
25
+ w = exif_data.width || exif_data.pixel_x_dimension
26
+ h = exif_data.height || exif_data.pixel_y_dimension
27
+
28
+ FormatParser::Image.new(
29
+ format: :arw,
30
+ width_px: w,
31
+ height_px: h,
32
+ display_width_px: exif_data.rotated? ? h : w,
33
+ display_height_px: exif_data.rotated? ? w : h,
34
+ orientation: exif_data.orientation_sym,
35
+ intrinsics: { exif: exif_data },
36
+ content_type: ARW_MIME_TYPE,
37
+ )
38
+ rescue EXIFR::MalformedTIFF
39
+ nil
40
+ end
41
+
42
+ def valid?(exif_data)
43
+ # taken directly from tiff_parser.rb
44
+ # Similar to how exiftool determines the image type as ARW, we are implementing a check here
45
+ # https://github.com/exiftool/exiftool/blob/e969456372fbaf4b980fea8bb094d71033ac8bf7/lib/Image/ExifTool/Exif.pm#L929
46
+ exif_data.compression == 6 && exif_data.new_subfile_type == 1 && exif_data.make&.start_with?('SONY')
47
+ end
48
+
49
+ FormatParser.register_parser new, natures: :image, formats: :arw
50
+ end
@@ -6,7 +6,6 @@ class FormatParser::TIFFParser
6
6
  MAGIC_BE = [0x4D, 0x4D, 0x0, 0x2A].pack('C4')
7
7
  HEADER_BYTES = [MAGIC_LE, MAGIC_BE]
8
8
  TIFF_MIME_TYPE = 'image/tiff'
9
- ARW_MIME_TYPE = 'image/x-sony-arw'
10
9
 
11
10
  def likely_match?(filename)
12
11
  filename =~ /\.tiff?$/i
@@ -28,20 +27,20 @@ class FormatParser::TIFFParser
28
27
  exif_data = exif_from_tiff_io(io)
29
28
  return unless exif_data
30
29
 
30
+ return if arw?(exif_data)
31
+
31
32
  w = exif_data.width || exif_data.pixel_x_dimension
32
33
  h = exif_data.height || exif_data.pixel_y_dimension
33
34
 
34
- format = arw?(exif_data) ? :arw : :tif
35
- mime_type = arw?(exif_data) ? ARW_MIME_TYPE : TIFF_MIME_TYPE
36
35
  FormatParser::Image.new(
37
- format: format,
36
+ format: :tif,
38
37
  width_px: w,
39
38
  height_px: h,
40
39
  display_width_px: exif_data.rotated? ? h : w,
41
40
  display_height_px: exif_data.rotated? ? w : h,
42
41
  orientation: exif_data.orientation_sym,
43
42
  intrinsics: {exif: exif_data},
44
- content_type: mime_type,
43
+ content_type: TIFF_MIME_TYPE,
45
44
  )
46
45
  rescue EXIFR::MalformedTIFF
47
46
  nil
@@ -55,7 +54,7 @@ class FormatParser::TIFFParser
55
54
  # Similar to how exiftool determines the image type as ARW, we are implementing a check here
56
55
  # https://github.com/exiftool/exiftool/blob/e969456372fbaf4b980fea8bb094d71033ac8bf7/lib/Image/ExifTool/Exif.pm#L929
57
56
  def arw?(exif_data)
58
- exif_data.compression == 6 && exif_data.new_subfile_type == 1 && exif_data.make == 'SONY'
57
+ exif_data.compression == 6 && exif_data.new_subfile_type == 1 && exif_data.make&.start_with?('SONY')
59
58
  end
60
59
 
61
60
  FormatParser.register_parser new, natures: :image, formats: :tif
@@ -0,0 +1,119 @@
1
+ require 'spec_helper'
2
+
3
+ describe FormatParser::ARWParser do
4
+ shared_examples 'likely_match for file' do |filename_with_extension|
5
+ it "matches '#{filename_with_extension}'" do
6
+ expect(subject.likely_match?(filename_with_extension)).to be_truthy
7
+ end
8
+ end
9
+
10
+ shared_examples 'no likely_match for file' do |filename_with_extension|
11
+ it "does not match '#{filename_with_extension}'" do
12
+ expect(subject.likely_match?(filename_with_extension)).to be_falsey
13
+ end
14
+ end
15
+
16
+ describe 'likely_match' do
17
+ filenames = ['raw_file', 'another raw file', 'and.another', 'one-more']
18
+ valid_extensions = ['.arw', '.Arw', '.aRw', '.arW', '.ARw', '.ArW', '.aRW', '.ARW']
19
+ invalid_extensions = ['.tiff', '.cr2', '.new', '.jpeg']
20
+ filenames.each do |filename|
21
+ valid_extensions.each do |extension|
22
+ include_examples 'likely_match for file', filename + extension
23
+ end
24
+ invalid_extensions.each do |extension|
25
+ include_examples 'no likely_match for file', filename + extension
26
+ end
27
+ end
28
+ end
29
+
30
+ describe 'parses Sony ARW fixtures as arw format file' do
31
+ expected_parsed_dimensions = {
32
+ 'RAW_SONY_A100.ARW' => {
33
+ width_px: 3872,
34
+ height_px: 2592,
35
+ display_width_px: 3872,
36
+ display_height_px: 2592,
37
+ orientation: :top_left
38
+ },
39
+ 'RAW_SONY_A700.ARW' => {
40
+ width_px: 4288,
41
+ height_px: 2856,
42
+ display_width_px: 4288,
43
+ display_height_px: 2856,
44
+ orientation: :top_left
45
+ },
46
+ 'RAW_SONY_A900.ARW' => {
47
+ width_px: 6080,
48
+ height_px: 4048,
49
+ display_width_px: 6080,
50
+ display_height_px: 4048,
51
+ orientation: :top_left
52
+ },
53
+ # rotated 90 degree image
54
+ 'RAW_SONY_DSC-RX100M2.ARW' => {
55
+ width_px: 5472,
56
+ height_px: 3648,
57
+ display_width_px: 3648,
58
+ display_height_px: 5472,
59
+ orientation: :right_top,
60
+ },
61
+ 'RAW_SONY_ILCE-7RM2.ARW' => {
62
+ width_px: 7952,
63
+ height_px: 5304,
64
+ display_width_px: 7952,
65
+ display_height_px: 5304,
66
+ orientation: :top_left,
67
+ },
68
+ 'RAW_SONY_NEX7.ARW' => {
69
+ width_px: 6000,
70
+ height_px: 4000,
71
+ display_width_px: 6000,
72
+ display_height_px: 4000,
73
+ orientation: :top_left,
74
+ },
75
+ 'RAW_SONY_SLTA55V.ARW' => {
76
+ width_px: 4928,
77
+ height_px: 3280,
78
+ display_width_px: 4928,
79
+ display_height_px: 3280,
80
+ orientation: :top_left,
81
+ },
82
+ }
83
+
84
+ Dir.glob(fixtures_dir + '/ARW/*.ARW').each do |arw_path|
85
+ it "is able to parse #{File.basename(arw_path)}" do
86
+ expected_dimension = expected_parsed_dimensions[File.basename(arw_path)]
87
+ # error if a new .arw test file is added without specifying the expected dimensions
88
+ expect(expected_dimension).not_to be_nil
89
+
90
+ parsed = subject.call(File.open(arw_path, 'rb'))
91
+ expect(parsed).not_to be_nil
92
+ expect(parsed.nature).to eq(:image)
93
+ expect(parsed.format).to eq(:arw)
94
+ expect(parsed.intrinsics[:exif]).not_to be_nil
95
+ expect(parsed.content_type).to eq('image/x-sony-arw')
96
+
97
+ expect(parsed.width_px).to eq(expected_dimension[:width_px])
98
+ expect(parsed.height_px).to eq(expected_dimension[:height_px])
99
+ expect(parsed.display_width_px).to eq(expected_dimension[:display_width_px])
100
+ expect(parsed.display_height_px).to eq(expected_dimension[:display_height_px])
101
+ expect(parsed.orientation).to eq(expected_dimension[:orientation])
102
+ end
103
+ end
104
+
105
+ shared_examples 'invalid filetype' do |filetype, fixture_path|
106
+ it "should fail to parse #{filetype}" do
107
+ file_path = fixtures_dir + fixture_path
108
+ parsed = subject.call(File.open(file_path, 'rb'))
109
+ expect(parsed).to be_nil
110
+ end
111
+ end
112
+
113
+ include_examples 'invalid filetype', 'NEF', '/NEF/RAW_NIKON_1S2.NEF'
114
+ include_examples 'invalid filetype', 'TIFF', '/TIFF/Shinbutsureijoushuincho.tiff'
115
+ include_examples 'invalid filetype', 'JPG', '/JPEG/orient_6.jpg'
116
+ include_examples 'invalid filetype', 'PNG', '/PNG/cat.png'
117
+ include_examples 'invalid filetype', 'CR2', '/CR2/RAW_CANON_1DM2.CR2'
118
+ end
119
+ end
@@ -47,21 +47,6 @@ describe FormatParser::TIFFParser do
47
47
  expect(parsed.intrinsics[:exif]).not_to be_nil
48
48
  end
49
49
 
50
- it 'parses Sony ARW fixture as arw format file' do
51
- arw_path = fixtures_dir + '/ARW/RAW_SONY_ILCE-7RM2.ARW'
52
-
53
- parsed = subject.call(File.open(arw_path, 'rb'))
54
-
55
- expect(parsed).not_to be_nil
56
- expect(parsed.nature).to eq(:image)
57
- expect(parsed.format).to eq(:arw)
58
-
59
- expect(parsed.width_px).to eq(7952)
60
- expect(parsed.height_px).to eq(5304)
61
- expect(parsed.intrinsics[:exif]).not_to be_nil
62
- expect(parsed.content_type).to eq('image/x-sony-arw')
63
- end
64
-
65
50
  describe 'correctly extracts dimensions from various TIFF flavors of the same file' do
66
51
  Dir.glob(fixtures_dir + '/TIFF/IMG_9266*.tif').each do |tiff_path|
67
52
  it "is able to parse #{File.basename(tiff_path)}" do
@@ -100,4 +85,13 @@ describe FormatParser::TIFFParser do
100
85
  end
101
86
  end
102
87
  end
88
+
89
+ describe 'bails out on ARW files, such as' do
90
+ Dir.glob(fixtures_dir + '/ARW/*.ARW').each do |arw_path|
91
+ it "skips #{File.basename(arw_path)}" do
92
+ parsed = subject.call(File.open(arw_path, 'rb'))
93
+ expect(parsed).to be_nil
94
+ end
95
+ end
96
+ end
103
97
  end
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: format_parser
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.6.0
4
+ version: 1.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Noah Berman
8
8
  - Julik Tarkhanov
9
- autorequire:
9
+ autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2022-09-21 00:00:00.000000000 Z
12
+ date: 2022-10-05 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: ks
@@ -232,6 +232,7 @@ files:
232
232
  - lib/parsers/aac_parser.rb
233
233
  - lib/parsers/aac_parser/adts_header_info.rb
234
234
  - lib/parsers/aiff_parser.rb
235
+ - lib/parsers/arw_parser.rb
235
236
  - lib/parsers/bmp_parser.rb
236
237
  - lib/parsers/cr2_parser.rb
237
238
  - lib/parsers/dpx_parser.rb
@@ -278,6 +279,7 @@ files:
278
279
  - spec/parsers/aac_parser_spec.rb
279
280
  - spec/parsers/adts_header_info_spec.rb
280
281
  - spec/parsers/aiff_parser_spec.rb
282
+ - spec/parsers/arw_parser_spec.rb
281
283
  - spec/parsers/bmp_parser_spec.rb
282
284
  - spec/parsers/cr2_parser_spec.rb
283
285
  - spec/parsers/dpx_parser_spec.rb
@@ -310,7 +312,7 @@ licenses:
310
312
  - MIT (Hippocratic)
311
313
  metadata:
312
314
  allowed_push_host: https://rubygems.org
313
- post_install_message:
315
+ post_install_message:
314
316
  rdoc_options: []
315
317
  require_paths:
316
318
  - lib
@@ -325,8 +327,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
325
327
  - !ruby/object:Gem::Version
326
328
  version: '0'
327
329
  requirements: []
328
- rubygems_version: 3.1.6
329
- signing_key:
330
+ rubygems_version: 3.3.7
331
+ signing_key:
330
332
  specification_version: 4
331
333
  summary: A library for efficient parsing of file metadata
332
334
  test_files: []