static void entry_getdata_aux (lua_State *L, ExifEntry *entry, unsigned int n) { ExifFormat format = entry->format; size_t formatsize = (size_t)exif_format_get_size(format); const unsigned char *ptr = entry->data+formatsize*n; ExifByteOrder order = exif_data_get_byte_order(entry->parent->parent); switch (format) { case EXIF_FORMAT_BYTE: lua_pushinteger(L, (ExifByte)*ptr); break; case EXIF_FORMAT_SBYTE: lua_pushinteger(L, (ExifSByte)*ptr); break; case EXIF_FORMAT_SHORT: lua_pushinteger(L, exif_get_short(ptr, order)); break; case EXIF_FORMAT_SSHORT: lua_pushinteger(L, exif_get_sshort(ptr, order)); break; case EXIF_FORMAT_LONG: lua_pushnumber(L, exif_get_long(ptr, order)); break; case EXIF_FORMAT_SLONG: lua_pushinteger(L, exif_get_slong(ptr, order)); break; case EXIF_FORMAT_RATIONAL: { ExifRational rat = exif_get_rational(ptr, order); pushrational(L, rat.numerator, rat.denominator); break; } case EXIF_FORMAT_SRATIONAL: { ExifSRational rat = exif_get_srational(ptr, order); pushrational(L, rat.numerator, rat.denominator); break; } case EXIF_FORMAT_ASCII: lua_pushinteger(L, *ptr); break; default: lua_pushnil(L); break; } }
qint64 ImageSlideInfo::readExifIntValue(ExifData* pExifData, ExifTag exifTag) { qint64 exifValue = 0; if (!pExifData) return exifValue; ExifByteOrder exifByteOrder = exif_data_get_byte_order(pExifData); ExifEntry* pExifEntry = exif_data_get_entry(pExifData, exifTag); if (pExifEntry) { // paranoic a bit if (pExifEntry->size <= sizeof(qint64)) { if (pExifEntry->format == EXIF_FORMAT_SBYTE) exifValue = static_cast<qint64>(*pExifEntry->data); if (pExifEntry->format == EXIF_FORMAT_SSHORT) exifValue = static_cast<qint64>(exif_get_sshort(pExifEntry->data, exifByteOrder)); if (pExifEntry->format == EXIF_FORMAT_SLONG) exifValue = static_cast<qint64>(exif_get_slong(pExifEntry->data, exifByteOrder)); } } return exifValue; }
static double exifDouble(ExifEntry *entry, ExifByteOrder byte_order) { switch (entry->format) { case EXIF_FORMAT_BYTE: return double(entry->data[0]); case EXIF_FORMAT_SHORT: return double(exif_get_short(entry->data, byte_order)); case EXIF_FORMAT_LONG: return double(exif_get_long(entry->data, byte_order)); case EXIF_FORMAT_RATIONAL: { ExifRational r = exif_get_rational(entry->data, byte_order); return double(r.numerator)/double(r.denominator); } case EXIF_FORMAT_SBYTE: return double(*(signed char *)entry->data); case EXIF_FORMAT_SSHORT: return double(exif_get_sshort(entry->data, byte_order)); case EXIF_FORMAT_SLONG: return double(exif_get_slong(entry->data, byte_order)); case EXIF_FORMAT_SRATIONAL: { ExifSRational r = exif_get_srational(entry->data, byte_order); return double(r.numerator)/double(r.denominator); } case EXIF_FORMAT_FLOAT: return double(((float *)entry->data)[0]); case EXIF_FORMAT_DOUBLE: return ((double *)entry->data)[0]; default: return nan(0); } }
static int getDouble(ExifData *ed, ExifByteOrder bo, ExifTag t, double *d) { ExifEntry * e = exif_data_get_entry(ed, t); if (!e) return 0; char *b = e->data; switch (e->format) { case EXIF_FORMAT_SHORT: *d = (double) exif_get_short(b, bo); return 1; case EXIF_FORMAT_SSHORT: *d = (double) exif_get_sshort(b, bo); return 1; case EXIF_FORMAT_LONG: *d = (double) exif_get_long(b, bo); return 1; case EXIF_FORMAT_SLONG: *d = (double) exif_get_slong(b, bo); return 1; case EXIF_FORMAT_RATIONAL: { ExifRational r = exif_get_rational(b, bo); *d = (double) r.numerator / (double) r.denominator; return 1; } case EXIF_FORMAT_SRATIONAL: { ExifSRational r = exif_get_srational(b, bo); *d = (double) r.numerator / (double) r.denominator; return 1; } default: return 0; } }
static int vips_exif_get_int( ExifData *ed, ExifEntry *entry, unsigned long component, int *out ) { ExifByteOrder bo = exif_data_get_byte_order( ed ); size_t sizeof_component = entry->size / entry->components; size_t offset = component * sizeof_component; if( entry->format == EXIF_FORMAT_SHORT ) *out = exif_get_short( entry->data + offset, bo ); else if( entry->format == EXIF_FORMAT_SSHORT ) *out = exif_get_sshort( entry->data + offset, bo ); else if( entry->format == EXIF_FORMAT_LONG ) /* This won't work for huge values, but who cares. */ *out = (int) exif_get_long( entry->data + offset, bo ); else if( entry->format == EXIF_FORMAT_SLONG ) *out = exif_get_slong( entry->data + offset, bo ); else return( -1 ); return( 0 ); }
static void foreach_exif_entry( ExifEntry * entry , void * _closure ) { if ( ! entry ) { return; } //......................................................................... // Bail out of types we don't handle switch( entry->format ) { case EXIF_FORMAT_UNDEFINED: case EXIF_FORMAT_FLOAT: case EXIF_FORMAT_DOUBLE: return; default: break; } //......................................................................... unsigned char component_size = exif_format_get_size( entry->format ); ExifIfd ifd = exif_content_get_ifd( entry->parent ); const char * tag_name = exif_tag_get_name_in_ifd( entry->tag , ifd ); if ( ! tag_name || ! entry->data || ! entry->size || ! component_size || ! entry->components ) { return; } //......................................................................... // Add a prefix based on the IFD String name( tag_name ); switch( ifd ) { case EXIF_IFD_0: name = "IMAGE/" + name; break; case EXIF_IFD_1: name = "THUMBNAIL/" + name; break; case EXIF_IFD_EXIF: name = "EXIF/" + name; break; case EXIF_IFD_GPS: name = "GPS/" + name; break; case EXIF_IFD_INTEROPERABILITY: name = "INTEROP/" + name; break; default: return; } ExifClosure * closure = ( ExifClosure * ) _closure; JSON::Object * tags = closure->tags; //......................................................................... // ASCII ones are easy if ( entry->format == EXIF_FORMAT_ASCII ) { (*tags)[ name ] = String( ( const char * ) entry->data , entry->size ); return; } //......................................................................... if ( ( entry->components * component_size ) != entry->size ) { return; } ExifByteOrder byte_order = exif_data_get_byte_order( closure->exif_data ); const unsigned char * data = entry->data; JSON::Array array; for ( unsigned long i = 0; i < entry->components; ++i ) { switch( entry->format ) { case EXIF_FORMAT_BYTE: array.append( JSON::Value( int( * data ) ) ); break; case EXIF_FORMAT_SHORT: array.append( JSON::Value( int( exif_get_short( data , byte_order ) ) ) ); break; case EXIF_FORMAT_LONG: array.append( JSON::Value( int( exif_get_long( data , byte_order ) ) ) ); break; case EXIF_FORMAT_SBYTE: array.append( JSON::Value( int( * ( ( const char * ) data ) ) ) ); break; case EXIF_FORMAT_SSHORT: array.append( JSON::Value( exif_get_sshort( data , byte_order ) ) ); break; case EXIF_FORMAT_SLONG: array.append( JSON::Value( exif_get_slong( data , byte_order ) ) ); break; // TODO: I don't like representing a rational number as a string with a slash, case EXIF_FORMAT_SRATIONAL: { ExifSRational r = exif_get_srational( data , byte_order ); array.append( Util::format("%ld/%ld" , r.numerator , r.denominator ) ); break; } case EXIF_FORMAT_RATIONAL: { ExifRational r = exif_get_rational( data , byte_order ); array.append( Util::format("%lu/%lu" , r.numerator , r.denominator ) ); break; } default: break; } data += component_size; } if ( array.size() == 1 ) { (*tags)[ name ] = array[ 0 ]; } else if ( array.size() > 1 ) { (*tags)[ name ] = array; } }