Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
deckerst committed Feb 7, 2024
2 parents 6f7f70b + 6c175cf commit 283a3eb
Show file tree
Hide file tree
Showing 31 changed files with 1,044 additions and 201 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,14 @@ All notable changes to this project will be documented in this file.

## <a id="unreleased"></a>[Unreleased]

## <a id="v1.10.4"></a>[v1.10.4] - 2024-02-07

### Fixed

- motion photo detection for xml variant of google container item
- HEIF size detection for some corrupted files
- viewer transition direction & effects for RTL locales

## <a id="v1.10.3"></a>[v1.10.3] - 2024-01-29

### Added
Expand Down
1 change: 1 addition & 0 deletions android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@
android:label="@string/app_name"
android:requestLegacyExternalStorage="true"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
tools:targetApi="tiramisu">
<activity
android:name=".MainActivity"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,13 @@ import com.bumptech.glide.load.resource.bitmap.TransformationUtils
import com.drew.metadata.xmp.XmpDirectory
import deckers.thibault.aves.channel.calls.Coresult.Companion.safe
import deckers.thibault.aves.channel.calls.Coresult.Companion.safeSuspend
import deckers.thibault.aves.metadata.GoogleDeviceContainer
import deckers.thibault.aves.metadata.Metadata
import deckers.thibault.aves.metadata.MultiPage
import deckers.thibault.aves.metadata.XMP
import deckers.thibault.aves.metadata.XMP.doesPropPathExist
import deckers.thibault.aves.metadata.XMP.getSafeStructField
import deckers.thibault.aves.metadata.XMPPropName
import deckers.thibault.aves.metadata.metadataextractor.Helper
import deckers.thibault.aves.metadata.xmp.GoogleDeviceContainer
import deckers.thibault.aves.metadata.xmp.GoogleXMP
import deckers.thibault.aves.metadata.xmp.XMP.getSafeStructField
import deckers.thibault.aves.metadata.xmp.XMPPropName
import deckers.thibault.aves.model.FieldMap
import deckers.thibault.aves.model.provider.ImageProvider
import deckers.thibault.aves.model.provider.ImageProviderFactory.getProvider
Expand Down Expand Up @@ -108,14 +107,7 @@ class EmbeddedDataHandler(private val context: Context) : MethodCallHandler {
// which is returned as a second XMP directory
val xmpDirs = metadata.getDirectoriesOfType(XmpDirectory::class.java)
try {
container = xmpDirs.firstNotNullOfOrNull {
val xmpMeta = it.xmpMeta
if (xmpMeta.doesPropPathExist(listOf(XMP.GDEVICE_CONTAINER_PROP_NAME, XMP.GDEVICE_CONTAINER_DIRECTORY_PROP_NAME))) {
GoogleDeviceContainer().apply { findItems(xmpMeta) }
} else {
null
}
}
container = xmpDirs.firstNotNullOfOrNull { GoogleXMP.getDeviceContainer(it.xmpMeta) }
} catch (e: XMPException) {
result.error("extractGoogleDeviceItem-xmp", "failed to read XMP directory for uri=$uri dataUri=$dataUri", e.message)
return
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,16 +50,6 @@ import deckers.thibault.aves.metadata.Mp4ParserHelper
import deckers.thibault.aves.metadata.MultiPage
import deckers.thibault.aves.metadata.PixyMetaHelper
import deckers.thibault.aves.metadata.QuickTimeMetadata
import deckers.thibault.aves.metadata.XMP
import deckers.thibault.aves.metadata.XMP.doesPropExist
import deckers.thibault.aves.metadata.XMP.getPropArrayItemValues
import deckers.thibault.aves.metadata.XMP.getSafeDateMillis
import deckers.thibault.aves.metadata.XMP.getSafeInt
import deckers.thibault.aves.metadata.XMP.getSafeLocalizedText
import deckers.thibault.aves.metadata.XMP.getSafeString
import deckers.thibault.aves.metadata.XMP.hasHdrGainMap
import deckers.thibault.aves.metadata.XMP.isMotionPhoto
import deckers.thibault.aves.metadata.XMP.isPanorama
import deckers.thibault.aves.metadata.metadataextractor.Helper
import deckers.thibault.aves.metadata.metadataextractor.Helper.PNG_ITXT_DIR_NAME
import deckers.thibault.aves.metadata.metadataextractor.Helper.PNG_LAST_MODIFICATION_TIME_FORMAT
Expand All @@ -78,6 +68,16 @@ import deckers.thibault.aves.metadata.metadataextractor.Helper.getSafeString
import deckers.thibault.aves.metadata.metadataextractor.Helper.isPngTextDir
import deckers.thibault.aves.metadata.metadataextractor.PngActlDirectory
import deckers.thibault.aves.metadata.metadataextractor.mpf.MpEntryDirectory
import deckers.thibault.aves.metadata.xmp.GoogleXMP
import deckers.thibault.aves.metadata.xmp.XMP
import deckers.thibault.aves.metadata.xmp.XMP.doesPropExist
import deckers.thibault.aves.metadata.xmp.XMP.getPropArrayItemValues
import deckers.thibault.aves.metadata.xmp.XMP.getSafeDateMillis
import deckers.thibault.aves.metadata.xmp.XMP.getSafeInt
import deckers.thibault.aves.metadata.xmp.XMP.getSafeLocalizedText
import deckers.thibault.aves.metadata.xmp.XMP.hasHdrGainMap
import deckers.thibault.aves.metadata.xmp.XMP.isMotionPhoto
import deckers.thibault.aves.metadata.xmp.XMP.isPanorama
import deckers.thibault.aves.model.FieldMap
import deckers.thibault.aves.utils.ContextUtils.queryContentPropValue
import deckers.thibault.aves.utils.LogUtils
Expand Down Expand Up @@ -1020,17 +1020,7 @@ class MetadataFetchHandler(private val context: Context) : MethodCallHandler {
fun processXmp(xmpMeta: XMPMeta, allowMultiple: Boolean = false) {
if (foundXmp && !allowMultiple) return
foundXmp = true
try {
xmpMeta.getSafeInt(XMP.GPANO_CROPPED_AREA_LEFT_PROP_NAME) { fields["croppedAreaLeft"] = it }
xmpMeta.getSafeInt(XMP.GPANO_CROPPED_AREA_TOP_PROP_NAME) { fields["croppedAreaTop"] = it }
xmpMeta.getSafeInt(XMP.GPANO_CROPPED_AREA_WIDTH_PROP_NAME) { fields["croppedAreaWidth"] = it }
xmpMeta.getSafeInt(XMP.GPANO_CROPPED_AREA_HEIGHT_PROP_NAME) { fields["croppedAreaHeight"] = it }
xmpMeta.getSafeInt(XMP.GPANO_FULL_PANO_WIDTH_PROP_NAME) { fields["fullPanoWidth"] = it }
xmpMeta.getSafeInt(XMP.GPANO_FULL_PANO_HEIGHT_PROP_NAME) { fields["fullPanoHeight"] = it }
xmpMeta.getSafeString(XMP.GPANO_PROJECTION_TYPE_PROP_NAME) { fields["projectionType"] = it }
} catch (e: XMPException) {
Log.w(LOG_TAG, "failed to read XMP directory for uri=$uri", e)
}
fields.putAll(GoogleXMP.getPanoramaInfo(xmpMeta))
}

if (canReadWithMetadataExtractor(mimeType) && !isLargeMp4(mimeType, sizeBytes)) {
Expand Down Expand Up @@ -1062,7 +1052,7 @@ class MetadataFetchHandler(private val context: Context) : MethodCallHandler {
if (fields.isEmpty()) {
result.error("getPanoramaInfo-empty", "failed to get info for mimeType=$mimeType uri=$uri", null)
} else {
fields["projectionType"] = fields["projectionType"] ?: XMP.GPANO_PROJECTION_TYPE_DEFAULT
fields["projectionType"] = fields["projectionType"] ?: GoogleXMP.GPANO_PROJECTION_TYPE_DEFAULT
result.success(fields)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package deckers.thibault.aves.metadata
import android.content.Context
import android.net.Uri
import android.util.Log
import deckers.thibault.aves.metadata.xmp.XMP
import deckers.thibault.aves.utils.LogUtils
import deckers.thibault.aves.utils.MimeTypes
import deckers.thibault.aves.utils.StorageUtils
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,11 @@ import android.util.Log
import com.adobe.internal.xmp.XMPMeta
import com.drew.imaging.jpeg.JpegSegmentType
import com.drew.metadata.xmp.XmpDirectory
import deckers.thibault.aves.metadata.XMP.countPropArrayItems
import deckers.thibault.aves.metadata.XMP.doesPropExist
import deckers.thibault.aves.metadata.XMP.getSafeLong
import deckers.thibault.aves.metadata.XMP.getSafeStructField
import deckers.thibault.aves.metadata.metadataextractor.Helper
import deckers.thibault.aves.metadata.metadataextractor.mpf.MpEntry
import deckers.thibault.aves.metadata.metadataextractor.mpf.MpEntryDirectory
import deckers.thibault.aves.metadata.xmp.GoogleXMP
import deckers.thibault.aves.metadata.xmp.XMP
import deckers.thibault.aves.model.FieldMap
import deckers.thibault.aves.utils.LogUtils
import deckers.thibault.aves.utils.MimeTypes
Expand Down Expand Up @@ -276,20 +274,7 @@ object MultiPage {
var foundXmp = false

fun processXmp(xmpMeta: XMPMeta) {
if (xmpMeta.doesPropExist(XMP.GCAMERA_VIDEO_OFFSET_PROP_NAME)) {
// `GCamera` motion photo
xmpMeta.getSafeLong(XMP.GCAMERA_VIDEO_OFFSET_PROP_NAME) { offsetFromEnd = it }
} else if (xmpMeta.doesPropExist(XMP.GCONTAINER_DIRECTORY_PROP_NAME)) {
// `Container` motion photo
val count = xmpMeta.countPropArrayItems(XMP.GCONTAINER_DIRECTORY_PROP_NAME)
for (i in 1 until count + 1) {
val mime = xmpMeta.getSafeStructField(listOf(XMP.GCONTAINER_DIRECTORY_PROP_NAME, i, XMP.GCONTAINER_ITEM_PROP_NAME, XMP.GCONTAINER_ITEM_MIME_PROP_NAME))?.value
val length = xmpMeta.getSafeStructField(listOf(XMP.GCONTAINER_DIRECTORY_PROP_NAME, i, XMP.GCONTAINER_ITEM_PROP_NAME, XMP.GCONTAINER_ITEM_LENGTH_PROP_NAME))?.value
if (MimeTypes.isVideo(mime) && length != null) {
offsetFromEnd = length.toLong()
}
}
}
offsetFromEnd = offsetFromEnd ?: GoogleXMP.getTrailingVideoOffsetFromEnd(xmpMeta)
}

try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import com.drew.imaging.mp4.Mp4Handler
import com.drew.metadata.Metadata
import com.drew.metadata.mp4.Mp4Context
import com.drew.metadata.mp4.media.Mp4UuidBoxHandler
import deckers.thibault.aves.metadata.XMP
import deckers.thibault.aves.metadata.xmp.XMP

class SafeMp4UuidBoxHandler(metadata: Metadata) : Mp4UuidBoxHandler(metadata) {
override fun processBox(type: String?, payload: ByteArray?, boxSize: Long, context: Mp4Context?): Mp4Handler<*> {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
package deckers.thibault.aves.metadata
package deckers.thibault.aves.metadata.xmp

import android.content.Context
import android.net.Uri
import com.adobe.internal.xmp.XMPMeta
import deckers.thibault.aves.metadata.XMP.countPropPathArrayItems
import deckers.thibault.aves.metadata.XMP.getSafeStructField
import deckers.thibault.aves.metadata.Metadata
import deckers.thibault.aves.metadata.xmp.XMP.countPropPathArrayItems
import deckers.thibault.aves.metadata.xmp.XMP.getSafeStructField
import deckers.thibault.aves.utils.indexOfBytes
import java.io.DataInputStream

Expand All @@ -15,12 +16,12 @@ class GoogleDeviceContainer {
private val offsets: MutableList<Int> = ArrayList()

fun findItems(xmpMeta: XMPMeta) {
val containerDirectoryPath = listOf(XMP.GDEVICE_CONTAINER_PROP_NAME, XMP.GDEVICE_CONTAINER_DIRECTORY_PROP_NAME)
val containerDirectoryPath = listOf(GoogleXMP.GDEVICE_CONTAINER_PROP_NAME, GoogleXMP.GDEVICE_CONTAINER_DIRECTORY_PROP_NAME)
val count = xmpMeta.countPropPathArrayItems(containerDirectoryPath)
for (i in 1 until count + 1) {
val mimeType = xmpMeta.getSafeStructField(containerDirectoryPath + listOf(i, XMP.GDEVICE_CONTAINER_ITEM_MIME_PROP_NAME))?.value
val length = xmpMeta.getSafeStructField(containerDirectoryPath + listOf(i, XMP.GDEVICE_CONTAINER_ITEM_LENGTH_PROP_NAME))?.value?.toLongOrNull()
val dataUri = xmpMeta.getSafeStructField(containerDirectoryPath + listOf(i, XMP.GDEVICE_CONTAINER_ITEM_DATA_URI_PROP_NAME))?.value
val mimeType = xmpMeta.getSafeStructField(containerDirectoryPath + listOf(i, GoogleXMP.GDEVICE_CONTAINER_ITEM_MIME_PROP_NAME))?.value
val length = xmpMeta.getSafeStructField(containerDirectoryPath + listOf(i, GoogleXMP.GDEVICE_CONTAINER_ITEM_LENGTH_PROP_NAME))?.value?.toLongOrNull()
val dataUri = xmpMeta.getSafeStructField(containerDirectoryPath + listOf(i, GoogleXMP.GDEVICE_CONTAINER_ITEM_DATA_URI_PROP_NAME))?.value
if (mimeType != null && length != null && dataUri != null) {
items.add(
GoogleDeviceContainerItem(
Expand Down
Loading

0 comments on commit 283a3eb

Please sign in to comment.