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(value.size());
00342 data.setRawData((char*)value.data(), value.size());
00343 QByteArray encodedData;
00344 KCodecs::base64Encode( data, encodedData );
00345 elmt.setAttribute("value", encodedData);
00346 }
00347 break;
00348 case EXIF_TYPE_SSHORT:
00349 for(uint i = 0; i < components(); i++)
00350 elmt.setAttribute(QString("value%1").arg(i), asSShort( i ) );
00351 break;
00352 case EXIF_TYPE_SLONG:
00353 for(uint i = 0; i < components(); i++)
00354 elmt.setAttribute(QString("value%1").arg(i), asSLong( i ) );
00355 break;
00356 case EXIF_TYPE_SRATIONAL:
00357 for(uint i = 0; i < components(); i++)
00358 {
00359 KisExifSRational r = asSRational(i);
00360 elmt.setAttribute(QString("numerator%1").arg(i), r.numerator );
00361 elmt.setAttribute(QString("denominator%1").arg(i), r.denominator );
00362 }
00363 break;
00364 case EXIF_TYPE_FLOAT:
00365 for(uint i = 0; i < components(); i++)
00366 elmt.setAttribute(QString("value%1").arg(i), asFloat( i ) );
00367 break;
00368 case EXIF_TYPE_DOUBLE:
00369 for(uint i = 0; i < components(); i++)
00370 elmt.setAttribute(QString("value%1").arg(i), asDouble( i ) );
00371 break;
00372 case EXIF_TYPE_UNKNOW:
00373 break;
00374 }
00375 return elmt;
00376 }
00377
00378
00379 void ExifValue::setValue(const unsigned char *data, unsigned int size, ExifValue::ByteOrder order)
00380 {
00381 switch(type())
00382 {
00383 case EXIF_TYPE_BYTE:
00384 if( size == components() )
00385 {
00386 ExifNumber n;
00387 for(uint i = 0; i < components(); i++)
00388 {
00389 n.m_byte = data[i];
00390 setAsExifNumber( i, n);
00391 }
00392 }
00393 break;
00394 case EXIF_TYPE_ASCII:
00395 setAsAscii((char*) data);
00396 break;
00397 case EXIF_TYPE_SHORT:
00398 if( size == 2*components() )
00399 {
00400 ExifNumber n;
00401 for(uint i = 0; i < components(); i++)
00402 {
00403 get16Bit( data + 2 * i, order, &n.m_short);
00404 setAsExifNumber( i, n);
00405 }
00406 }
00407 break;
00408 case EXIF_TYPE_LONG:
00409 if( size == 4*components() )
00410 {
00411 ExifNumber n;
00412 for(uint i = 0; i < components(); i++)
00413 {
00414 get32Bit( data + 4 * i, order, &n.m_long);
00415 setAsExifNumber( i, n);
00416 }
00417 }
00418 break;
00419 case EXIF_TYPE_RATIONAL:
00420 if( size == 8*components() )
00421 {
00422 ExifNumber n;
00423 for(uint i = 0; i < components(); i++)
00424 {
00425 get32Bit( data + 8 * i, order, &n.m_rational.numerator);
00426 get32Bit( data + 8 * i + 4, order, &n.m_rational.denominator);
00427 setAsExifNumber( i, n);
00428 }
00429 }
00430 break;
00431 case EXIF_TYPE_SBYTE:
00432 if( size == components() )
00433 {
00434 ExifNumber n;
00435 for(uint i = 0; i < components(); i++)
00436 {
00437 n.m_sbyte = ((Q_INT8*)data)[i];
00438 setAsExifNumber( i, n);
00439 }
00440 }
00441 break;
00442 case EXIF_TYPE_UNDEFINED:
00443 setAsUndefined(data, size);
00444 break;
00445 case EXIF_TYPE_SSHORT:
00446 if( size == 2*components() )
00447 {
00448 ExifNumber n;
00449 for(uint i = 0; i < components(); i++)
00450 {
00451 get16Bit( data + 2 * i, order, (Q_UINT16*)&n.m_sshort);
00452 setAsExifNumber( i, n);
00453 }
00454 }
00455 break;
00456 case EXIF_TYPE_SLONG:
00457 if( size == 4*components() )
00458 {
00459 ExifNumber n;
00460 for(uint i = 0; i < components(); i++)
00461 {
00462 get32Bit( data + 4 * i, order, (Q_UINT32*)&n.m_slong);
00463 setAsExifNumber( i, n);
00464 }
00465 }
00466 break;
00467 case EXIF_TYPE_SRATIONAL:
00468 if( size == 8*components() )
00469 {
00470 ExifNumber n;
00471 for(uint i = 0; i < components(); i++)
00472 {
00473 get32Bit( data + 8 * i, order, (Q_UINT32*)&n.m_srational.numerator);
00474 get32Bit( data + 8 * i + 4, order, (Q_UINT32*)&n.m_srational.denominator);
00475 setAsExifNumber( i, n);
00476 }
00477 }
00478 break;
00479 case EXIF_TYPE_FLOAT:
00480 if( size == 4*components() )
00481 {
00482 ExifNumber n;
00483 for(uint i = 0; i < components(); i++)
00484 {
00485 get32Bit( data + 4 * i, order, (Q_UINT32*)&n.m_float);
00486 setAsExifNumber( i, n);
00487 }
00488 }
00489 break;
00490 case EXIF_TYPE_DOUBLE:
00491 if( size == 8*components() )
00492 {
00493 ExifNumber n;
00494 for(uint i = 0; i < components(); i++)
00495 {
00496 get64Bit( data + 8 * i, order, (Q_UINT64*)&n.m_double);
00497 setAsExifNumber( i, n);
00498 }
00499 }
00500 break;
00501 case EXIF_TYPE_UNKNOW:
00502 break;
00503 }
00504 }
00505
00506 void ExifValue::convertToData(unsigned char ** data, unsigned int* size, ExifValue::ByteOrder order)
00507 {
00508 switch(type())
00509 {
00510 case EXIF_TYPE_BYTE:
00511 *size = components();
00512 *data = new uchar[*size];
00513 for(uint i = 0; i < components(); i++)
00514 {
00515 (*data)[i] = asExifNumber(i).m_byte;
00516 }
00517 return;
00518 case EXIF_TYPE_ASCII:
00519 {
00520 QString str = asAscii();
00521 *size = str.length();
00522 *data = new uchar[ *size ];
00523 uchar* ptr = *data;
00524 memcpy(ptr, str.ascii(), (*size)*sizeof(uchar));
00525 }
00526 return;
00527 break;
00528 case EXIF_TYPE_SHORT:
00529 {
00530 *size = 2*components();
00531 *data = new uchar[*size];
00532 for(uint i = 0; i < components(); i++)
00533 {
00534 set16Bit( (*data) + 2 * i, order, &asExifNumber(i).m_short);
00535 }
00536 return;
00537 }
00538 case EXIF_TYPE_LONG:
00539 {
00540 *size = 4*components();
00541 *data = new uchar[*size];
00542 for(uint i = 0; i < components(); i++)
00543 {
00544 set32Bit( (*data) + 4 * i, order, &asExifNumber(i).m_long);
00545 }
00546 return;
00547 }
00548 case EXIF_TYPE_RATIONAL:
00549 *size = 8*components();
00550 *data = new uchar[*size];
00551 for(uint i = 0; i < components(); i++)
00552 {
00553 ExifNumber n = asExifNumber(i);
00554 set32Bit( (*data) + 8 * i, order, &n.m_rational.numerator);
00555 set32Bit( (*data) + 8 * i + 4, order, &n.m_rational.denominator);
00556 }
00557 return;
00558 case EXIF_TYPE_SBYTE:
00559 *size = components();
00560 *data = new uchar[*size];
00561 for(uint i = 0; i < components(); i++)
00562 {
00563 *(((Q_INT8*)*data) + i) = asExifNumber(i).m_sbyte;
00564 }
00565 return;
00566 case EXIF_TYPE_UNDEFINED:
00567 {
00568 UByteArray array = asUndefined();
00569 *size = array.size();
00570 *data = new uchar[*size];
00571 memcpy( *data, array.data(), (*size)*sizeof(unsigned char));
00572 }
00573 return;
00574 case EXIF_TYPE_SSHORT:
00575 *size = 2*components();
00576 *data = new uchar[*size];
00577 for(uint i = 0; i < components(); i++)
00578 {
00579 set16Bit( (*data) + 2 * i, order, (Q_UINT16*)&asExifNumber(i).m_sshort);
00580 }
00581 return;
00582 case EXIF_TYPE_SLONG:
00583 *size = 4*components();
00584 *data = new uchar[*size];
00585 for(uint i = 0; i < components(); i++)
00586 {
00587 set32Bit( (*data) + 4 * i, order, (Q_UINT32*)&asExifNumber(i).m_slong);
00588 }
00589 return;
00590 case EXIF_TYPE_SRATIONAL:
00591 *size = 8*components();
00592 *data = new uchar[*size];
00593 for(uint i = 0; i < components(); i++)
00594 {
00595 ExifNumber n = asExifNumber(i);
00596 set32Bit( (*data) + 4 * i, order, (Q_UINT32*)&asExifNumber(i).m_srational.numerator);
00597 set32Bit( (*data) + 4 * i + 4, order, (Q_UINT32*)&asExifNumber(i).m_srational.denominator);
00598 }
00599 return;
00600 case EXIF_TYPE_FLOAT:
00601 *size = 4*components();
00602 *data = new uchar[*size];
00603 for(uint i = 0; i < components(); i++)
00604 {
00605 set32Bit( (*data) + 4 * i, order, (Q_UINT32*)&asExifNumber(i).m_float);
00606 }
00607 return;
00608 case EXIF_TYPE_DOUBLE:
00609 *size = 8*components();
00610 *data = new uchar[*size];
00611 for(uint i = 0; i < components(); i++)
00612 {
00613 set64Bit( (*data) + 4 * i, order, (Q_UINT64*)&asExifNumber(i).m_double);
00614 }
00615 return;
00616 case EXIF_TYPE_UNKNOW:
00617 break;
00618 }
00619 }
00620
00621 QString ExifValue::toString()
00622 {
00623 switch(type())
00624 {
00625 case EXIF_TYPE_ASCII:
00626 return asAscii();
00627 case EXIF_TYPE_UNDEFINED:
00628 {
00629 QString undefined = "undefined";
00630 UByteArray array = asUndefined();
00631 for(uint i = 0; i < components(); i++)
00632 {
00633 undefined += "\\" + QString().setNum( array[i] );
00634 }
00635 return undefined;
00636 }
00637 default:
00638 {
00639 QString str = "";
00640 for(uint i = 0; i < components(); i++)
00641 {
00642 str += toString(i);
00643 }
00644 return str;
00645 }
00646 }
00647 }
00648
00649 QString ExifValue::toString(uint i)
00650 {
00651 switch(type())
00652 {
00653 case EXIF_TYPE_BYTE:
00654 return QString("%1 ").arg( asExifNumber( i ).m_byte );
00655 case EXIF_TYPE_SHORT:
00656 return QString("%1 ").arg( asExifNumber( i ).m_short );
00657 case EXIF_TYPE_LONG:
00658 return QString("%1 ").arg( asExifNumber( i ).m_long );
00659 case EXIF_TYPE_RATIONAL:
00660 return QString("%1 / %2 ").arg( asExifNumber( i ).m_rational.numerator ).arg( asExifNumber( i ).m_rational.denominator );
00661 case EXIF_TYPE_SBYTE:
00662 return QString("%1 ").arg( asExifNumber( i ).m_sbyte );
00663 case EXIF_TYPE_SSHORT:
00664 return QString("%1 ").arg( asExifNumber( i ).m_sshort );
00665 case EXIF_TYPE_SLONG:
00666 return QString("%1 ").arg( asExifNumber( i ).m_slong );
00667 case EXIF_TYPE_SRATIONAL:
00668 return QString("%1 / %2 ").arg( asExifNumber( i ).m_srational.numerator ).arg( asExifNumber( i ).m_srational.denominator );
00669 case EXIF_TYPE_FLOAT:
00670 return QString("%1 ").arg( asExifNumber( i ).m_float );
00671 case EXIF_TYPE_DOUBLE:
00672 return QString("%1 ").arg( asExifNumber( i ).m_double );
00673 default:
00674 return "unknow ";
00675 }
00676 }
00677