tifffile 0.0.1 → 0.0.2

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
  SHA1:
3
- metadata.gz: 23dd0e7c0379cdaa6ccc08bb996a297150f30298
4
- data.tar.gz: 213b127a798ce4cba57936321ca94983b72c28ea
3
+ metadata.gz: 73ee12cfcfb7b19f45966c553780006c9e2ea981
4
+ data.tar.gz: aadabb05a8725757870334ebdffec87f22d0451d
5
5
  SHA512:
6
- metadata.gz: 904c860a603bee5fd5bd0a7549e5fc3a5102e799e4457615a7e01b0b1c7f77b266609edb35dc61f05577b3692a324caabb3df14ef121abba9297c2b7049350c1
7
- data.tar.gz: 8a1a2da681b979a680ae321ded5f3291ff3f004a4b372ea8c1eca3de7fb59bf594af8b77992506087d07f94da39ac3ec789e74d0a2108d7808925e9af8a8fd16
6
+ metadata.gz: 7713c2989ad9be58d24c32cdb9dc63ea10971f32c376102627e442efe013b0e7d5492118ace195b65af387c0538a3e77b96d93f1d23a06f955880712d57a590a
7
+ data.tar.gz: 072ec891538ef01d00efd6210417ad0d90e7cf6b877f716cf72a8caab050841f14bfc9c50d4c37d9dee9373d60d8da2bab112f53c187e30aa64d1a2f55f23612
data/.gemspec CHANGED
@@ -2,8 +2,8 @@ require File.expand_path("../lib/tifffile/version", __FILE__)
2
2
 
3
3
  Gem::Specification.new do |gem|
4
4
  gem.name = 'tifffile'
5
- gem.version = TiffFile::VERSION
6
- gem.date = '2016-03-21'
5
+ gem.version = TiffFileVersion::VERSION
6
+ gem.date = '2016-03-22'
7
7
 
8
8
  gem.summary = "TIFF reader and writer"
9
9
  gem.description = ""
data/Rakefile CHANGED
@@ -1,6 +1,14 @@
1
1
  require "rake/extensiontask"
2
+ require 'rspec/core'
3
+ require 'rspec/core/rake_task'
4
+
2
5
 
3
6
  Rake::ExtensionTask.new "tifffile" do |ext|
4
7
  ext.lib_dir = "lib/tifffile"
5
8
  end
6
9
 
10
+ RSpec::Core::RakeTask.new(:spec) do |spec|
11
+ Rake::Task['compile'].invoke
12
+ spec.pattern = FileList['spec/**/*_spec.rb']
13
+ end
14
+
@@ -0,0 +1,28 @@
1
+ #!/usr/bin/python
2
+
3
+ import numpy as np
4
+ from libtiff import TIFFfile
5
+ from libtiff import TIFF
6
+
7
+ def read(fileName):
8
+ """
9
+ Script to import tif file from imageJ,
10
+ usage: zstack = tiff.read(inFileName)
11
+ PTW 2015/01/29
12
+ """
13
+ tiff = TIFFfile(fileName)
14
+ samples, sample_names = tiff.get_samples()
15
+
16
+ outList = []
17
+ for sample in samples:
18
+ outList.append(np.copy(sample)[...,np.newaxis])
19
+
20
+ out = np.concatenate(outList,axis=-1)
21
+ out = np.rollaxis(out,0,3)
22
+ out = np.flipud(out)
23
+
24
+ tiff.close()
25
+
26
+ return out
27
+
28
+ print(read('a.tiff'))
@@ -1,7 +1,12 @@
1
1
  require "mkmf"
2
2
 
3
- #LIBDIR = Config::CONFIG['libdir']
4
- #INCLUDEDIR = Config::CONFIG['includedir']
3
+ # Add C++ support
4
+
5
+ have_library( 'stdc++' );
6
+ $CFLAGS << " -Wall"
7
+
8
+
9
+
5
10
 
