diff --git a/.idea/dictionaries/tateisu.xml b/.idea/dictionaries/tateisu.xml
index 80706fab..d171d3b2 100644
--- a/.idea/dictionaries/tateisu.xml
+++ b/.idea/dictionaries/tateisu.xml
@@ -51,6 +51,8 @@
idempotency
ihdr
infos
+ iptc
+ jfif
kapt
kddi
kenglxn
diff --git a/exif/src/main/java/it/sephiroth/android/library/exif2/ByteBufferInputStream.kt b/exif/src/main/java/it/sephiroth/android/library/exif2/ByteBufferInputStream.kt
deleted file mode 100644
index 6ade7d36..00000000
--- a/exif/src/main/java/it/sephiroth/android/library/exif2/ByteBufferInputStream.kt
+++ /dev/null
@@ -1,38 +0,0 @@
-///*
-// * Copyright (C) 2012 The Android Open Source Project
-// *
-// * Licensed under the Apache License, Version 2.0 (the "License");
-// * you may not use this file except in compliance with the License.
-// * You may obtain a copy of the License at
-// *
-// * http://www.apache.org/licenses/LICENSE-2.0
-// *
-// * Unless required by applicable law or agreed to in writing, software
-// * distributed under the License is distributed on an "AS IS" BASIS,
-// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// * See the License for the specific language governing permissions and
-// * limitations under the License.
-// */
-//
-
-package it.sephiroth.android.library.exif2
-
-//
-//import java.io.InputStream
-//import java.nio.ByteBuffer
-//import kotlin.math.min
-//
-//internal class ByteBufferInputStream(private val mBuf : ByteBuffer) : InputStream() {
-//
-// override fun read() : Int = when {
-// ! mBuf.hasRemaining() -> - 1
-// else -> mBuf.get().toInt() and 0xFF
-// }
-//
-// override fun read(bytes : ByteArray, off : Int, len : Int) : Int {
-// if(! mBuf.hasRemaining()) return - 1
-// val willRead = min(len, mBuf.remaining())
-// mBuf.get(bytes, off, willRead)
-// return willRead
-// }
-//}
diff --git a/exif/src/main/java/it/sephiroth/android/library/exif2/ExifData.kt b/exif/src/main/java/it/sephiroth/android/library/exif2/ExifData.kt
index 89b55e18..76ff143d 100644
--- a/exif/src/main/java/it/sephiroth/android/library/exif2/ExifData.kt
+++ b/exif/src/main/java/it/sephiroth/android/library/exif2/ExifData.kt
@@ -17,6 +17,7 @@
package it.sephiroth.android.library.exif2
import android.util.Log
+import it.sephiroth.android.library.exif2.utils.notEmpty
import java.io.UnsupportedEncodingException
import java.nio.ByteOrder
@@ -33,94 +34,74 @@ import java.util.Arrays
* @see IfdData
*/
@Suppress("unused")
-internal open class ExifData( val byteOrder : ByteOrder ) {
+internal class ExifData(
+ val byteOrder : ByteOrder = ExifInterface.DEFAULT_BYTE_ORDER,
+ val sections : List = ArrayList(),
+ val mUncompressedDataPosition : Int = 0,
+ val qualityGuess : Int = 0,
+ val jpegProcess : Short = 0
+) {
- var sections : List? = null
- private val mIfdDatas = arrayOfNulls(IfdId.TYPE_IFD_COUNT)
- /**
- * Gets the compressed thumbnail. Returns null if there is no compressed
- * thumbnail.
- *
- * @see .hasCompressedThumbnail
- */
- /**
- * Sets the compressed thumbnail.
- */
- var compressedThumbnail : ByteArray? = null
- private val mStripBytes = ArrayList()
- var qualityGuess = 0
private var imageLength = - 1
private var imageWidth = - 1
- var jpegProcess : Short = 0
- var mUncompressedDataPosition = 0
- /**
- * Gets the strip count.
- */
+ private val mIfdDatas = arrayOfNulls(IfdData.TYPE_IFD_COUNT)
+
+ // the compressed thumbnail.
+ // null if there is no compressed thumbnail.
+ var compressedThumbnail : ByteArray? = null
+
+ private val mStripBytes = ArrayList()
val stripCount : Int
get() = mStripBytes.size
- /**
- * Decodes the user comment tag into string as specified in the EXIF
- * standard. Returns null if decoding failed.
- */
+ // Decodes the user comment tag into string as specified in the EXIF standard.
+ // Returns null if decoding failed.
val userComment : String?
get() {
- val ifdData = mIfdDatas[IfdId.TYPE_IFD_0] ?: return null
+
+ val ifdData = mIfdDatas[IfdData.TYPE_IFD_0]
+ ?: return null
+
val tag = ifdData.getTag(ExifInterface.getTrueTagKey(ExifInterface.TAG_USER_COMMENT))
?: return null
- if(tag.componentCount < 8) {
+
+ if(tag.componentCount < 8)
return null
- }
-
- val buf = ByteArray(tag.componentCount)
- tag.getBytes(buf)
-
- val code = ByteArray(8)
- System.arraycopy(buf, 0, code, 0, 8)
return try {
- when {
- code.contentEquals(USER_COMMENT_ASCII) -> String(
- buf,
- 8,
- buf.size - 8,
- Charsets.US_ASCII
- )
- code.contentEquals(USER_COMMENT_JIS) -> String(
- buf,
- 8,
- buf.size - 8,
- Charset.forName("EUC-JP")
- )
- code.contentEquals(USER_COMMENT_UNICODE) -> String(
- buf,
- 8,
- buf.size - 8,
- Charsets.UTF_16
- )
+
+ val buf = ByteArray(tag.componentCount)
+ tag.getBytes(buf)
+
+ val code = ByteArray(8)
+ System.arraycopy(buf, 0, code, 0, 8)
+
+ val charset = when {
+ code.contentEquals(USER_COMMENT_ASCII) -> Charsets.US_ASCII
+ code.contentEquals(USER_COMMENT_JIS) -> eucJp
+ code.contentEquals(USER_COMMENT_UNICODE) -> Charsets.UTF_16
else -> null
}
+ if(charset == null) null else String(buf, 8, buf.size - 8, charset)
} catch(e : UnsupportedEncodingException) {
Log.w(TAG, "Failed to decode the user comment")
null
}
}
- /**
- * Returns a list of all [ExifTag]s in the ExifData or null if there
- * are none.
- */
- val allTags : List?
- get() {
- val ret = ArrayList()
- mIfdDatas.forEach { it?.allTags?.forEach { tag -> ret.add(tag) } }
- return if(ret.isEmpty()) null else ret
- }
+ // list of all [ExifTag]s in the ExifData
+ // or null if there are none.
+ val allTags : List
+ get() = ArrayList()
+ .apply { mIfdDatas.forEach { if(it != null) addAll(it.allTagsCollection) } }
val imageSize : IntArray
get() = intArrayOf(imageWidth, imageLength)
+ val stripList : List?
+ get() = mStripBytes.filterNotNull().notEmpty()
+
/**
* Returns true it this header contains a compressed thumbnail.
*/
@@ -166,41 +147,36 @@ internal open class ExifData( val byteOrder : ByteOrder ) {
* Returns the tag with a given TID in the given IFD if the tag exists.
* Otherwise returns null.
*/
- fun getTag(tag : Short, ifd : Int) : ExifTag? {
- val ifdData = mIfdDatas[ifd]
- return ifdData?.getTag(tag)
- }
+ fun getTag(tag : Short, ifd : Int) : ExifTag? =
+ mIfdDatas[ifd]?.getTag(tag)
/**
* Adds the given ExifTag to its default IFD and returns an existing ExifTag
* with the same TID or null if none exist.
*/
- fun addTag(tag : ExifTag?) : ExifTag? {
- if(tag != null) {
- val ifd = tag.ifd
- return addTag(tag, ifd)
+ fun addTag(tag : ExifTag?) : ExifTag? =
+ when(tag) {
+ null -> null
+ else -> addTag(tag, tag.ifd)
}
- return null
- }
/**
* Adds the given ExifTag to the given IFD and returns an existing ExifTag
* with the same TID or null if none exist.
*/
- private fun addTag(tag : ExifTag?, ifdId : Int) : ExifTag? {
- if(tag != null && ExifTag.isValidIfd(ifdId)) {
- val ifdData = getOrCreateIfdData(ifdId)
- return ifdData.setTag(tag)
+ private fun addTag(tag : ExifTag?, ifdId : Int) : ExifTag? =
+ when {
+ tag == null -> null
+ ! ExifTag.isValidIfd(ifdId) -> null
+ else -> getOrCreateIfdData(ifdId).setTag(tag)
}
- return null
- }
/**
* Returns the [IfdData] object corresponding to a given IFD or
* generates one if none exist.
*/
private fun getOrCreateIfdData(ifdId : Int) : IfdData {
- var ifdData : IfdData? = mIfdDatas[ifdId]
+ var ifdData = mIfdDatas[ifdId]
if(ifdData == null) {
ifdData = IfdData(ifdId)
mIfdDatas[ifdId] = ifdData
@@ -211,9 +187,9 @@ internal open class ExifData( val byteOrder : ByteOrder ) {
/**
* Removes the thumbnail and its related tags. IFD1 will be removed.
*/
- protected fun removeThumbnailData() {
+ fun removeThumbnailData() {
clearThumbnailAndStrips()
- mIfdDatas[IfdId.TYPE_IFD_1] = null
+ mIfdDatas[IfdData.TYPE_IFD_1] = null
}
fun clearThumbnailAndStrips() {
@@ -233,17 +209,8 @@ internal open class ExifData( val byteOrder : ByteOrder ) {
* Returns a list of all [ExifTag]s in a given IFD or null if there
* are none.
*/
- fun getAllTagsForIfd(ifd : Int) : List? {
- val d = mIfdDatas[ifd] ?: return null
- val tags = d.allTags
- val ret = ArrayList(tags.size)
- for(t in tags) {
- ret.add(t)
- }
- return if(ret.size == 0) {
- null
- } else ret
- }
+ fun getAllTagsForIfd(ifd : Int) : List? =
+ mIfdDatas[ifd]?.allTagsCollection?.notEmpty()?.toList()
// Returns a list of all [ExifTag]s with a given TID
// or null if there are none.
@@ -280,7 +247,7 @@ internal open class ExifData( val byteOrder : ByteOrder ) {
}
}
- for(i in 0 until IfdId.TYPE_IFD_COUNT) {
+ for(i in 0 until IfdData.TYPE_IFD_COUNT) {
val ifd1 = other.getIfdData(i)
val ifd2 = getIfdData(i)
if(ifd1 != ifd2) return false
@@ -294,10 +261,9 @@ internal open class ExifData( val byteOrder : ByteOrder ) {
* Returns the [IfdData] object corresponding to a given IFD if it
* exists or null.
*/
- fun getIfdData(ifdId : Int) : IfdData? {
- return if(ExifTag.isValidIfd(ifdId)) {
- mIfdDatas[ifdId]
- } else null
+ fun getIfdData(ifdId : Int) = when {
+ ! ExifTag.isValidIfd(ifdId) -> null
+ else -> mIfdDatas[ifdId]
}
fun setImageSize(imageWidth : Int, imageLength : Int) {
@@ -307,7 +273,7 @@ internal open class ExifData( val byteOrder : ByteOrder ) {
override fun hashCode() : Int {
var result = byteOrder.hashCode()
- result = 31 * result + (sections?.hashCode() ?: 0)
+ result = 31 * result + (sections.hashCode())
result = 31 * result + mIfdDatas.contentHashCode()
result = 31 * result + (compressedThumbnail?.contentHashCode() ?: 0)
result = 31 * result + mStripBytes.hashCode()
@@ -330,5 +296,8 @@ internal open class ExifData( val byteOrder : ByteOrder ) {
private val USER_COMMENT_UNICODE =
byteArrayOf(0x55, 0x4E, 0x49, 0x43, 0x4F, 0x44, 0x45, 0x00)
+
+ private val eucJp = Charset.forName("EUC-JP")
+
}
}
diff --git a/exif/src/main/java/it/sephiroth/android/library/exif2/ExifInterface.kt b/exif/src/main/java/it/sephiroth/android/library/exif2/ExifInterface.kt
index 435e031d..3e73fe06 100644
--- a/exif/src/main/java/it/sephiroth/android/library/exif2/ExifInterface.kt
+++ b/exif/src/main/java/it/sephiroth/android/library/exif2/ExifInterface.kt
@@ -49,7 +49,7 @@ import kotlin.math.ln
@Suppress("unused", "unused")
class ExifInterface {
- private var mData = ExifData(DEFAULT_BYTE_ORDER)
+ private var mData = ExifData()
private val mGPSTimeStampCalendar = Calendar.getInstance(TimeZone.getTimeZone("UTC"))
@@ -58,7 +58,7 @@ class ExifInterface {
*
* @return a List of [ExifTag]s.
*/
- val allTags : List?
+ val allTags : List
get() = mData.allTags
val tagInfo : SparseIntArray by lazy { SparseIntArray().also { it.initTagInfo() } }
@@ -69,16 +69,19 @@ class ExifInterface {
* @return the thumbnail as a bitmap.
*/
val thumbnailBitmap : Bitmap?
- get() = when {
- mData.hasCompressedThumbnail() -> {
- val thumb = mData.compressedThumbnail
- BitmapFactory.decodeByteArray(thumb, 0, thumb !!.size)
+ get() {
+ val compressedThumbnail = mData.compressedThumbnail
+ if(compressedThumbnail != null) {
+ return BitmapFactory
+ .decodeByteArray(compressedThumbnail, 0, compressedThumbnail.size)
+ }
+ val stripList = mData.stripList
+ if(stripList != null) {
+ // TODO: decoding uncompressed thumbnail is not implemented.
+ return null
}
- // TODO: implement uncompressed
- mData.hasUncompressedStrip() -> null
-
- else -> null
+ return null
}
/**
@@ -270,18 +273,8 @@ class ExifInterface {
* @see .readExif
*/
@Throws(IOException::class)
- fun readExif(inFileName : String?, options : Int) {
- requireNotNull(inFileName) { NULL_ARGUMENT_STRING }
- var `is` : InputStream? = null
- try {
- `is` = BufferedInputStream(FileInputStream(inFileName))
- readExif(`is`, options)
- } catch(e : IOException) {
- closeSilently(`is`)
- throw e
- }
-
- `is`.close()
+ fun readExif(inFileName : String, options : Int) {
+ BufferedInputStream(FileInputStream(inFileName)).use { readExif(it, options) }
}
/**
@@ -301,11 +294,7 @@ class ExifInterface {
*/
@Throws(IOException::class)
fun readExif(inStream : InputStream, options : Int) {
- try {
- mData = ExifReader(this).read(inStream, options)
- } catch(e : ExifInvalidFormatException) {
- throw IOException("Invalid exif format : $e")
- }
+ mData = ExifReader(this).read(inStream, options)
}
/**
@@ -323,7 +312,7 @@ class ExifInterface {
* Clears this ExifInterface object's existing exif tags.
*/
private fun clearExif() {
- mData = ExifData(DEFAULT_BYTE_ORDER)
+ mData = ExifData()
}
/**
@@ -333,8 +322,7 @@ class ExifInterface {
* @param tags a Collection of ExifTags.
* @see .setTag
*/
- private fun setTags(tags : Collection?) {
- if(null == tags) return
+ private fun setTags(tags : Collection) {
for(t in tags) {
setTag(t)
}
@@ -399,19 +387,17 @@ class ExifInterface {
// exif tags are not used here
// 3. rename dst file into backup file
- val input = FileInputStream(srcFilename)
- val output = FileOutputStream(dstFilename)
-
- val position = writeExif_internal(input, output, mData)
-
- // 7. write the rest of the image..
- val in_channel = input.channel
- val out_channel = output.channel
- in_channel.transferTo(position.toLong(), in_channel.size() - position, out_channel)
- output.flush()
-
- closeQuietly(input)
- closeQuietly(output)
+ FileInputStream(srcFilename).use { input ->
+ FileOutputStream(dstFilename).use { output ->
+ val position = writeExif_internal(input, output, mData)
+
+ // 7. write the rest of the image..
+ val in_channel = input.channel
+ val out_channel = output.channel
+ in_channel.transferTo(position.toLong(), in_channel.size() - position, out_channel)
+ output.flush()
+ }
+ }
}
@Throws(IOException::class)
@@ -435,7 +421,7 @@ class ExifInterface {
fun writeExif(input : Bitmap, dstFilename : String, quality : Int) {
Log.i(TAG, "writeExif: $dstFilename")
- // inpur is used *ONLY* to read the image uncompressed data
+ // input is used *ONLY* to read the image uncompressed data
// exif tags are not used here
val out = ByteArrayOutputStream()
@@ -547,162 +533,54 @@ class ExifInterface {
return t?.getValue()
}
- /**
- * @see .getTagValue
- */
- private fun getTagStringValue(tagId : Int, ifdId : Int) : String? {
- val t = getTag(tagId, ifdId) ?: return null
- return t.valueAsString
- }
+ private fun getTagStringValue(
+ tagId : Int,
+ ifdId : Int = getDefinedTagDefaultIfd(tagId)
+ ) : String? =
+ getTag(tagId, ifdId)?.valueAsString
- /**
- * @see .getTagValue
- */
- private fun getTagStringValue(tagId : Int) : String? {
- val ifdId = getDefinedTagDefaultIfd(tagId)
- return getTagStringValue(tagId, ifdId)
- }
+ // array
- /**
- * @see .getTagValue
- */
- fun getTagLongValue(tagId : Int) : Long? {
- val ifdId = getDefinedTagDefaultIfd(tagId)
- return getTagLongValue(tagId, ifdId)
- }
+ private fun getTagLongValues(
+ tagId : Int,
+ ifdId : Int = getDefinedTagDefaultIfd(tagId)
+ ) : LongArray? =
+ getTag(tagId, ifdId)?.valueAsLongs
- /**
- * @see .getTagValue
- */
- private fun getTagLongValue(tagId : Int, ifdId : Int) : Long? {
- val l = getTagLongValues(tagId, ifdId)
- return if(l == null || l.isEmpty()) {
- null
- } else l[0]
- }
+ private fun getTagIntValues(
+ tagId : Int,
+ ifdId : Int = getDefinedTagDefaultIfd(tagId)
+ ) : IntArray? =
+ getTag(tagId, ifdId)?.valueAsInts
- /**
- * @see .getTagValue
- */
- private fun getTagLongValues(tagId : Int, ifdId : Int) : LongArray? {
- val t = getTag(tagId, ifdId) ?: return null
- return t.valueAsLongs
- }
+ private fun getTagByteValues(
+ tagId : Int,
+ ifdId : Int = getDefinedTagDefaultIfd(tagId)
+ ) : ByteArray? =
+ getTag(tagId, ifdId)?.valueAsBytes
- /**
- * @see .getTagValue
- */
- fun getTagIntValue(tagId : Int) : Int? {
- val ifdId = getDefinedTagDefaultIfd(tagId)
- return getTagIntValue(tagId, ifdId)
- }
+ private fun getTagRationalValues(
+ tagId : Int,
+ ifdId : Int = getDefinedTagDefaultIfd(tagId)
+ ) : Array? =
+ getTag(tagId, ifdId)?.valueAsRationals
- /**
- * @see .getTagValue
- */
- private fun getTagIntValue(tagId : Int, ifdId : Int) : Int? {
- val l = getTagIntValues(tagId, ifdId)
- return if(l == null || l.isEmpty()) {
- null
- } else l[0]
- }
+ // single value
- /**
- * @see .getTagValue
- */
- private fun getTagIntValues(tagId : Int, ifdId : Int) : IntArray? {
- val t = getTag(tagId, ifdId) ?: return null
- return t.valueAsInts
- }
+ fun getTagLongValue(tagId : Int, ifdId : Int = getDefinedTagDefaultIfd(tagId)) : Long? =
+ getTagLongValues(tagId, ifdId)?.firstOrNull()
- /**
- * @see .getTagValue
- */
- private fun getTagByteValue(tagId : Int) : Byte? {
- val ifdId = getDefinedTagDefaultIfd(tagId)
- return getTagByteValue(tagId, ifdId)
- }
+ fun getTagIntValue(tagId : Int, ifdId : Int = getDefinedTagDefaultIfd(tagId)) : Int? =
+ getTagIntValues(tagId, ifdId)?.firstOrNull()
- /**
- * @see .getTagValue
- */
- private fun getTagByteValue(tagId : Int, ifdId : Int) : Byte? {
- val l = getTagByteValues(tagId, ifdId)
- return if(l == null || l.isEmpty()) {
- null
- } else l[0]
- }
+ private fun getTagByteValue(tagId : Int, ifdId : Int = getDefinedTagDefaultIfd(tagId)) : Byte? =
+ getTagByteValues(tagId, ifdId)?.firstOrNull()
- /**
- * @see .getTagValue
- */
- private fun getTagByteValues(tagId : Int, ifdId : Int) : ByteArray? {
- val t = getTag(tagId, ifdId) ?: return null
- return t.valueAsBytes
- }
-
- /**
- * @see .getTagValue
- */
- private fun getTagRationalValue(tagId : Int) : Rational? {
- val ifdId = getDefinedTagDefaultIfd(tagId)
- return getTagRationalValue(tagId, ifdId)
- }
-
- /**
- * @see .getTagValue
- */
- private fun getTagRationalValue(tagId : Int, ifdId : Int) : Rational? {
- val l = getTagRationalValues(tagId, ifdId)
- return if(l == null || l.isEmpty()) {
- null
- } else Rational(l[0])
- }
-
- /*
- * Getter methods that are similar to getTagValue. Null is returned if the
- * tag value cannot be cast into the return type.
- */
-
- /**
- * @see .getTagValue
- */
- private fun getTagRationalValues(tagId : Int, ifdId : Int) : Array? {
- val t = getTag(tagId, ifdId) ?: return null
- return t.valueAsRationals
- }
-
- /**
- * @see .getTagValue
- */
- fun getTagLongValues(tagId : Int) : LongArray? {
- val ifdId = getDefinedTagDefaultIfd(tagId)
- return getTagLongValues(tagId, ifdId)
- }
-
- /**
- * @see .getTagValue
- */
- fun getTagIntValues(tagId : Int) : IntArray? {
- val ifdId = getDefinedTagDefaultIfd(tagId)
- return getTagIntValues(tagId, ifdId)
- }
-
- /**
- * @see .getTagValue
- */
- fun getTagByteValues(tagId : Int) : ByteArray? {
- val ifdId = getDefinedTagDefaultIfd(tagId)
- return getTagByteValues(tagId, ifdId)
- }
-
- /**
- * @see .getTagValue
- */
- private fun getTagRationalValues(tagId : Int) : Array? {
- val ifdId = getDefinedTagDefaultIfd(tagId)
- return getTagRationalValues(tagId, ifdId)
- }
+ private fun getTagRationalValue(
+ tagId : Int,
+ ifdId : Int = getDefinedTagDefaultIfd(tagId)
+ ) : Rational? =
+ getTagRationalValues(tagId, ifdId)?.firstOrNull()
/**
* Checks whether a tag has a defined number of elements.
@@ -881,7 +759,7 @@ class ExifInterface {
}
private fun getTagDefinitionsForTagId(tagId : Short) : IntArray? {
- val ifds = IfdId.list
+ val ifds = IfdData.list
val defs = IntArray(ifds.size)
var counter = 0
val infos = tagInfo
@@ -942,12 +820,12 @@ class ExifInterface {
tagInfo.delete(tagId)
}
-// /**
-// * Resets tag definitions to the default ones.
-// */
-// fun resetTagDefinitions() {
-// mTagInfo = null
-// }
+ // /**
+ // * Resets tag definitions to the default ones.
+ // */
+ // fun resetTagDefinitions() {
+ // mTagInfo = null
+ // }
/**
* Check if thumbnail exists.
@@ -1642,9 +1520,10 @@ class ExifInterface {
*/
// IFD 0
- private val TAG_IMAGE_WIDTH = defineTag(IfdId.TYPE_IFD_0, 0x0100.toShort())
- private val TAG_IMAGE_LENGTH = defineTag(IfdId.TYPE_IFD_0, 0x0101.toShort()) // Image height
- private val TAG_BITS_PER_SAMPLE = defineTag(IfdId.TYPE_IFD_0, 0x0102.toShort())
+ private val TAG_IMAGE_WIDTH = defineTag(IfdData.TYPE_IFD_0, 0x0100.toShort())
+ private val TAG_IMAGE_LENGTH =
+ defineTag(IfdData.TYPE_IFD_0, 0x0101.toShort()) // Image height
+ private val TAG_BITS_PER_SAMPLE = defineTag(IfdData.TYPE_IFD_0, 0x0102.toShort())
/**
* Value is unsigned int.
@@ -1655,24 +1534,24 @@ class ExifInterface {
* * 6 = JPEG compression (thumbnails only)
* * Other = reserved
*/
- private val TAG_COMPRESSION = defineTag(IfdId.TYPE_IFD_0, 0x0103.toShort())
- private val TAG_PHOTOMETRIC_INTERPRETATION = defineTag(IfdId.TYPE_IFD_0, 0x0106.toShort())
- private val TAG_IMAGE_DESCRIPTION = defineTag(IfdId.TYPE_IFD_0, 0x010E.toShort())
+ private val TAG_COMPRESSION = defineTag(IfdData.TYPE_IFD_0, 0x0103.toShort())
+ private val TAG_PHOTOMETRIC_INTERPRETATION = defineTag(IfdData.TYPE_IFD_0, 0x0106.toShort())
+ private val TAG_IMAGE_DESCRIPTION = defineTag(IfdData.TYPE_IFD_0, 0x010E.toShort())
/**
* Value is ascii string
* The manufacturer of the recording equipment. This is the manufacturer of the DSC, scanner, video digitizer or other equipment
* that generated the image. When the field is left blank, it is treated as unknown.
*/
- private val TAG_MAKE = defineTag(IfdId.TYPE_IFD_0, 0x010F.toShort())
+ private val TAG_MAKE = defineTag(IfdData.TYPE_IFD_0, 0x010F.toShort())
/**
* Value is ascii string
* The model name or model number of the equipment. This is the model name of number of the DSC, scanner, video digitizer or
* other equipment that generated the image. When the field is left blank, it is treated as unknown.
*/
- private val TAG_MODEL = defineTag(IfdId.TYPE_IFD_0, 0x0110.toShort())
- val TAG_STRIP_OFFSETS = defineTag(IfdId.TYPE_IFD_0, 0x0111.toShort())
+ private val TAG_MODEL = defineTag(IfdData.TYPE_IFD_0, 0x0110.toShort())
+ val TAG_STRIP_OFFSETS = defineTag(IfdData.TYPE_IFD_0, 0x0111.toShort())
/**
* Value is int
@@ -1690,25 +1569,26 @@ class ExifInterface {
* * '9' undefined
*
*/
- val TAG_ORIENTATION = defineTag(IfdId.TYPE_IFD_0, 0x0112.toShort())
- private val TAG_SAMPLES_PER_PIXEL = defineTag(IfdId.TYPE_IFD_0, 0x0115.toShort())
- private val TAG_ROWS_PER_STRIP = defineTag(IfdId.TYPE_IFD_0, 0x0116.toShort())
- val TAG_STRIP_BYTE_COUNTS = defineTag(IfdId.TYPE_IFD_0, 0x0117.toShort())
+ val TAG_ORIENTATION = defineTag(IfdData.TYPE_IFD_0, 0x0112.toShort())
+ private val TAG_SAMPLES_PER_PIXEL = defineTag(IfdData.TYPE_IFD_0, 0x0115.toShort())
+ private val TAG_ROWS_PER_STRIP = defineTag(IfdData.TYPE_IFD_0, 0x0116.toShort())
+ val TAG_STRIP_BYTE_COUNTS = defineTag(IfdData.TYPE_IFD_0, 0x0117.toShort())
- private val TAG_INTEROP_VERSION = defineTag(IfdId.TYPE_IFD_INTEROPERABILITY, 0x0002.toShort())
+ private val TAG_INTEROP_VERSION =
+ defineTag(IfdData.TYPE_IFD_INTEROPERABILITY, 0x0002.toShort())
/**
* Value is unsigned double.
* Display/Print resolution of image. Large number of digicam uses 1/72inch, but it has no mean because personal computer doesn't
* use this value to display/print out.
*/
- private val TAG_X_RESOLUTION = defineTag(IfdId.TYPE_IFD_0, 0x011A.toShort())
+ private val TAG_X_RESOLUTION = defineTag(IfdData.TYPE_IFD_0, 0x011A.toShort())
/**
* @see .TAG_X_RESOLUTION
*/
- private val TAG_Y_RESOLUTION = defineTag(IfdId.TYPE_IFD_0, 0x011B.toShort())
- private val TAG_PLANAR_CONFIGURATION = defineTag(IfdId.TYPE_IFD_0, 0x011C.toShort())
+ private val TAG_Y_RESOLUTION = defineTag(IfdData.TYPE_IFD_0, 0x011B.toShort())
+ private val TAG_PLANAR_CONFIGURATION = defineTag(IfdData.TYPE_IFD_0, 0x011C.toShort())
/**
* Value is unsigned int.
@@ -1721,21 +1601,21 @@ class ExifInterface {
* * '5' micrometer
*
*/
- private val TAG_RESOLUTION_UNIT = defineTag(IfdId.TYPE_IFD_0, 0x0128.toShort())
- private val TAG_TRANSFER_FUNCTION = defineTag(IfdId.TYPE_IFD_0, 0x012D.toShort())
+ private val TAG_RESOLUTION_UNIT = defineTag(IfdData.TYPE_IFD_0, 0x0128.toShort())
+ private val TAG_TRANSFER_FUNCTION = defineTag(IfdData.TYPE_IFD_0, 0x012D.toShort())
/**
* Value is ascii string
* Shows firmware(internal software of digicam) version number.
*/
- private val TAG_SOFTWARE = defineTag(IfdId.TYPE_IFD_0, 0x0131.toShort())
+ private val TAG_SOFTWARE = defineTag(IfdData.TYPE_IFD_0, 0x0131.toShort())
/**
* Value is ascii string (20)
* Date/Time of image was last modified. Data format is "YYYY:MM:DD HH:MM:SS"+0x00, total 20bytes. In usual, it has the same
* value of DateTimeOriginal(0x9003)
*/
- val TAG_DATE_TIME = defineTag(IfdId.TYPE_IFD_0, 0x0132.toShort())
+ val TAG_DATE_TIME = defineTag(IfdData.TYPE_IFD_0, 0x0132.toShort())
/**
* Vallue is ascii String
@@ -1743,31 +1623,31 @@ class ExifInterface {
* recommended that the information be written as in the example below for ease of Interoperability. When the field is left
* blank, it is treated as unknown.
*/
- private val TAG_ARTIST = defineTag(IfdId.TYPE_IFD_0, 0x013B.toShort())
- private val TAG_WHITE_POINT = defineTag(IfdId.TYPE_IFD_0, 0x013E.toShort())
- private val TAG_PRIMARY_CHROMATICITIES = defineTag(IfdId.TYPE_IFD_0, 0x013F.toShort())
- private val TAG_Y_CB_CR_COEFFICIENTS = defineTag(IfdId.TYPE_IFD_0, 0x0211.toShort())
- private val TAG_Y_CB_CR_SUB_SAMPLING = defineTag(IfdId.TYPE_IFD_0, 0x0212.toShort())
- private val TAG_Y_CB_CR_POSITIONING = defineTag(IfdId.TYPE_IFD_0, 0x0213.toShort())
- private val TAG_REFERENCE_BLACK_WHITE = defineTag(IfdId.TYPE_IFD_0, 0x0214.toShort())
+ private val TAG_ARTIST = defineTag(IfdData.TYPE_IFD_0, 0x013B.toShort())
+ private val TAG_WHITE_POINT = defineTag(IfdData.TYPE_IFD_0, 0x013E.toShort())
+ private val TAG_PRIMARY_CHROMATICITIES = defineTag(IfdData.TYPE_IFD_0, 0x013F.toShort())
+ private val TAG_Y_CB_CR_COEFFICIENTS = defineTag(IfdData.TYPE_IFD_0, 0x0211.toShort())
+ private val TAG_Y_CB_CR_SUB_SAMPLING = defineTag(IfdData.TYPE_IFD_0, 0x0212.toShort())
+ private val TAG_Y_CB_CR_POSITIONING = defineTag(IfdData.TYPE_IFD_0, 0x0213.toShort())
+ private val TAG_REFERENCE_BLACK_WHITE = defineTag(IfdData.TYPE_IFD_0, 0x0214.toShort())
/**
* Values is ascii string
* Shows copyright information
*/
- private val TAG_COPYRIGHT = defineTag(IfdId.TYPE_IFD_0, 0x8298.toShort())
- val TAG_EXIF_IFD = defineTag(IfdId.TYPE_IFD_0, 0x8769.toShort())
- val TAG_GPS_IFD = defineTag(IfdId.TYPE_IFD_0, 0x8825.toShort())
+ private val TAG_COPYRIGHT = defineTag(IfdData.TYPE_IFD_0, 0x8298.toShort())
+ val TAG_EXIF_IFD = defineTag(IfdData.TYPE_IFD_0, 0x8769.toShort())
+ val TAG_GPS_IFD = defineTag(IfdData.TYPE_IFD_0, 0x8825.toShort())
// IFD 1
- val TAG_JPEG_INTERCHANGE_FORMAT = defineTag(IfdId.TYPE_IFD_1, 0x0201.toShort())
- val TAG_JPEG_INTERCHANGE_FORMAT_LENGTH = defineTag(IfdId.TYPE_IFD_1, 0x0202.toShort())
+ val TAG_JPEG_INTERCHANGE_FORMAT = defineTag(IfdData.TYPE_IFD_1, 0x0201.toShort())
+ val TAG_JPEG_INTERCHANGE_FORMAT_LENGTH = defineTag(IfdData.TYPE_IFD_1, 0x0202.toShort())
// IFD Exif Tags
/**
* Value is unsigned double
* Exposure time (reciprocal of shutter speed). Unit is second
*/
- private val TAG_EXPOSURE_TIME = defineTag(IfdId.TYPE_IFD_EXIF, 0x829A.toShort())
+ private val TAG_EXPOSURE_TIME = defineTag(IfdData.TYPE_IFD_EXIF, 0x829A.toShort())
/**
* Value is unsigned double
@@ -1775,7 +1655,7 @@ class ExifInterface {
*
* @see .TAG_APERTURE_VALUE
*/
- val TAG_F_NUMBER = defineTag(IfdId.TYPE_IFD_EXIF, 0x829D.toShort())
+ val TAG_F_NUMBER = defineTag(IfdData.TYPE_IFD_EXIF, 0x829D.toShort())
/**
* Value is unsigned int.
@@ -1791,44 +1671,46 @@ class ExifInterface {
* * '8' landscape mode.
*
*/
- private val TAG_EXPOSURE_PROGRAM = defineTag(IfdId.TYPE_IFD_EXIF, 0x8822.toShort())
- private val TAG_SPECTRAL_SENSITIVITY = defineTag(IfdId.TYPE_IFD_EXIF, 0x8824.toShort())
+ private val TAG_EXPOSURE_PROGRAM = defineTag(IfdData.TYPE_IFD_EXIF, 0x8822.toShort())
+ private val TAG_SPECTRAL_SENSITIVITY = defineTag(IfdData.TYPE_IFD_EXIF, 0x8824.toShort())
/**
* Value is unsigned int.
* CCD sensitivity equivalent to Ag-Hr film speedrate.
* Indicates the ISO Speed and ISO Latitude of the camera or input device as specified in ISO 12232
*/
- private val TAG_ISO_SPEED_RATINGS = defineTag(IfdId.TYPE_IFD_EXIF, 0x8827.toShort())
- private val TAG_OECF = defineTag(IfdId.TYPE_IFD_EXIF, 0x8828.toShort())
+ private val TAG_ISO_SPEED_RATINGS = defineTag(IfdData.TYPE_IFD_EXIF, 0x8827.toShort())
+ private val TAG_OECF = defineTag(IfdData.TYPE_IFD_EXIF, 0x8828.toShort())
/**
* ASCII string (4).
* The version of this standard supported. Nonexistence of this field is taken to mean nonconformance to the standard (see
* section 4.2). Conformance to this standard is indicated by recording "0220" as 4-byte ASCII
*/
- private val TAG_EXIF_VERSION = defineTag(IfdId.TYPE_IFD_EXIF, 0x9000.toShort())
+ private val TAG_EXIF_VERSION = defineTag(IfdData.TYPE_IFD_EXIF, 0x9000.toShort())
/**
* Value is ascii string (20)
* Date/Time of original image taken. This value should not be modified by user program.
*/
- val TAG_DATE_TIME_ORIGINAL = defineTag(IfdId.TYPE_IFD_EXIF, 0x9003.toShort())
+ val TAG_DATE_TIME_ORIGINAL = defineTag(IfdData.TYPE_IFD_EXIF, 0x9003.toShort())
/**
* Value is ascii string (20)
* Date/Time of image digitized. Usually, it contains the same value of DateTimeOriginal(0x9003).
*/
- val TAG_DATE_TIME_DIGITIZED = defineTag(IfdId.TYPE_IFD_EXIF, 0x9004.toShort())
- private val TAG_COMPONENTS_CONFIGURATION = defineTag(IfdId.TYPE_IFD_EXIF, 0x9101.toShort())
- private val TAG_COMPRESSED_BITS_PER_PIXEL = defineTag(IfdId.TYPE_IFD_EXIF, 0x9102.toShort())
+ val TAG_DATE_TIME_DIGITIZED = defineTag(IfdData.TYPE_IFD_EXIF, 0x9004.toShort())
+ private val TAG_COMPONENTS_CONFIGURATION =
+ defineTag(IfdData.TYPE_IFD_EXIF, 0x9101.toShort())
+ private val TAG_COMPRESSED_BITS_PER_PIXEL =
+ defineTag(IfdData.TYPE_IFD_EXIF, 0x9102.toShort())
/**
* Value is signed double.
* Shutter speed. To convert this value to ordinary 'Shutter Speed'; calculate this value's power of 2, then reciprocal. For
* example, if value is '4', shutter speed is 1/(2^4)=1/16 second.
*/
- private val TAG_SHUTTER_SPEED_VALUE = defineTag(IfdId.TYPE_IFD_EXIF, 0x9201.toShort())
+ private val TAG_SHUTTER_SPEED_VALUE = defineTag(IfdData.TYPE_IFD_EXIF, 0x9201.toShort())
/**
* Value is unsigned double
@@ -1843,19 +1725,19 @@ class ExifInterface {
*
* @see .TAG_F_NUMBER
*/
- val TAG_APERTURE_VALUE = defineTag(IfdId.TYPE_IFD_EXIF, 0x9202.toShort())
+ val TAG_APERTURE_VALUE = defineTag(IfdData.TYPE_IFD_EXIF, 0x9202.toShort())
/**
* Value is signed double
* Brightness of taken subject, unit is EV.
*/
- private val TAG_BRIGHTNESS_VALUE = defineTag(IfdId.TYPE_IFD_EXIF, 0x9203.toShort())
+ private val TAG_BRIGHTNESS_VALUE = defineTag(IfdData.TYPE_IFD_EXIF, 0x9203.toShort())
/**
* Value is signed double.
* The exposure bias. The unit is the APEX value. Ordinarily it is given in the range of -99.99 to 99.99
*/
- private val TAG_EXPOSURE_BIAS_VALUE = defineTag(IfdId.TYPE_IFD_EXIF, 0x9204.toShort())
+ private val TAG_EXPOSURE_BIAS_VALUE = defineTag(IfdData.TYPE_IFD_EXIF, 0x9204.toShort())
/**
* Value is unsigned double.
@@ -1867,13 +1749,13 @@ class ExifInterface {
* FNumber = Math.exp( MaxApertureValue * Math.log( 2 ) * 0.5 )
*
*/
- private val TAG_MAX_APERTURE_VALUE = defineTag(IfdId.TYPE_IFD_EXIF, 0x9205.toShort())
+ private val TAG_MAX_APERTURE_VALUE = defineTag(IfdData.TYPE_IFD_EXIF, 0x9205.toShort())
/**
* Value if signed double.
* Distance to focus point, unit is meter. If value < 0 then focus point is infinite
*/
- private val TAG_SUBJECT_DISTANCE = defineTag(IfdId.TYPE_IFD_EXIF, 0x9206.toShort())
+ private val TAG_SUBJECT_DISTANCE = defineTag(IfdData.TYPE_IFD_EXIF, 0x9206.toShort())
/**
* Value is unsigned int.
@@ -1890,7 +1772,7 @@ class ExifInterface {
* * 255 = other
*
*/
- private val TAG_METERING_MODE = defineTag(IfdId.TYPE_IFD_EXIF, 0x9207.toShort())
+ private val TAG_METERING_MODE = defineTag(IfdData.TYPE_IFD_EXIF, 0x9207.toShort())
/**
* Value is unsigned int.
@@ -1920,7 +1802,7 @@ class ExifInterface {
* * Other = reserved
*
*/
- private val TAG_LIGHT_SOURCE = defineTag(IfdId.TYPE_IFD_EXIF, 0x9208.toShort())
+ private val TAG_LIGHT_SOURCE = defineTag(IfdData.TYPE_IFD_EXIF, 0x9208.toShort())
/**
* Value is unsigned integer
@@ -1964,20 +1846,20 @@ class ExifInterface {
*
* @see [http://www.exif.org/Exif2-2.PDF](http://www.exif.org/Exif2-2.PDF)
*/
- private val TAG_FLASH = defineTag(IfdId.TYPE_IFD_EXIF, 0x9209.toShort())
+ private val TAG_FLASH = defineTag(IfdData.TYPE_IFD_EXIF, 0x9209.toShort())
/**
* Value is unsigned double
* Focal length of lens used to take image. Unit is millimeter.
*/
- private val TAG_FOCAL_LENGTH = defineTag(IfdId.TYPE_IFD_EXIF, 0x920A.toShort())
- private val TAG_SUBJECT_AREA = defineTag(IfdId.TYPE_IFD_EXIF, 0x9214.toShort())
- private val TAG_MAKER_NOTE = defineTag(IfdId.TYPE_IFD_EXIF, 0x927C.toShort())
- val TAG_USER_COMMENT = defineTag(IfdId.TYPE_IFD_EXIF, 0x9286.toShort())
- private val TAG_SUB_SEC_TIME = defineTag(IfdId.TYPE_IFD_EXIF, 0x9290.toShort())
- private val TAG_SUB_SEC_TIME_ORIGINAL = defineTag(IfdId.TYPE_IFD_EXIF, 0x9291.toShort())
- private val TAG_SUB_SEC_TIME_DIGITIZED = defineTag(IfdId.TYPE_IFD_EXIF, 0x9292.toShort())
- private val TAG_FLASHPIX_VERSION = defineTag(IfdId.TYPE_IFD_EXIF, 0xA000.toShort())
+ private val TAG_FOCAL_LENGTH = defineTag(IfdData.TYPE_IFD_EXIF, 0x920A.toShort())
+ private val TAG_SUBJECT_AREA = defineTag(IfdData.TYPE_IFD_EXIF, 0x9214.toShort())
+ private val TAG_MAKER_NOTE = defineTag(IfdData.TYPE_IFD_EXIF, 0x927C.toShort())
+ val TAG_USER_COMMENT = defineTag(IfdData.TYPE_IFD_EXIF, 0x9286.toShort())
+ private val TAG_SUB_SEC_TIME = defineTag(IfdData.TYPE_IFD_EXIF, 0x9290.toShort())
+ private val TAG_SUB_SEC_TIME_ORIGINAL = defineTag(IfdData.TYPE_IFD_EXIF, 0x9291.toShort())
+ private val TAG_SUB_SEC_TIME_DIGITIZED = defineTag(IfdData.TYPE_IFD_EXIF, 0x9292.toShort())
+ private val TAG_FLASHPIX_VERSION = defineTag(IfdData.TYPE_IFD_EXIF, 0xA000.toShort())
/**
* Value is int.
@@ -1990,7 +1872,7 @@ class ExifInterface {
* * 'other' = Reserved
*
*/
- private val TAG_COLOR_SPACE = defineTag(IfdId.TYPE_IFD_EXIF, 0xA001.toShort())
+ private val TAG_COLOR_SPACE = defineTag(IfdData.TYPE_IFD_EXIF, 0xA001.toShort())
/**
* Value is unsigned int.
@@ -1998,16 +1880,17 @@ class ExifInterface {
* the meaningful image shall be recorded in this tag, whether or not there is padding data or a restart marker. This tag should
* not exist in an uncompressed file.
*/
- private val TAG_PIXEL_X_DIMENSION = defineTag(IfdId.TYPE_IFD_EXIF, 0xA002.toShort())
+ private val TAG_PIXEL_X_DIMENSION = defineTag(IfdData.TYPE_IFD_EXIF, 0xA002.toShort())
/**
* @see .TAG_PIXEL_X_DIMENSION
*/
- private val TAG_PIXEL_Y_DIMENSION = defineTag(IfdId.TYPE_IFD_EXIF, 0xA003.toShort())
- private val TAG_RELATED_SOUND_FILE = defineTag(IfdId.TYPE_IFD_EXIF, 0xA004.toShort())
- val TAG_INTEROPERABILITY_IFD = defineTag(IfdId.TYPE_IFD_EXIF, 0xA005.toShort())
- private val TAG_FLASH_ENERGY = defineTag(IfdId.TYPE_IFD_EXIF, 0xA20B.toShort())
- private val TAG_SPATIAL_FREQUENCY_RESPONSE = defineTag(IfdId.TYPE_IFD_EXIF, 0xA20C.toShort())
+ private val TAG_PIXEL_Y_DIMENSION = defineTag(IfdData.TYPE_IFD_EXIF, 0xA003.toShort())
+ private val TAG_RELATED_SOUND_FILE = defineTag(IfdData.TYPE_IFD_EXIF, 0xA004.toShort())
+ val TAG_INTEROPERABILITY_IFD = defineTag(IfdData.TYPE_IFD_EXIF, 0xA005.toShort())
+ private val TAG_FLASH_ENERGY = defineTag(IfdData.TYPE_IFD_EXIF, 0xA20B.toShort())
+ private val TAG_SPATIAL_FREQUENCY_RESPONSE =
+ defineTag(IfdData.TYPE_IFD_EXIF, 0xA20C.toShort())
/**
* Value is unsigned double.
@@ -2016,12 +1899,14 @@ class ExifInterface {
*
* @see .TAG_FOCAL_PLANE_RESOLUTION_UNIT
*/
- private val TAG_FOCAL_PLANE_X_RESOLUTION = defineTag(IfdId.TYPE_IFD_EXIF, 0xA20E.toShort())
+ private val TAG_FOCAL_PLANE_X_RESOLUTION =
+ defineTag(IfdData.TYPE_IFD_EXIF, 0xA20E.toShort())
/**
* @see .TAG_FOCAL_PLANE_X_RESOLUTION
*/
- private val TAG_FOCAL_PLANE_Y_RESOLUTION = defineTag(IfdId.TYPE_IFD_EXIF, 0xA20F.toShort())
+ private val TAG_FOCAL_PLANE_Y_RESOLUTION =
+ defineTag(IfdData.TYPE_IFD_EXIF, 0xA20F.toShort())
/**
* Value is unsigned int.
@@ -2042,9 +1927,10 @@ class ExifInterface {
* CCDWidth = ( PixelXDimension * FocalPlaneResolutionUnit / FocalPlaneXResolution )
*
*/
- private val TAG_FOCAL_PLANE_RESOLUTION_UNIT = defineTag(IfdId.TYPE_IFD_EXIF, 0xA210.toShort())
- private val TAG_SUBJECT_LOCATION = defineTag(IfdId.TYPE_IFD_EXIF, 0xA214.toShort())
- private val TAG_EXPOSURE_INDEX = defineTag(IfdId.TYPE_IFD_EXIF, 0xA215.toShort())
+ private val TAG_FOCAL_PLANE_RESOLUTION_UNIT =
+ defineTag(IfdData.TYPE_IFD_EXIF, 0xA210.toShort())
+ private val TAG_SUBJECT_LOCATION = defineTag(IfdData.TYPE_IFD_EXIF, 0xA214.toShort())
+ private val TAG_EXPOSURE_INDEX = defineTag(IfdData.TYPE_IFD_EXIF, 0xA215.toShort())
/**
* Value is unsigned int.
@@ -2060,11 +1946,11 @@ class ExifInterface {
* * Other = reserved
*
*/
- private val TAG_SENSING_METHOD = defineTag(IfdId.TYPE_IFD_EXIF, 0xA217.toShort())
- private val TAG_FILE_SOURCE = defineTag(IfdId.TYPE_IFD_EXIF, 0xA300.toShort())
- private val TAG_SCENE_TYPE = defineTag(IfdId.TYPE_IFD_EXIF, 0xA301.toShort())
- private val TAG_CFA_PATTERN = defineTag(IfdId.TYPE_IFD_EXIF, 0xA302.toShort())
- private val TAG_CUSTOM_RENDERED = defineTag(IfdId.TYPE_IFD_EXIF, 0xA401.toShort())
+ private val TAG_SENSING_METHOD = defineTag(IfdData.TYPE_IFD_EXIF, 0xA217.toShort())
+ private val TAG_FILE_SOURCE = defineTag(IfdData.TYPE_IFD_EXIF, 0xA300.toShort())
+ private val TAG_SCENE_TYPE = defineTag(IfdData.TYPE_IFD_EXIF, 0xA301.toShort())
+ private val TAG_CFA_PATTERN = defineTag(IfdData.TYPE_IFD_EXIF, 0xA302.toShort())
+ private val TAG_CUSTOM_RENDERED = defineTag(IfdData.TYPE_IFD_EXIF, 0xA401.toShort())
/**
* Value is int.
@@ -2077,15 +1963,15 @@ class ExifInterface {
* * Other = reserved
*
*/
- private val TAG_EXPOSURE_MODE = defineTag(IfdId.TYPE_IFD_EXIF, 0xA402.toShort())
- private val TAG_WHITE_BALANCE = defineTag(IfdId.TYPE_IFD_EXIF, 0xA403.toShort())
+ private val TAG_EXPOSURE_MODE = defineTag(IfdData.TYPE_IFD_EXIF, 0xA402.toShort())
+ private val TAG_WHITE_BALANCE = defineTag(IfdData.TYPE_IFD_EXIF, 0xA403.toShort())
/**
* Value is double.
* This tag indicates the digital zoom ratio when the image was shot. If the numerator of the recorded value is 0, this indicates
* that digital zoom was not used
*/
- private val TAG_DIGITAL_ZOOM_RATIO = defineTag(IfdId.TYPE_IFD_EXIF, 0xA404.toShort())
+ private val TAG_DIGITAL_ZOOM_RATIO = defineTag(IfdData.TYPE_IFD_EXIF, 0xA404.toShort())
/**
* Value is unsigned int.
@@ -2098,7 +1984,8 @@ class ExifInterface {
* FocalLengthIn35mmFilm = ( FocalLength / CCDWidth * 36 + 0.5 );
*
*/
- private val TAG_FOCAL_LENGTH_IN_35_MM_FILE = defineTag(IfdId.TYPE_IFD_EXIF, 0xA405.toShort())
+ private val TAG_FOCAL_LENGTH_IN_35_MM_FILE =
+ defineTag(IfdData.TYPE_IFD_EXIF, 0xA405.toShort())
/**
* Value is int.
@@ -2112,7 +1999,7 @@ class ExifInterface {
* * Other = reserved
*
*/
- private val TAG_SCENE_CAPTURE_TYPE = defineTag(IfdId.TYPE_IFD_EXIF, 0xA406.toShort())
+ private val TAG_SCENE_CAPTURE_TYPE = defineTag(IfdData.TYPE_IFD_EXIF, 0xA406.toShort())
/**
* Value is int.
@@ -2126,7 +2013,7 @@ class ExifInterface {
* * Other = reserved
*
*/
- private val TAG_GAIN_CONTROL = defineTag(IfdId.TYPE_IFD_EXIF, 0xA407.toShort())
+ private val TAG_GAIN_CONTROL = defineTag(IfdData.TYPE_IFD_EXIF, 0xA407.toShort())
/**
* Value is int.
@@ -2138,7 +2025,7 @@ class ExifInterface {
* * Other = reserved
*
*/
- private val TAG_CONTRAST = defineTag(IfdId.TYPE_IFD_EXIF, 0xA408.toShort())
+ private val TAG_CONTRAST = defineTag(IfdData.TYPE_IFD_EXIF, 0xA408.toShort())
/**
* Value is int.
@@ -2150,7 +2037,7 @@ class ExifInterface {
* * Other = reserved
*
*/
- private val TAG_SATURATION = defineTag(IfdId.TYPE_IFD_EXIF, 0xA409.toShort())
+ private val TAG_SATURATION = defineTag(IfdData.TYPE_IFD_EXIF, 0xA409.toShort())
/**
* Value is int.
@@ -2162,8 +2049,9 @@ class ExifInterface {
* * Other = reserved
*
*/
- private val TAG_SHARPNESS = defineTag(IfdId.TYPE_IFD_EXIF, 0xA40A.toShort())
- private val TAG_DEVICE_SETTING_DESCRIPTION = defineTag(IfdId.TYPE_IFD_EXIF, 0xA40B.toShort())
+ private val TAG_SHARPNESS = defineTag(IfdData.TYPE_IFD_EXIF, 0xA40A.toShort())
+ private val TAG_DEVICE_SETTING_DESCRIPTION =
+ defineTag(IfdData.TYPE_IFD_EXIF, 0xA40B.toShort())
/**
* Value is int.
@@ -2176,12 +2064,12 @@ class ExifInterface {
* * Other = reserved
*
*/
- private val TAG_SUBJECT_DISTANCE_RANGE = defineTag(IfdId.TYPE_IFD_EXIF, 0xA40C.toShort())
+ private val TAG_SUBJECT_DISTANCE_RANGE = defineTag(IfdData.TYPE_IFD_EXIF, 0xA40C.toShort())
/**
* [ExifTag.TYPE_ASCII]
*/
- private val TAG_IMAGE_UNIQUE_ID = defineTag(IfdId.TYPE_IFD_EXIF, 0xA420.toShort())
+ private val TAG_IMAGE_UNIQUE_ID = defineTag(IfdData.TYPE_IFD_EXIF, 0xA420.toShort())
/**
* Lens Specifications. The value it's a 4 rational containing:
@@ -2198,7 +2086,7 @@ class ExifInterface {
* @see it.sephiroth.android.library.exif2.ExifUtil.processLensSpecifications
* @since EXIF 2.3
*/
- val TAG_LENS_SPECS = defineTag(IfdId.TYPE_IFD_EXIF, 0xA432.toShort())
+ val TAG_LENS_SPECS = defineTag(IfdData.TYPE_IFD_EXIF, 0xA432.toShort())
/**
* Lens maker
@@ -2206,14 +2094,14 @@ class ExifInterface {
*
* @since EXIF 2.3
*/
- private val TAG_LENS_MAKE = defineTag(IfdId.TYPE_IFD_EXIF, 0xA433.toShort())
+ private val TAG_LENS_MAKE = defineTag(IfdData.TYPE_IFD_EXIF, 0xA433.toShort())
/**
* Lens model name and number
* [ExifTag.TYPE_ASCII]
*
* @since EXIF 2.3
*/
- val TAG_LENS_MODEL = defineTag(IfdId.TYPE_IFD_EXIF, 0xA434.toShort())
+ val TAG_LENS_MODEL = defineTag(IfdData.TYPE_IFD_EXIF, 0xA434.toShort())
/**
* The SensitivityType tag indicates which one of the parameters of ISO12232 is the
@@ -2241,16 +2129,16 @@ class ExifInterface {
*
* @since EXIF 2.3
*/
- private val TAG_SENSITIVITY_TYPE = defineTag(IfdId.TYPE_IFD_EXIF, 0x8830.toShort())
+ private val TAG_SENSITIVITY_TYPE = defineTag(IfdData.TYPE_IFD_EXIF, 0x8830.toShort())
// IFD GPS tags
- private val TAG_GPS_VERSION_ID = defineTag(IfdId.TYPE_IFD_GPS, 0.toShort())
+ private val TAG_GPS_VERSION_ID = defineTag(IfdData.TYPE_IFD_GPS, 0.toShort())
/**
* Value is string(1)
* Indicates whether the latitude is north or south latitude. The ASCII value 'N' indicates north latitude, and 'S' is south latitude.
*/
- val TAG_GPS_LATITUDE_REF = defineTag(IfdId.TYPE_IFD_GPS, 1.toShort())
+ val TAG_GPS_LATITUDE_REF = defineTag(IfdData.TYPE_IFD_GPS, 1.toShort())
/**
* Value is string.
@@ -2259,13 +2147,13 @@ class ExifInterface {
* dd/1,mm/1,ss/1. When degrees and minutes are used and, for example, fractions of minutes are given up to two
* decimal places, the format would be dd/1,mmmm/100,0/1.
*/
- val TAG_GPS_LATITUDE = defineTag(IfdId.TYPE_IFD_GPS, 2.toShort())
+ val TAG_GPS_LATITUDE = defineTag(IfdData.TYPE_IFD_GPS, 2.toShort())
/**
* Value is string(1)
* Indicates whether the longitude is east or west longitude. ASCII 'E' indicates east longitude, and 'W' is west longitude.
*/
- val TAG_GPS_LONGITUDE_REF = defineTag(IfdId.TYPE_IFD_GPS, 3.toShort())
+ val TAG_GPS_LONGITUDE_REF = defineTag(IfdData.TYPE_IFD_GPS, 3.toShort())
/**
* Value is string.
@@ -2274,7 +2162,7 @@ class ExifInterface {
* ddd/1,mm/1,ss/1. When degrees and minutes are used and, for example, fractions of minutes are given up to two
* decimal places, the format would be ddd/1,mmmm/100,0/1.
*/
- val TAG_GPS_LONGITUDE = defineTag(IfdId.TYPE_IFD_GPS, 4.toShort())
+ val TAG_GPS_LONGITUDE = defineTag(IfdData.TYPE_IFD_GPS, 4.toShort())
/**
* Value is byte
@@ -2282,49 +2170,50 @@ class ExifInterface {
* 0 is given. If the altitude is below sea level, a value of 1 is given and the altitude is indicated as an absolute value in
* the GPSAltitude tag. The reference unit is meters. Note that this tag is BYTE type, unlike other reference tags
*/
- val TAG_GPS_ALTITUDE_REF = defineTag(IfdId.TYPE_IFD_GPS, 5.toShort())
+ val TAG_GPS_ALTITUDE_REF = defineTag(IfdData.TYPE_IFD_GPS, 5.toShort())
/**
* Value is string.
* Indicates the altitude based on the reference in GPSAltitudeRef. Altitude is expressed as one RATIONAL value. The reference unit is meters.
*/
- val TAG_GPS_ALTITUDE = defineTag(IfdId.TYPE_IFD_GPS, 6.toShort())
- val TAG_GPS_TIME_STAMP = defineTag(IfdId.TYPE_IFD_GPS, 7.toShort())
- private val TAG_GPS_SATTELLITES = defineTag(IfdId.TYPE_IFD_GPS, 8.toShort())
- private val TAG_GPS_STATUS = defineTag(IfdId.TYPE_IFD_GPS, 9.toShort())
- private val TAG_GPS_MEASURE_MODE = defineTag(IfdId.TYPE_IFD_GPS, 10.toShort())
- private val TAG_GPS_DOP = defineTag(IfdId.TYPE_IFD_GPS, 11.toShort())
+ val TAG_GPS_ALTITUDE = defineTag(IfdData.TYPE_IFD_GPS, 6.toShort())
+ val TAG_GPS_TIME_STAMP = defineTag(IfdData.TYPE_IFD_GPS, 7.toShort())
+ private val TAG_GPS_SATTELLITES = defineTag(IfdData.TYPE_IFD_GPS, 8.toShort())
+ private val TAG_GPS_STATUS = defineTag(IfdData.TYPE_IFD_GPS, 9.toShort())
+ private val TAG_GPS_MEASURE_MODE = defineTag(IfdData.TYPE_IFD_GPS, 10.toShort())
+ private val TAG_GPS_DOP = defineTag(IfdData.TYPE_IFD_GPS, 11.toShort())
/**
* Value is string(1).
* Indicates the unit used to express the GPS receiver speed of movement. 'K' 'M' and 'N' represents kilometers per hour, miles per hour, and knots.
*/
- private val TAG_GPS_SPEED_REF = defineTag(IfdId.TYPE_IFD_GPS, 12.toShort())
+ private val TAG_GPS_SPEED_REF = defineTag(IfdData.TYPE_IFD_GPS, 12.toShort())
/**
* Value is string.
* Indicates the speed of GPS receiver movement
*/
- private val TAG_GPS_SPEED = defineTag(IfdId.TYPE_IFD_GPS, 13.toShort())
- private val TAG_GPS_TRACK_REF = defineTag(IfdId.TYPE_IFD_GPS, 14.toShort())
- private val TAG_GPS_TRACK = defineTag(IfdId.TYPE_IFD_GPS, 15.toShort())
- private val TAG_GPS_IMG_DIRECTION_REF = defineTag(IfdId.TYPE_IFD_GPS, 16.toShort())
- private val TAG_GPS_IMG_DIRECTION = defineTag(IfdId.TYPE_IFD_GPS, 17.toShort())
- private val TAG_GPS_MAP_DATUM = defineTag(IfdId.TYPE_IFD_GPS, 18.toShort())
- private val TAG_GPS_DEST_LATITUDE_REF = defineTag(IfdId.TYPE_IFD_GPS, 19.toShort())
- private val TAG_GPS_DEST_LATITUDE = defineTag(IfdId.TYPE_IFD_GPS, 20.toShort())
- val TAG_GPS_DEST_LONGITUDE_REF = defineTag(IfdId.TYPE_IFD_GPS, 21.toShort())
- val TAG_GPS_DEST_LONGITUDE = defineTag(IfdId.TYPE_IFD_GPS, 22.toShort())
- private val TAG_GPS_DEST_BEARING_REF = defineTag(IfdId.TYPE_IFD_GPS, 23.toShort())
- private val TAG_GPS_DEST_BEARING = defineTag(IfdId.TYPE_IFD_GPS, 24.toShort())
- private val TAG_GPS_DEST_DISTANCE_REF = defineTag(IfdId.TYPE_IFD_GPS, 25.toShort())
- private val TAG_GPS_DEST_DISTANCE = defineTag(IfdId.TYPE_IFD_GPS, 26.toShort())
- private val TAG_GPS_PROCESSING_METHOD = defineTag(IfdId.TYPE_IFD_GPS, 27.toShort())
- private val TAG_GPS_AREA_INFORMATION = defineTag(IfdId.TYPE_IFD_GPS, 28.toShort())
- val TAG_GPS_DATE_STAMP = defineTag(IfdId.TYPE_IFD_GPS, 29.toShort())
- private val TAG_GPS_DIFFERENTIAL = defineTag(IfdId.TYPE_IFD_GPS, 30.toShort())
+ private val TAG_GPS_SPEED = defineTag(IfdData.TYPE_IFD_GPS, 13.toShort())
+ private val TAG_GPS_TRACK_REF = defineTag(IfdData.TYPE_IFD_GPS, 14.toShort())
+ private val TAG_GPS_TRACK = defineTag(IfdData.TYPE_IFD_GPS, 15.toShort())
+ private val TAG_GPS_IMG_DIRECTION_REF = defineTag(IfdData.TYPE_IFD_GPS, 16.toShort())
+ private val TAG_GPS_IMG_DIRECTION = defineTag(IfdData.TYPE_IFD_GPS, 17.toShort())
+ private val TAG_GPS_MAP_DATUM = defineTag(IfdData.TYPE_IFD_GPS, 18.toShort())
+ private val TAG_GPS_DEST_LATITUDE_REF = defineTag(IfdData.TYPE_IFD_GPS, 19.toShort())
+ private val TAG_GPS_DEST_LATITUDE = defineTag(IfdData.TYPE_IFD_GPS, 20.toShort())
+ val TAG_GPS_DEST_LONGITUDE_REF = defineTag(IfdData.TYPE_IFD_GPS, 21.toShort())
+ val TAG_GPS_DEST_LONGITUDE = defineTag(IfdData.TYPE_IFD_GPS, 22.toShort())
+ private val TAG_GPS_DEST_BEARING_REF = defineTag(IfdData.TYPE_IFD_GPS, 23.toShort())
+ private val TAG_GPS_DEST_BEARING = defineTag(IfdData.TYPE_IFD_GPS, 24.toShort())
+ private val TAG_GPS_DEST_DISTANCE_REF = defineTag(IfdData.TYPE_IFD_GPS, 25.toShort())
+ private val TAG_GPS_DEST_DISTANCE = defineTag(IfdData.TYPE_IFD_GPS, 26.toShort())
+ private val TAG_GPS_PROCESSING_METHOD = defineTag(IfdData.TYPE_IFD_GPS, 27.toShort())
+ private val TAG_GPS_AREA_INFORMATION = defineTag(IfdData.TYPE_IFD_GPS, 28.toShort())
+ val TAG_GPS_DATE_STAMP = defineTag(IfdData.TYPE_IFD_GPS, 29.toShort())
+ private val TAG_GPS_DIFFERENTIAL = defineTag(IfdData.TYPE_IFD_GPS, 30.toShort())
// IFD Interoperability tags
- private val TAG_INTEROPERABILITY_INDEX = defineTag(IfdId.TYPE_IFD_INTEROPERABILITY, 1.toShort())
+ private val TAG_INTEROPERABILITY_INDEX =
+ defineTag(IfdData.TYPE_IFD_INTEROPERABILITY, 1.toShort())
val DEFAULT_BYTE_ORDER : ByteOrder = ByteOrder.BIG_ENDIAN
private const val NULL_ARGUMENT_STRING = "Argument is null"
@@ -2438,9 +2327,9 @@ class ExifInterface {
fun getAllowedIfdsFromInfo(info : Int) : IntArray? {
val ifdFlags = getAllowedIfdFlagsFromInfo(info)
- val ifds = IfdId.list
+ val ifds = IfdData.list
val l = ArrayList()
- for(i in 0 until IfdId.TYPE_IFD_COUNT) {
+ for(i in 0 until IfdData.TYPE_IFD_COUNT) {
val flag = ifdFlags shr i and 1
if(flag == 1) {
l.add(ifds[i])
@@ -2457,27 +2346,6 @@ class ExifInterface {
return ret
}
- fun closeSilently(c : Closeable?) {
- if(c != null) {
- try {
- c.close()
- } catch(e : Throwable) {
- // ignored
- }
-
- }
- }
-
- fun closeQuietly(input : InputStream) {
- @Suppress("DEPRECATION")
- IOUtils.closeQuietly(input)
- }
-
- fun closeQuietly(output : OutputStream) {
- @Suppress("DEPRECATION")
- IOUtils.closeQuietly(output)
- }
-
@Throws(IOException::class)
private fun writeExif_internal(
input : InputStream,
@@ -2495,26 +2363,24 @@ class ExifInterface {
output.write(0xFF)
output.write(JpegHeader.TAG_SOI)
- val sections = src_exif.mData.sections !!
+ val sections = src_exif.mData.sections
// 6. write all the sections from the srcFilename
- if(sections[0].type != JpegHeader.TAG_M_JFIF) {
+ if(sections.firstOrNull()?.type != JpegHeader.TAG_M_JFIF) {
Log.w(TAG, "first section is not a JFIF or EXIF tag")
output.write(JpegHeader.JFIF_HEADER)
}
// 6.1 write the *new* EXIF tag
- val eo = ExifOutputStream(src_exif)
- eo.exifData = exifData
+ val eo = ExifOutputStream(src_exif, exifData)
eo.writeExifData(output)
// 6.2 write all the sections except for the SOS ( start of scan )
- for(a in 0 until sections.size - 1) {
- val current = sections[a]
+ sections.forEach {
// Log.v( TAG, "writing section.. " + String.format( "0x%2X", current.type ) );
output.write(0xFF)
- output.write(current.type)
- output.write(current.data !!)
+ output.write(it.type)
+ output.write(it.data)
}
// 6.3 write the last SOS marker
@@ -2522,7 +2388,7 @@ class ExifInterface {
// Log.v( TAG, "writing last section.. " + String.format( "0x%2X", current.type ) );
output.write(0xFF)
output.write(current.type)
- output.write(current.data !!)
+ output.write(current.data)
// return the position where the input stream should be copied
return src_exif.mData.mUncompressedDataPosition
@@ -2548,8 +2414,8 @@ class ExifInterface {
return 0
}
var flags = 0
- val ifds = IfdId.list
- for(i in 0 until IfdId.TYPE_IFD_COUNT) {
+ val ifds = IfdData.list
+ for(i in 0 until IfdData.TYPE_IFD_COUNT) {
for(j in allowedIfds) {
if(ifds[i] == j) {
flags = flags or (1 shl i)
@@ -2623,7 +2489,7 @@ class ExifInterface {
}
fun isIfdAllowed(info : Int, ifd : Int) : Boolean {
- val ifds = IfdId.list
+ val ifds = IfdData.list
val ifdFlags = getAllowedIfdFlagsFromInfo(info)
for(i in ifds.indices) {
if(ifd == ifds[i] && ifdFlags shr i and 1 == 1) {
@@ -2676,7 +2542,7 @@ class ExifInterface {
*/
// IFD0 tags
- f = getFlagsFromAllowedIfds(intArrayOf(IfdId.TYPE_IFD_0, IfdId.TYPE_IFD_1)) shl 24
+ f = getFlagsFromAllowedIfds(intArrayOf(IfdData.TYPE_IFD_0, IfdData.TYPE_IFD_1)) shl 24
put(TAG_MAKE, f or (ExifTag.TYPE_ASCII shl 16))
put(TAG_IMAGE_WIDTH, f or (ExifTag.TYPE_UNSIGNED_LONG shl 16) or 1)
@@ -2710,12 +2576,12 @@ class ExifInterface {
put(TAG_GPS_IFD, f or (ExifTag.TYPE_UNSIGNED_LONG shl 16) or 1)
// IFD1 tags
- f = getFlagsFromAllowedIfds(intArrayOf(IfdId.TYPE_IFD_1)) shl 24
+ f = getFlagsFromAllowedIfds(intArrayOf(IfdData.TYPE_IFD_1)) shl 24
put(TAG_JPEG_INTERCHANGE_FORMAT, f or (ExifTag.TYPE_UNSIGNED_LONG shl 16) or 1)
put(TAG_JPEG_INTERCHANGE_FORMAT_LENGTH, f or (ExifTag.TYPE_UNSIGNED_LONG shl 16) or 1)
// Exif tags
- f = getFlagsFromAllowedIfds(intArrayOf(IfdId.TYPE_IFD_EXIF)) shl 24
+ f = getFlagsFromAllowedIfds(intArrayOf(IfdData.TYPE_IFD_EXIF)) shl 24
put(TAG_EXIF_VERSION, f or (ExifTag.TYPE_UNDEFINED shl 16) or 4)
put(TAG_FLASHPIX_VERSION, f or (ExifTag.TYPE_UNDEFINED shl 16) or 4)
put(TAG_COLOR_SPACE, f or (ExifTag.TYPE_UNSIGNED_SHORT shl 16) or 1)
@@ -2779,7 +2645,7 @@ class ExifInterface {
put(TAG_INTEROPERABILITY_IFD, f or (ExifTag.TYPE_UNSIGNED_LONG shl 16) or 1)
// GPS tag
- f = getFlagsFromAllowedIfds(intArrayOf(IfdId.TYPE_IFD_GPS)) shl 24
+ f = getFlagsFromAllowedIfds(intArrayOf(IfdData.TYPE_IFD_GPS)) shl 24
put(TAG_GPS_VERSION_ID, f or (ExifTag.TYPE_UNSIGNED_BYTE shl 16) or 4)
put(TAG_GPS_LATITUDE_REF, f or (ExifTag.TYPE_ASCII shl 16) or 2)
put(TAG_GPS_LONGITUDE_REF, f or (ExifTag.TYPE_ASCII shl 16) or 2)
@@ -2811,7 +2677,7 @@ class ExifInterface {
put(TAG_GPS_DIFFERENTIAL, f or (ExifTag.TYPE_UNSIGNED_SHORT shl 16) or 11)
// Interoperability tag
- f = getFlagsFromAllowedIfds(intArrayOf(IfdId.TYPE_IFD_INTEROPERABILITY)) shl 24
+ f = getFlagsFromAllowedIfds(intArrayOf(IfdData.TYPE_IFD_INTEROPERABILITY)) shl 24
put(TAG_INTEROPERABILITY_INDEX, f or (ExifTag.TYPE_ASCII shl 16))
put(TAG_INTEROP_VERSION, f or (ExifTag.TYPE_UNDEFINED shl 16) or 4)
}
diff --git a/exif/src/main/java/it/sephiroth/android/library/exif2/ExifOutputStream.kt b/exif/src/main/java/it/sephiroth/android/library/exif2/ExifOutputStream.kt
index 2f2e0ab5..b20299c1 100644
--- a/exif/src/main/java/it/sephiroth/android/library/exif2/ExifOutputStream.kt
+++ b/exif/src/main/java/it/sephiroth/android/library/exif2/ExifOutputStream.kt
@@ -17,25 +17,23 @@
package it.sephiroth.android.library.exif2
import android.util.Log
-
+import it.sephiroth.android.library.exif2.utils.OrderedDataOutputStream
import java.io.BufferedOutputStream
import java.io.IOException
import java.io.OutputStream
import java.nio.ByteBuffer
import java.nio.ByteOrder
-import java.util.ArrayList
+import java.util.*
@Suppress("unused")
-internal class ExifOutputStream(private val mInterface : ExifInterface) {
- /**
- * Gets the Exif header to be written into the JPEF file.
- */
- /**
- * Sets the ExifData to be written into the JPEG file. Should be called
- * before writing image data.
- */
- var exifData : ExifData? = null
-
+internal class ExifOutputStream(
+
+ private val mInterface : ExifInterface,
+
+ // the Exif header to be written into the JPEG file.
+ private val exifData : ExifData
+) {
+
private val mBuffer = ByteBuffer.allocate(4)
private fun requestByteToBuffer(
@@ -49,13 +47,9 @@ internal class ExifOutputStream(private val mInterface : ExifInterface) {
@Throws(IOException::class)
fun writeExifData(out : OutputStream) {
- if(exifData == null) {
- return
- }
-
Log.v(TAG, "Writing exif data...")
- val nullTags = stripNullValueTags(exifData !!)
+ val nullTags = stripNullValueTags(exifData)
createRequiredIfdAndTag()
val exifSize = calculateAllOffset()
// Log.i(TAG, "exifSize: " + (exifSize + 8));
@@ -64,7 +58,8 @@ internal class ExifOutputStream(private val mInterface : ExifInterface) {
}
val outputStream = BufferedOutputStream(out, STREAMBUFFER_SIZE)
- val dataOutputStream = OrderedDataOutputStream(outputStream)
+ val dataOutputStream =
+ OrderedDataOutputStream(outputStream)
dataOutputStream.setByteOrder(ByteOrder.BIG_ENDIAN)
@@ -73,12 +68,12 @@ internal class ExifOutputStream(private val mInterface : ExifInterface) {
dataOutputStream.writeShort((exifSize + 8).toShort())
dataOutputStream.writeInt(EXIF_HEADER)
dataOutputStream.writeShort(0x0000.toShort())
- if(exifData !!.byteOrder == ByteOrder.BIG_ENDIAN) {
+ if(exifData.byteOrder == ByteOrder.BIG_ENDIAN) {
dataOutputStream.writeShort(TIFF_BIG_ENDIAN)
} else {
dataOutputStream.writeShort(TIFF_LITTLE_ENDIAN)
}
- dataOutputStream.setByteOrder(exifData !!.byteOrder)
+ dataOutputStream.setByteOrder(exifData.byteOrder)
dataOutputStream.writeShort(TIFF_HEADER)
dataOutputStream.writeInt(8)
writeAllTags(dataOutputStream)
@@ -86,57 +81,55 @@ internal class ExifOutputStream(private val mInterface : ExifInterface) {
writeThumbnail(dataOutputStream)
for(t in nullTags) {
- exifData !!.addTag(t)
+ exifData.addTag(t)
}
dataOutputStream.flush()
}
- private fun stripNullValueTags(data : ExifData) : ArrayList {
- val nullTags = ArrayList()
- for(t in data.allTags !!) {
- if(t.getValue() == null && ! ExifInterface.isOffsetTag(t.tagId)) {
- data.removeTag(t.tagId, t.ifd)
- nullTags.add(t)
+ // strip tags that has null value
+ // return list of removed tags
+ private fun stripNullValueTags(data : ExifData) =
+ ArrayList()
+ .apply {
+ for(t in data.allTags) {
+ if(t.getValue() == null && ! ExifInterface.isOffsetTag(t.tagId)) {
+ data.removeTag(t.tagId, t.ifd)
+ add(t)
+ }
+ }
}
- }
- return nullTags
- }
@Throws(IOException::class)
private fun writeThumbnail(dataOutputStream : OrderedDataOutputStream) {
- if(exifData !!.hasCompressedThumbnail()) {
+ val compressedThumbnail = exifData.compressedThumbnail
+ if(compressedThumbnail != null) {
Log.d(TAG, "writing thumbnail..")
- dataOutputStream.write(exifData !!.compressedThumbnail !!)
- } else if(exifData !!.hasUncompressedStrip()) {
- Log.d(TAG, "writing uncompressed strip..")
- for(i in 0 until exifData !!.stripCount) {
- dataOutputStream.write(exifData !!.getStrip(i) !!)
+ dataOutputStream.write(compressedThumbnail)
+ } else {
+ val stripList = exifData.stripList
+ if(stripList != null) {
+ Log.d(TAG, "writing uncompressed strip..")
+ stripList.forEach {
+ dataOutputStream.write(it)
+ }
}
}
}
@Throws(IOException::class)
private fun writeAllTags(dataOutputStream : OrderedDataOutputStream) {
- writeIfd(exifData !!.getIfdData(IfdId.TYPE_IFD_0) !!, dataOutputStream)
- writeIfd(exifData !!.getIfdData(IfdId.TYPE_IFD_EXIF) !!, dataOutputStream)
- val interoperabilityIfd = exifData !!.getIfdData(IfdId.TYPE_IFD_INTEROPERABILITY)
- if(interoperabilityIfd != null) {
- writeIfd(interoperabilityIfd, dataOutputStream)
- }
- val gpsIfd = exifData !!.getIfdData(IfdId.TYPE_IFD_GPS)
- if(gpsIfd != null) {
- writeIfd(gpsIfd, dataOutputStream)
- }
- val ifd1 = exifData !!.getIfdData(IfdId.TYPE_IFD_1)
- if(ifd1 != null) {
- writeIfd(exifData !!.getIfdData(IfdId.TYPE_IFD_1) !!, dataOutputStream)
- }
+ writeIfd(exifData.getIfdData(IfdData.TYPE_IFD_0), dataOutputStream)
+ writeIfd(exifData.getIfdData(IfdData.TYPE_IFD_EXIF), dataOutputStream)
+ writeIfd(exifData.getIfdData(IfdData.TYPE_IFD_INTEROPERABILITY), dataOutputStream)
+ writeIfd(exifData.getIfdData(IfdData.TYPE_IFD_GPS), dataOutputStream)
+ writeIfd(exifData.getIfdData(IfdData.TYPE_IFD_1), dataOutputStream)
}
@Throws(IOException::class)
- private fun writeIfd(ifd : IfdData, dataOutputStream : OrderedDataOutputStream) {
- val tags = ifd.allTags
+ private fun writeIfd(ifd : IfdData?, dataOutputStream : OrderedDataOutputStream) {
+ ifd ?: return
+ val tags = ifd.allTagsCollection
dataOutputStream.writeShort(tags.size.toShort())
for(tag in tags) {
dataOutputStream.writeShort(tag.tagId)
@@ -166,8 +159,8 @@ internal class ExifOutputStream(private val mInterface : ExifInterface) {
private fun calculateOffsetOfIfd(ifd : IfdData, offsetArg : Int) : Int {
var offset = offsetArg
offset += 2 + ifd.tagCount * TAG_SIZE + 4
- val tags = ifd.allTags
- for(tag in tags) {
+
+ for(tag in ifd.allTagsCollection) {
if(tag.dataSize > 4) {
tag.offset = offset
offset += tag.dataSize
@@ -178,49 +171,53 @@ internal class ExifOutputStream(private val mInterface : ExifInterface) {
@Throws(IOException::class)
private fun createRequiredIfdAndTag() {
+
// IFD0 is required for all file
- var ifd0 = exifData !!.getIfdData(IfdId.TYPE_IFD_0)
+ var ifd0 = exifData.getIfdData(IfdData.TYPE_IFD_0)
if(ifd0 == null) {
- ifd0 = IfdData(IfdId.TYPE_IFD_0)
- exifData !!.addIfdData(ifd0)
+ ifd0 = IfdData(IfdData.TYPE_IFD_0)
+ exifData.addIfdData(ifd0)
}
+
val exifOffsetTag = mInterface.buildUninitializedTag(ExifInterface.TAG_EXIF_IFD)
?: throw IOException("No definition for crucial exif tag: " + ExifInterface.TAG_EXIF_IFD)
ifd0.setTag(exifOffsetTag)
// Exif IFD is required for all files.
- var exifIfd = exifData !!.getIfdData(IfdId.TYPE_IFD_EXIF)
+ var exifIfd = exifData.getIfdData(IfdData.TYPE_IFD_EXIF)
if(exifIfd == null) {
- exifIfd = IfdData(IfdId.TYPE_IFD_EXIF)
- exifData !!.addIfdData(exifIfd)
+ exifIfd = IfdData(IfdData.TYPE_IFD_EXIF)
+ exifData.addIfdData(exifIfd)
}
// GPS IFD
- val gpsIfd = exifData !!.getIfdData(IfdId.TYPE_IFD_GPS)
+ val gpsIfd = exifData.getIfdData(IfdData.TYPE_IFD_GPS)
if(gpsIfd != null) {
val gpsOffsetTag = mInterface.buildUninitializedTag(ExifInterface.TAG_GPS_IFD)
- ?: throw IOException("No definition for crucial exif tag: " + ExifInterface.TAG_GPS_IFD)
+ ?: throw IOException("No definition for crucial exif tag: ${ExifInterface.TAG_GPS_IFD}")
ifd0.setTag(gpsOffsetTag)
}
// Interoperability IFD
- val interIfd = exifData !!.getIfdData(IfdId.TYPE_IFD_INTEROPERABILITY)
+ val interIfd = exifData.getIfdData(IfdData.TYPE_IFD_INTEROPERABILITY)
if(interIfd != null) {
val interOffsetTag =
mInterface.buildUninitializedTag(ExifInterface.TAG_INTEROPERABILITY_IFD)
- ?: throw IOException("No definition for crucial exif tag: " + ExifInterface.TAG_INTEROPERABILITY_IFD)
+ ?: throw IOException("No definition for crucial exif tag: ${ExifInterface.TAG_INTEROPERABILITY_IFD}")
exifIfd.setTag(interOffsetTag)
}
- var ifd1 = exifData !!.getIfdData(IfdId.TYPE_IFD_1)
+ var ifd1 = exifData.getIfdData(IfdData.TYPE_IFD_1)
// thumbnail
+ val compressedThumbnail = exifData.compressedThumbnail
+ val stripList = exifData.stripList
when {
- exifData !!.hasCompressedThumbnail() -> {
-
+
+ compressedThumbnail != null -> {
if(ifd1 == null) {
- ifd1 = IfdData(IfdId.TYPE_IFD_1)
- exifData !!.addIfdData(ifd1)
+ ifd1 = IfdData(IfdData.TYPE_IFD_1)
+ exifData.addIfdData(ifd1)
}
val offsetTag =
@@ -232,34 +229,35 @@ internal class ExifOutputStream(private val mInterface : ExifInterface) {
mInterface.buildUninitializedTag(ExifInterface.TAG_JPEG_INTERCHANGE_FORMAT_LENGTH)
?: throw IOException("No definition for crucial exif tag: ${ExifInterface.TAG_JPEG_INTERCHANGE_FORMAT_LENGTH}")
- lengthTag.setValue(exifData !!.compressedThumbnail !!.size)
+ lengthTag.setValue(compressedThumbnail.size)
ifd1.setTag(lengthTag)
// Get rid of tags for uncompressed if they exist.
ifd1.removeTag(ExifInterface.getTrueTagKey(ExifInterface.TAG_STRIP_OFFSETS))
ifd1.removeTag(ExifInterface.getTrueTagKey(ExifInterface.TAG_STRIP_BYTE_COUNTS))
}
- exifData !!.hasUncompressedStrip() -> {
+
+ stripList != null -> {
if(ifd1 == null) {
- ifd1 = IfdData(IfdId.TYPE_IFD_1)
- exifData !!.addIfdData(ifd1)
+ ifd1 = IfdData(IfdData.TYPE_IFD_1)
+ exifData.addIfdData(ifd1)
}
- val stripCount = exifData !!.stripCount
val offsetTag = mInterface.buildUninitializedTag(ExifInterface.TAG_STRIP_OFFSETS)
?: throw IOException("No definition for crucial exif tag: ${ExifInterface.TAG_STRIP_OFFSETS}")
- val lengthTag = mInterface.buildUninitializedTag(ExifInterface.TAG_STRIP_BYTE_COUNTS)
- ?: throw IOException("No definition for crucial exif tag: ${ExifInterface.TAG_STRIP_BYTE_COUNTS}")
- val lengths = LongArray(stripCount)
- for(i in 0 until exifData !!.stripCount) {
- lengths[i] = exifData !!.getStrip(i) !!.size.toLong()
- }
- lengthTag.setValue(lengths)
+ val lengthTag =
+ mInterface.buildUninitializedTag(ExifInterface.TAG_STRIP_BYTE_COUNTS)
+ ?: throw IOException("No definition for crucial exif tag: ${ExifInterface.TAG_STRIP_BYTE_COUNTS}")
+
+ val bytesList = LongArray(stripList.size)
+ stripList.forEachIndexed { index, bytes -> bytesList[index] = bytes.size.toLong() }
+ lengthTag.setValue(bytesList)
ifd1.setTag(offsetTag)
ifd1.setTag(lengthTag)
// Get rid of tags for compressed if they exist.
ifd1.removeTag(ExifInterface.getTrueTagKey(ExifInterface.TAG_JPEG_INTERCHANGE_FORMAT))
ifd1.removeTag(ExifInterface.getTrueTagKey(ExifInterface.TAG_JPEG_INTERCHANGE_FORMAT_LENGTH))
}
+
ifd1 != null -> {
// Get rid of offset and length tags if there is no thumbnail.
ifd1.removeTag(ExifInterface.getTrueTagKey(ExifInterface.TAG_STRIP_OFFSETS))
@@ -272,50 +270,55 @@ internal class ExifOutputStream(private val mInterface : ExifInterface) {
private fun calculateAllOffset() : Int {
var offset = TIFF_HEADER_SIZE.toInt()
- val exifData = this.exifData !!
- val ifd0 = exifData.getIfdData(IfdId.TYPE_IFD_0)
- offset = calculateOffsetOfIfd(ifd0 !!, offset)
- ifd0.getTag(ExifInterface.getTrueTagKey(ExifInterface.TAG_EXIF_IFD))
- ?.setValue(offset)
- val exifIfd = exifData.getIfdData(IfdId.TYPE_IFD_EXIF)
- offset = calculateOffsetOfIfd(exifIfd !!, offset)
-
- val interIfd = exifData.getIfdData(IfdId.TYPE_IFD_INTEROPERABILITY)
- if(interIfd != null) {
- exifIfd.getTag(ExifInterface.getTrueTagKey(ExifInterface.TAG_INTEROPERABILITY_IFD))
- ?.setValue(offset)
- offset = calculateOffsetOfIfd(interIfd, offset)
+ val ifd0 = exifData.getIfdData(IfdData.TYPE_IFD_0)?.also {
+ offset = calculateOffsetOfIfd(it, offset)
}
- val gpsIfd = exifData.getIfdData(IfdId.TYPE_IFD_GPS)
- if(gpsIfd != null) {
- ifd0.getTag(ExifInterface.getTrueTagKey(ExifInterface.TAG_GPS_IFD))
+ val exifIfd = exifData.getIfdData(IfdData.TYPE_IFD_EXIF)?.also { it ->
+ ifd0?.getTag(ExifInterface.getTrueTagKey(ExifInterface.TAG_EXIF_IFD))
?.setValue(offset)
- offset = calculateOffsetOfIfd(gpsIfd, offset)
+ offset = calculateOffsetOfIfd(it, offset)
}
- val ifd1 = exifData.getIfdData(IfdId.TYPE_IFD_1)
- if(ifd1 != null) {
- ifd0.offsetToNextIfd = offset
- offset = calculateOffsetOfIfd(ifd1, offset)
+ exifData.getIfdData(IfdData.TYPE_IFD_INTEROPERABILITY)?.also { it ->
+ exifIfd?.getTag(ExifInterface.getTrueTagKey(ExifInterface.TAG_INTEROPERABILITY_IFD))
+ ?.setValue(offset)
+ offset = calculateOffsetOfIfd(it, offset)
}
- // thumbnail
- if(exifData .hasCompressedThumbnail()) {
- ifd1 !!.getTag(ExifInterface.getTrueTagKey(ExifInterface.TAG_JPEG_INTERCHANGE_FORMAT))
+ exifData.getIfdData(IfdData.TYPE_IFD_GPS)?.also {
+ ifd0?.getTag(ExifInterface.getTrueTagKey(ExifInterface.TAG_GPS_IFD))
?.setValue(offset)
- offset += exifData .compressedThumbnail !!.size
- } else if(exifData .hasUncompressedStrip()) {
- val stripCount = exifData .stripCount
- val offsets = LongArray(stripCount)
- for(i in 0 until exifData .stripCount) {
- offsets[i] = offset.toLong()
- offset += exifData .getStrip(i) !!.size
+ offset = calculateOffsetOfIfd(it, offset)
+ }
+
+ val ifd1 = exifData.getIfdData(IfdData.TYPE_IFD_1)?.also {
+ ifd0?.offsetToNextIfd = offset
+ offset = calculateOffsetOfIfd(it, offset)
+ }
+
+ val compressedThumbnail = exifData.compressedThumbnail
+ if(compressedThumbnail != null) {
+ ifd1
+ ?.getTag(ExifInterface.getTrueTagKey(ExifInterface.TAG_JPEG_INTERCHANGE_FORMAT))
+ ?.setValue(offset)
+ offset += compressedThumbnail.size
+ } else {
+ // uncompressed thumbnail
+ val stripList = exifData.stripList
+ if(stripList != null) {
+ val offsets = LongArray(stripList.size)
+ stripList.forEachIndexed { index, bytes ->
+ offsets[index] = offset.toLong()
+ offset += bytes.size
+ }
+ ifd1
+ ?.getTag(ExifInterface.getTrueTagKey(ExifInterface.TAG_STRIP_OFFSETS))
+ ?.setValue(offsets)
}
- ifd1 !!.getTag(ExifInterface.getTrueTagKey(ExifInterface.TAG_STRIP_OFFSETS))
- ?.setValue(offsets)
}
+
return offset
}
diff --git a/exif/src/main/java/it/sephiroth/android/library/exif2/ExifParser.kt b/exif/src/main/java/it/sephiroth/android/library/exif2/ExifParser.kt
index 8b835d01..6f4d99c1 100644
--- a/exif/src/main/java/it/sephiroth/android/library/exif2/ExifParser.kt
+++ b/exif/src/main/java/it/sephiroth/android/library/exif2/ExifParser.kt
@@ -17,6 +17,7 @@
package it.sephiroth.android.library.exif2
import android.util.Log
+import it.sephiroth.android.library.exif2.utils.CountedDataInputStream
import java.io.ByteArrayInputStream
import java.io.IOException
import java.io.InputStream
@@ -40,15 +41,15 @@ private constructor(
/**
* the ID of current IFD.
*
- * @see IfdId.TYPE_IFD_0
- * @see IfdId.TYPE_IFD_1
- * @see IfdId.TYPE_IFD_GPS
- * @see IfdId.TYPE_IFD_INTEROPERABILITY
- * @see IfdId.TYPE_IFD_EXIF
+ * @see IfdData.TYPE_IFD_0
+ * @see IfdData.TYPE_IFD_1
+ * @see IfdData.TYPE_IFD_GPS
+ * @see IfdData.TYPE_IFD_INTEROPERABILITY
+ * @see IfdData.TYPE_IFD_EXIF
*/
var currentIfd : Int = 0
private set
-
+
/**
* If [.next] return [.EVENT_NEW_TAG] or
* [.EVENT_VALUE_OF_REGISTERED_TAG], call this function to get the
@@ -154,10 +155,10 @@ private constructor(
throw ExifInvalidFormatException("Invalid offset $offset")
}
mIfd0Position = offset.toInt()
- currentIfd = IfdId.TYPE_IFD_0
+ currentIfd = IfdData.TYPE_IFD_0
- if(isIfdRequested(IfdId.TYPE_IFD_0) || needToParseOffsetsInCurrentIfd()) {
- registerIfd(IfdId.TYPE_IFD_0, offset)
+ if(isIfdRequested(IfdData.TYPE_IFD_0) || needToParseOffsetsInCurrentIfd()) {
+ registerIfd(IfdData.TYPE_IFD_0, offset)
if(offset != DEFAULT_IFD0_OFFSET.toLong()) {
val ba = ByteArray(offset.toInt() - DEFAULT_IFD0_OFFSET)
mDataAboveIfd0 = ba
@@ -182,15 +183,16 @@ private constructor(
@Throws(IOException::class, ExifInvalidFormatException::class)
private fun seekTiffData(inputStream : InputStream) : CountedDataInputStream {
- val dataStream = CountedDataInputStream(inputStream)
+ val dataStream =
+ CountedDataInputStream(inputStream)
var tiffStream : CountedDataInputStream? = null
var a = dataStream.readUnsignedByte()
val b = dataStream.readUnsignedByte()
-
+
if(a == 137 && b == 80) error("maybe PNG image")
-
+
if(a != 0xFF || b != JpegHeader.TAG_SOI) error("invalid jpeg header")
while(true) {
@@ -213,9 +215,6 @@ private constructor(
Log.w(TAG, "Extraneous ${a - 1} padding bytes before section $marker")
}
- val section = Section()
- section.type = marker
-
// Read the length of the section.
val lh = dataStream.readByte().toInt()
val ll = dataStream.readByte().toInt()
@@ -225,8 +224,6 @@ private constructor(
throw ExifInvalidFormatException("Invalid marker")
}
- section.size = itemlen
-
data = ByteArray(itemlen)
data[0] = lh.toByte()
data[1] = ll.toByte()
@@ -240,7 +237,7 @@ private constructor(
throw ExifInvalidFormatException("Premature end of file? Expecting " + (itemlen - 2) + ", received " + got)
}
- section.data = data
+ val section = Section(type = marker, size = itemlen, data = data)
var ignore = false
@@ -286,7 +283,9 @@ private constructor(
// header = Exif, headerTail=\0\0
if(header == EXIF_HEADER && headerTail == EXIF_HEADER_TAIL) {
tiffStream =
- CountedDataInputStream(ByteArrayInputStream(data, 8, itemlen - 8))
+ CountedDataInputStream(
+ ByteArrayInputStream(data, 8, itemlen - 8)
+ )
tiffStream.end = itemlen - 6
ignore = false
} else {
@@ -428,11 +427,11 @@ private constructor(
private fun isIfdRequested(ifdType : Int) : Boolean {
when(ifdType) {
- IfdId.TYPE_IFD_0 -> return mOptions and ExifInterface.Options.OPTION_IFD_0 != 0
- IfdId.TYPE_IFD_1 -> return mOptions and ExifInterface.Options.OPTION_IFD_1 != 0
- IfdId.TYPE_IFD_EXIF -> return mOptions and ExifInterface.Options.OPTION_IFD_EXIF != 0
- IfdId.TYPE_IFD_GPS -> return mOptions and ExifInterface.Options.OPTION_IFD_GPS != 0
- IfdId.TYPE_IFD_INTEROPERABILITY -> return mOptions and ExifInterface.Options.OPTION_IFD_INTEROPERABILITY != 0
+ IfdData.TYPE_IFD_0 -> return mOptions and ExifInterface.Options.OPTION_IFD_0 != 0
+ IfdData.TYPE_IFD_1 -> return mOptions and ExifInterface.Options.OPTION_IFD_1 != 0
+ IfdData.TYPE_IFD_EXIF -> return mOptions and ExifInterface.Options.OPTION_IFD_EXIF != 0
+ IfdData.TYPE_IFD_GPS -> return mOptions and ExifInterface.Options.OPTION_IFD_GPS != 0
+ IfdData.TYPE_IFD_INTEROPERABILITY -> return mOptions and ExifInterface.Options.OPTION_IFD_INTEROPERABILITY != 0
}
return false
}
@@ -440,17 +439,17 @@ private constructor(
private fun needToParseOffsetsInCurrentIfd() : Boolean {
return when(currentIfd) {
- IfdId.TYPE_IFD_0 ->
- isIfdRequested(IfdId.TYPE_IFD_EXIF) ||
- isIfdRequested(IfdId.TYPE_IFD_GPS) ||
- isIfdRequested(IfdId.TYPE_IFD_INTEROPERABILITY) ||
- isIfdRequested(IfdId.TYPE_IFD_1)
+ IfdData.TYPE_IFD_0 ->
+ isIfdRequested(IfdData.TYPE_IFD_EXIF) ||
+ isIfdRequested(IfdData.TYPE_IFD_GPS) ||
+ isIfdRequested(IfdData.TYPE_IFD_INTEROPERABILITY) ||
+ isIfdRequested(IfdData.TYPE_IFD_1)
- IfdId.TYPE_IFD_1 -> isThumbnailRequested
+ IfdData.TYPE_IFD_1 -> isThumbnailRequested
- IfdId.TYPE_IFD_EXIF ->
+ IfdData.TYPE_IFD_EXIF ->
// The offset to interoperability IFD is located in Exif IFD
- isIfdRequested(IfdId.TYPE_IFD_INTEROPERABILITY)
+ isIfdRequested(IfdData.TYPE_IFD_INTEROPERABILITY)
else -> false
}
@@ -508,11 +507,11 @@ private constructor(
return EVENT_NEW_TAG
} else if(offset == endOfTags) {
// There is a link to ifd1 at the end of ifd0
- if(currentIfd == IfdId.TYPE_IFD_0) {
+ if(currentIfd == IfdData.TYPE_IFD_0) {
val ifdOffset = readUnsignedLong()
- if(isIfdRequested(IfdId.TYPE_IFD_1) || isThumbnailRequested) {
+ if(isIfdRequested(IfdData.TYPE_IFD_1) || isThumbnailRequested) {
if(ifdOffset != 0L) {
- registerIfd(IfdId.TYPE_IFD_1, ifdOffset)
+ registerIfd(IfdData.TYPE_IFD_1, ifdOffset)
}
}
} else {
@@ -610,9 +609,9 @@ private constructor(
}
val ifdOffset = readUnsignedLong()
// For ifd0, there is a link to ifd1 in the end of all tags
- if(currentIfd == IfdId.TYPE_IFD_0 && (isIfdRequested(IfdId.TYPE_IFD_1) || isThumbnailRequested)) {
+ if(currentIfd == IfdData.TYPE_IFD_0 && (isIfdRequested(IfdData.TYPE_IFD_1) || isThumbnailRequested)) {
if(ifdOffset > 0) {
- registerIfd(IfdId.TYPE_IFD_1, ifdOffset)
+ registerIfd(IfdData.TYPE_IFD_1, ifdOffset)
}
}
}
@@ -720,19 +719,19 @@ private constructor(
val tid = tag.tagId
val ifd = tag.ifd
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))
+ if(isIfdRequested(IfdData.TYPE_IFD_EXIF) || isIfdRequested(IfdData.TYPE_IFD_INTEROPERABILITY)) {
+ registerIfd(IfdData.TYPE_IFD_EXIF, tag.getValueAt(0))
}
} else if(tid == TAG_GPS_IFD && checkAllowed(ifd, ExifInterface.TAG_GPS_IFD)) {
- if(isIfdRequested(IfdId.TYPE_IFD_GPS)) {
- registerIfd(IfdId.TYPE_IFD_GPS, tag.getValueAt(0))
+ if(isIfdRequested(IfdData.TYPE_IFD_GPS)) {
+ registerIfd(IfdData.TYPE_IFD_GPS, tag.getValueAt(0))
}
} else if(tid == TAG_INTEROPERABILITY_IFD && checkAllowed(
ifd,
ExifInterface.TAG_INTEROPERABILITY_IFD
)) {
- if(isIfdRequested(IfdId.TYPE_IFD_INTEROPERABILITY)) {
- registerIfd(IfdId.TYPE_IFD_INTEROPERABILITY, tag.getValueAt(0))
+ if(isIfdRequested(IfdData.TYPE_IFD_INTEROPERABILITY)) {
+ registerIfd(IfdData.TYPE_IFD_INTEROPERABILITY, tag.getValueAt(0))
}
} else if(tid == TAG_JPEG_INTERCHANGE_FORMAT && checkAllowed(
ifd,
@@ -750,7 +749,7 @@ private constructor(
}
} else if(tid == TAG_STRIP_OFFSETS && checkAllowed(ifd, ExifInterface.TAG_STRIP_OFFSETS)) {
if(isThumbnailRequested) {
- if(tag.hasValue()) {
+ if(tag.hasValue) {
for(i in 0 until tag.componentCount) {
if(tag.dataType == ExifTag.TYPE_UNSIGNED_SHORT) {
registerUncompressedStrip(i, tag.getValueAt(i))
@@ -765,16 +764,16 @@ private constructor(
} else if(tid == TAG_STRIP_BYTE_COUNTS && checkAllowed(
ifd,
ExifInterface.TAG_STRIP_BYTE_COUNTS
- ) && isThumbnailRequested && tag.hasValue()) {
+ ) && isThumbnailRequested && tag.hasValue) {
mStripSizeTag = tag
}
}
- fun isDefinedTag(ifdId : Int, tagId : Int) : Boolean {
+ fun isDefinedTag(ifdId : Int, tagId : Short) : Boolean {
return mInterface.tagInfo.get(
ExifInterface.defineTag(
ifdId,
- tagId.toShort()
+ tagId
)
) != ExifInterface.DEFINITION_NULL
}
@@ -946,12 +945,8 @@ private constructor(
internal var isRequested : Boolean
)
- class Section {
- internal var size : Int = 0
- internal var type : Int = 0
- internal var data : ByteArray? = null
- }
-
+ class Section(var size : Int, var type : Int, var data : ByteArray)
+
companion object {
private const val TAG = "ExifParser"
diff --git a/exif/src/main/java/it/sephiroth/android/library/exif2/ExifReader.kt b/exif/src/main/java/it/sephiroth/android/library/exif2/ExifReader.kt
index 94c59588..078dcfe0 100644
--- a/exif/src/main/java/it/sephiroth/android/library/exif2/ExifReader.kt
+++ b/exif/src/main/java/it/sephiroth/android/library/exif2/ExifReader.kt
@@ -37,12 +37,13 @@ internal class ExifReader(private val mInterface : ExifInterface) {
@Throws(ExifInvalidFormatException::class, IOException::class)
fun read(inputStream : InputStream, options : Int) : ExifData {
val parser = ExifParser.parse(inputStream, options, mInterface)
- val exifData = ExifData(parser.byteOrder )
- exifData.sections = parser.sections
- exifData.mUncompressedDataPosition = parser.uncompressedDataPosition
-
- exifData.qualityGuess = parser.qualityGuess
- exifData.jpegProcess = parser.jpegProcess
+ val exifData = ExifData(
+ byteOrder = parser.byteOrder,
+ sections = parser.sections,
+ mUncompressedDataPosition = parser.uncompressedDataPosition,
+ qualityGuess = parser.qualityGuess,
+ jpegProcess = parser.jpegProcess
+ )
val w = parser.imageWidth
val h = parser.imageLength
@@ -51,33 +52,34 @@ internal class ExifReader(private val mInterface : ExifInterface) {
exifData.setImageSize(w, h)
}
- var tag : ExifTag?
-
var event = parser.next()
while(event != ExifParser.EVENT_END) {
when(event) {
- ExifParser.EVENT_START_OF_IFD -> exifData.addIfdData(IfdData(parser.currentIfd))
+
+ ExifParser.EVENT_START_OF_IFD ->
+ exifData.addIfdData(IfdData(parser.currentIfd))
ExifParser.EVENT_NEW_TAG -> {
- tag = parser.tag
-
-
-
- if(! tag !!.hasValue()) {
- parser.registerForTagValue(tag)
- } else {
- // Log.v(TAG, "parsing id " + tag.getTagId() + " = " + tag);
- if(parser.isDefinedTag(tag.ifd, tag.tagId.toInt())) {
- exifData.getIfdData(tag.ifd) !!.setTag(tag)
- } else {
+ val tag = parser.tag
+ when {
+ tag == null ->
+ Log.w(TAG, "parser.tag is null")
+
+ ! tag.hasValue ->
+ parser.registerForTagValue(tag)
+
+ ! parser.isDefinedTag(tag.ifd, tag.tagId) ->
Log.w(TAG, "skip tag because not registered in the tag table:$tag")
- }
+
+ else ->
+ exifData.getIfdData(tag.ifd)?.setTag(tag)
}
+
}
ExifParser.EVENT_VALUE_OF_REGISTERED_TAG -> {
- tag = parser.tag
- if(tag !!.dataType == ExifTag.TYPE_UNDEFINED) {
+ val tag = parser.tag !!
+ if(tag.dataType == ExifTag.TYPE_UNDEFINED) {
parser.readFullTagValue(tag)
}
exifData.getIfdData(tag.ifd) !!.setTag(tag)
diff --git a/exif/src/main/java/it/sephiroth/android/library/exif2/ExifTag.kt b/exif/src/main/java/it/sephiroth/android/library/exif2/ExifTag.kt
index aea52276..ae31336d 100644
--- a/exif/src/main/java/it/sephiroth/android/library/exif2/ExifTag.kt
+++ b/exif/src/main/java/it/sephiroth/android/library/exif2/ExifTag.kt
@@ -52,11 +52,11 @@ open class ExifTag internal constructor(
// The ifd that this tag should be put in. the ID of the IFD this tag belongs to.
/*
- * @see IfdId.TYPE_IFD_0
- * @see IfdId.TYPE_IFD_1
- * @see IfdId.TYPE_IFD_EXIF
- * @see IfdId.TYPE_IFD_GPS
- * @see IfdId.TYPE_IFD_INTEROPERABILITY
+ * @see IfdData.TYPE_IFD_0
+ * @see IfdData.TYPE_IFD_1
+ * @see IfdData.TYPE_IFD_EXIF
+ * @see IfdData.TYPE_IFD_GPS
+ * @see IfdData.TYPE_IFD_INTEROPERABILITY
*/
var ifd : Int,
@@ -69,7 +69,7 @@ open class ExifTag internal constructor(
*/
// TODO: fix integer overflows with this
- var componentCount : Int = 0
+ var componentCount : Int = componentCount
private set
// The value (array of elements of type Tag Type)
@@ -83,7 +83,6 @@ open class ExifTag internal constructor(
val dataSize : Int
get() = componentCount * getElementSize(dataType)
-
/**
* Gets the value as a byte array. This method should be used for tags of
* type [.TYPE_UNDEFINED] or [.TYPE_UNSIGNED_BYTE].
@@ -124,9 +123,9 @@ open class ExifTag internal constructor(
*/
// Truncates
val valueAsInts : IntArray?
- get() = when(val v = mValue){
- is LongArray-> IntArray(v.size){ v[it].toInt()}
- else ->null
+ get() = when(val v = mValue) {
+ is LongArray -> IntArray(v.size) { v[it].toInt() }
+ else -> null
}
/**
@@ -143,7 +142,6 @@ open class ExifTag internal constructor(
else -> null
}
-
/**
* Gets the [.TYPE_ASCII] data.
*
@@ -159,11 +157,6 @@ open class ExifTag internal constructor(
val stringByte : ByteArray?
get() = mValue as? ByteArray
- init {
- this.componentCount = componentCount
- mValue = null
- }
-
/**
* Sets the component count of this tag. Call this function before
* setValue() if the length of value does not match the component count.
@@ -176,9 +169,8 @@ open class ExifTag internal constructor(
* Returns true if this ExifTag contains value; otherwise, this tag will
* contain an offset value that is determined when the tag is written.
*/
- fun hasValue() : Boolean {
- return mValue != null
- }
+ val hasValue :Boolean
+ get() = mValue != null
/**
* Sets integer values into this tag. This method should be used for tags of
@@ -225,9 +217,7 @@ open class ExifTag internal constructor(
* * The component count in the definition of this tag is not 1.
*
*/
- fun setValue(value : Int) : Boolean {
- return setValue(intArrayOf(value))
- }
+ fun setValue(value : Int) = setValue(intArrayOf(value))
/**
* Sets long values into this tag. This method should be used for tags of
@@ -260,9 +250,7 @@ open class ExifTag internal constructor(
* * The component count in the definition for this tag is not 1.
*
*/
- fun setValue(value : Long) : Boolean {
- return setValue(longArrayOf(value))
- }
+ fun setValue(value : Long) = setValue(longArrayOf(value))
/**
* Sets Rational values into this tag. This method should be used for tags
@@ -309,8 +297,7 @@ open class ExifTag internal constructor(
*
* @see Rational
*/
- fun setValue(value : Rational) : Boolean =
- setValue(arrayOf(value))
+ fun setValue(value : Rational) =setValue(arrayOf(value))
/**
* Sets byte values into this tag. This method should be used for tags of
@@ -332,7 +319,7 @@ open class ExifTag internal constructor(
return false
}
componentCount = length
- mValue = ByteArray(length).also{
+ mValue = ByteArray(length).also {
System.arraycopy(value, offset, it, 0, length)
}
return true
@@ -348,8 +335,7 @@ open class ExifTag internal constructor(
* * The component count in the definition for this tag is not 1.
*
*/
- fun setValue(value : Byte) : Boolean =
- setValue(byteArrayOf(value))
+ fun setValue(value : Byte) = setValue(byteArrayOf(value))
/**
* Sets the value for this tag using an appropriate setValue method for the
@@ -375,31 +361,33 @@ open class ExifTag internal constructor(
is Int -> return setValue(obj.toInt())
is Long -> return setValue(obj.toLong())
- else ->{
-
+ else -> {
+
@Suppress("UNCHECKED_CAST")
val ra = obj as? Array
- if(ra != null) return setValue( ra )
+ if(ra != null) return setValue(ra)
// Nulls in this array are treated as zeroes.
@Suppress("UNCHECKED_CAST")
val sa = obj as? Array
- if( sa != null) return setValue(IntArray(sa.size){ (sa[it]?.toInt() ?: 0) and 0xffff})
+ if(sa != null) return setValue(IntArray(sa.size) {
+ (sa[it]?.toInt() ?: 0) and 0xffff
+ })
// Nulls in this array are treated as zeroes.
@Suppress("UNCHECKED_CAST")
val ia = obj as? Array
- if( ia != null) return setValue(IntArray(ia.size){ ia[it] ?: 0 })
+ if(ia != null) return setValue(IntArray(ia.size) { ia[it] ?: 0 })
// Nulls in this array are treated as zeroes.
@Suppress("UNCHECKED_CAST")
val la = obj as? Array
- if( la != null) return setValue(LongArray(la.size){ la[it] ?: 0L })
+ if(la != null) return setValue(LongArray(la.size) { la[it] ?: 0L })
// Nulls in this array are treated as zeroes.
@Suppress("UNCHECKED_CAST")
val ba = obj as? Array
- if( ba != null) return setValue(ByteArray(ba.size){ ba[it] ?: 0 })
+ if(ba != null) return setValue(ByteArray(ba.size) { ba[it] ?: 0 })
return false
}
@@ -487,7 +475,7 @@ open class ExifTag internal constructor(
*/
fun getValueAsByte(defaultValue : Byte) : Byte {
val array = valueAsBytes
- return if(array?.isNotEmpty()==true) array[0] else defaultValue
+ return if(array?.isNotEmpty() == true) array[0] else defaultValue
}
/**
@@ -501,7 +489,7 @@ open class ExifTag internal constructor(
* @return the tag's value as a Rational, or the defaultValue.
*/
fun getValueAsRational(defaultValue : Long) : Rational =
- getValueAsRational( Rational(defaultValue, 1))
+ getValueAsRational(Rational(defaultValue, 1))
/**
* Gets the value as a Rational. If there are more than 1 Rationals in this
@@ -514,7 +502,7 @@ open class ExifTag internal constructor(
*/
private fun getValueAsRational(defaultValue : Rational) : Rational {
val array = valueAsRationals
- return if(array?.isNotEmpty()==true) array[0] else defaultValue
+ return if(array?.isNotEmpty() == true) array[0] else defaultValue
}
/**
@@ -528,7 +516,7 @@ open class ExifTag internal constructor(
*/
fun getValueAsInt(defaultValue : Int) : Int {
val array = valueAsInts
- return if(array?.isNotEmpty()==true) array[0] else defaultValue
+ return if(array?.isNotEmpty() == true) array[0] else defaultValue
}
/**
@@ -542,7 +530,7 @@ open class ExifTag internal constructor(
*/
fun getValueAsLong(defaultValue : Long) : Long {
val array = valueAsLongs
- return if(array?.isNotEmpty()==true) array[0] else defaultValue
+ return if(array?.isNotEmpty() == true) array[0] else defaultValue
}
/**
@@ -636,54 +624,24 @@ open class ExifTag internal constructor(
var hasDefinedCount : Boolean
get() = mHasDefinedDefaultComponentCount
- set(value){
+ set(value) {
mHasDefinedDefaultComponentCount = value
}
- private fun checkOverflowForUnsignedShort(value : IntArray) : Boolean {
- for(v in value) {
- if(v > UNSIGNED_SHORT_MAX || v < 0) {
- return true
- }
- }
- return false
- }
+ private fun checkOverflowForUnsignedShort(value : IntArray) : Boolean =
+ null != value.find { it !in 0 .. UNSIGNED_SHORT_MAX }
- private fun checkOverflowForUnsignedLong(value : LongArray) : Boolean {
- for(v in value) {
- if(v < 0 || v > UNSIGNED_LONG_MAX) {
- return true
- }
- }
- return false
- }
+ private fun checkOverflowForUnsignedLong(value : LongArray) : Boolean =
+ null != value.find { it !in 0 .. UNSIGNED_LONG_MAX }
- private fun checkOverflowForUnsignedLong(value : IntArray) : Boolean {
- for(v in value) {
- if(v < 0) {
- return true
- }
- }
- return false
- }
+ private fun checkOverflowForUnsignedLong(value : IntArray) : Boolean =
+ null != value.find { it < 0 }
- private fun checkOverflowForUnsignedRational(value : Array) : Boolean {
- for(v in value) {
- if(v.numerator < 0 || v.denominator < 0 || v.numerator > UNSIGNED_LONG_MAX || v.denominator > UNSIGNED_LONG_MAX) {
- return true
- }
- }
- return false
- }
+ private fun checkOverflowForUnsignedRational(value : Array) : Boolean =
+ null != value.find { it.numerator !in 0 .. UNSIGNED_LONG_MAX || it.denominator !in 0 .. UNSIGNED_LONG_MAX }
- private fun checkOverflowForRational(value : Array) : Boolean {
- for(v in value) {
- if(v.numerator < LONG_MIN || v.denominator < LONG_MIN || v.numerator > LONG_MAX || v.denominator > LONG_MAX) {
- return true
- }
- }
- return false
- }
+ private fun checkOverflowForRational(value : Array) : Boolean =
+ null != value.find { it.numerator !in LONG_MIN .. LONG_MAX || it.denominator !in LONG_MIN .. LONG_MAX }
override fun hashCode() : Int {
var result = tagId.toInt()
@@ -766,8 +724,6 @@ open class ExifTag internal constructor(
}
}
-
-
companion object {
/**
* The BYTE type in the EXIF standard. An 8-bit unsigned integer.
@@ -832,11 +788,11 @@ open class ExifTag internal constructor(
*/
fun isValidIfd(ifdId : Int) : Boolean =
when(ifdId) {
- IfdId.TYPE_IFD_0,
- IfdId.TYPE_IFD_1,
- IfdId.TYPE_IFD_EXIF,
- IfdId.TYPE_IFD_INTEROPERABILITY,
- IfdId.TYPE_IFD_GPS -> true
+ IfdData.TYPE_IFD_0,
+ IfdData.TYPE_IFD_1,
+ IfdData.TYPE_IFD_EXIF,
+ IfdData.TYPE_IFD_INTEROPERABILITY,
+ IfdData.TYPE_IFD_GPS -> true
else -> false
}
@@ -883,11 +839,4 @@ open class ExifTag internal constructor(
else -> ""
}
}
-
}
-/**
- * Equivalent to setValue(value, 0, value.length).
- */
-/**
- * Equivalent to getBytes(buffer, 0, buffer.length).
- */
diff --git a/exif/src/main/java/it/sephiroth/android/library/exif2/IfdData.kt b/exif/src/main/java/it/sephiroth/android/library/exif2/IfdData.kt
index 981137d0..4e62636a 100644
--- a/exif/src/main/java/it/sephiroth/android/library/exif2/IfdData.kt
+++ b/exif/src/main/java/it/sephiroth/android/library/exif2/IfdData.kt
@@ -18,35 +18,33 @@ package it.sephiroth.android.library.exif2
import java.util.HashMap
-
-/**
- * The constants of the IFD ID defined in EXIF spec.
- */
-object IfdId {
- const val TYPE_IFD_0 = 0
- const val TYPE_IFD_1 = 1
- const val TYPE_IFD_EXIF = 2
- const val TYPE_IFD_INTEROPERABILITY = 3
- const val TYPE_IFD_GPS = 4
- /* This is used in ExifData to allocate enough IfdData */
- const val TYPE_IFD_COUNT = 5
-
- val list = intArrayOf(
- TYPE_IFD_0,
- TYPE_IFD_1,
- TYPE_IFD_EXIF,
- TYPE_IFD_INTEROPERABILITY,
- TYPE_IFD_GPS
- )
-}
-
-
// This class stores all the tags in an IFD.
// an IfdData with given IFD ID.
internal class IfdData(
- // the ID of this IFD.
- val id : Int
+ val id : Int // the ID of this IFD.
) {
+
+ companion object {
+ /**
+ * The constants of the IFD ID defined in EXIF spec.
+ */
+ const val TYPE_IFD_0 = 0
+ const val TYPE_IFD_1 = 1
+ const val TYPE_IFD_EXIF = 2
+ const val TYPE_IFD_INTEROPERABILITY = 3
+ const val TYPE_IFD_GPS = 4
+ /* This is used in ExifData to allocate enough IfdData */
+ const val TYPE_IFD_COUNT = 5
+
+ val list = intArrayOf(
+ TYPE_IFD_0,
+ TYPE_IFD_1,
+ TYPE_IFD_EXIF,
+ TYPE_IFD_INTEROPERABILITY,
+ TYPE_IFD_GPS
+ )
+ }
+
private val mExifTags = HashMap()
// the offset of next IFD.
@@ -56,9 +54,9 @@ internal class IfdData(
val tagCount : Int
get() = mExifTags.size
- // a array the contains all [ExifTag] in this IFD.
- val allTags : Array
- get() = mExifTags.values.toTypedArray()
+ // Collection the contains all [ExifTag] in this IFD.
+ val allTagsCollection : Collection
+ get() = mExifTags.values
// checkCollision
fun contains(tagId : Short) : Boolean {
@@ -87,19 +85,12 @@ internal class IfdData(
* IFDs offset or thumbnail offset will be ignored.
*/
override fun equals(other : Any?) : Boolean {
- if(other === null) return false
- if(other === this) return true
if(other is IfdData) {
+ if(other === this) return true
if(other.id == id && other.tagCount == tagCount) {
- val tags = other.allTags
- for(tag in tags) {
- if(ExifInterface.isOffsetTag(tag.tagId)) {
- continue
- }
- val tag2 = mExifTags[tag.tagId]
- if(tag != tag2) {
- return false
- }
+ for(tag in other.allTagsCollection) {
+ if(ExifInterface.isOffsetTag(tag.tagId)) continue
+ if(tag != mExifTags[tag.tagId]) return false
}
return true
}
diff --git a/exif/src/main/java/it/sephiroth/android/library/exif2/Rational.kt b/exif/src/main/java/it/sephiroth/android/library/exif2/Rational.kt
index c9cc52e8..bdede84f 100644
--- a/exif/src/main/java/it/sephiroth/android/library/exif2/Rational.kt
+++ b/exif/src/main/java/it/sephiroth/android/library/exif2/Rational.kt
@@ -30,6 +30,7 @@ class Rational(
) {
// copy from a Rational.
+ @Suppress("unused")
constructor(r : Rational) : this(
numerator = r.numerator,
denominator = r.denominator
diff --git a/exif/src/main/java/it/sephiroth/android/library/exif2/CountedDataInputStream.kt b/exif/src/main/java/it/sephiroth/android/library/exif2/utils/CountedDataInputStream.kt
similarity index 98%
rename from exif/src/main/java/it/sephiroth/android/library/exif2/CountedDataInputStream.kt
rename to exif/src/main/java/it/sephiroth/android/library/exif2/utils/CountedDataInputStream.kt
index af9dca5f..b57801c7 100644
--- a/exif/src/main/java/it/sephiroth/android/library/exif2/CountedDataInputStream.kt
+++ b/exif/src/main/java/it/sephiroth/android/library/exif2/utils/CountedDataInputStream.kt
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package it.sephiroth.android.library.exif2
+package it.sephiroth.android.library.exif2.utils
import java.io.EOFException
import java.io.FilterInputStream
diff --git a/exif/src/main/java/it/sephiroth/android/library/exif2/OrderedDataOutputStream.kt b/exif/src/main/java/it/sephiroth/android/library/exif2/utils/OrderedDataOutputStream.kt
similarity index 94%
rename from exif/src/main/java/it/sephiroth/android/library/exif2/OrderedDataOutputStream.kt
rename to exif/src/main/java/it/sephiroth/android/library/exif2/utils/OrderedDataOutputStream.kt
index 817c9246..104502c4 100644
--- a/exif/src/main/java/it/sephiroth/android/library/exif2/OrderedDataOutputStream.kt
+++ b/exif/src/main/java/it/sephiroth/android/library/exif2/utils/OrderedDataOutputStream.kt
@@ -14,8 +14,9 @@
* limitations under the License.
*/
-package it.sephiroth.android.library.exif2
+package it.sephiroth.android.library.exif2.utils
+import it.sephiroth.android.library.exif2.Rational
import java.io.FilterOutputStream
import java.io.IOException
import java.io.OutputStream
diff --git a/exif/src/main/java/it/sephiroth/android/library/exif2/utils/Utils.kt b/exif/src/main/java/it/sephiroth/android/library/exif2/utils/Utils.kt
new file mode 100644
index 00000000..26416c9f
--- /dev/null
+++ b/exif/src/main/java/it/sephiroth/android/library/exif2/utils/Utils.kt
@@ -0,0 +1,7 @@
+package it.sephiroth.android.library.exif2.utils
+
+internal fun Collection?.notEmpty() : Collection? =
+ if(this?.isNotEmpty() == true) this else null
+
+internal fun List?.notEmpty() : List? =
+ if(this?.isNotEmpty() == true) this else null
diff --git a/exif/src/test/java/it/sephiroth/android/library/exif2/Test1.kt b/exif/src/test/java/it/sephiroth/android/library/exif2/Test1.kt
index b797b551..73bd1d29 100644
--- a/exif/src/test/java/it/sephiroth/android/library/exif2/Test1.kt
+++ b/exif/src/test/java/it/sephiroth/android/library/exif2/Test1.kt
@@ -2,8 +2,7 @@ package it.sephiroth.android.library.exif2
import android.util.Log
import android.util.SparseIntArray
-import org.junit.Assert.assertEquals
-import org.junit.Assert.assertTrue
+import org.junit.Assert.*
import org.junit.Test
import java.io.File
import java.io.FileInputStream
@@ -12,7 +11,7 @@ class Test1 {
@Test
fun testLog() {
- Log.v("TEST","test")
+ Log.v("TEST", "test")
assertTrue("using android.util.Log", true)
}
@@ -32,29 +31,48 @@ class Test1 {
}
}
- private fun getOrientation(fileName : String) : Pair =
- try{
- val o = FileInputStream(getFile(fileName)).use { inStream ->
- ExifInterface()
- .apply {
- readExif(
- inStream,
- ExifInterface.Options.OPTION_IFD_0
- or ExifInterface.Options.OPTION_IFD_1
- or ExifInterface.Options.OPTION_IFD_EXIF
- )
- }
- .getTagIntValue(ExifInterface.TAG_ORIENTATION)
+ private fun getOrientation(fileName : String) : Pair =
+ try {
+ val o = FileInputStream(getFile(fileName)).use { inStream ->
+ ExifInterface()
+ .apply {
+ readExif(
+ inStream,
+ ExifInterface.Options.OPTION_IFD_0
+ or ExifInterface.Options.OPTION_IFD_1
+ or ExifInterface.Options.OPTION_IFD_EXIF
+ )
+ }
+ .getTagIntValue(ExifInterface.TAG_ORIENTATION)
+ }
+ Pair(o, null)
+ } catch(ex : Throwable) {
+ Pair(null, ex)
+ }
+
+ private fun getThumbnailBytes(fileName : String) : Pair =
+ try {
+ val o = FileInputStream(getFile(fileName)).use { inStream ->
+ ExifInterface()
+ .apply {
+ readExif(
+ inStream,
+ ExifInterface.Options.OPTION_IFD_0
+ or ExifInterface.Options.OPTION_IFD_1
+ or ExifInterface.Options.OPTION_IFD_EXIF
+ )
+ }
+ .thumbnailBytes
+ }
+ Pair(o, null)
+ } catch(ex : Throwable) {
+ Pair(null, ex)
}
- Pair(o,null)
- }catch(ex:Throwable){
- Pair(null,ex)
- }
private fun testNotJpegSub(fileName : String) {
- val(o,ex) = getOrientation(fileName)
- assertTrue("testNotJpegSub",o ==null && ex!=null)
- if( ex!= null) println("exception raised: ${ex::class.java} ${ex.message}")
+ val (o, ex) = getOrientation(fileName)
+ assertTrue("testNotJpegSub", o == null && ex != null)
+ if(ex != null) println("exception raised: ${ex::class.java} ${ex.message}")
}
@Test
@@ -66,23 +84,32 @@ class Test1 {
@Test
fun testJpeg() {
- var fileName :String
- var rv : Pair
-
- // this file has orientation 1
- fileName = "test1.jpg"
- rv = getOrientation(fileName)
- assertEquals(fileName,1,rv.first)
-
- // this file has no orientation, it raises exception.
- fileName = "test2.jpg"
- rv = getOrientation(fileName)
- assertTrue(fileName,rv.second != null)
+ var fileName : String
+ var rvO : Pair
+ var rvT : Pair
// this file has orientation 6.
fileName = "test3.jpg"
- rv = getOrientation(fileName)
- assertEquals(fileName,rv.first , 6)
+ rvO = getOrientation(fileName)
+ assertEquals(fileName, 6, rvO.first)
+ rvT = getThumbnailBytes(fileName)
+ assertNull(fileName,rvT.first)
+
+ // this file has orientation 1
+ fileName = "test1.jpg"
+ rvO = getOrientation(fileName)
+ assertEquals(fileName, 1, rvO.first)
+ rvT = getThumbnailBytes(fileName)
+ assertNull(fileName,rvT.first)
+
+ // this file has no orientation, it raises exception.
+ fileName = "test2.jpg"
+ rvO = getOrientation(fileName)
+ assertNotNull(fileName, rvO.second) //
+
+ rvT = getThumbnailBytes(fileName)
+ assertNotNull(fileName,rvT.second) //
+
}
}
\ No newline at end of file