hydra-derivatives 0.0.7 → 0.0.8
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
-
[![Gem Version](https://badge.fury.io/rb/hydra-derivatives.png)](http://badge.fury.io/rb/hydra-derivatives)
|
1
|
+
# hydra-derivatives [![Version](https://badge.fury.io/rb/hydra-derivatives.png)](http://badge.fury.io/rb/hydra-derivatives) [![Build Status](https://travis-ci.org/projecthydra/hydra-derivatives.png?branch=master)](https://travis-ci.org/projecthydra/hydra-derivatives) [![Dependency Status](https://gemnasium.com/projecthydra/hydra-derivatives.png)](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
|