6
11
  HEADER_DIRS = [
7
12
  # First search /opt/local for macports
@@ -0,0 +1,237 @@
1
+ #include <ruby.h>
2
+ #include <stdio.h>
3
+ #include <stdlib.h>
4
+ #include <string>
5
+ #include "tiffio.h"
6
+ #include <vector>
7
+ #include <algorithm>
8
+
9
+ using namespace std;
10
+
11
+ template <class T>
12
+ static bool rows_size_compare(std::vector<T> & a, std::vector<T> & b)
13
+ {
14
+ return (a.size() < b.size());
15
+ }
16
+
17
+ template <class T>
18
+ void calculate_width_height(std::vector<std::vector<T> > & data, uint32 & width, uint32 & height){
19
+ height = data.size();
20
+ width = std::max_element(data.begin(), data.end(), rows_size_compare<T>)->size();
21
+ }
22
+
23
+
24
+ template <class T>
25
+ void write_data_to_row_buffer(std::vector<T> & data, unsigned char *buf, uint64 buff_size, uint8 sampleperpixel, uint8 bitspersample){
26
+ memset(buf, 0, buff_size);
27
+ buff_size = std::min<uint64>(buff_size, sizeof(T) * data.size());
28
+ memcpy(buf, (void *)(&(data[0])), buff_size);
29
+ }
30
+
31
+
32
+ template <class T>
33
+ bool write_tiff_file(std::string filename, std::vector<std::vector<T> > & data, uint8 sampleperpixel, uint8 bitspersample, std::string description, std::string software){
34
+ try {
35
+ TIFF* tif = TIFFOpen(filename.c_str(), "w");
36
+
37
+ uint32 width, height;
38
+ calculate_width_height(data, width, height);
39
+
40
+ TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, width);
41
+ TIFFSetField(tif, TIFFTAG_IMAGELENGTH, height);
42
+ TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, sampleperpixel);
43
+ TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, bitspersample);
44
+ TIFFSetField(tif, TIFFTAG_ORIENTATION, (int)ORIENTATION_TOPLEFT);
45
+ TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
46
+ TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_NONE);
47
+ TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK);
48
+ TIFFSetField(tif, TIFFTAG_IMAGEDESCRIPTION, (char*)description.c_str());
49
+ TIFFSetField(tif, TIFFTAG_SOFTWARE, (char*)software.c_str());
50
+
51
+ uint64 linebytes = sampleperpixel * width * (bitspersample / 8);
52
+ unsigned char *buf = NULL;
53
+ buf = (unsigned char *)_TIFFmalloc(linebytes);
54
+
55
+ TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, 1);
56
+
57
+ for (uint32 row = 0; row < height; row++){
58
+ std::vector<T> row_data = data[row];
59
+ write_data_to_row_buffer(row_data, buf, linebytes, sampleperpixel, bitspersample);
60
+ if (TIFFWriteScanline(tif, buf, row, 0) < 0)
61
+ break;
62
+ }
63
+
64
+ if (buf)
65
+ _TIFFfree(buf);
66
+
67
+ TIFFClose(tif);
68
+ }
69
+ catch (...){
70
+ return false;
71
+ }
72
+ return true;
73
+ }
74
+
75
+
76
+ bool get_matrix_element_type(VALUE data_matrix, bool &is_float){
77
+ if (!RB_TYPE_P(data_matrix, T_ARRAY) || RARRAY_LEN(data_matrix) < 1)
78
+ return false;
79
+
80
+ VALUE first_row = RARRAY_PTR(data_matrix)[0];
81
+
82
+ if (!RB_TYPE_P(first_row, T_ARRAY) || RARRAY_LEN(first_row) < 1)
83
+ return false;
84
+
85
+ VALUE first_item = RARRAY_PTR(first_row)[0];
86
+
87
+ if (!RB_TYPE_P(first_item, T_FIXNUM) && !RB_TYPE_P(first_item, T_FLOAT))
88
+ return false;
89
+
90
+ is_float = RB_TYPE_P(first_item, T_FLOAT);
91
+
92
+ return true;
93
+ }
94
+
95
+ template <class F, class T>
96
+ vector<vector<T> > matrix_type_cast(vector<vector<F> > & from){
97
+ vector<vector<T> > result;
98
+ result.resize(from.size());
99
+
100
+ for (int i = 0; i < from.size(); i++)
101
+ result[i].assign(from[i].begin(), from[i].end());
102
+
103
+ return result;
104
+ };
105
+
106
+ VALUE TiffFile = Qnil;
107
+
108
+ VALUE method_tifffile_converter_to_tiff(VALUE self, VALUE filename, VALUE data_matrix, VALUE sample_size, VALUE sample_unsigned, VALUE description, VALUE software){
109
+ data_matrix = rb_check_array_type(data_matrix);
110
+
111
+
112
+ Check_Type(filename, T_STRING);
113
+ Check_Type(data_matrix, T_ARRAY);
114
+ Check_Type(sample_size, T_FIXNUM);
115
+ Check_Type(description, T_STRING);
116
+ Check_Type(software, T_STRING);
117
+
118
+ uint8 size = std::min<uint8>(NUM2USHORT(sample_size), 8);
119
+
120
+ bool unsigned_flag = RTEST(sample_unsigned);
121
+
122
+ bool is_float_matrix;
123
+ if (!get_matrix_element_type(data_matrix, is_float_matrix))
124
+ rb_raise(rb_eRuntimeError, "Invalid matrix items type");
125
+
126
+ if (size != 1 && size != 2 && size != 4 && size != 8)
127
+ rb_raise(rb_eRuntimeError, "Sample size should be in range [1, 2, 4, 8]");
128
+
129
+ if (is_float_matrix && (size % 4) != 0)
130
+ rb_raise(rb_eRuntimeError, "Sample size should be 4 or 8 on non-fixnum matrix");
131
+
132
+ vector<vector<double> > data_d;
133
+ vector<double> temp_d;
134
+ vector<vector<int64> > data_i;
135
+ vector<int64> temp_i;
136
+
137
+ VALUE row, item;
138
+
139
+ if (is_float_matrix)
140
+ data_d.resize(RARRAY_LEN(data_matrix));
141
+ else
142
+ data_i.resize(RARRAY_LEN(data_matrix));
143
+
144
+
145
+ for (long i = 0; i < RARRAY_LEN(data_matrix); i++){
146
+ row = RARRAY_PTR(data_matrix)[i];
147
+
148
+ if (!RB_TYPE_P(row, T_ARRAY))
149
+ rb_raise(rb_eRuntimeError, "Matrix row %ld is not an array", i);
150
+
151
+ // Clear row buffer
152
+ if (is_float_matrix){
153
+ temp_d.clear();
154
+ temp_d.resize(RARRAY_LEN(row));
155
+ } else {
156
+ temp_i.clear();
157
+ temp_i.resize(RARRAY_LEN(row));
158
+ }
159
+
160
+
161
+ // Read row
162
+ for (long j = 0; j < RARRAY_LEN(row); j++){
163
+ item = RARRAY_PTR(row)[j];
164
+ Check_Type(item, is_float_matrix ? T_FLOAT : T_FIXNUM);
165
+ if (is_float_matrix)
166
+ temp_d[j] = RFLOAT_VALUE(item);
167
+ else
168
+ temp_i[j] = FIX2LONG(item);
169
+ }
170
+
171
+ if (is_float_matrix)
172
+ data_d[i] = temp_d;
173
+ else
174
+ data_i[i] = temp_i;
175
+ }
176
+
177
+
178
+ bool result = false;
179
+ if (is_float_matrix){
180
+ if (size == 8)
181
+ result = write_tiff_file<double>(StringValuePtr(filename), data_d, 1, 64, StringValuePtr(description), StringValuePtr(software));
182
+ else if (size == 4){
183
+ vector<vector<float> > cast_buffer = matrix_type_cast<double, float>(data_d);
184
+ result = write_tiff_file<float>(StringValuePtr(filename), cast_buffer, 1, 32, StringValuePtr(description), StringValuePtr(software));
185
+ }
186
+ else
187
+ rb_raise(rb_eRuntimeError, "unrecognized sample size for float matrix : %d", size);
188
+ }
189
+ else {
190
+ if (unsigned_flag){
191
+ if (size == 8){
192
+ vector<vector<uint64> > cast_buffer = matrix_type_cast<int64, uint64>(data_i);
193
+ result = write_tiff_file<uint64>(StringValuePtr(filename), cast_buffer, 1, 64, StringValuePtr(description), StringValuePtr(software));
194
+ }
195
+ else if (size == 4){
196
+ vector<vector<uint32> > cast_buffer = matrix_type_cast<int64, uint32>(data_i);
197
+ result = write_tiff_file<uint32>(StringValuePtr(filename), cast_buffer, 1, 32, StringValuePtr(description), StringValuePtr(software));
198
+ }
199
+ else if (size == 2){
200
+ vector<vector<uint16> > cast_buffer = matrix_type_cast<int64, uint16>(data_i);
201
+ result = write_tiff_file<uint16>(StringValuePtr(filename), cast_buffer, 1, 16, StringValuePtr(description), StringValuePtr(software));
202
+ }
203
+ else if (size == 1){
204
+ vector<vector<uint8> > cast_buffer = matrix_type_cast<int64, uint8>(data_i);
205
+ result = write_tiff_file<uint8>(StringValuePtr(filename), cast_buffer, 1, 8, StringValuePtr(description), StringValuePtr(software));
206
+ }
207
+ else
208
+ rb_raise(rb_eRuntimeError, "unrecognized sample size for unsigned numeric matrix : %d", size);
209
+ }
210
+ else {
211
+ if (size == 8){
212
+ result = write_tiff_file<int64>(StringValuePtr(filename), data_i, 1, 64, StringValuePtr(description), StringValuePtr(software));
213
+ }
214
+ else if (size == 4){
215
+ vector<vector<int32> > cast_buffer = matrix_type_cast<int64, int32>(data_i);
216
+ result = write_tiff_file<int32>(StringValuePtr(filename), cast_buffer, 1, 32, StringValuePtr(description), StringValuePtr(software));
217
+ }
218
+ else if (size == 2){
219
+ vector<vector<int16> > cast_buffer = matrix_type_cast<int64, int16>(data_i);
220
+ result = write_tiff_file<int16>(StringValuePtr(filename), cast_buffer, 1, 16, StringValuePtr(description), StringValuePtr(software));
221
+ }
222
+ else if (size == 1){
223
+ vector<vector<int8> > cast_buffer = matrix_type_cast<int64, int8>(data_i);
224
+ result = write_tiff_file<int8>(StringValuePtr(filename), cast_buffer, 1, 8, StringValuePtr(description), StringValuePtr(software));
225
+ }
226
+ else
227
+ rb_raise(rb_eRuntimeError, "unrecognized sample size for signed numeric matrix : %d", size);
228
+ }
229
+ }
230
+
231
+ return result ? Qtrue : Qfalse;
232
+ }
233
+
234
+ extern "C" void Init_tifffile(){
235
+ TiffFile = rb_define_module("TiffFile");
236
+ rb_define_singleton_method(TiffFile, "to_tiff", (VALUE(*)(ANYARGS))method_tifffile_converter_to_tiff, 6);
237
+ }
@@ -1,2 +1,28 @@
1
1
  require 'tifffile/version'
