Skip to content

Commit

Permalink
Introduced MetadataUpdate.GpsCoordinatesAndLocationShown to one-shot …
Browse files Browse the repository at this point in the history
…update GPS & location info.
  • Loading branch information
StefanOltmann committed Jan 29, 2025
1 parent 6b20d8e commit 8676b80
Show file tree
Hide file tree
Showing 16 changed files with 123 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,8 @@ internal object JpegUpdater : MetadataUpdater {
update !is MetadataUpdate.Orientation &&
update !is MetadataUpdate.TakenDate &&
update !is MetadataUpdate.Description &&
update !is MetadataUpdate.GpsCoordinates
update !is MetadataUpdate.GpsCoordinates &&
update !is MetadataUpdate.GpsCoordinatesAndLocationShown
)
return inputBytes

Expand Down Expand Up @@ -191,6 +192,7 @@ internal object JpegUpdater : MetadataUpdater {
update !is MetadataUpdate.Title &&
update !is MetadataUpdate.Description &&
update !is MetadataUpdate.LocationShown &&
update !is MetadataUpdate.GpsCoordinatesAndLocationShown &&
update !is MetadataUpdate.Keywords
)
return inputBytes
Expand Down Expand Up @@ -246,6 +248,32 @@ internal object JpegUpdater : MetadataUpdater {
}
}

if (update is MetadataUpdate.GpsCoordinatesAndLocationShown) {

newRecords.addAll(
oldRecords.filter {
it.iptcType != IptcTypes.CITY &&
it.iptcType != IptcTypes.PROVINCE_STATE &&
it.iptcType != IptcTypes.COUNTRY_PRIMARY_LOCATION_NAME
}
)

if (update.locationShown != null) {

update.locationShown.city?.let { city ->
newRecords.add(IptcRecord(IptcTypes.CITY, city))
}

update.locationShown.state?.let { state ->
newRecords.add(IptcRecord(IptcTypes.PROVINCE_STATE, state))
}

update.locationShown.country?.let { country ->
newRecords.add(IptcRecord(IptcTypes.COUNTRY_PRIMARY_LOCATION_NAME, country))
}
}
}

