chalk

kis_exif_value.cpp
1/*
2 * This file is part of Chalk
3 *
4 * Copyright (c) 2006 Cyrille Berger <cberger@cberger.net>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 */
20
21#include "kis_exif_value.h"
22
23#include <kdebug.h>
24#include <kmdcodec.h>
25
26namespace {
27void set16Bit (unsigned char *data, ExifValue::ByteOrder order, const TQ_UINT16* value)
28{
29 switch (order) {
30 case ExifValue::BYTE_ORDER_MOTOROLA:
31 data[0] = (unsigned char) (*value >> 8);
32 data[1] = (unsigned char) *value;
33 break;
34 case ExifValue::BYTE_ORDER_INTEL:
35 data[0] = (unsigned char) *value;
36 data[1] = (unsigned char) (*value >> 8);
37 break;
38 }
39}
40
41void get16Bit (const unsigned char *data, ExifValue::ByteOrder order, TQ_UINT16* value)
42{
43 switch (order) {
44 case ExifValue::BYTE_ORDER_MOTOROLA:
45 *value = ((data[0] << 8) | data[1]);
46 break;
47 case ExifValue::BYTE_ORDER_INTEL:
48 *value = ((data[1] << 8) | data[0]);
49 break;
50 }
51}
52
53void get32Bit (const unsigned char *data, ExifValue::ByteOrder order, TQ_UINT32* value)
54{
55 switch (order) {
56 case ExifValue::BYTE_ORDER_MOTOROLA:
57 *value = ((data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3]);
58 break;
59 case ExifValue::BYTE_ORDER_INTEL:
60 *value = ((data[3] << 24) | (data[2] << 16) | (data[1] << 8) | data[0]);
61 }
62}
63
64void set32Bit(unsigned char *data, ExifValue::ByteOrder order, const TQ_UINT32* value)
65{
66 switch (order) {
67 case ExifValue::BYTE_ORDER_MOTOROLA:
68 data[0] = (unsigned char) (*value >> 24);
69 data[1] = (unsigned char) (*value >> 16);
70 data[2] = (unsigned char) (*value >> 8);
71 data[3] = (unsigned char) *value;
72 break;
73 case ExifValue::BYTE_ORDER_INTEL:
74 data[3] = (unsigned char) (*value >> 24);
75 data[2] = (unsigned char) (*value >> 16);
76 data[1] = (unsigned char) (*value >> 8);
77 data[0] = (unsigned char) *value;
78 break;
79 }
80}
81
82void get64Bit (const unsigned char *data, ExifValue::ByteOrder order, TQ_UINT64* value)
83{
84 switch (order) {
85 case ExifValue::BYTE_ORDER_MOTOROLA:
86 *value = (((TQ_UINT64)data[0] << 56) | ((TQ_UINT64)data[1] << 48) | ((TQ_UINT64)data[2] << 40) | ((TQ_UINT64)data[3] << 32) | ((TQ_UINT64)data[4] << 24) | ((TQ_UINT64)data[5] << 16) | ((TQ_UINT64)data[6] << 8) | (TQ_UINT64)data[7]);
87 break;
88 case ExifValue::BYTE_ORDER_INTEL:
89 *value = (((TQ_UINT64)data[7] << 56) | ((TQ_UINT64)data[6] << 48) | ((TQ_UINT64)data[5] << 40) | ((TQ_UINT64)data[4] << 32) | ((TQ_UINT64)data[3] << 24) | ((TQ_UINT64)data[2] << 16) | ((TQ_UINT64)data[1] << 8) | (TQ_UINT64)data[0]);
90 }
91}
92
93void set64Bit(unsigned char *data, ExifValue::ByteOrder order, const TQ_UINT64* value)
94{
95 switch (order) {
96 case ExifValue::BYTE_ORDER_MOTOROLA:
97 data[0] = (unsigned char) (*value >> 56);
98 data[1] = (unsigned char) (*value >> 48);
99 data[2] = (unsigned char) (*value >> 40);
100 data[3] = (unsigned char) (*value >> 32);
101 data[4] = (unsigned char) (*value >> 24);
102 data[5] = (unsigned char) (*value >> 16);
103 data[6] = (unsigned char) (*value >> 8);
104 data[7] = (unsigned char) *value;
105 break;
106 case ExifValue::BYTE_ORDER_INTEL:
107 data[7] = (unsigned char) (*value >> 56);
108 data[6] = (unsigned char) (*value >> 48);
109 data[5] = (unsigned char) (*value >> 40);
110 data[4] = (unsigned char) (*value >> 32);
111 data[3] = (unsigned char) (*value >> 24);
112 data[2] = (unsigned char) (*value >> 16);
113 data[1] = (unsigned char) (*value >> 8);
114 data[0] = (unsigned char) *value;
115 break;
116 }
117}
118
119
120}
121
122ExifValue::ExifValue(ExifType ntype, unsigned char *data, unsigned int size, int ifd, uint ncomponents, ExifValue::ByteOrder order ) : m_ifd(ifd), m_type(ntype), m_components(ncomponents), m_value(0)
123{
124 allocData();
125 setValue(data, size, order);
126}
127
128void ExifValue::allocData()
129{
130 if( type() != EXIF_TYPE_ASCII && type() != EXIF_TYPE_UNDEFINED)
131 {
132 m_value = new ExifNumber[components()];
133 } else if ( type() == EXIF_TYPE_ASCII )
134 {
135 m_value = new TQString();
136 } else if ( type() == EXIF_TYPE_UNDEFINED)
137 {
138 m_value = new UByteArray();
139 }
140}
141
142bool ExifValue::load(const TQDomElement& elmt)
143{
144 TQString attr;
145 if( (attr = elmt.attribute("ifd")).isNull() )
146 return false;
147 m_ifd = attr.toInt();
148 if( (attr = elmt.attribute("components")).isNull() )
149 return false;
150 m_components = attr.toInt();
151 if( (attr = elmt.attribute("type")).isNull() )
152 return false;
153 m_type = (ExifValue::ExifType)attr.toInt();
154 allocData();
155 switch(type())
156 {
157 case EXIF_TYPE_BYTE:
158 for(uint i = 0; i < components(); i++)
159 {
160 if( (attr = elmt.attribute(TQString("value%1").arg(i) ) ).isNull() )
161 {
162 setValue(i, (TQ_UINT8)0);
163 } else {
164 setValue(i, (TQ_UINT8) attr.toUInt());
165 }
166 }
167 break;
168 case EXIF_TYPE_ASCII:
169 setAsAscii( elmt.attribute("value" ) );
170 break;
171 case EXIF_TYPE_SHORT:
172 for(uint i = 0; i < components(); i++)
173 {
174 if( (attr = elmt.attribute(TQString("value%1").arg(i) ) ).isNull() )
175 {
176 setValue(i, (TQ_UINT16)0);
177 } else {
178 setValue(i, (TQ_UINT16) attr.toUInt());
179 }
180 }
181 break;
182 case EXIF_TYPE_LONG:
183 for(uint i = 0; i < components(); i++)
184 {
185 if( (attr = elmt.attribute(TQString("value%1").arg(i) ) ).isNull() )
186 {
187 setValue(i, (TQ_UINT32)0);
188 } else {
189 setValue(i, (TQ_UINT32) attr.toUInt());
190 }
191 }
192 break;
193 case EXIF_TYPE_RATIONAL:
194 for(uint i = 0; i < components(); i++)
195 {
196 KisExifRational r;
197 if( (attr = elmt.attribute(TQString("numerator%1").arg(i) ) ).isNull() )
198 {
199 r.numerator = (TQ_UINT32)0;
200 } else {
201 r.numerator = (TQ_UINT32) attr.toUInt();
202 }
203 if( (attr = elmt.attribute(TQString("denominator%1").arg(i) ) ).isNull() )
204 {
205 r.denominator = (TQ_UINT32)0;
206 } else {
207 r.denominator = (TQ_UINT32) attr.toUInt();
208 }
209 setValue(i, r);
210 }
211 break;
212 case EXIF_TYPE_SBYTE:
213 for(uint i = 0; i < components(); i++)
214 {
215 if( (attr = elmt.attribute(TQString("value%1").arg(i) ) ).isNull() )
216 {
217 setValue(i, (TQ_INT8)0);
218 } else {
219 setValue(i, (TQ_INT8) attr.toInt());
220 }
221 }
222 break;
223 case EXIF_TYPE_UNDEFINED:
224 {
225 TQString instr = elmt.attribute("value");
226 TQByteArray out;
227 TQByteArray in = instr.utf8();
228 KCodecs::base64Decode( in, out);
229 out.resize(out.size() - 2 );
230 setAsUndefined((uchar*)out.data(), out.size() );
231 }
232 break;
233 case EXIF_TYPE_SSHORT:
234 for(uint i = 0; i < components(); i++)
235 {
236 if( (attr = elmt.attribute(TQString("value%1").arg(i) ) ).isNull() )
237 {
238 setValue(i, (TQ_INT16)0);
239 } else {
240 setValue(i, (TQ_INT16) attr.toInt());
241 }
242 }
243 break;
244 case EXIF_TYPE_SLONG:
245 for(uint i = 0; i < components(); i++)
246 {
247 if( (attr = elmt.attribute(TQString("value%1").arg(i) ) ).isNull() )
248 {
249 setValue(i, (TQ_INT32)0);
250 } else {
251 setValue(i, (TQ_INT32) attr.toInt());
252 }
253 }
254 break;
255 case EXIF_TYPE_SRATIONAL:
256 for(uint i = 0; i < components(); i++)
257 {
258 KisExifSRational r;
259 if( (attr = elmt.attribute(TQString("numerator%1").arg(i) ) ).isNull() )
260 {
261 r.numerator = (TQ_INT32)0;
262 } else {
263 r.numerator = (TQ_INT32) attr.toInt();
264 }
265 if( (attr = elmt.attribute(TQString("denominator%1").arg(i) ) ).isNull() )
266 {
267 r.denominator = (TQ_UINT32)0;
268 } else {
269 r.denominator = (TQ_UINT32) attr.toInt();
270 }
271 setValue(i, r);
272 }
273 break;
274 case EXIF_TYPE_FLOAT:
275 for(uint i = 0; i < components(); i++)
276 {
277 if( (attr = elmt.attribute(TQString("value%1").arg(i) ) ).isNull() )
278 {
279 setValue(i, (float)0);
280 } else {
281 setValue(i, (float) attr.toFloat());
282 }
283 }
284 break;
285 case EXIF_TYPE_DOUBLE:
286 for(uint i = 0; i < components(); i++)
287 {
288 if( (attr = elmt.attribute(TQString("value%1").arg(i) ) ).isNull() )
289 {
290 setValue(i, (double)0);
291 } else {
292 setValue(i, (double) attr.toDouble());
293 }
294 }
295 break;
296 case EXIF_TYPE_UNKNOW:
297 break;
298
299 }
300 return true;
301}
302
303TQDomElement ExifValue::save(TQDomDocument& doc)
304{
305 TQDomElement elmt = doc.createElement("ExifValue");
306 elmt.setAttribute("ifd", ifd());
307 elmt.setAttribute("components", components() );
308 elmt.setAttribute("type", type() );
309 switch(type())
310 {
311 case EXIF_TYPE_BYTE:
312 for(uint i = 0; i < components(); i++)
313 elmt.setAttribute(TQString("value%1").arg(i), asByte( i ) );
314 break;
315 case EXIF_TYPE_ASCII:
316 elmt.setAttribute("value", asAscii() );
317 break;
318 case EXIF_TYPE_SHORT:
319 for(uint i = 0; i < components(); i++)
320 elmt.setAttribute(TQString("value%1").arg(i), asShort( i ) );
321 break;
322 case EXIF_TYPE_LONG:
323 for(uint i = 0; i < components(); i++)
324 elmt.setAttribute(TQString("value%1").arg(i), asLong( i ) );
325 break;
326 case EXIF_TYPE_RATIONAL:
327 for(uint i = 0; i < components(); i++)
328 {
329 KisExifRational r = asRational(i);
330 elmt.setAttribute(TQString("numerator%1").arg(i), r.numerator );
331 elmt.setAttribute(TQString("denominator%1").arg(i), r.denominator );
332 }
333 break;
334 case EXIF_TYPE_SBYTE:
335 for(uint i = 0; i < components(); i++)
336 elmt.setAttribute(TQString("value%1").arg(i), asSByte( i ) );
337 break;
338 case EXIF_TYPE_UNDEFINED:
339 {
340 UByteArray value = asUndefined();
341 TQByteArray data;
342 data.setRawData((char*)value.data(), value.size());
343 TQByteArray encodedData;
344 KCodecs::base64Encode( data, encodedData );
345 data.resetRawData( (char*)value.data(), value.size());
346 elmt.setAttribute("value", TQString(encodedData));
347 }
348 break;
349 case EXIF_TYPE_SSHORT:
350 for(uint i = 0; i < components(); i++)
351 elmt.setAttribute(TQString("value%1").arg(i), asSShort( i ) );
352 break;
353 case EXIF_TYPE_SLONG:
354 for(uint i = 0; i < components(); i++)
355 elmt.setAttribute(TQString("value%1").arg(i), asSLong( i ) );
356 break;
357 case EXIF_TYPE_SRATIONAL:
358 for(uint i = 0; i < components(); i++)
359 {
360 KisExifSRational r = asSRational(i);
361 elmt.setAttribute(TQString("numerator%1").arg(i), r.numerator );
362 elmt.setAttribute(TQString("denominator%1").arg(i), r.denominator );
363 }
364 break;
365 case EXIF_TYPE_FLOAT:
366 for(uint i = 0; i < components(); i++)
367 elmt.setAttribute(TQString("value%1").arg(i), asFloat( i ) );
368 break;
369 case EXIF_TYPE_DOUBLE:
370 for(uint i = 0; i < components(); i++)
371 elmt.setAttribute(TQString("value%1").arg(i), asDouble( i ) );
372 break;
373 case EXIF_TYPE_UNKNOW:
374 break;
375 }
376 return elmt;
377}
378
379
380void ExifValue::setValue(const unsigned char *data, unsigned int size, ExifValue::ByteOrder order)
381{
382 switch(type())
383 {
384 case EXIF_TYPE_BYTE:
385 if( size == components() )
386 {
387 ExifNumber n;
388 for(uint i = 0; i < components(); i++)
389 {
390 n.m_byte = data[i];
391 setAsExifNumber( i, n);
392 }
393 }
394 break;
395 case EXIF_TYPE_ASCII:
396 setAsAscii((char*) data);
397 break;
398 case EXIF_TYPE_SHORT:
399 if( size == 2*components() )
400 {
401 ExifNumber n;
402 for(uint i = 0; i < components(); i++)
403 {
404 get16Bit( data + 2 * i, order, &n.m_short);
405 setAsExifNumber( i, n);
406 }
407 }
408 break;
409 case EXIF_TYPE_LONG:
410 if( size == 4*components() )
411 {
412 ExifNumber n;
413 for(uint i = 0; i < components(); i++)
414 {
415 get32Bit( data + 4 * i, order, &n.m_long);
416 setAsExifNumber( i, n);
417 }
418 }
419 break;
420 case EXIF_TYPE_RATIONAL:
421 if( size == 8*components() )
422 {
423 ExifNumber n;
424 for(uint i = 0; i < components(); i++)
425 {
426 get32Bit( data + 8 * i, order, &n.m_rational.numerator);
427 get32Bit( data + 8 * i + 4, order, &n.m_rational.denominator);
428 setAsExifNumber( i, n);
429 }
430 }
431 break;
432 case EXIF_TYPE_SBYTE:
433 if( size == components() )
434 {
435 ExifNumber n;
436 for(uint i = 0; i < components(); i++)
437 {
438 n.m_sbyte = ((TQ_INT8*)data)[i];
439 setAsExifNumber( i, n);
440 }
441 }
442 break;
443 case EXIF_TYPE_UNDEFINED:
444 setAsUndefined(data, size);
445 break;
446 case EXIF_TYPE_SSHORT:
447 if( size == 2*components() )
448 {
449 ExifNumber n;
450 for(uint i = 0; i < components(); i++)
451 {
452 get16Bit( data + 2 * i, order, (TQ_UINT16*)&n.m_sshort);
453 setAsExifNumber( i, n);
454 }
455 }
456 break;
457 case EXIF_TYPE_SLONG:
458 if( size == 4*components() )
459 {
460 ExifNumber n;
461 for(uint i = 0; i < components(); i++)
462 {
463 get32Bit( data + 4 * i, order, (TQ_UINT32*)&n.m_slong);
464 setAsExifNumber( i, n);
465 }
466 }
467 break;
468 case EXIF_TYPE_SRATIONAL:
469 if( size == 8*components() )
470 {
471 ExifNumber n;
472 for(uint i = 0; i < components(); i++)
473 {
474 get32Bit( data + 8 * i, order, (TQ_UINT32*)&n.m_srational.numerator);
475 get32Bit( data + 8 * i + 4, order, (TQ_UINT32*)&n.m_srational.denominator);
476 setAsExifNumber( i, n);
477 }
478 }
479 break;
480 case EXIF_TYPE_FLOAT:
481 if( size == 4*components() )
482 {
483 ExifNumber n;
484 for(uint i = 0; i < components(); i++)
485 {
486 get32Bit( data + 4 * i, order, (TQ_UINT32*)&n.m_float);
487 setAsExifNumber( i, n);
488 }
489 }
490 break;
491 case EXIF_TYPE_DOUBLE:
492 if( size == 8*components() )
493 {
494 ExifNumber n;
495 for(uint i = 0; i < components(); i++)
496 {
497 get64Bit( data + 8 * i, order, (TQ_UINT64*)&n.m_double);
498 setAsExifNumber( i, n);
499 }
500 }
501 break;
502 case EXIF_TYPE_UNKNOW:
503 break;
504 }
505}
506
507void ExifValue::convertToData(unsigned char ** data, unsigned int* size, ExifValue::ByteOrder order)
508{
509 switch(type())
510 {
511 case EXIF_TYPE_BYTE:
512 *size = components();
513 *data = new uchar[*size];
514 for(uint i = 0; i < components(); i++)
515 {
516 (*data)[i] = asExifNumber(i).m_byte;
517 }
518 return;
519 case EXIF_TYPE_ASCII:
520 {
521 TQString str = asAscii();
522 *size = str.length();
523 *data = new uchar[ *size ];
524 uchar* ptr = *data;
525 memcpy(ptr, str.ascii(), (*size)*sizeof(uchar));
526 }
527 return;
528 break;
529 case EXIF_TYPE_SHORT:
530 {
531 *size = 2*components();
532 *data = new uchar[*size];
533 for(uint i = 0; i < components(); i++)
534 {
535 TQ_UINT16 aenms = asExifNumber(i).m_short;
536 set16Bit( (*data) + 2 * i, order, &aenms);
537 }
538 return;
539 }
540 case EXIF_TYPE_LONG:
541 {
542 *size = 4*components();
543 *data = new uchar[*size];
544 for(uint i = 0; i < components(); i++)
545 {
546 TQ_UINT32 aenml = asExifNumber(i).m_long;
547 set32Bit( (*data) + 4 * i, order, &aenml);
548 }
549 return;
550 }
551 case EXIF_TYPE_RATIONAL:
552 *size = 8*components();
553 *data = new uchar[*size];
554 for(uint i = 0; i < components(); i++)
555 {
556 ExifNumber n = asExifNumber(i);
557 set32Bit( (*data) + 8 * i, order, &n.m_rational.numerator);
558 set32Bit( (*data) + 8 * i + 4, order, &n.m_rational.denominator);
559 }
560 return;
561 case EXIF_TYPE_SBYTE:
562 *size = components();
563 *data = new uchar[*size];
564 for(uint i = 0; i < components(); i++)
565 {
566 *(((TQ_INT8*)*data) + i) = asExifNumber(i).m_sbyte;
567 }
568 return;
569 case EXIF_TYPE_UNDEFINED:
570 {
571 UByteArray array = asUndefined();
572 *size = array.size();
573 *data = new uchar[*size];
574 memcpy( *data, array.data(), (*size)*sizeof(unsigned char));
575 }
576 return;
577 case EXIF_TYPE_SSHORT:
578 *size = 2*components();
579 *data = new uchar[*size];
580 for(uint i = 0; i < components(); i++)
581 {
582 TQ_INT16 aenmss = asExifNumber(i).m_sshort;
583 set16Bit( (*data) + 2 * i, order, (TQ_UINT16*)&aenmss);
584 }
585 return;
586 case EXIF_TYPE_SLONG:
587 *size = 4*components();
588 *data = new uchar[*size];
589 for(uint i = 0; i < components(); i++)
590 {
591 TQ_INT32 aenmsl = asExifNumber(i).m_slong;
592 set32Bit( (*data) + 4 * i, order, (TQ_UINT32*)&aenmsl);
593 }
594 return;
595 case EXIF_TYPE_SRATIONAL:
596 *size = 8*components();
597 *data = new uchar[*size];
598 for(uint i = 0; i < components(); i++)
599 {
600 ExifNumber n = asExifNumber(i);
601 TQ_INT32 aenmsr_numerator = asExifNumber(i).m_srational.numerator;
602 TQ_INT32 aenmsr_denominator = asExifNumber(i).m_srational.denominator;
603 set32Bit( (*data) + 4 * i, order, (TQ_UINT32*)&aenmsr_numerator);
604 set32Bit( (*data) + 4 * i + 4, order, (TQ_UINT32*)&aenmsr_denominator);
605 }
606 return;
607 case EXIF_TYPE_FLOAT:
608 *size = 4*components();
609 *data = new uchar[*size];
610 for(uint i = 0; i < components(); i++)
611 {
612 float aenmf = asExifNumber(i).m_float;
613 set32Bit( (*data) + 4 * i, order, (TQ_UINT32*)&aenmf);
614 }
615 return;
616 case EXIF_TYPE_DOUBLE:
617 *size = 8*components();
618 *data = new uchar[*size];
619 for(uint i = 0; i < components(); i++)
620 {
621 double aenmd = asExifNumber(i).m_double;
622 set64Bit( (*data) + 4 * i, order, (TQ_UINT64*)&aenmd);
623 }
624 return;
625 case EXIF_TYPE_UNKNOW:
626 break;
627 }
628}
629
630TQString ExifValue::toString()
631{
632 switch(type())
633 {
634 case EXIF_TYPE_ASCII:
635 return asAscii();
636 case EXIF_TYPE_UNDEFINED:
637 {
638 TQString undefined = "undefined";
639 UByteArray array = asUndefined();
640 for(uint i = 0; i < components(); i++)
641 {
642 undefined += "\\" + TQString().setNum( array[i] );
643 }
644 return undefined;
645 }
646 default:
647 {
648 TQString str = "";
649 for(uint i = 0; i < components(); i++)
650 {
651 str += toString(i);
652 }
653 return str;
654 }
655 }
656}
657
658TQString ExifValue::toString(uint i)
659{
660 switch(type())
661 {
662 case EXIF_TYPE_BYTE:
663 return TQString("%1 ").arg( asExifNumber( i ).m_byte );
664 case EXIF_TYPE_SHORT:
665 return TQString("%1 ").arg( asExifNumber( i ).m_short );
666 case EXIF_TYPE_LONG:
667 return TQString("%1 ").arg( asExifNumber( i ).m_long );
668 case EXIF_TYPE_RATIONAL:
669 return TQString("%1 / %2 ").arg( asExifNumber( i ).m_rational.numerator ).arg( asExifNumber( i ).m_rational.denominator );
670 case EXIF_TYPE_SBYTE: {
671 /* workaround to compiler bug on Raspbian Wheezy */
672 TQ_INT8 o_sbyte = asExifNumber( i ).m_sbyte;
673 return TQString("%1 ").arg( o_sbyte );
674 }
675 case EXIF_TYPE_SSHORT:
676 return TQString("%1 ").arg( asExifNumber( i ).m_sshort );
677 case EXIF_TYPE_SLONG:
678 return TQString("%1 ").arg( asExifNumber( i ).m_slong );
679 case EXIF_TYPE_SRATIONAL:
680 return TQString("%1 / %2 ").arg( asExifNumber( i ).m_srational.numerator ).arg( asExifNumber( i ).m_srational.denominator );
681 case EXIF_TYPE_FLOAT:
682 return TQString("%1 ").arg( asExifNumber( i ).m_float );
683 case EXIF_TYPE_DOUBLE:
684 return TQString("%1 ").arg( asExifNumber( i ).m_double );
685 default:
686 return "unknow ";
687 }
688}
689