2
2
  require "tifffile/tifffile"
3
+
4
+ module TiffFile
5
+
6
+ include TiffFileVersion
7
+
8
+ # Will write a TIFF file +destination+, that contains +values+ matrix (in one channel), each sample has +sample_size+ in bytes (1, 2, 4 or 8), +sample_unsigned+.
9
+ # Also, image have +description+ and reference to +software+
10
+ def self.tiff2file(destination, values, sample_size=16, sample_unsigned=false, description=nil, software=nil)
11
+ self.to_tiff(destination.to_s, values, sample_size.to_i, sample_unsigned == true, description.to_s, software.to_s)
12
+ end
13
+
14
+
15
+ # Binary get TIFF file that contains +values+ matrix (in one channel), each sample has +sample_size+ in bytes (1, 2, 4 or 8), +sample_unsigned+.
16
+ # Also, image have +description+ and reference to +software+
17
+ def self.tiff2binary(values, sample_size=16, description=nil, software=nil)
18
+ file = Tempfile.new('tiff2binary')
19
+ file.close
20
+
21
+ tiff2file(file.path, values, sample_size, description, software)
22
+
23
+ data = File.read(file)
24
+ file.unlink
25
+ data
26
+ end
27
+
28
+ end
@@ -1,3 +1,3 @@
1
- module TiffFile
2
- VERSION = "0.0.1"
1
+ module TiffFileVersion
2
+ VERSION = "0.0.2"
3
3
  end
