Mercurial > octave-libtiff
comparison libinterp/dldfcn/__tiff__.cc @ 31094:ab5b33e447b0
Modified getTag to account for different tag data types and multivalued tags, the current implementation is still buggy for most tags and data types
author | magedrifaat <magedrifaat@gmail.com> |
---|---|
date | Wed, 22 Jun 2022 23:32:22 +0200 |
parents | e2bed4daae82 |
children | edfedae9972a |
comparison
equal
deleted
inserted
replaced
31093:e2bed4daae82 | 31094:ab5b33e447b0 |
---|---|
1 #include <string> | 1 #include <string> |
2 #include <iostream> | |
2 | 3 |
3 #include "defun-dld.h" | 4 #include "defun-dld.h" |
4 #include "ov.h" | 5 #include "ov.h" |
5 #include "ovl.h" | 6 #include "ovl.h" |
6 #include "error.h" | 7 #include "error.h" |
8 #include <tiffio.h> | 9 #include <tiffio.h> |
9 | 10 |
10 | 11 |
11 // TODO(maged): Tidy up the formatting to be consistant with octave | 12 // TODO(maged): Tidy up the formatting to be consistant with octave |
12 | 13 |
14 octave_value interpret_data(void *data, uint32_t count, TIFFDataType tag_datatype) | |
15 { | |
16 // TODO(maged): Find the correct way fo returning multivalues | |
17 octave_value_list ov_data; | |
18 switch (tag_datatype) | |
19 { | |
20 case TIFF_BYTE: | |
21 case TIFF_UNDEFINED: | |
22 for (uint32_t i = 0; i < count; i++) | |
23 { | |
24 ov_data(i) = octave_value(((uint8_t *)data)[i]); | |
25 } | |
26 break; | |
27 | |
28 case TIFF_ASCII: | |
29 ov_data(0) = octave_value((char *)data); | |
30 break; | |
31 | |
32 case TIFF_SHORT: | |
33 for (uint32_t i = 0; i < count; i++) | |
34 { | |
35 ov_data(i) = octave_value(((uint16_t *)data)[i]); | |
36 } | |
37 break; | |
38 | |
39 case TIFF_LONG: | |
40 for (uint32_t i = 0; i < count; i++) | |
41 { | |
42 ov_data(i) = octave_value(((uint32_t *)data)[i]); | |
43 } | |
44 break; | |
45 | |
46 // case TIFF_RATIONAL: | |
47 // uint32_t *u32data = (uint32_t *)data; | |
48 // for (uint32_t i = 0; i < count; i+=2) | |
49 // { | |
50 // ov_data(i / 2) = octave_value((float)u32data[i] / (float)u32data[i+1]); | |
51 // } | |
52 // break; | |
53 | |
54 // case TIFF_SBYTE: | |
55 // int8_t *s8data = (int8_t *)data; | |
56 // for (uint32_t i = 0; i < count; i++) | |
57 // { | |
58 // ov_data(i) = octave_value(s8data[i]); | |
59 // } | |
60 // break; | |
61 | |
62 // case TIFF_SSHORT: | |
63 // int16_t *s16data = (int16_t *)data; | |
64 // for (uint32_t i = 0; i < count; i++) | |
65 // { | |
66 // ov_data(i) = octave_value(s16data[i]); | |
67 // } | |
68 // break; | |
69 | |
70 // case TIFF_SLONG: | |
71 // int32_t *s32data = (int32_t *)data; | |
72 // for (uint32_t i = 0; i < count; i++) | |
73 // { | |
74 // ov_data(i) = octave_value(s32data[i]); | |
75 // } | |
76 // break; | |
77 | |
78 // case TIFF_FLOAT: | |
79 // float *float_data = (float *)data; | |
80 // for (uint32_t i = 0; i < count; i++) | |
81 // { | |
82 // ov_data(i) = octave_value(double_data[i]); | |
83 // } | |
84 // break; | |
85 | |
86 // case TIFF_DOUBLE: | |
87 // double *double_data = (double *)data; | |
88 // for (uint32_t i = 0; i < count; i++) | |
89 // { | |
90 // ov_data(i) = octave_value(double_data[i]); | |
91 // } | |
92 // break; | |
93 | |
94 // case TIFF_SRATIONAL: | |
95 // int32_t *s32data = (int32_t *)data; | |
96 // for (uint32_t i = 0; i < count; i+=2) | |
97 // { | |
98 // ov_data(i / 2) = octave_value((float)s32data[i] / (float)s32data[i+1]); | |
99 // } | |
100 // break; | |
101 | |
102 case TIFF_IFD: | |
103 // TODO(maged): implement IFD datatype | |
104 error("Unimplemented IFFD data type"); | |
105 break; | |
106 default: | |
107 // TODO(maged): find the correct response in this case | |
108 error("Unsupported tag data type"); | |
109 } | |
110 | |
111 return octave_value(ov_data); | |
112 } | |
113 | |
13 DEFUN_DLD (__open_tiff__, args, nargout, | 114 DEFUN_DLD (__open_tiff__, args, nargout, |
14 "Open a Tiff file and return its handle") | 115 "Open a Tiff file and return its handle") |
15 { | 116 { |
16 int nargin = args.length(); | 117 int nargin = args.length(); |
17 | 118 |
26 | 127 |
27 // TODO(maged): check valid mode | 128 // TODO(maged): check valid mode |
28 if (nargin == 2) | 129 if (nargin == 2) |
29 mode = args(1).string_value(); | 130 mode = args(1).string_value(); |
30 | 131 |
132 // TODO(maged): Look into unwind action | |
31 TIFF *tif = TIFFOpen(filename.c_str(), mode.c_str()); | 133 TIFF *tif = TIFFOpen(filename.c_str(), mode.c_str()); |
32 // TODO(maged): print a better error | 134 // TODO(maged): print a better error |
33 if (!tif) | 135 if (!tif) |
34 error("Failed to open Tiff file\n"); | 136 error("Failed to open Tiff file\n"); |
35 | 137 |
71 } | 173 } |
72 | 174 |
73 TIFF *tif = (TIFF *)(args(0).uint64_value()); | 175 TIFF *tif = (TIFF *)(args(0).uint64_value()); |
74 | 176 |
75 uint32_t tag_ID; | 177 uint32_t tag_ID; |
178 const TIFFField *fip; | |
76 if (args(1).type_name() == "string") | 179 if (args(1).type_name() == "string") |
77 { | 180 { |
78 std::string tagName = args(1).string_value(); | 181 std::string tagName = args(1).string_value(); |
79 const TIFFField *fip = TIFFFieldWithName(tif, tagName.c_str()); | 182 fip = TIFFFieldWithName(tif, tagName.c_str()); |
80 if (!fip) | 183 if (!fip) |
81 error("Tiff tag not found\n"); | 184 error("Tiff tag not found\n"); |
82 | 185 |
83 tag_ID = TIFFFieldTag(fip); | 186 tag_ID = TIFFFieldTag(fip); |
84 } | 187 } |
85 else | 188 else |
86 { | 189 { |
87 tag_ID = args(1).int_value(); | 190 tag_ID = args(1).int_value(); |
88 const TIFFField *fip = TIFFFieldWithTag(tif, tag_ID); | 191 fip = TIFFFieldWithTag(tif, tag_ID); |
89 // TODO(maged): Handle other types of errors | 192 // TODO(maged): Handle other types of errors (e.g. unsupported tags) |
90 if (!fip) | 193 if (!fip) |
91 error("Tiff tag not found\n"); | 194 error("Tiff tag not found\n"); |
92 } | 195 } |
93 | 196 |
94 // TODO(maged): Handle different data types/ multivalued tags. | 197 TIFFDataType tag_datatype = TIFFFieldDataType(fip); |
95 uint32_t tag_data; | 198 |
96 TIFFGetField(tif, tag_ID, &tag_data); | 199 int count = TIFFFieldReadCount(fip); |
97 | 200 octave_value tag_data_ov; |
98 return octave_value_list (octave_value(tag_data)); | 201 void *data; |
99 } | 202 if (count == TIFF_VARIABLE) |
203 { | |
204 uint16_t count_param; | |
205 if (TIFFGetField(tif, tag_ID, &count_param, &data)) | |
206 { | |
207 tag_data_ov = interpret_data(data, count_param, tag_datatype); | |
208 } | |
209 else | |
210 { | |
211 // TODO(maged): Give a better error message? | |
212 error("Failed to read tag"); | |
213 } | |
214 } | |
215 else if (count == TIFF_VARIABLE2) | |
216 { | |
217 uint32_t count_param; | |
218 if (TIFFGetField(tif, tag_ID, &count_param, &data)) | |
219 { | |
220 tag_data_ov = interpret_data(data, count_param, tag_datatype); | |
221 } | |
222 else | |
223 { | |
224 // TODO(maged): Give a better error message? | |
225 error("Failed to read tag"); | |
226 } | |
227 } | |
228 else if (count == TIFF_SPP) | |
229 { | |
230 // TODO(maged): Handle TIFF_SPP | |
231 error("Unimplemented TIFF_SPP count"); | |
232 } | |
233 else | |
234 { | |
235 int type_size = TIFFDataWidth(tag_datatype); | |
236 data = _TIFFmalloc(type_size * count); | |
237 // TODO(maged): This won't always work, e.g. string exepcts char ** | |
238 if (TIFFGetField(tif, tag_ID, data)) | |
239 { | |
240 tag_data_ov = interpret_data(data, count, tag_datatype); | |
241 _TIFFfree(data); | |
242 } | |
243 else | |
244 { | |
245 _TIFFfree(data); | |
246 | |
247 // TODO(maged): Give a better error message? | |
248 error("Failed to read tag"); | |
249 } | |
250 | |
251 } | |
252 | |
253 return octave_value_list (octave_value(tag_data_ov)); | |
254 } |