hydra-derivatives 0.0.7 → 0.0.8
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 +4 -4
- data/.gitignore +1 -0
- data/History.md +23 -0
- data/README.md +32 -8
- data/VERSION +1 -1
- data/lib/color_profiles/license.txt +7 -0
- data/lib/color_profiles/sRGB_IEC61966-2-1_no_black_scaling.icc +0 -0
- data/lib/hydra/derivatives.rb +6 -1
- data/lib/hydra/derivatives/config.rb +39 -1
- data/lib/hydra/derivatives/extract_metadata.rb +1 -1
- data/lib/hydra/derivatives/ffmpeg.rb +8 -1
- data/lib/hydra/derivatives/jpeg2k_config.yml +20 -0
- data/lib/hydra/derivatives/jpeg2k_image.rb +147 -0
- data/lib/hydra/derivatives/railtie.rb +7 -0
- data/lib/hydra/derivatives/video.rb +17 -3
- data/spec/fixtures/adobe1998.tif +0 -0
- data/spec/fixtures/jpeg2k_config.yml +20 -0
- data/spec/fixtures/test.tif +0 -0
- data/spec/units/config_spec.rb +9 -0
- data/spec/units/jpeg2k_spec.rb +54 -0
- data/spec/units/transcoding_spec.rb +30 -2
- data/spec/units/video_spec.rb +12 -2
- metadata +39 -26
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1bc8abf9416fda90a423323e7717b6ff5b889f70
|
4
|
+
data.tar.gz: db345a163681b8b2d981f5f4aad33e868951d03c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 57b97d9fbd4b63233ae73d58da47546f2c466a78de5bea3ef687f818cf3d493d17ed4c128f8a0c312f3a872d17bf0771a754479fbac1ddcdb359f5f02ef6f81f
|
7
|
+
data.tar.gz: 30f51ea9f6b6fc4be16631b89d46c090a7ee26e96b46a2d0f70c3e76f71eedcf890d0940db488413082e6446d5b059bd71a54e6fefc3cf8b37274f13cc49fbd0
|
data/.gitignore
CHANGED
data/History.md
CHANGED
@@ -1,3 +1,26 @@
|
|
1
|
+
## 0.0.8 (2013-04-09)
|
2
|
+
- Add support for JPEG2000 Derivatives
|
3
|
+
- Correcting Railtie initializer
|
4
|
+
- Added ImageMagick dependency
|
5
|
+
- Updated FITS URL
|
6
|
+
- Adding input and output options to ffmpeg and video processor
|
7
|
+
- Revert "Switch to streamio_ffmpeg for easier handling of ffmpeg arguments"
|
8
|
+
- Switch to streamio_ffmpeg for easier handling of ffmpeg arguments
|
9
|
+
- Adding Railtie for initialization
|
10
|
+
|
11
|
+
## 0.0.7 (2013-10-11)
|
12
|
+
- Restore `Hydra::Derivatives::ExtractMetadata#to_tempfile`
|
13
|
+
|
14
|
+
## 0.0.6 (2013-10-10)
|
15
|
+
- Added version badge
|
16
|
+
- Adding Hydra::FileCharacterization
|
17
|
+
- Updating CONTRIBUTING.md as per Hydra v6.0.0
|
18
|
+
- Adding microsoft openxmlformats as output formats
|
19
|
+
- Adding rewind to allow image data to be extracted properly
|
20
|
+
- Replacing rmagick with mini_magick
|
21
|
+
- Refactoring extraction to implicitly close
|
22
|
+
- Changes audio encoding to libfdk_aac for video derivatives
|
23
|
+
|
1
24
|
## 0.0.5 (2013-07-25)
|
2
25
|
- Allow images to change format without being resize [Justin Coyne]
|
3
26
|
|
data/README.md
CHANGED
@@ -1,6 +1,4 @@
|
|
1
|
-
hydra-derivatives
|
2
|
-
=================
|
3
|
-
[](http://badge.fury.io/rb/hydra-derivatives)
|
1
|
+
# hydra-derivatives [](http://badge.fury.io/rb/hydra-derivatives) [](https://travis-ci.org/projecthydra/hydra-derivatives) [](https://gemnasium.com/projecthydra/hydra-derivatives)
|
4
2
|
|
5
3
|
Derivative generation for hydra
|
6
4
|
|
@@ -23,6 +21,8 @@ If you have an ActiveFedora class like this:
|
|
23
21
|
obj.transform_datastream :content, { :mp4 => {format: 'mp4'}, :webm => {format: 'webm'} }, processor: :video
|
24
22
|
when 'image/png', 'image/jpg'
|
25
23
|
obj.transform_datastream :content, { :medium => "300x300>", :thumb => "100x100>" }
|
24
|
+
when 'image/tiff'
|
25
|
+
obj.transform_datastream :content, { :service => { resize: "3600x3600>" } }, processor: 'jpeg2k_image'
|
26
26
|
end
|
27
27
|
end
|
28
28
|
end
|
@@ -48,8 +48,10 @@ Or a class like this:
|
|
48
48
|
transform_datastream :content, { :mp3 => {format: 'mp3'}, :ogg => {format: 'ogg'} }, processor: :audio
|
49
49
|
when 'video/avi'
|
50
50
|
transform_datastream :content, { :mp4 => {format: 'mp4'}, :webm => {format: 'webm'} }, processor: :video
|
51
|
-
when 'image/png', 'image/jpg'
|
51
|
+
when 'image/png', 'image/jpg'
|
52
52
|
transform_datastream :content, { :medium => "300x300>", :thumb => {size: "100x100>", datastream: 'thumbnail'} }
|
53
|
+
when 'image/tiff'
|
54
|
+
transform_datastream :content, { :service => { recipe: :default } }, processor: 'jpeg2k_image'
|
53
55
|
end
|
54
56
|
end
|
55
57
|
end
|
@@ -60,7 +62,7 @@ And you add some content to it:
|
|
60
62
|
```ruby
|
61
63
|
obj = GenericFile.new
|
62
64
|
obj.content.content = File.open(...)
|
63
|
-
obj.mime_type = 'image/
|
65
|
+
obj.mime_type = 'image/jpg'
|
64
66
|
obj.save
|
65
67
|
```
|
66
68
|
|
@@ -74,11 +76,15 @@ Just add `gem 'hydra-derivatives'` to your Gemfile.
|
|
74
76
|
|
75
77
|
## Dependencies
|
76
78
|
|
77
|
-
* [
|
79
|
+
* [FITS](http://fitstool.org/)
|
78
80
|
* [FFMpeg](http://www.ffmpeg.org/)
|
79
81
|
* [LibreOffice](https://www.libreoffice.org/)
|
82
|
+
* [ImageMagick](http://www.imagemagick.org/)
|
83
|
+
* Kakadu's [kdu_compress](http://www.kakadusoftware.com/)
|
84
|
+
|
85
|
+
To enable LibreOffice, FFMpeg, ImageMagick, FITS support, and kdu_compress support, make sure they are on your path. Most people will put that in their .bash_profile or somewhere similar.
|
80
86
|
|
81
|
-
|
87
|
+
For example:
|
82
88
|
|
83
89
|
```bash
|
84
90
|
# in .bash_profile
|
@@ -90,5 +96,23 @@ Alternatively, you can configure their paths:
|
|
90
96
|
Hydra::Derivatives.ffmpeg_path = '/opt/local/ffmpeg/bin/ffmpeg'
|
91
97
|
Hydra::Derivatives.fits_path = '/opt/local/fits/bin/fits.sh'
|
92
98
|
Hydra::Derivatives.libreoffice_path = '/opt/local/libreoffice_path/bin/soffice'
|
93
|
-
|
99
|
+
Hydra::Derivatives.kdu_compress_path = '/usr/local/bin/kdu_compress'
|
94
100
|
```
|
101
|
+
|
102
|
+
## JPEG2k Directives
|
103
|
+
|
104
|
+
Unlike the other processors, the `Jpeg2kImage` processor does not generally accept arguments that directly (or nearly so) translate to the arguments you would give to the corresponding command line utility.
|
105
|
+
|
106
|
+
Instead, each directive may contain these arguments:
|
107
|
+
|
108
|
+
* `:datastream` (String) : The name for the new datastream
|
109
|
+
* `:to_srgb` (Boolean) : If `true` and the image is a color image it will map the source image color profile to sRGB. Default: `true`
|
110
|
+
* `:resize` (String) : Geometry; the same syntax as the `Hydra::Derivatives::Image` processor
|
111
|
+
* `:recipe` :
|
112
|
+
- If a Symbol the recipe will be read from the `Hydra::Derivatives.kdu_compress_recipes` hash. You can override this, or a couple of samples are supplied. The symbol in the config file should be the name in the model + `_{quality}`, e.g. `recipe: :default` will look `:default_color` or `:default_grey` in the hash.
|
113
|
+
- If a String the recipe in the string will be used. You may include anything the command line utility will accept except `-i` or `-o`. See `$ kdu_compress -usage` in your shell.
|
114
|
+
- If no `:recipe` is provided the processor will examine the image and make a best guess, but you can set a few basic options (the remainder of this list). Note that these are ignored if you provided a recipe via either of the first two methods described.
|
115
|
+
* `:levels` (Integer) : The number of decomposition levels. The default is the number of times the long dimension can be divided by two, down to 96, e.g. a 7200 pixel image would have 6 levels (3600, 1800, 900, 450, 225, 112)
|
116
|
+
* `:layers` (Integer) : The number of quality layers. Default: 8
|
117
|
+
* `:compression` (Integer) : The left number of the compression ratio `n:1`, e.g. 12 will apply 12:1 compression. Default: 10.
|
118
|
+
* `:tile_size` (Integer) : Pixel dimension of the tiles. Default: 1024
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.8
|
@@ -0,0 +1,7 @@
|
|
1
|
+
Terms of use (from http://www.color.org/srgbprofiles.xalter#v2)
|
2
|
+
|
3
|
+
To anyone who acknowledges that the files "sRGB_IEC61966-2-1_no_black_scaling.icc" and "sRGB_IEC61966-2-1_black scaled.icc"
|
4
|
+
are provided "AS IS" WITH NO EXPRESS OR IMPLIED WARRANTY, permission to use, copy and distribute these file for any purpose
|
5
|
+
is hereby granted without fee, provided that the files are not changed including the ICC copyright notice tag, and that the
|
6
|
+
name of ICC shall not be used in advertising or publicity pertaining to distribution of the software without specific,
|
7
|
+
written prior permission. ICC makes no representations about the suitability of this software for any purpose.
|
Binary file
|
data/lib/hydra/derivatives.rb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
1
|
require 'active_fedora'
|
2
|
+
require 'hydra/derivatives/railtie' if defined?(Rails)
|
3
|
+
|
2
4
|
module Hydra
|
3
5
|
module Derivatives
|
4
6
|
extend ActiveSupport::Concern
|
@@ -13,6 +15,7 @@ module Hydra
|
|
13
15
|
autoload :Document
|
14
16
|
autoload :ExtractMetadata
|
15
17
|
autoload :ShellBasedProcessor
|
18
|
+
autoload :Jpeg2kImage
|
16
19
|
|
17
20
|
def self.config
|
18
21
|
@config ||= reset_config!
|
@@ -22,7 +25,9 @@ module Hydra
|
|
22
25
|
@config = Config.new
|
23
26
|
end
|
24
27
|
|
25
|
-
|
28
|
+
|
29
|
+
[:ffmpeg_path, :libreoffice_path, :temp_file_base, :fits_path, :kdu_compress_path,
|
30
|
+
:kdu_compress_recipes, :enable_ffmpeg].each do |method|
|
26
31
|
module_eval <<-RUBY
|
27
32
|
def self.#{method.to_s}
|
28
33
|
config.#{method.to_s}
|
@@ -1,7 +1,8 @@
|
|
1
1
|
module Hydra
|
2
2
|
module Derivatives
|
3
3
|
class Config
|
4
|
-
attr_writer :ffmpeg_path, :libreoffice_path, :temp_file_base, :fits_path,
|
4
|
+
attr_writer :ffmpeg_path, :libreoffice_path, :temp_file_base, :fits_path,
|
5
|
+
:enable_ffmpeg, :kdu_compress_path, :kdu_compress_recipes
|
5
6
|
def ffmpeg_path
|
6
7
|
@ffmpeg_path ||= 'ffmpeg'
|
7
8
|
end
|
@@ -22,6 +23,43 @@ module Hydra
|
|
22
23
|
@enable_ffmpeg ||= true
|
23
24
|
end
|
24
25
|
|
26
|
+
def kdu_compress_path
|
27
|
+
@kdu_compress_path ||= 'kdu_compress'
|
28
|
+
end
|
29
|
+
|
30
|
+
def kdu_compress_recipes
|
31
|
+
@kdu_compress_recipes ||= {
|
32
|
+
default_color: %Q{-rate 2.4,1.48331273,.91673033,.56657224,.35016049,.21641118,.13374944,.08266171
|
33
|
+
-jp2_space sRGB
|
34
|
+
-double_buffering 10
|
35
|
+
-num_threads 4
|
36
|
+
-no_weights
|
37
|
+
Clevels=6
|
38
|
+
Clayers=8
|
39
|
+
Cblk=\{64,64\}
|
40
|
+
Cuse_sop=yes
|
41
|
+
Cuse_eph=yes
|
42
|
+
Corder=RPCL
|
43
|
+
ORGgen_plt=yes
|
44
|
+
ORGtparts=R
|
45
|
+
Stiles=\{1024,1024\} }.gsub(/\s+/, " ").strip,
|
46
|
+
default_grey: %Q{-rate 2.4,1.48331273,.91673033,.56657224,.35016049,.21641118,.13374944,.08266171
|
47
|
+
-jp2_space sLUM
|
48
|
+
-double_buffering 10
|
49
|
+
-num_threads 4
|
50
|
+
-no_weights
|
51
|
+
Clevels=6
|
52
|
+
Clayers=8
|
53
|
+
Cblk=\{64,64\}
|
54
|
+
Cuse_sop=yes
|
55
|
+
Cuse_eph=yes
|
56
|
+
Corder=RPCL
|
57
|
+
ORGgen_plt=yes
|
58
|
+
ORGtparts=R
|
59
|
+
Stiles=\{1024,1024\} }.gsub(/\s+/, " ").strip
|
60
|
+
}
|
61
|
+
end
|
62
|
+
|
25
63
|
end
|
26
64
|
end
|
27
65
|
end
|
@@ -8,6 +8,9 @@ module Hydra
|
|
8
8
|
module Ffmpeg
|
9
9
|
extend ActiveSupport::Concern
|
10
10
|
|
11
|
+
INPUT_OPTIONS=:input_options
|
12
|
+
OUTPUT_OPTIONS=:output_options
|
13
|
+
|
11
14
|
included do
|
12
15
|
include ShellBasedProcessor
|
13
16
|
end
|
@@ -16,7 +19,11 @@ module Hydra
|
|
16
19
|
module ClassMethods
|
17
20
|
|
18
21
|
def encode(path, options, output_file)
|
19
|
-
|
22
|
+
inopts = options[INPUT_OPTIONS] if options
|
23
|
+
inopts ||= "-y"
|
24
|
+
outopts = options[OUTPUT_OPTIONS] if options
|
25
|
+
outopts ||= options
|
26
|
+
execute "#{Hydra::Derivatives.ffmpeg_path} #{inopts} -i \"#{path}\" #{outopts} #{output_file}"
|
20
27
|
end
|
21
28
|
end
|
22
29
|
|
@@ -0,0 +1,20 @@
|
|
1
|
+
defaults: &defaults
|
2
|
+
jp2_recipes:
|
3
|
+
# note that these aren't real recipes, just enough to test configuration options
|
4
|
+
myrecipe_color: >
|
5
|
+
-rate 2.4
|
6
|
+
-jp2_space sRGB
|
7
|
+
Stiles=\{1024,1024\}
|
8
|
+
myrecipe_grey: >
|
9
|
+
-rate 2.4
|
10
|
+
-jp2_space sLUM
|
11
|
+
Stiles=\{1024,1024\}
|
12
|
+
|
13
|
+
development:
|
14
|
+
<<: *defaults
|
15
|
+
|
16
|
+
test:
|
17
|
+
<<: *defaults
|
18
|
+
|
19
|
+
production:
|
20
|
+
<<: *defaults
|
@@ -0,0 +1,147 @@
|
|
1
|
+
require 'mini_magick'
|
2
|
+
require 'nokogiri'
|
3
|
+
|
4
|
+
|
5
|
+
module Hydra
|
6
|
+
module Derivatives
|
7
|
+
class Jpeg2kImage < Processor
|
8
|
+
include ShellBasedProcessor
|
9
|
+
|
10
|
+
def process
|
11
|
+
quality, colorspace = extract_quality_and_colorspace
|
12
|
+
directives.each do |name, args|
|
13
|
+
file_path = nil
|
14
|
+
long_dim = nil
|
15
|
+
to_srgb = args.fetch(:to_srgb, true)
|
16
|
+
if args[:resize] || to_srgb
|
17
|
+
image = preprocess(resize: args[:resize], to_srgb: to_srgb, src_quality: quality)
|
18
|
+
long_dim = self.class.long_dim(image)
|
19
|
+
file_path = self.class.tmp_file('.tif')
|
20
|
+
image.write file_path
|
21
|
+
else
|
22
|
+
long_dim = self.class.long_dim(MiniMagick::Image.read(source_datastream.content))
|
23
|
+
end
|
24
|
+
recipe = self.class.kdu_compress_recipe(args, quality, long_dim)
|
25
|
+
output_datastream_name = args[:datastream] || output_datastream_id(name)
|
26
|
+
encode_datastream(output_datastream_name, recipe, file_path: file_path)
|
27
|
+
File.unlink(file_path) unless file_path.nil?
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def encode_datastream(dest_dsid, recipe, opts={})
|
32
|
+
output_file = self.class.tmp_file('.jp2')
|
33
|
+
if opts[:file_path]
|
34
|
+
self.class.encode(opts[:file_path], recipe, output_file)
|
35
|
+
else
|
36
|
+
source_datastream.to_tempfile do |f|
|
37
|
+
self.class.encode(f.path, recipe, output_file)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
out_file = File.open(output_file, "rb")
|
41
|
+
object.add_file_datastream(out_file.read, dsid: dest_dsid, mimeType: 'image/jp2')
|
42
|
+
File.unlink(output_file)
|
43
|
+
end
|
44
|
+
|
45
|
+
protected
|
46
|
+
def preprocess(opts={})
|
47
|
+
# resize: <geometry>, to_srgb: <bool>,src_quality: 'color'|'grey'
|
48
|
+
image = MiniMagick::Image.read(source_datastream.content)
|
49
|
+
image.combine_options do |c|
|
50
|
+
c.resize(opts[:resize]) if opts[:resize]
|
51
|
+
c.profile self.class.srgb_profile_path if opts[:src_quality] == 'color' && opts[:to_srgb]
|
52
|
+
end
|
53
|
+
image
|
54
|
+
end
|
55
|
+
|
56
|
+
def extract_quality_and_colorspace
|
57
|
+
xml = source_datastream.extract_metadata
|
58
|
+
doc = Nokogiri::XML(xml).remove_namespaces!
|
59
|
+
bps = doc.xpath('//bitsPerSample').first.content
|
60
|
+
quality = bps == '8 8 8' ? 'color' : 'grey'
|
61
|
+
colorspace = doc.xpath('.//colorSpace').first.content
|
62
|
+
[quality, colorspace]
|
63
|
+
end
|
64
|
+
|
65
|
+
def self.encode(path, recipe, output_file)
|
66
|
+
kdu_compress = Hydra::Derivatives.kdu_compress_path
|
67
|
+
execute "#{kdu_compress} -i #{path} -o #{output_file} #{recipe}"
|
68
|
+
end
|
69
|
+
|
70
|
+
def self.srgb_profile_path
|
71
|
+
File.join [
|
72
|
+
File.expand_path('../../../', __FILE__),
|
73
|
+
'color_profiles',
|
74
|
+
'sRGB_IEC61966-2-1_no_black_scaling.icc'
|
75
|
+
]
|
76
|
+
end
|
77
|
+
|
78
|
+
def self.tmp_file(ext)
|
79
|
+
Dir::Tmpname.create(['sufia', ext], Hydra::Derivatives.temp_file_base){}
|
80
|
+
end
|
81
|
+
|
82
|
+
def self.long_dim(image)
|
83
|
+
[image[:width], image[:height]].max
|
84
|
+
end
|
85
|
+
|
86
|
+
def self.kdu_compress_recipe(args, quality, long_dim)
|
87
|
+
if args[:recipe].is_a? Symbol
|
88
|
+
recipe = [args[:recipe].to_s, quality].join('_')
|
89
|
+
if Hydra::Derivatives.kdu_compress_recipes.has_key? recipe
|
90
|
+
return Hydra::Derivatives.kdu_compress_recipes[recipe]
|
91
|
+
else
|
92
|
+
logger.warn "No JP2 recipe for :#{args[:recipe].to_s} ('#{recipe}') found in configuration. Using best guess."
|
93
|
+
return Hydra::Derivatives::Jpeg2kImage.calculate_recipe(args,quality,long_dim)
|
94
|
+
end
|
95
|
+
elsif args[:recipe].is_a? String
|
96
|
+
return args[:recipe]
|
97
|
+
else
|
98
|
+
return Hydra::Derivatives::Jpeg2kImage.calculate_recipe(args, quality, long_dim)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def self.calculate_recipe(args, quality, long_dim)
|
103
|
+
levels_arg = args.fetch(:levels, Hydra::Derivatives::Jpeg2kImage.level_count_for_size(long_dim))
|
104
|
+
rates_arg = Hydra::Derivatives::Jpeg2kImage.layer_rates(args.fetch(:layers, 8), args.fetch(:compression, 10))
|
105
|
+
tile_size = args.fetch(:tile_size, 1024)
|
106
|
+
tiles_arg = "\{#{tile_size},#{tile_size}\}"
|
107
|
+
jp2_space_arg = quality == 'grey' ? 'sLUM' : 'sRGB'
|
108
|
+
|
109
|
+
%Q{-rate #{rates_arg}
|
110
|
+
-jp2_space #{jp2_space_arg}
|
111
|
+
-double_buffering 10
|
112
|
+
-num_threads 4
|
113
|
+
-no_weights
|
114
|
+
Clevels=#{levels_arg}
|
115
|
+
Stiles=#{tiles_arg}
|
116
|
+
Cblk=\{64,64\}
|
117
|
+
Cuse_sop=yes
|
118
|
+
Cuse_eph=yes
|
119
|
+
Corder=RPCL
|
120
|
+
ORGgen_plt=yes
|
121
|
+
ORGtparts=R }.gsub(/\s+/, " ").strip
|
122
|
+
end
|
123
|
+
|
124
|
+
def self.level_count_for_size(long_dim)
|
125
|
+
levels = 0
|
126
|
+
level_size = long_dim
|
127
|
+
while level_size >= 96
|
128
|
+
level_size = level_size/2
|
129
|
+
levels+=1
|
130
|
+
end
|
131
|
+
levels-1
|
132
|
+
end
|
133
|
+
|
134
|
+
def self.layer_rates(layer_count,compression_numerator)
|
135
|
+
#e.g. if compression_numerator = 10 then compression is 10:1
|
136
|
+
rates = []
|
137
|
+
cmp = 24.0/compression_numerator
|
138
|
+
layer_count.times do
|
139
|
+
rates << cmp
|
140
|
+
cmp = (cmp/1.618).round(8)
|
141
|
+
end
|
142
|
+
rates.map(&:to_s ).join(',')
|
143
|
+
end
|
144
|
+
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
@@ -6,7 +6,17 @@ module Hydra
|
|
6
6
|
protected
|
7
7
|
|
8
8
|
def options_for(format)
|
9
|
-
"
|
9
|
+
input_options=""
|
10
|
+
output_options = "-s #{size_attributes} #{codecs(format)}"
|
11
|
+
|
12
|
+
if (format == "jpg")
|
13
|
+
input_options +=" -itsoffset -2"
|
14
|
+
output_options+= " -vframes 1 -an -f rawvideo"
|
15
|
+
else
|
16
|
+
output_options +=" #{video_attributes} #{audio_attributes}"
|
17
|
+
end
|
18
|
+
|
19
|
+
{ Ffmpeg::OUTPUT_OPTIONS => output_options, Ffmpeg::INPUT_OPTIONS => input_options}
|
10
20
|
end
|
11
21
|
|
12
22
|
def video_bitrate
|
@@ -30,14 +40,18 @@ module Hydra
|
|
30
40
|
when 'mp4'
|
31
41
|
"-vcodec libx264 -acodec libfdk_aac"
|
32
42
|
when 'webm'
|
33
|
-
"-acodec libvorbis"
|
43
|
+
"-vcodec libvpx -acodec libvorbis"
|
44
|
+
when "mkv"
|
45
|
+
"-vcodec ffv1"
|
46
|
+
when "jpg"
|
47
|
+
"-vcodec mjpeg"
|
34
48
|
else
|
35
49
|
raise ArgumentError, "Unknown format `#{format}'"
|
36
50
|
end
|
37
51
|
end
|
38
52
|
|
39
53
|
def new_mime_type(format)
|
40
|
-
"video/#{format}"
|
54
|
+
format == "jpg" ? "image/jpeg" : "video/#{format}"
|
41
55
|
end
|
42
56
|
end
|
43
57
|
end
|
Binary file
|
@@ -0,0 +1,20 @@
|
|
1
|
+
defaults: &defaults
|
2
|
+
jp2_recipes:
|
3
|
+
# note that these aren't real recipes, just enough to test configuration options
|
4
|
+
myrecipe_color: >
|
5
|
+
-rate 2.4
|
6
|
+
-jp2_space sRGB
|
7
|
+
Stiles=\{1024,1024\}
|
8
|
+
myrecipe_grey: >
|
9
|
+
-rate 2.4
|
10
|
+
-jp2_space sLUM
|
11
|
+
Stiles=\{1024,1024\}
|
12
|
+
|
13
|
+
development:
|
14
|
+
<<: *defaults
|
15
|
+
|
16
|
+
test:
|
17
|
+
<<: *defaults
|
18
|
+
|
19
|
+
production:
|
20
|
+
<<: *defaults
|
Binary file
|
data/spec/units/config_spec.rb
CHANGED
@@ -9,17 +9,26 @@ describe "the configuration" do
|
|
9
9
|
subject.libreoffice_path.should == 'soffice'
|
10
10
|
subject.temp_file_base.should == '/tmp'
|
11
11
|
subject.fits_path.should == 'fits.sh'
|
12
|
+
subject.kdu_compress_path.should == 'kdu_compress'
|
12
13
|
end
|
13
14
|
|
14
15
|
it "should let you change the configuration" do
|
15
16
|
subject.ffmpeg_path = '/usr/local/ffmpeg-1.0/bin/ffmpeg'
|
16
17
|
subject.ffmpeg_path.should == '/usr/local/ffmpeg-1.0/bin/ffmpeg'
|
18
|
+
|
19
|
+
subject.kdu_compress_path = '/opt/local/bin/kdu_compress'
|
20
|
+
subject.kdu_compress_path.should == '/opt/local/bin/kdu_compress'
|
21
|
+
|
17
22
|
end
|
18
23
|
|
19
24
|
it "should let you reset the configuration" do
|
20
25
|
subject.ffmpeg_path = '/usr/local/ffmpeg-1.0/bin/ffmpeg'
|
21
26
|
subject.reset_config!
|
22
27
|
subject.ffmpeg_path.should == 'ffmpeg'
|
28
|
+
|
29
|
+
subject.kdu_compress_path = '/usr/local/bin/kdu_compress'
|
30
|
+
subject.reset_config!
|
31
|
+
subject.kdu_compress_path.should == 'kdu_compress'
|
23
32
|
end
|
24
33
|
|
25
34
|
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'yaml'
|
3
|
+
|
4
|
+
describe Hydra::Derivatives::Jpeg2kImage do
|
5
|
+
let(:object) { ActiveFedora::Base.new }
|
6
|
+
|
7
|
+
describe "#calculate_recipe" do
|
8
|
+
it "calculates the number of levels from a size" do
|
9
|
+
dim = 7200
|
10
|
+
Hydra::Derivatives::Jpeg2kImage.level_count_for_size(dim).should == 6
|
11
|
+
end
|
12
|
+
|
13
|
+
it "calculates the compression rates for each quality layer" do
|
14
|
+
compression_num = 10
|
15
|
+
layers = 8
|
16
|
+
calc = Hydra::Derivatives::Jpeg2kImage.layer_rates(layers, compression_num)
|
17
|
+
calc.should == "2.4,1.48331273,0.91675694,0.56659885,0.3501847,0.21643059,0.13376427,0.0826726"
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "#kdu_compress_recipe" do
|
23
|
+
before(:all) do
|
24
|
+
@sample_cfg = YAML.load_file(File.expand_path('../../fixtures/jpeg2k_config.yml', __FILE__))['test']
|
25
|
+
Hydra::Derivatives.kdu_compress_recipes = @sample_cfg['jp2_recipes']
|
26
|
+
end
|
27
|
+
|
28
|
+
it "can get the recipe from a config file" do
|
29
|
+
args = { recipe: :myrecipe }
|
30
|
+
r = Hydra::Derivatives::Jpeg2kImage.kdu_compress_recipe(args, 'grey', 7200)
|
31
|
+
r.should == @sample_cfg['jp2_recipes']['myrecipe_grey']
|
32
|
+
end
|
33
|
+
|
34
|
+
it "can take a recipe as a string" do
|
35
|
+
args = { recipe: '-my -excellent -recipe' }
|
36
|
+
r = Hydra::Derivatives::Jpeg2kImage.kdu_compress_recipe(args, 'grey', 7200)
|
37
|
+
r.should == args[:recipe]
|
38
|
+
end
|
39
|
+
|
40
|
+
it "will fall back to a #calculate_recipe if a symbol is passed but no recipe is found" do
|
41
|
+
args = { recipe: :x }
|
42
|
+
r = Hydra::Derivatives::Jpeg2kImage.kdu_compress_recipe(args, 'grey', 7200)
|
43
|
+
r.should == Hydra::Derivatives::Jpeg2kImage.calculate_recipe(args, 'grey', 7200)
|
44
|
+
end
|
45
|
+
|
46
|
+
it "will fall back to a #calculate_recipe if there is no attempt to provide one" do
|
47
|
+
args = {}
|
48
|
+
r = Hydra::Derivatives::Jpeg2kImage.kdu_compress_recipe(args, 'grey', 7200)
|
49
|
+
r.should == Hydra::Derivatives::Jpeg2kImage.calculate_recipe(args, 'grey', 7200)
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
@@ -11,7 +11,7 @@ describe "Transcoder" do
|
|
11
11
|
m.field "mime_type", :string
|
12
12
|
end
|
13
13
|
|
14
|
-
|
14
|
+
has_attributes :mime_type, datastream: :characterization, multiple: false
|
15
15
|
has_file_datastream 'content', type: ContentDatastream
|
16
16
|
|
17
17
|
makes_derivatives do |obj|
|
@@ -21,7 +21,8 @@ describe "Transcoder" do
|
|
21
21
|
when 'audio/wav'
|
22
22
|
obj.transform_datastream :content, { :mp3 => {format: 'mp3'}, :ogg => {format: 'ogg'} }, processor: :audio
|
23
23
|
when 'video/avi'
|
24
|
-
obj.transform_datastream :content, { :mp4 => {format: 'mp4'}, :webm => {format: 'webm'}
|
24
|
+
obj.transform_datastream :content, { :mp4 => {format: 'mp4'}, :webm => {format: 'webm'},
|
25
|
+
:thumbnail=> {:format => 'jpg' , datastream: 'thumbnail'} }, processor: :video
|
25
26
|
when 'image/png', 'image/jpg'
|
26
27
|
obj.transform_datastream :content, { :medium => "300x300>", :thumb => "100x100>", :access => {format: 'jpg', datastream: 'access'} }
|
27
28
|
when 'application/vnd.ms-powerpoint'
|
@@ -32,6 +33,14 @@ describe "Transcoder" do
|
|
32
33
|
obj.transform_datastream :content, { :access => { :format=>'pdf' }, :preservation=> {:format => 'docx' } }, processor: 'document'
|
33
34
|
when 'application/vnd.ms-excel'
|
34
35
|
obj.transform_datastream :content, { :access => { :format=>'pdf' }, :preservation=> {:format => 'xslx' } }, processor: 'document'
|
36
|
+
when 'image/tiff'
|
37
|
+
obj.transform_datastream :content, {
|
38
|
+
resized: { recipe: :default, resize: "600x600>", datastream: 'resized' },
|
39
|
+
config_lookup: { recipe: :default, datastream: 'config_lookup' },
|
40
|
+
string_recipe: { recipe: '-quiet', datastream: 'string_recipe' },
|
41
|
+
diy: { }
|
42
|
+
}, processor: 'jpeg2k_image'
|
43
|
+
|
35
44
|
end
|
36
45
|
|
37
46
|
end
|
@@ -117,6 +126,8 @@ describe "Transcoder" do
|
|
117
126
|
file.datastreams['content_mp4'].mimeType.should == 'video/mp4'
|
118
127
|
file.datastreams['content_webm'].should have_content
|
119
128
|
file.datastreams['content_webm'].mimeType.should == 'video/webm'
|
129
|
+
file.datastreams['thumbnail'].should have_content
|
130
|
+
file.datastreams['thumbnail'].mimeType.should == 'image/jpeg'
|
120
131
|
end
|
121
132
|
end
|
122
133
|
|
@@ -187,4 +198,21 @@ describe "Transcoder" do
|
|
187
198
|
end
|
188
199
|
end
|
189
200
|
|
201
|
+
describe "with an attached tiff", unless: ENV['TRAVIS'] == 'true' do
|
202
|
+
|
203
|
+
let(:attachment) { File.open(File.expand_path('../../fixtures/test.tif', __FILE__))}
|
204
|
+
let(:file) { GenericFile.new(mime_type: 'image/tiff').tap { |t| t.content.content = attachment; t.save } }
|
205
|
+
it "should transcode" do
|
206
|
+
file.create_derivatives
|
207
|
+
file.datastreams['content_diy'].should have_content
|
208
|
+
file.datastreams['content_diy'].mimeType.should == 'image/jp2'
|
209
|
+
file.datastreams['config_lookup'].should have_content
|
210
|
+
file.datastreams['config_lookup'].mimeType.should == 'image/jp2'
|
211
|
+
file.datastreams['resized'].should have_content
|
212
|
+
file.datastreams['resized'].mimeType.should == 'image/jp2'
|
213
|
+
file.datastreams['string_recipe'].should have_content
|
214
|
+
file.datastreams['string_recipe'].mimeType.should == 'image/jp2'
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
190
218
|
end
|
data/spec/units/video_spec.rb
CHANGED
@@ -6,7 +6,7 @@ describe Hydra::Derivatives::Video do
|
|
6
6
|
let(:directives) {{ :thumb => {format: "webm", datastream: 'thumbnail'} }}
|
7
7
|
subject { Hydra::Derivatives::Video.new(double(:obj), 'content', directives)}
|
8
8
|
it "should create a datastream with the specified name" do
|
9
|
-
subject.should_receive(:encode_datastream).with("thumbnail", "webm", 'video/webm', "-s 320x240 -g 30 -b:v 345k -
|
9
|
+
subject.should_receive(:encode_datastream).with("thumbnail", "webm", 'video/webm', {Hydra::Derivatives::Ffmpeg::OUTPUT_OPTIONS =>"-s 320x240 -vcodec libvpx -acodec libvorbis -g 30 -b:v 345k -ac 2 -ab 96k -ar 44100", Hydra::Derivatives::Ffmpeg::INPUT_OPTIONS=>""})
|
10
10
|
subject.process
|
11
11
|
|
12
12
|
end
|
@@ -16,7 +16,17 @@ describe Hydra::Derivatives::Video do
|
|
16
16
|
let(:directives) {{ :thumb => {format: "webm"} }}
|
17
17
|
subject { Hydra::Derivatives::Video.new(double(:obj), 'content', directives)}
|
18
18
|
it "should create a datastream and infer the name" do
|
19
|
-
subject.should_receive(:encode_datastream).with("content_thumb", "webm", 'video/webm', "-s 320x240 -g 30 -b:v 345k -
|
19
|
+
subject.should_receive(:encode_datastream).with("content_thumb", "webm", 'video/webm', {Hydra::Derivatives::Ffmpeg::OUTPUT_OPTIONS =>"-s 320x240 -vcodec libvpx -acodec libvorbis -g 30 -b:v 345k -ac 2 -ab 96k -ar 44100", Hydra::Derivatives::Ffmpeg::INPUT_OPTIONS=>""})
|
20
|
+
subject.process
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe "and jpg is requested" do
|
26
|
+
let(:directives) {{ :thumb => {:format => 'jpg' , datastream: 'thumbnail'} }}
|
27
|
+
subject { Hydra::Derivatives::Video.new(double(:obj), 'content', directives)}
|
28
|
+
it "should create a datastream and infer the name" do
|
29
|
+
subject.should_receive(:encode_datastream).with("thumbnail", "jpg", "image/jpeg", {:output_options=>"-s 320x240 -vcodec mjpeg -vframes 1 -an -f rawvideo", :input_options=>" -itsoffset -2"})
|
20
30
|
subject.process
|
21
31
|
|
22
32
|
end
|
metadata
CHANGED
@@ -1,131 +1,131 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hydra-derivatives
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Justin Coyne
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2014-04-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - ~>
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '1.3'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - ~>
|
24
|
+
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '1.3'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- -
|
31
|
+
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '0'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- -
|
38
|
+
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: jettywrapper
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- -
|
45
|
+
- - ">="
|
46
46
|
- !ruby/object:Gem::Version
|
47
47
|
version: '0'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- -
|
52
|
+
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: rspec
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- -
|
59
|
+
- - ">="
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: '0'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- -
|
66
|
+
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: active-fedora
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- -
|
73
|
+
- - ">="
|
74
74
|
- !ruby/object:Gem::Version
|
75
75
|
version: '0'
|
76
76
|
type: :runtime
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
|
-
- -
|
80
|
+
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: hydra-file_characterization
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
|
-
- -
|
87
|
+
- - ">="
|
88
88
|
- !ruby/object:Gem::Version
|
89
89
|
version: '0'
|
90
90
|
type: :runtime
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
|
-
- -
|
94
|
+
- - ">="
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '0'
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
98
|
name: mini_magick
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
100
100
|
requirements:
|
101
|
-
- -
|
101
|
+
- - ">="
|
102
102
|
- !ruby/object:Gem::Version
|
103
103
|
version: '0'
|
104
104
|
type: :runtime
|
105
105
|
prerelease: false
|
106
106
|
version_requirements: !ruby/object:Gem::Requirement
|
107
107
|
requirements:
|
108
|
-
- -
|
108
|
+
- - ">="
|
109
109
|
- !ruby/object:Gem::Version
|
110
110
|
version: '0'
|
111
111
|
- !ruby/object:Gem::Dependency
|
112
112
|
name: activesupport
|
113
113
|
requirement: !ruby/object:Gem::Requirement
|
114
114
|
requirements:
|
115
|
-
- -
|
115
|
+
- - ">="
|
116
116
|
- !ruby/object:Gem::Version
|
117
117
|
version: 3.2.13
|
118
|
-
- - <
|
118
|
+
- - "<"
|
119
119
|
- !ruby/object:Gem::Version
|
120
120
|
version: '5.0'
|
121
121
|
type: :runtime
|
122
122
|
prerelease: false
|
123
123
|
version_requirements: !ruby/object:Gem::Requirement
|
124
124
|
requirements:
|
125
|
-
- -
|
125
|
+
- - ">="
|
126
126
|
- !ruby/object:Gem::Version
|
127
127
|
version: 3.2.13
|
128
|
-
- - <
|
128
|
+
- - "<"
|
129
129
|
- !ruby/object:Gem::Version
|
130
130
|
version: '5.0'
|
131
131
|
description: Derivative generation plugin for hydra
|
@@ -135,9 +135,9 @@ executables: []
|
|
135
135
|
extensions: []
|
136
136
|
extra_rdoc_files: []
|
137
137
|
files:
|
138
|
-
- .gitignore
|
139
|
-
- .rspec
|
140
|
-
- .travis.yml
|
138
|
+
- ".gitignore"
|
139
|
+
- ".rspec"
|
140
|
+
- ".travis.yml"
|
141
141
|
- CONTRIBUTING.md
|
142
142
|
- Gemfile
|
143
143
|
- History.md
|
@@ -148,6 +148,8 @@ files:
|
|
148
148
|
- VERSION
|
149
149
|
- config/jetty.yml
|
150
150
|
- hydra-derivatives.gemspec
|
151
|
+
- lib/color_profiles/license.txt
|
152
|
+
- lib/color_profiles/sRGB_IEC61966-2-1_no_black_scaling.icc
|
151
153
|
- lib/hydra/derivatives.rb
|
152
154
|
- lib/hydra/derivatives/audio.rb
|
153
155
|
- lib/hydra/derivatives/config.rb
|
@@ -155,15 +157,21 @@ files:
|
|
155
157
|
- lib/hydra/derivatives/extract_metadata.rb
|
156
158
|
- lib/hydra/derivatives/ffmpeg.rb
|
157
159
|
- lib/hydra/derivatives/image.rb
|
160
|
+
- lib/hydra/derivatives/jpeg2k_config.yml
|
161
|
+
- lib/hydra/derivatives/jpeg2k_image.rb
|
158
162
|
- lib/hydra/derivatives/processor.rb
|
163
|
+
- lib/hydra/derivatives/railtie.rb
|
159
164
|
- lib/hydra/derivatives/shell_based_processor.rb
|
160
165
|
- lib/hydra/derivatives/video.rb
|
161
166
|
- spec/fixtures/FlashPix.ppt
|
167
|
+
- spec/fixtures/adobe1998.tif
|
162
168
|
- spec/fixtures/countdown.avi
|
169
|
+
- spec/fixtures/jpeg2k_config.yml
|
163
170
|
- spec/fixtures/piano_note.wav
|
164
171
|
- spec/fixtures/sample.rtf
|
165
172
|
- spec/fixtures/test.doc
|
166
173
|
- spec/fixtures/test.pdf
|
174
|
+
- spec/fixtures/test.tif
|
167
175
|
- spec/fixtures/test.xls
|
168
176
|
- spec/fixtures/world.png
|
169
177
|
- spec/lib/hydra/derivatives/extract_metadata_spec.rb
|
@@ -171,6 +179,7 @@ files:
|
|
171
179
|
- spec/units/config_spec.rb
|
172
180
|
- spec/units/extract_spec.rb
|
173
181
|
- spec/units/image_spec.rb
|
182
|
+
- spec/units/jpeg2k_spec.rb
|
174
183
|
- spec/units/transcoding_spec.rb
|
175
184
|
- spec/units/video_spec.rb
|
176
185
|
homepage: https://github.com/projecthydra/hydra-derivatives
|
@@ -183,27 +192,30 @@ require_paths:
|
|
183
192
|
- lib
|
184
193
|
required_ruby_version: !ruby/object:Gem::Requirement
|
185
194
|
requirements:
|
186
|
-
- -
|
195
|
+
- - ">="
|
187
196
|
- !ruby/object:Gem::Version
|
188
197
|
version: '0'
|
189
198
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
190
199
|
requirements:
|
191
|
-
- -
|
200
|
+
- - ">="
|
192
201
|
- !ruby/object:Gem::Version
|
193
202
|
version: '0'
|
194
203
|
requirements: []
|
195
204
|
rubyforge_project:
|
196
|
-
rubygems_version: 2.
|
205
|
+
rubygems_version: 2.2.2
|
197
206
|
signing_key:
|
198
207
|
specification_version: 4
|
199
208
|
summary: Derivative generation plugin for hydra
|
200
209
|
test_files:
|
201
210
|
- spec/fixtures/FlashPix.ppt
|
211
|
+
- spec/fixtures/adobe1998.tif
|
202
212
|
- spec/fixtures/countdown.avi
|
213
|
+
- spec/fixtures/jpeg2k_config.yml
|
203
214
|
- spec/fixtures/piano_note.wav
|
204
215
|
- spec/fixtures/sample.rtf
|
205
216
|
- spec/fixtures/test.doc
|
206
217
|
- spec/fixtures/test.pdf
|
218
|
+
- spec/fixtures/test.tif
|
207
219
|
- spec/fixtures/test.xls
|
208
220
|
- spec/fixtures/world.png
|
209
221
|
- spec/lib/hydra/derivatives/extract_metadata_spec.rb
|
@@ -211,5 +223,6 @@ test_files:
|
|
211
223
|
- spec/units/config_spec.rb
|
212
224
|
- spec/units/extract_spec.rb
|
213
225
|
- spec/units/image_spec.rb
|
226
|
+
- spec/units/jpeg2k_spec.rb
|
214
227
|
- spec/units/transcoding_spec.rb
|
215
228
|
- spec/units/video_spec.rb
|