if (update is MetadataUpdate.Keywords) {

newRecords.addAll(oldRecords.filter { it.iptcType != IptcTypes.KEYWORDS })
Expand Down
12 changes: 7 additions & 5 deletions src/commonMain/kotlin/com/ashampoo/kim/format/jxl/JxlUpdater.kt
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,12 @@ internal object JxlUpdater : MetadataUpdater {

val updatedXmp = XmpWriter.updateXmp(xmpMeta, update, true)

val isExifUpdate = update is MetadataUpdate.Orientation ||
update is MetadataUpdate.TakenDate ||
update is MetadataUpdate.Description ||
update is MetadataUpdate.GpsCoordinates
val isExifUpdate =
update is MetadataUpdate.Orientation ||
update is MetadataUpdate.TakenDate ||
update is MetadataUpdate.Description ||
update is MetadataUpdate.GpsCoordinates ||
update is MetadataUpdate.GpsCoordinatesAndLocationShown

val exifBytes: ByteArray? = if (isExifUpdate) {

Expand Down Expand Up @@ -131,6 +133,6 @@ internal object JxlUpdater : MetadataUpdater {
xmp = null // No change to XMP
)

return byteWriter.toByteArray()
return@tryWithImageWriteException byteWriter.toByteArray()
}
}
12 changes: 7 additions & 5 deletions src/commonMain/kotlin/com/ashampoo/kim/format/png/PngUpdater.kt
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,12 @@ internal object PngUpdater : MetadataUpdater {

val updatedXmp = XmpWriter.updateXmp(xmpMeta, update, true)

val isExifUpdate = update is MetadataUpdate.Orientation ||
update is MetadataUpdate.TakenDate ||
update is MetadataUpdate.Description ||
update is MetadataUpdate.GpsCoordinates
val isExifUpdate =
update is MetadataUpdate.Orientation ||
update is MetadataUpdate.TakenDate ||
update is MetadataUpdate.Description ||
update is MetadataUpdate.GpsCoordinates ||
update is MetadataUpdate.GpsCoordinatesAndLocationShown

val exifBytes: ByteArray? = if (isExifUpdate) {

Expand Down Expand Up @@ -131,6 +133,6 @@ internal object PngUpdater : MetadataUpdater {
xmp = null // No change to XMP
)

return@updateThumbnail byteWriter.toByteArray()
return@tryWithImageWriteException byteWriter.toByteArray()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,11 @@ public class TiffOutputSet(
setGpsCoordinates(update.gpsCoordinates)
}

is MetadataUpdate.GpsCoordinatesAndLocationShown -> {

setGpsCoordinates(update.gpsCoordinates)
}

else -> throw ImageWriteException("Can't perform update $update.")
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,12 @@ internal object WebPUpdater : MetadataUpdater {

val updatedXmp = XmpWriter.updateXmp(xmpMeta, update, true)

val isExifUpdate = update is MetadataUpdate.Orientation ||
update is MetadataUpdate.TakenDate ||
update is MetadataUpdate.Description ||
update is MetadataUpdate.GpsCoordinates
val isExifUpdate =
update is MetadataUpdate.Orientation ||
update is MetadataUpdate.TakenDate ||
update is MetadataUpdate.Description ||
update is MetadataUpdate.GpsCoordinates ||
update is MetadataUpdate.GpsCoordinatesAndLocationShown

val exifBytes: ByteArray? = if (isExifUpdate) {

Expand Down Expand Up @@ -124,6 +126,6 @@ internal object WebPUpdater : MetadataUpdater {
xmp = null // No change to XMP
)

return byteWriter.toByteArray()
return@tryWithImageWriteException byteWriter.toByteArray()
}
}
32 changes: 32 additions & 0 deletions src/commonMain/kotlin/com/ashampoo/kim/format/xmp/XmpWriter.kt
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,38 @@ public object XmpWriter {
)
}

is MetadataUpdate.GpsCoordinatesAndLocationShown -> {

/* GPS */

if (update.gpsCoordinates != null)
setGpsCoordinates(
GpsUtil.decimalLatitudeToDDM(update.gpsCoordinates.latitude),
GpsUtil.decimalLongitudeToDDM(update.gpsCoordinates.longitude)
)
else
deleteGpsCoordinates()

/* Location */

val locationShown = update.locationShown

if (locationShown == null) {
setLocation(null)
return
}

setLocation(
XMPLocation(
name = locationShown.name,
location = locationShown.location,
city = locationShown.city,
state = locationShown.state,
country = locationShown.country
)
)
}

is MetadataUpdate.Title ->
setTitle(update.title)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,14 @@ public sealed interface MetadataUpdate {
val locationShown: com.ashampoo.kim.model.LocationShown?
) : MetadataUpdate

/*
* One-shot update GPS coordinates & location
*/
public data class GpsCoordinatesAndLocationShown(
val gpsCoordinates: com.ashampoo.kim.model.GpsCoordinates?,
val locationShown: com.ashampoo.kim.model.LocationShown?
) : MetadataUpdate

/**
* New title or NULL to remove it
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,34 @@ abstract class AbstractUpdaterTest(
compare("new_location_shown.no_metadata.$format", newBytes)
}

@Test
fun testUpdateGpsCoordinatesAndLocationShown() {

val newBytes = Kim.update(
bytes = originalBytes,
update = MetadataUpdate.GpsCoordinatesAndLocationShown(
gpsCoordinates = crashBuildingGps,
locationShown = crashBuildingLocation
)
)

compare("new_gps_coordinates_and_location_shown.$format", newBytes)
}

@Test
fun testUpdateGpsCoordinatesAndLocationShownOnEmptyImage() {

val newBytes = Kim.update(
bytes = noMetadataBytes,
update = MetadataUpdate.GpsCoordinatesAndLocationShown(
gpsCoordinates = crashBuildingGps,
locationShown = crashBuildingLocation
)
)

compare("new_gps_coordinates_and_location_shown.no_metadata.$format", newBytes)
}

@Test
fun testUpdateTitle() {

Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Binary file not shown.

0 comments on commit 8676b80

Please sign in to comment.