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 }