@@ -0,0 +1,7 @@
1
+ require 'tifffile'
2
+
3
+ describe "TiffFile" do
4
+ it "building tiff file" do
5
+ p TiffFile.tiff2file 'a.tiff', [[10, 21], [20, 30]], 8, false, "Image description", "SOFTWARE"
6
+ end
7
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tifffile
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kirill Makhonin
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-03-21 00:00:00.000000000 Z
11
+ date: 2016-03-22 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: ''
14
14
  email: kroks.rus@gmail.com
@@ -25,11 +25,12 @@ files:
25
25
  - ".idea/tifffile-ruby.iml"
26
26
  - LICENSE
27
27
  - Rakefile
28
+ - analyzer.py
28
29
  - ext/tifffile/extconf.rb
29
- - ext/tifffile/tifffile.c
30
- - ext/tifffile/tifffile.h
30
+ - ext/tifffile/tifffile.cpp
31
31
  - lib/tifffile.rb
32
32
  - lib/tifffile/version.rb
33
+ - spec/tifffile_spec.rb
33
34
  homepage: https://github.com/kirillmakhonin/tifffile-ruby
34
35
  licenses:
35
36
  - MIT
@@ -1,74 +0,0 @@
1
- #include <tifffile.h>
2
-
3
- struct my_malloc {
4
- size_t size;
5
- void *ptr;
6
- };
7
-
8
- static void
9
- my_malloc_free(void *p) {
10
- struct my_malloc *ptr = p;
11
-
12
- if (ptr->size > 0)
13
- free(ptr->ptr);
14
- }
15
-
16
- static VALUE
17
- my_malloc_alloc(VALUE klass) {
18
- VALUE obj;
19
- struct my_malloc *ptr;
20
-
21
- obj = Data_Make_Struct(klass, struct my_malloc, NULL, my_malloc_free, ptr);
22
-
23
- ptr->size = 0;
24
- ptr->ptr = NULL;
25
-
26
- return obj;
27
- }
28
-
29
- static VALUE
30
- my_malloc_init(VALUE self, VALUE size) {
31
- struct my_malloc *ptr;
32
- size_t requested = NUM2SIZET(size);
33
-
34
- if (0 == requested)
35
- rb_raise(rb_eArgError, "unable to allocate 0 bytes");
36
-
37
- Data_Get_Struct(self, struct my_malloc, ptr);
38
-
39
- ptr->ptr = malloc(requested);
40
-
41
- if (NULL == ptr->ptr)
42
- rb_raise(rb_eNoMemError, "unable to allocate %ld bytes", requested);
43
-
44
- ptr->size = requested;
45
-
46
- return self;
47
- }
48
-
49
- static VALUE
50
- my_malloc_release(VALUE self) {
51
- struct my_malloc *ptr;
52
-
53
- Data_Get_Struct(self, struct my_malloc, ptr);
54
-
55
- if (0 == ptr->size)
56
- return self;
57
-
58
- ptr->size = 0;
59
- free(ptr->ptr);
60
-
61
- return self;
62
- }
63
-
64
- void
65
- Init_my_malloc(void) {
66
- VALUE cMyMalloc;
67
-
68
- cMyMalloc = rb_const_get(rb_cObject, rb_intern("TiffFile"));
69
-
70
- rb_define_alloc_func(cMyMalloc, my_malloc_alloc);
71
- rb_define_method(cMyMalloc, "initialize", my_malloc_init, 1);
72
- rb_define_method(cMyMalloc, "free", my_malloc_release, 0);
73
- }
74
-
@@ -1 +0,0 @@
1
- #include <ruby.h>