@Override public String toString() { return String.format( "tag id: %04X\n", mTagId ) + "ifd id: " + mIfd + "\ntype: " + convertTypeToString( mDataType ) + "\ncount: " + mComponentCountActual + "\noffset: " + mOffset + "\nvalue: " + forceGetValueAsString() + "\n"; }
@SuppressWarnings( "unused" ) protected int getTagDefinitionForTag( ExifTag tag ) { short type = tag.getDataType(); int count = tag.getComponentCount(); int ifd = tag.getIfd(); return getTagDefinitionForTag( tag.getTagId(), type, count, ifd ); }
/** * Gets the value as a String. This method should be used for tags of type * {@link #TYPE_ASCII}. * * @param defaultValue the String to return if the tag's value does not * exist or cannot be converted to a String. * @return the tag's value as a String, or the defaultValue. */ public String getValueAsString( String defaultValue ) { String s = getValueAsString(); if( s == null ) { return defaultValue; } return s; }
/** * Sets long values into this tag. This method should be used for tags of * type {@link #TYPE_UNSIGNED_LONG}. This method will fail if: * <ul> * <li>The component type of this tag is not {@link #TYPE_UNSIGNED_LONG}.</li> * <li>The value overflows.</li> * <li>The value.length does NOT match the component count in the definition * for this tag.</li> * </ul> */ public boolean setValue( long[] value ) { if( checkBadComponentCount( value.length ) || mDataType != TYPE_UNSIGNED_LONG ) { return false; } if( checkOverflowForUnsignedLong( value ) ) { return false; } mValue = value; mComponentCountActual = value.length; return true; }
if( tag.getComponentCount() == 0 ) { return; short tid = tag.getTagId(); int ifd = tag.getIfd(); if( tid == TAG_EXIF_IFD && checkAllowed( ifd, ExifInterface.TAG_EXIF_IFD ) ) { if( isIfdRequested( IfdId.TYPE_IFD_EXIF ) || isIfdRequested( IfdId.TYPE_IFD_INTEROPERABILITY ) ) { registerIfd( IfdId.TYPE_IFD_EXIF, tag.getValueAt( 0 ) ); registerIfd( IfdId.TYPE_IFD_GPS, tag.getValueAt( 0 ) ); registerIfd( IfdId.TYPE_IFD_INTEROPERABILITY, tag.getValueAt( 0 ) ); registerCompressedImage( tag.getValueAt( 0 ) ); if( tag.hasValue() ) { for( int i = 0; i < tag.getComponentCount(); i++ ) { if( tag.getDataType() == ExifTag.TYPE_UNSIGNED_SHORT ) { registerUncompressedStrip( i, tag.getValueAt( i ) ); registerUncompressedStrip( i, tag.getValueAt( i ) ); mCorrespondingEvent.put( tag.getOffset(), new ExifTagEvent( tag, false ) ); else if( tid == TAG_STRIP_BYTE_COUNTS && checkAllowed( ifd, ExifInterface.TAG_STRIP_BYTE_COUNTS ) && isThumbnailRequested() && tag.hasValue() ) { mStripSizeTag = tag;
if( ! ExifTag.isValidType( dataFormat ) ) { Log.w( TAG, String.format( "Tag %04x: Invalid data type %d", tagId, dataFormat ) ); mTiffStream.skip( 4 ); ExifTag tag = new ExifTag( tagId, dataFormat, (int) numOfComp, mIfdType, ( (int) numOfComp ) != ExifTag.SIZE_UNDEFINED ); int dataSize = tag.getDataSize(); if( dataSize > 4 ) { long offset = mTiffStream.readUnsignedInt(); byte[] buf = new byte[Math.min(mDataAboveIfd0.length, (int) numOfComp)]; System.arraycopy( mDataAboveIfd0, (int) offset - DEFAULT_IFD0_OFFSET, buf, 0, buf.length ); tag.setValue( buf ); tag.setOffset( (int) offset ); boolean defCount = tag.hasDefinedCount(); tag.setHasDefinedCount( false ); tag.setHasDefinedCount( defCount ); mTiffStream.skip( 4 - dataSize ); tag.setOffset( mTiffStream.getReadByteCount() - 4 );
private void writeIfd( IfdData ifd, OrderedDataOutputStream dataOutputStream ) throws IOException { ExifTag[] tags = ifd.getAllTags(); dataOutputStream.writeShort( (short) tags.length ); for( ExifTag tag : tags ) { dataOutputStream.writeShort( tag.getTagId() ); dataOutputStream.writeShort( tag.getDataType() ); dataOutputStream.writeInt( tag.getComponentCount() ); // Log.v( TAG, "\n" + tag.toString() ); if( tag.getDataSize() > 4 ) { dataOutputStream.writeInt( tag.getOffset() ); } else { ExifOutputStream.writeTagValue( tag, dataOutputStream ); for( int i = 0, n = 4 - tag.getDataSize(); i < n; i++ ) { dataOutputStream.write( 0 ); } } } dataOutputStream.writeInt( ifd.getOffsetToNextIfd() ); for( ExifTag tag : tags ) { if( tag.getDataSize() > 4 ) { ExifOutputStream.writeTagValue( tag, dataOutputStream ); } } }
short type = tag.getDataType(); final int componentCount = tag.getComponentCount(); int size = tag.getComponentCount(); if( mCorrespondingEvent.size() > 0 ) { if( mCorrespondingEvent.firstEntry().getKey() < mTiffStream.getReadByteCount() + size ) { Log.w( TAG, "Thumbnail overlaps value for tag: \n" + tag.toString() ); Entry<Integer, Object> entry = mCorrespondingEvent.pollFirstEntry(); Log.w( TAG, "Invalid thumbnail offset: " + entry.getKey() ); Log.w( TAG, "Ifd " + ( (IfdEvent) event ).ifd + " overlaps value for tag: \n" + tag.toString() ); Log.w( TAG, "Tag value for tag: \n" + ( (ExifTagEvent) event ).tag.toString() + " overlaps value for tag: \n" + tag.toString() ); Log.w( TAG, "Invalid size of tag: \n" + tag.toString() + " setting count to: " + size ); tag.forceSetComponentCount( size ); switch( tag.getDataType() ) { case ExifTag.TYPE_UNSIGNED_BYTE: case ExifTag.TYPE_UNDEFINED: { byte buf[] = new byte[componentCount]; read( buf ); tag.setValue( buf ); tag.setValue( readString(componentCount) ); break; case ExifTag.TYPE_UNSIGNED_LONG: {
if( ! tag.hasValue() ) { parser.registerForTagValue( tag ); if (parser.isDefinedTag(tag.getIfd(), tag.getTagId())) { exifData.getIfdData(tag.getIfd()).setTag(tag); case ExifParser.EVENT_VALUE_OF_REGISTERED_TAG: tag = parser.getTag(); if( tag.getDataType() == ExifTag.TYPE_UNDEFINED ) { parser.readFullTagValue( tag ); exifData.getIfdData( tag.getIfd() ).setTag( tag ); break; case ExifParser.EVENT_COMPRESSED_IMAGE:
int ifid = tag.getIfd(); String ifdid_str = ""; Date date = ExifInterface.getDateTime( tag.getValueAsString(), TimeZone.getDefault() ); if( null != date ) { exifString += java.text.DateFormat.getDateTimeInstance().format( date ); exifString += tag.forceGetValueAsString();
private ArrayList<ExifTag> stripNullValueTags( ExifData data ) { ArrayList<ExifTag> nullTags = new ArrayList<ExifTag>(); for( ExifTag t : data.getAllTags() ) { if( t.getValue() == null && ! ExifInterface.isOffsetTag( t.getTagId() ) ) { data.removeTag( t.getTagId(), t.getIfd() ); nullTags.add( t ); } } return nullTags; }
string.append( "<b>Exif version: </b> " + tag.getValueAsString() + "<br>" ); double speed = shutterSpeed.getValueAsRational( 0 ).toDouble(); Log.d( LOG_TAG, "speed: " + speed ); Log.i( LOG_TAG, "---- remaining tags ---" ); for( ExifTag remaining_tag : all_tags ) { Log.v( LOG_TAG, "tag: " + String.format( "0x%X", remaining_tag.getTagId() ) + ", value: " + remaining_tag );
if( checkBadComponentCount( value.length ) ) { return false; return false; if( mDataType == TYPE_UNSIGNED_RATIONAL && checkOverflowForUnsignedRational( value ) ) { return false; else if( mDataType == TYPE_RATIONAL && checkOverflowForRational( value ) ) { return false;
if( checkBadComponentCount( value.length ) ) { return false; return false; if( mDataType == TYPE_UNSIGNED_SHORT && checkOverflowForUnsignedShort( value ) ) { return false; else if( mDataType == TYPE_UNSIGNED_LONG && checkOverflowForUnsignedLong( value ) ) { return false;
/** * Returns true if all tags in this two IFDs are equal. Note that tags of * IFDs offset or thumbnail offset will be ignored. */ @Override public boolean equals( Object obj ) { if( this == obj ) { return true; } if( obj == null ) { return false; } if( obj instanceof IfdData ) { IfdData data = (IfdData) obj; if( data.getId() == mIfdId && data.getTagCount() == getTagCount() ) { ExifTag[] tags = data.getAllTags(); for( ExifTag tag : tags ) { if( ExifInterface.isOffsetTag( tag.getTagId() ) ) { continue; } ExifTag tag2 = mExifTags.get( tag.getTagId() ); if( ! tag.equals( tag2 ) ) { return false; } } return true; } } return false; }
/** * Creates a tag for a defined tag constant in a given IFD if that IFD is * allowed for the tag. This method will fail anytime the appropriate * {@link ExifTag#setValue} for this tag's datatype would fail. * * @param tagId a tag constant, e.g. {@link #TAG_IMAGE_WIDTH}. * @param ifdId the IFD that the tag should be in. * @param val the value of the tag to set. * @return an ExifTag object or null if one could not be constructed. * @see #buildTag */ public ExifTag buildTag( int tagId, int ifdId, Object val ) { int info = getTagInfo().get( tagId ); if( info == 0 || val == null ) { return null; } short type = getTypeFromInfo( info ); int definedCount = getComponentCountFromInfo( info ); boolean hasDefinedCount = ( definedCount != ExifTag.SIZE_UNDEFINED ); if( ! ExifInterface.isIfdAllowed( info, ifdId ) ) { return null; } ExifTag t = new ExifTag( getTrueTagKey( tagId ), type, definedCount, ifdId, hasDefinedCount ); if( ! t.setValue( val ) ) { return null; } return t; }
/** * Adds the given ExifTag to its default IFD and returns an existing ExifTag * with the same TID or null if none exist. */ protected ExifTag addTag( ExifTag tag ) { if( tag != null ) { int ifd = tag.getIfd(); return addTag( tag, ifd ); } return null; }
/** * Gets the value as a Rational. If there are more than 1 Rationals in this * value, gets the first one. This method should be used for tags of type * {@link #TYPE_RATIONAL} or {@link #TYPE_UNSIGNED_RATIONAL}. * * @param defaultValue the numerator of the Rational to return if tag's * value does not exist or cannot be converted to a Rational (the * denominator will be 1). * @return the tag's value as a Rational, or the defaultValue. */ public Rational getValueAsRational( long defaultValue ) { Rational defaultVal = new Rational( defaultValue, 1 ); return getValueAsRational( defaultVal ); }
private void dumpToFile( ExifInterface exif ) { if( null == exif ) return; try { File file = new File( Environment.getExternalStoragePublicDirectory( Environment.DIRECTORY_DOWNLOADS ), "exif.txt" ); Log.d( LOG_TAG, "writing to " + file.getAbsolutePath() ); FileOutputStream stream = new FileOutputStream( file ); List<ExifTag> tags = exif.getAllTags(); if( null == tags ) return; for( ExifTag key : tags ) { String line = key.toString() + "\n"; stream.write( line.getBytes() ); } stream.flush(); stream.close(); } catch( IOException e ) { e.printStackTrace(); } }