tifffile 0.0.1 → 0.0.2

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
  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>