/** * Returns the {@link IfdData} object corresponding to a given IFD or * generates one if none exist. */ protected IfdData getOrCreateIfdData( int ifdId ) { IfdData ifdData = mIfdDatas[ifdId]; if( ifdData == null ) { ifdData = new IfdData( ifdId ); mIfdDatas[ifdId] = ifdData; } return ifdData; }
/** * Returns a list of all {@link ExifTag}s in the ExifData or null if there * are none. */ protected List<ExifTag> getAllTags() { ArrayList<ExifTag> ret = new ArrayList<ExifTag>(); for( IfdData d : mIfdDatas ) { if( d != null ) { ExifTag[] tags = d.getAllTags(); if( tags != null ) { for( ExifTag t : tags ) { ret.add( t ); } } } } if( ret.size() == 0 ) { return null; } return ret; }
/** * Adds IFD data. If IFD data of the same type already exists, it will be * replaced by the new data. */ protected void addIfdData( IfdData data ) { mIfdDatas[data.getId()] = data; }
/** * 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; }
ifd0 = new IfdData( IfdId.TYPE_IFD_0 ); mExifData.addIfdData( ifd0 ); ifd0.setTag( exifOffsetTag ); exifIfd = new IfdData( IfdId.TYPE_IFD_EXIF ); mExifData.addIfdData( exifIfd ); ifd0.setTag( gpsOffsetTag ); exifIfd.setTag( interOffsetTag ); ifd1 = new IfdData( IfdId.TYPE_IFD_1 ); mExifData.addIfdData( ifd1 ); ifd1.setTag( offsetTag ); ExifTag lengthTag = mInterface.buildUninitializedTag( ExifInterface.TAG_JPEG_INTERCHANGE_FORMAT_LENGTH ); if( lengthTag == null ) { ifd1.setTag( lengthTag ); ifd1.removeTag( ExifInterface.getTrueTagKey( ExifInterface.TAG_STRIP_OFFSETS ) ); ifd1.removeTag( ExifInterface.getTrueTagKey( ExifInterface.TAG_STRIP_BYTE_COUNTS ) ); ifd1 = new IfdData( IfdId.TYPE_IFD_1 ); mExifData.addIfdData( ifd1 ); ifd1.setTag( offsetTag ); ifd1.setTag( lengthTag );
protected static int getFlagsFromAllowedIfds( int[] allowedIfds ) { if( allowedIfds == null || allowedIfds.length == 0 ) { return 0; } int flags = 0; int[] ifds = IfdData.getIfds(); for( int i = 0; i < IfdId.TYPE_IFD_COUNT; i++ ) { for( int j : allowedIfds ) { if( ifds[i] == j ) { flags |= 1 << i; break; } } } return flags; }
private int calculateOffsetOfIfd( IfdData ifd, int offset ) { offset += 2 + ifd.getTagCount() * TAG_SIZE + 4; ExifTag[] tags = ifd.getAllTags(); for( ExifTag tag : tags ) { if( tag.getDataSize() > 4 ) { tag.setOffset( offset ); offset += tag.getDataSize(); } } return offset; }
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 ); } } }
IfdData ifd0 = mExifData.getIfdData( IfdId.TYPE_IFD_0 ); offset = calculateOffsetOfIfd( ifd0, offset ); ifd0.getTag( ExifInterface.getTrueTagKey( ExifInterface.TAG_EXIF_IFD ) ).setValue( offset ); exifIfd.getTag( ExifInterface.getTrueTagKey( ExifInterface.TAG_INTEROPERABILITY_IFD ) ).setValue( offset ); offset = calculateOffsetOfIfd( interIfd, offset ); ifd0.getTag( ExifInterface.getTrueTagKey( ExifInterface.TAG_GPS_IFD ) ).setValue( offset ); offset = calculateOffsetOfIfd( gpsIfd, offset ); ifd0.setOffsetToNextIfd( offset ); offset = calculateOffsetOfIfd( ifd1, offset ); ifd1.getTag( ExifInterface.getTrueTagKey( ExifInterface.TAG_JPEG_INTERCHANGE_FORMAT ) ).setValue( offset ); offset += mExifData.getCompressedThumbnail().length; offset += mExifData.getStrip( i ).length; ifd1.getTag( ExifInterface.getTrueTagKey( ExifInterface.TAG_STRIP_OFFSETS ) ).setValue( offsets );
switch( event ) { case ExifParser.EVENT_START_OF_IFD: exifData.addIfdData( new IfdData( parser.getCurrentIfd() ) ); break; case ExifParser.EVENT_NEW_TAG: exifData.getIfdData(tag.getIfd()).setTag(tag); parser.readFullTagValue( tag ); exifData.getIfdData( tag.getIfd() ).setTag( tag ); break; case ExifParser.EVENT_COMPRESSED_IMAGE:
/** * Returns the tag with a given TID in the given IFD if the tag exists. * Otherwise returns null. */ protected ExifTag getTag( short tag, int ifd ) { IfdData ifdData = mIfdDatas[ifd]; return ( ifdData == null ) ? null : ifdData.getTag( tag ); }
/** * Removes the tag with a given TID and IFD. */ protected void removeTag( short tagId, int ifdId ) { IfdData ifdData = mIfdDatas[ifdId]; if( ifdData == null ) { return; } ifdData.removeTag( tagId ); }
IfdData ifd1 = data.getIfdData( i ); IfdData ifd2 = getIfdData( i ); if( ifd1 != ifd2 && ifd1 != null && ! ifd1.equals( ifd2 ) ) { 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; }
ifd0 = new IfdData( IfdId.TYPE_IFD_0 ); mExifData.addIfdData( ifd0 ); ifd0.setTag( exifOffsetTag ); exifIfd = new IfdData( IfdId.TYPE_IFD_EXIF ); mExifData.addIfdData( exifIfd ); ifd0.setTag( gpsOffsetTag ); exifIfd.setTag( interOffsetTag ); ifd1 = new IfdData( IfdId.TYPE_IFD_1 ); mExifData.addIfdData( ifd1 ); ifd1.setTag( offsetTag ); ExifTag lengthTag = mInterface.buildUninitializedTag( ExifInterface.TAG_JPEG_INTERCHANGE_FORMAT_LENGTH ); if( lengthTag == null ) { ifd1.setTag( lengthTag ); ifd1.removeTag( ExifInterface.getTrueTagKey( ExifInterface.TAG_STRIP_OFFSETS ) ); ifd1.removeTag( ExifInterface.getTrueTagKey( ExifInterface.TAG_STRIP_BYTE_COUNTS ) ); ifd1 = new IfdData( IfdId.TYPE_IFD_1 ); mExifData.addIfdData( ifd1 ); ifd1.setTag( offsetTag ); ifd1.setTag( lengthTag );
protected static int getFlagsFromAllowedIfds( int[] allowedIfds ) { if( allowedIfds == null || allowedIfds.length == 0 ) { return 0; } int flags = 0; int[] ifds = IfdData.getIfds(); for( int i = 0; i < IfdId.TYPE_IFD_COUNT; i++ ) { for( int j : allowedIfds ) { if( ifds[i] == j ) { flags |= 1 << i; break; } } } return flags; }
private int calculateOffsetOfIfd( IfdData ifd, int offset ) { offset += 2 + ifd.getTagCount() * TAG_SIZE + 4; ExifTag[] tags = ifd.getAllTags(); for( ExifTag tag : tags ) { if( tag.getDataSize() > 4 ) { tag.setOffset( offset ); offset += tag.getDataSize(); } } return offset; }
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 ); } } }
IfdData ifd0 = mExifData.getIfdData( IfdId.TYPE_IFD_0 ); offset = calculateOffsetOfIfd( ifd0, offset ); ifd0.getTag( ExifInterface.getTrueTagKey( ExifInterface.TAG_EXIF_IFD ) ).setValue( offset ); exifIfd.getTag( ExifInterface.getTrueTagKey( ExifInterface.TAG_INTEROPERABILITY_IFD ) ).setValue( offset ); offset = calculateOffsetOfIfd( interIfd, offset ); ifd0.getTag( ExifInterface.getTrueTagKey( ExifInterface.TAG_GPS_IFD ) ).setValue( offset ); offset = calculateOffsetOfIfd( gpsIfd, offset ); ifd0.setOffsetToNextIfd( offset ); offset = calculateOffsetOfIfd( ifd1, offset ); ifd1.getTag( ExifInterface.getTrueTagKey( ExifInterface.TAG_JPEG_INTERCHANGE_FORMAT ) ).setValue( offset ); offset += mExifData.getCompressedThumbnail().length; offset += mExifData.getStrip( i ).length; ifd1.getTag( ExifInterface.getTrueTagKey( ExifInterface.TAG_STRIP_OFFSETS ) ).setValue( offsets );
switch( event ) { case ExifParser.EVENT_START_OF_IFD: exifData.addIfdData( new IfdData( parser.getCurrentIfd() ) ); break; case ExifParser.EVENT_NEW_TAG: exifData.getIfdData(tag.getIfd()).setTag(tag); parser.readFullTagValue( tag ); exifData.getIfdData( tag.getIfd() ).setTag( tag ); break; case ExifParser.EVENT_COMPRESSED_IMAGE: