format_parser 1.6.0 → 1.7.0

Sign up to get free protection for your applications and to get access to all the features.
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: []