00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "kis_exif_value.h"
00022
00023 #include <kdebug.h>
00024 #include <kmdcodec.h>
00025
00026 namespace {
00027 void set16Bit (unsigned char *data, ExifValue::ByteOrder order, const Q_UINT16* value)
00028 {
00029 switch (order) {
00030 case ExifValue::BYTE_ORDER_MOTOROLA:
00031 data[0] = (unsigned char) (*value >> 8);
00032 data[1] = (unsigned char) *value;
00033 break;
00034 case ExifValue::BYTE_ORDER_INTEL:
00035 data[0] = (unsigned char) *value;
00036 data[1] = (unsigned char) (*value >> 8);
00037 break;
00038 }
00039 }
00040
00041 void get16Bit (const unsigned char *data, ExifValue::ByteOrder order, Q_UINT16* value)
00042 {
00043 switch (order) {
00044 case ExifValue::BYTE_ORDER_MOTOROLA:
00045 *value = ((data[0] << 8) | data[1]);
00046 break;
00047 case ExifValue::BYTE_ORDER_INTEL:
00048 *value = ((data[1] << 8) | data[0]);
00049 break;
00050 }
00051 }
00052
00053 void get32Bit (const unsigned char *data, ExifValue::ByteOrder order, Q_UINT32* value)
00054 {
00055 switch (order) {
00056 case ExifValue::BYTE_ORDER_MOTOROLA:
00057 *value = ((data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3]);
00058 break;
00059 case ExifValue::BYTE_ORDER_INTEL:
00060 *value = ((data[3] << 24) | (data[2] << 16) | (data[1] << 8) | data[0]);
00061 }
00062 }
00063
00064 void set32Bit(unsigned char *data, ExifValue::ByteOrder order, const Q_UINT32* value)
00065 {
00066 switch (order) {
00067 case ExifValue::BYTE_ORDER_MOTOROLA:
00068 data[0] = (unsigned char) (*value >> 24);
00069 data[1] = (unsigned char) (*value >> 16);
00070 data[2] = (unsigned char) (*value >> 8);
00071 data[3] = (unsigned char) *value;
00072 break;
00073 case ExifValue::BYTE_ORDER_INTEL:
00074 data[3] = (unsigned char) (*value >> 24);
00075 data[2] = (unsigned char) (*value >> 16);
00076 data[1] = (unsigned char) (*value >> 8);
00077 data[0] = (unsigned char) *value;
00078 break;
00079 }
00080 }
00081
00082 void get64Bit (const unsigned char *data, ExifValue::ByteOrder order, Q_UINT64* value)
00083 {
00084 switch (order) {
00085 case ExifValue::BYTE_ORDER_MOTOROLA:
00086 *value = (((Q_UINT64)data[0] << 56) | ((Q_UINT64)data[1] << 48) | ((Q_UINT64)data[2] << 40) | ((Q_UINT64)data[3] << 32) | ((Q_UINT64)data[4] << 24) | ((Q_UINT64)data[5] << 16) | ((Q_UINT64)data[6] << 8) | (Q_UINT64)data[7]);
00087 break;
00088 case ExifValue::BYTE_ORDER_INTEL:
00089 *value = (((Q_UINT64)data[7] << 56) | ((Q_UINT64)data[6] << 48) | ((Q_UINT64)data[5] << 40) | ((Q_UINT64)data[4] << 32) | ((Q_UINT64)data[3] << 24) | ((Q_UINT64)data[2] << 16) | ((Q_UINT64)data[1] << 8) | (Q_UINT64)data[0]);
00090 }
00091 }
00092
00093 void set64Bit(unsigned char *data, ExifValue::ByteOrder order, const Q_UINT64* value)
00094 {
00095 switch (order) {
00096 case ExifValue::BYTE_ORDER_MOTOROLA:
00097 data[0] = (unsigned char) (*value >> 56);
00098 data[1] = (unsigned char) (*value >> 48);
00099 data[2] = (unsigned char) (*value >> 40);
00100 data[3] = (unsigned char) (*value >> 32);
00101 data[4] = (unsigned char) (*value >> 24);
00102 data[5] = (unsigned char) (*value >> 16);
00103 data[6] = (unsigned char) (*value >> 8);
00104 data[7] = (unsigned char) *value;
00105 break;
00106 case ExifValue::BYTE_ORDER_INTEL:
00107 data[7] = (unsigned char) (*value >> 56);
00108 data[6] = (unsigned char) (*value >> 48);
00109 data[5] = (unsigned char) (*value >> 40);
00110 data[4] = (unsigned char) (*value >> 32);
00111 data[3] = (unsigned char) (*value >> 24);
00112 data[2] = (unsigned char) (*value >> 16);
00113 data[1] = (unsigned char) (*value >> 8);
00114 data[0] = (unsigned char) *value;
00115 break;
00116 }
00117 }
00118
00119
00120 }
00121
00122 ExifValue::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)
00123 {
00124 allocData();
00125 setValue(data, size, order);
00126 }
00127
00128 void ExifValue::allocData()
00129 {
00130 if( type() != EXIF_TYPE_ASCII && type() != EXIF_TYPE_UNDEFINED)
00131 {
00132 m_value = new ExifNumber[components()];
00133 } else if ( type() == EXIF_TYPE_ASCII )
00134 {
00135 m_value = new QString();
00136 } else if ( type() == EXIF_TYPE_UNDEFINED)
00137 {
00138 m_value = new UByteArray();
00139 }
00140 }
00141
00142 bool ExifValue::load(const QDomElement& elmt)
00143 {
00144 QString attr;
00145 if( (attr = elmt.attribute("ifd")).isNull() )
00146 return false;
00147 m_ifd = attr.toInt();
00148 if( (attr = elmt.attribute("components")).isNull() )
00149 return false;
00150 m_components = attr.toInt();
00151 if( (attr = elmt.attribute("type")).isNull() )
00152 return false;
00153 m_type = (ExifValue::ExifType)attr.toInt();
00154 allocData();
00155 switch(type())
00156 {
00157 case EXIF_TYPE_BYTE:
00158 for(uint i = 0; i < components(); i++)
00159 {
00160 if( (attr = elmt.attribute(QString("value%1").arg(i) ) ).isNull() )
00161 {
00162 setValue(i, (Q_UINT8)0);
00163 } else {
00164 setValue(i, (Q_UINT8) attr.toUInt());
00165 }
00166 }
00167 break;
00168 case EXIF_TYPE_ASCII:
00169 setAsAscii( elmt.attribute("value" ) );
00170 break;
00171 case EXIF_TYPE_SHORT:
00172 for(uint i = 0; i < components(); i++)
00173 {
00174 if( (attr = elmt.attribute(QString("value%1").arg(i) ) ).isNull() )
00175 {
00176 setValue(i, (Q_UINT16)0);
00177 } else {
00178 setValue(i, (Q_UINT16) attr.toUInt());
00179 }
00180 }
00181 break;
00182 case EXIF_TYPE_LONG:
00183 for(uint i = 0; i < components(); i++)
00184 {
00185 if( (attr = elmt.attribute(QString("value%1").arg(i) ) ).isNull() )
00186 {
00187 setValue(i, (Q_UINT32)0);
00188 } else {
00189 setValue(i, (Q_UINT32) attr.toUInt());
00190 }
00191 }
00192 break;
00193 case EXIF_TYPE_RATIONAL:
00194 for(uint i = 0; i < components(); i++)
00195 {
00196 KisExifRational r;
00197 if( (attr = elmt.attribute(QString("numerator%1").arg(i) ) ).isNull() )
00198 {
00199 r.numerator = (Q_UINT32)0;
00200 } else {
00201 r.numerator = (Q_UINT32) attr.toUInt();
00202 }
00203 if( (attr = elmt.attribute(QString("denominator%1").arg(i) ) ).isNull() )
00204 {
00205 r.denominator = (Q_UINT32)0;
00206 } else {
00207 r.denominator = (Q_UINT32) attr.toUInt();
00208 }
00209 setValue(i, r);
00210 }
00211 break;
00212 case EXIF_TYPE_SBYTE:
00213 for(uint i = 0; i < components(); i++)
00214 {
00215 if( (attr = elmt.attribute(QString("value%1").arg(i) ) ).isNull() )
00216 {
00217 setValue(i, (Q_INT8)0);
00218 } else {
00219 setValue(i, (Q_INT8) attr.toInt());
00220 }
00221 }
00222 break;
00223 case EXIF_TYPE_UNDEFINED:
00224 {
00225 QString instr = elmt.attribute("value");
00226 QByteArray out;
00227 QByteArray in = instr.utf8();
00228 KCodecs::base64Decode( in, out);
00229 out.resize(out.size() - 2 );
00230 setAsUndefined((uchar*)out.data(), out.size() );
00231 }
00232 break;
00233 case EXIF_TYPE_SSHORT:
00234 for(uint i = 0; i < components(); i++)
00235 {
00236 if( (attr = elmt.attribute(QString("value%1").arg(i) ) ).isNull() )
00237 {
00238 setValue(i, (Q_INT16)0);
00239 } else {
00240 setValue(i, (Q_INT16) attr.toInt());
00241 }
00242 }
00243 break;
00244 case EXIF_TYPE_SLONG:
00245 for(uint i = 0; i < components(); i++)
00246 {
00247 if( (attr = elmt.attribute(QString("value%1").arg(i) ) ).isNull() )
00248 {
00249 setValue(i, (Q_INT32)0);
00250 } else {
00251 setValue(i, (Q_INT32) attr.toInt());
00252 }
00253 }
00254 break;
00255 case EXIF_TYPE_SRATIONAL:
00256 for(uint i = 0; i < components(); i++)
00257 {
00258 KisExifSRational r;
00259 if( (attr = elmt.attribute(QString("numerator%1").arg(i) ) ).isNull() )
00260 {
00261 r.numerator = (Q_INT32)0;
00262 } else {
00263 r.numerator = (Q_INT32) attr.toInt();
00264 }
00265 if( (attr = elmt.attribute(QString("denominator%1").arg(i) ) ).isNull() )
00266 {
00267 r.denominator = (Q_UINT32)0;
00268 } else {
00269 r.denominator = (Q_UINT32) attr.toInt();
00270 }
00271 setValue(i, r);
00272 }
00273 break;
00274 case EXIF_TYPE_FLOAT:
00275 for(uint i = 0; i < components(); i++)
00276 {
00277 if( (attr = elmt.attribute(QString("value%1").arg(i) ) ).isNull() )
00278 {
00279 setValue(i, (float)0);
00280 } else {
00281 setValue(i, (float) attr.toFloat());
00282 }
00283 }
00284 break;
00285 case EXIF_TYPE_DOUBLE:
00286 for(uint i = 0; i < components(); i++)
00287 {
00288 if( (attr = elmt.attribute(QString("value%1").arg(i) ) ).isNull() )
00289 {
00290 setValue(i, (double)0);
00291 } else {
00292 setValue(i, (double) attr.toDouble());
00293 }
00294 }
00295 break;
00296 case EXIF_TYPE_UNKNOW:
00297 break;
00298
00299 }
00300 return true;
00301 }
00302
00303 QDomElement ExifValue::save(QDomDocument& doc)
00304 {
00305 QDomElement elmt = doc.createElement("ExifValue");
00306 elmt.setAttribute("ifd", ifd());
00307 elmt.setAttribute("components", components() );
00308 elmt.setAttribute("type", type() );
00309 switch(type())
00310 {
00311 case EXIF_TYPE_BYTE:
00312 for(uint i = 0; i < components(); i++)
00313 elmt.setAttribute(QString("value%1").arg(i), asByte( i ) );
00314 break;
00315 case EXIF_TYPE_ASCII:
00316 elmt.setAttribute("value", asAscii() );
00317 break;
00318 case EXIF_TYPE_SHORT:
00319 for(uint i = 0; i < components(); i++)
00320 elmt.setAttribute(QString("value%1").arg(i), asShort( i ) );
00321 break;
00322 case EXIF_TYPE_LONG:
00323 for(uint i = 0; i < components(); i++)
00324 elmt.setAttribute(QString("value%1").arg(i), asLong( i ) );
00325 break;
00326 case EXIF_TYPE_RATIONAL:
00327 for(uint i = 0; i < components(); i++)
00328 {
00329 KisExifRational r = asRational(i);
00330 elmt.setAttribute(QString("numerator%1").arg(i), r.numerator );
00331 elmt.setAttribute(QString("denominator%1").arg(i), r.denominator );
00332 }
00333 break;
00334 case EXIF_TYPE_SBYTE:
00335 for(uint i = 0; i < components(); i++)
00336 elmt.setAttribute(QString("value%1").arg(i), asSByte( i ) );
00337 break;
00338 case EXIF_TYPE_UNDEFINED:
00339 {
00340 UByteArray value = asUndefined();
00341 QByteArray data;
00342 data.setRawData((char*)value.data(), value.size());
00343 QByteArray encodedData;
00344 KCodecs::base64Encode( data, encodedData );
00345 data.resetRawData( (char*)value.data(), value.size());
00346 elmt.setAttribute("value", encodedData);
00347 }
00348 break;
00349 case EXIF_TYPE_SSHORT:
00350 for(uint i = 0; i < components(); i++)
00351 elmt.setAttribute(QString("value%1").arg(i), asSShort( i ) );
00352 break;
00353 case EXIF_TYPE_SLONG:
00354 for(uint i = 0; i < components(); i++)
00355 elmt.setAttribute(QString("value%1").arg(i), asSLong( i ) );
00356 break;
00357 case EXIF_TYPE_SRATIONAL:
00358 for(uint i = 0; i < components(); i++)
00359 {
00360 KisExifSRational r = asSRational(i);
00361 elmt.setAttribute(QString("numerator%1").arg(i), r.numerator );
00362 elmt.setAttribute(QString("denominator%1").arg(i), r.denominator );
00363 }
00364 break;
00365 case EXIF_TYPE_FLOAT:
00366 for(uint i = 0; i < components(); i++)
00367 elmt.setAttribute(QString("value%1").arg(i), asFloat( i ) );
00368 break;
00369 case EXIF_TYPE_DOUBLE:
00370 for(uint i = 0; i < components(); i++)
00371 elmt.setAttribute(QString("value%1").arg(i), asDouble( i ) );
00372 break;
00373 case EXIF_TYPE_UNKNOW:
00374 break;
00375 }
00376 return elmt;
00377 }
00378
00379
00380 void ExifValue::setValue(const unsigned char *data, unsigned int size, ExifValue::ByteOrder order)
00381 {
00382 switch(type())
00383 {
00384 case EXIF_TYPE_BYTE:
00385 if( size == components() )
00386 {
00387 ExifNumber n;
00388 for(uint i = 0; i < components(); i++)
00389 {
00390 n.m_byte = data[i];
00391 setAsExifNumber( i, n);
00392 }
00393 }
00394 break;
00395 case EXIF_TYPE_ASCII:
00396 setAsAscii((char*) data);
00397 break;
00398 case EXIF_TYPE_SHORT:
00399 if( size == 2*components() )
00400 {
00401 ExifNumber n;
00402 for(uint i = 0; i < components(); i++)
00403 {
00404 get16Bit( data + 2 * i, order, &n.m_short);
00405 setAsExifNumber( i, n);
00406 }
00407 }
00408 break;
00409 case EXIF_TYPE_LONG:
00410 if( size == 4*components() )
00411 {
00412 ExifNumber n;
00413 for(uint i = 0; i < components(); i++)
00414 {
00415 get32Bit( data + 4 * i, order, &n.m_long);
00416 setAsExifNumber( i, n);
00417 }
00418 }
00419 break;
00420 case EXIF_TYPE_RATIONAL:
00421 if( size == 8*components() )
00422 {
00423 ExifNumber n;
00424 for(uint i = 0; i < components(); i++)
00425 {
00426 get32Bit( data + 8 * i, order, &n.m_rational.numerator);
00427 get32Bit( data + 8 * i + 4, order, &n.m_rational.denominator);
00428 setAsExifNumber( i, n);
00429 }
00430 }
00431 break;
00432 case EXIF_TYPE_SBYTE:
00433 if( size == components() )
00434 {
00435 ExifNumber n;
00436 for(uint i = 0; i < components(); i++)
00437 {
00438 n.m_sbyte = ((Q_INT8*)data)[i];
00439 setAsExifNumber( i, n);
00440 }
00441 }
00442 break;
00443 case EXIF_TYPE_UNDEFINED:
00444 setAsUndefined(data, size);
00445 break;
00446 case EXIF_TYPE_SSHORT:
00447 if( size == 2*components() )
00448 {
00449 ExifNumber n;
00450 for(uint i = 0; i < components(); i++)
00451 {
00452 get16Bit( data + 2 * i, order, (Q_UINT16*)&n.m_sshort);
00453 setAsExifNumber( i, n);
00454 }
00455 }
00456 break;
00457 case EXIF_TYPE_SLONG:
00458 if( size == 4*components() )
00459 {
00460 ExifNumber n;
00461 for(uint i = 0; i < components(); i++)
00462 {
00463 get32Bit( data + 4 * i, order, (Q_UINT32*)&n.m_slong);
00464 setAsExifNumber( i, n);
00465 }
00466 }
00467 break;
00468 case EXIF_TYPE_SRATIONAL:
00469 if( size == 8*components() )
00470 {
00471 ExifNumber n;
00472 for(uint i = 0; i < components(); i++)
00473 {
00474 get32Bit( data + 8 * i, order, (Q_UINT32*)&n.m_srational.numerator);
00475 get32Bit( data + 8 * i + 4, order, (Q_UINT32*)&n.m_srational.denominator);
00476 setAsExifNumber( i, n);
00477 }
00478 }
00479 break;
00480 case EXIF_TYPE_FLOAT:
00481 if( size == 4*components() )
00482 {
00483 ExifNumber n;
00484 for(uint i = 0; i < components(); i++)
00485 {
00486 get32Bit( data + 4 * i, order, (Q_UINT32*)&n.m_float);
00487 setAsExifNumber( i, n);
00488 }
00489 }
00490 break;
00491 case EXIF_TYPE_DOUBLE:
00492 if( size == 8*components() )
00493 {
00494 ExifNumber n;
00495 for(uint i = 0; i < components(); i++)
00496 {
00497 get64Bit( data + 8 * i, order, (Q_UINT64*)&n.m_double);
00498 setAsExifNumber( i, n);
00499 }
00500 }
00501 break;
00502 case EXIF_TYPE_UNKNOW:
00503 break;
00504 }
00505 }
00506
00507 void ExifValue::convertToData(unsigned char ** data, unsigned int* size, ExifValue::ByteOrder order)
00508 {
00509 switch(type())
00510 {
00511 case EXIF_TYPE_BYTE:
00512 *size = components();
00513 *data = new uchar[*size];
00514 for(uint i = 0; i < components(); i++)
00515 {
00516 (*data)[i] = asExifNumber(i).m_byte;
00517 }
00518 return;
00519 case EXIF_TYPE_ASCII:
00520 {
00521 QString str = asAscii();
00522 *size = str.length();
00523 *data = new uchar[ *size ];
00524 uchar* ptr = *data;
00525 memcpy(ptr, str.ascii(), (*size)*sizeof(uchar));
00526 }
00527 return;
00528 break;
00529 case EXIF_TYPE_SHORT:
00530 {
00531 *size = 2*components();
00532 *data = new uchar[*size];
00533 for(uint i = 0; i < components(); i++)
00534 {
00535 set16Bit( (*data) + 2 * i, order, &asExifNumber(i).m_short);
00536 }
00537 return;
00538 }
00539 case EXIF_TYPE_LONG:
00540 {
00541 *size = 4*components();
00542 *data = new uchar[*size];
00543 for(uint i = 0; i < components(); i++)
00544 {
00545 set32Bit( (*data) + 4 * i, order, &asExifNumber(i).m_long);
00546 }
00547 return;
00548 }
00549 case EXIF_TYPE_RATIONAL:
00550 *size = 8*components();
00551 *data = new uchar[*size];
00552 for(uint i = 0; i < components(); i++)
00553 {
00554 ExifNumber n = asExifNumber(i);
00555 set32Bit( (*data) + 8 * i, order, &n.m_rational.numerator);
00556 set32Bit( (*data) + 8 * i + 4, order, &n.m_rational.denominator);
00557 }
00558 return;
00559 case EXIF_TYPE_SBYTE:
00560 *size = components();
00561 *data = new uchar[*size];
00562 for(uint i = 0; i < components(); i++)
00563 {
00564 *(((Q_INT8*)*data) + i) = asExifNumber(i).m_sbyte;
00565 }
00566 return;
00567 case EXIF_TYPE_UNDEFINED:
00568 {
00569 UByteArray array = asUndefined();
00570 *size = array.size();
00571 *data = new uchar[*size];
00572 memcpy( *data, array.data(), (*size)*sizeof(unsigned char));
00573 }
00574 return;
00575 case EXIF_TYPE_SSHORT:
00576 *size = 2*components();
00577 *data = new uchar[*size];
00578 for(uint i = 0; i < components(); i++)
00579 {
00580 set16Bit( (*data) + 2 * i, order, (Q_UINT16*)&asExifNumber(i).m_sshort);
00581 }
00582 return;
00583 case EXIF_TYPE_SLONG:
00584 *size = 4*components();
00585 *data = new uchar[*size];
00586 for(uint i = 0; i < components(); i++)
00587 {
00588 set32Bit( (*data) + 4 * i, order, (Q_UINT32*)&asExifNumber(i).m_slong);
00589 }
00590 return;
00591 case EXIF_TYPE_SRATIONAL:
00592 *size = 8*components();
00593 *data = new uchar[*size];
00594 for(uint i = 0; i < components(); i++)
00595 {
00596 ExifNumber n = asExifNumber(i);
00597 set32Bit( (*data) + 4 * i, order, (Q_UINT32*)&asExifNumber(i).m_srational.numerator);
00598 set32Bit( (*data) + 4 * i + 4, order, (Q_UINT32*)&asExifNumber(i).m_srational.denominator);
00599 }
00600 return;
00601 case EXIF_TYPE_FLOAT:
00602 *size = 4*components();
00603 *data = new uchar[*size];
00604 for(uint i = 0; i < components(); i++)
00605 {
00606 set32Bit( (*data) + 4 * i, order, (Q_UINT32*)&asExifNumber(i).m_float);
00607 }
00608 return;
00609 case EXIF_TYPE_DOUBLE:
00610 *size = 8*components();
00611 *data = new uchar[*size];
00612 for(uint i = 0; i < components(); i++)
00613 {
00614 set64Bit( (*data) + 4 * i, order, (Q_UINT64*)&asExifNumber(i).m_double);
00615 }
00616 return;
00617 case EXIF_TYPE_UNKNOW:
00618 break;
00619 }
00620 }
00621
00622 QString ExifValue::toString()
00623 {
00624 switch(type())
00625 {
00626 case EXIF_TYPE_ASCII:
00627 return asAscii();
00628 case EXIF_TYPE_UNDEFINED:
00629 {
00630 QString undefined = "undefined";
00631 UByteArray array = asUndefined();
00632 for(uint i = 0; i < components(); i++)
00633 {
00634 undefined += "\\" + QString().setNum( array[i] );
00635 }
00636 return undefined;
00637 }
00638 default:
00639 {
00640 QString str = "";
00641 for(uint i = 0; i < components(); i++)
00642 {
00643 str += toString(i);
00644 }
00645 return str;
00646 }
00647 }
00648 }
00649
00650 QString ExifValue::toString(uint i)
00651 {
00652 switch(type())
00653 {
00654 case EXIF_TYPE_BYTE:
00655 return QString("%1 ").arg( asExifNumber( i ).m_byte );
00656 case EXIF_TYPE_SHORT:
00657 return QString("%1 ").arg( asExifNumber( i ).m_short );
00658 case EXIF_TYPE_LONG:
00659 return QString("%1 ").arg( asExifNumber( i ).m_long );
00660 case EXIF_TYPE_RATIONAL:
00661 return QString("%1 / %2 ").arg( asExifNumber( i ).m_rational.numerator ).arg( asExifNumber( i ).m_rational.denominator );
00662 case EXIF_TYPE_SBYTE:
00663 return QString("%1 ").arg( asExifNumber( i ).m_sbyte );
00664 case EXIF_TYPE_SSHORT:
00665 return QString("%1 ").arg( asExifNumber( i ).m_sshort );
00666 case EXIF_TYPE_SLONG:
00667 return QString("%1 ").arg( asExifNumber( i ).m_slong );
00668 case EXIF_TYPE_SRATIONAL:
00669 return QString("%1 / %2 ").arg( asExifNumber( i ).m_srational.numerator ).arg( asExifNumber( i ).m_srational.denominator );
00670 case EXIF_TYPE_FLOAT:
00671 return QString("%1 ").arg( asExifNumber( i ).m_float );
00672 case EXIF_TYPE_DOUBLE:
00673 return QString("%1 ").arg( asExifNumber( i ).m_double );
00674 default:
00675 return "unknow ";
00676 }
00677 }
00678