Skip to content

Commit

Permalink
Linux support (#76)
Browse files Browse the repository at this point in the history
Added Linux target.
  • Loading branch information
StefanOltmann authored Feb 21, 2024
1 parent a496d44 commit 80028c8
Show file tree
Hide file tree
Showing 194 changed files with 1,283 additions and 969 deletions.
24 changes: 24 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,30 @@ jobs:
if-no-files-found: error
name: kim-win-lib.zip
path: build/bin/win/releaseStatic
- name: Upload kim-linuxArm64.kexe
uses: actions/upload-artifact@v3
with:
if-no-files-found: error
name: kim-linuxArm64.kexe
path: build/bin/linuxArm64/releaseExecutable/kim.kexe
- name: Upload kim-linuxX64-lib.zip
uses: actions/upload-artifact@v3
with:
if-no-files-found: error
name: kim-linuxX64-lib.zip
path: build/bin/linuxX64/releaseStatic
- name: Upload kim-linuxX64.kexe
uses: actions/upload-artifact@v3
with:
if-no-files-found: error
name: kim-linuxX64.kexe
path: build/bin/linuxX64/releaseExecutable/kim.kexe
- name: Upload kim-linuxArm64-lib.zip
uses: actions/upload-artifact@v3
with:
if-no-files-found: error
name: kim-linuxArm64-lib.zip
path: build/bin/linuxArm64/releaseStatic
- name: Export secring.pgp
if: startsWith(github.ref, 'refs/tags/') # Only for releases
run: |
Expand Down
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@
[![Kotlin](https://img.shields.io/badge/kotlin-1.9.22-blue.svg?logo=kotlin)](httpw://kotlinlang.org)
![JVM](https://img.shields.io/badge/-JVM-gray.svg?style=flat)
![Android](https://img.shields.io/badge/-Android-gray.svg?style=flat)
![macOS](https://img.shields.io/badge/-macOS-gray.svg?style=flat)
![iOS](https://img.shields.io/badge/-iOS-gray.svg?style=flat)
![Windows](https://img.shields.io/badge/-Windows-gray.svg?style=flat)
![Linux](https://img.shields.io/badge/-Linux-gray.svg?style=flat)
![macOS](https://img.shields.io/badge/-macOS-gray.svg?style=flat)
![WASM](https://img.shields.io/badge/-WASM-gray.svg?style=flat)
[![Coverage](https://sonarcloud.io/api/project_badges/measure?project=kim&metric=coverage)](https://sonarcloud.io/summary/new_code?id=kim)

Expand Down Expand Up @@ -37,7 +38,7 @@ of Ashampoo Photos, which, in turn, is driven by user community feedback.
## Installation

```
implementation("com.ashampoo:kim:0.14.2")
implementation("com.ashampoo:kim:0.15")
```

## Sample usages
Expand Down
71 changes: 56 additions & 15 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ import org.jetbrains.kotlin.gradle.targets.js.dsl.ExperimentalWasmDsl

plugins {
kotlin("multiplatform") version "1.9.22"
id("com.android.library") version "8.1.1"
id("com.android.library") version "8.2.2"
id("maven-publish")
id("signing")
id("io.gitlab.arturbosch.detekt") version "1.23.4"
id("io.gitlab.arturbosch.detekt") version "1.23.5"
id("org.sonarqube") version "4.3.1.3277"
id("org.jetbrains.kotlinx.kover") version "0.6.1"
id("com.asarkar.gradle.build-time-tracker") version "4.3.0"
Expand All @@ -25,7 +25,7 @@ repositories {
val productName = "Ashampoo Kim"

val ktorVersion: String = "2.3.8"
val xmpCoreVersion: String = "1.0.0"
val xmpCoreVersion: String = "1.1.0"
val dateTimeVersion: String = "0.5.0"
val testRessourcesVersion: String = "0.4.0"
val ioCoreVersion: String = "0.3.1"
Expand Down Expand Up @@ -138,6 +138,28 @@ kotlin {
}
}

linuxX64 {
binaries {
executable(setOf(NativeBuildType.RELEASE)) {
entryPoint = "com.ashampoo.kim.main"
}
staticLib(namePrefix = "", setOf(NativeBuildType.RELEASE)) {
baseName = "kim"
}
}
}

linuxArm64 {
binaries {
executable(setOf(NativeBuildType.RELEASE)) {
entryPoint = "com.ashampoo.kim.main"
}
staticLib(namePrefix = "", setOf(NativeBuildType.RELEASE)) {
baseName = "kim"
}
}
}

jvm {

java {
Expand Down Expand Up @@ -187,6 +209,8 @@ kotlin {
listOf(
/* App Store */
iosArm64(),
/* Apple Intel iOS Simulator */
iosX64(),
/* Apple Silicon iOS Simulator */
iosSimulatorArm64(),
/* macOS Devices */
Expand Down Expand Up @@ -243,7 +267,18 @@ kotlin {
dependsOn(posixMain)
}

@Suppress("UnusedPrivateMember", "UNUSED_VARIABLE") // False positive
val linuxX64Main by sourceSets.getting {
dependsOn(posixMain)
}

@Suppress("UnusedPrivateMember", "UNUSED_VARIABLE") // False positive
val linuxArm64Main by sourceSets.getting {
dependsOn(posixMain)
}

val iosArm64Main by sourceSets.getting
val iosX64Main by sourceSets.getting
val iosSimulatorArm64Main by sourceSets.getting
val macosX64Main by sourceSets.getting
val macosArm64Main by sourceSets.getting
Expand All @@ -256,12 +291,14 @@ kotlin {
dependsOn(posixMain)

iosArm64Main.dependsOn(this)
iosX64Main.dependsOn(this)
iosSimulatorArm64Main.dependsOn(this)
macosX64Main.dependsOn(this)
macosArm64Main.dependsOn(this)
}

val iosArm64Test by sourceSets.getting
val iosX64Test by sourceSets.getting
val iosSimulatorArm64Test by sourceSets.getting
val macosX64Test by sourceSets.getting
val macosArm64Test by sourceSets.getting
Expand All @@ -272,6 +309,7 @@ kotlin {
dependsOn(commonTest)

iosArm64Test.dependsOn(this)
iosX64Test.dependsOn(this)
iosSimulatorArm64Test.dependsOn(this)
macosX64Test.dependsOn(this)
macosArm64Test.dependsOn(this)
Expand All @@ -280,6 +318,7 @@ kotlin {
val wasmJsMain by sourceSets.getting
// val wasmWasiMain by sourceSets.getting

@Suppress("UnusedPrivateMember", "UNUSED_VARIABLE") // False positive
val wasmMain by sourceSets.creating {

dependsOn(commonMain)
Expand Down Expand Up @@ -313,7 +352,7 @@ android {
sourceSets["main"].res.srcDirs("src/commonMain/resources")

defaultConfig {
minSdk = 23
minSdk = 21
}

compileOptions {
Expand Down Expand Up @@ -356,42 +395,53 @@ afterEvaluate {
val signJvmPublication by tasks.getting
val signAndroidReleasePublication by tasks.getting
val signIosArm64Publication by tasks.getting
val signIosX64Publication by tasks.getting
val signIosSimulatorArm64Publication by tasks.getting
val signMacosArm64Publication by tasks.getting
val signMacosX64Publication by tasks.getting
val signWinPublication by tasks.getting
val signLinuxX64Publication by tasks.getting
val signLinuxArm64Publication by tasks.getting
val signWasmJsPublication by tasks.getting
// val signWasmWasiPublication by tasks.getting
val signKotlinMultiplatformPublication by tasks.getting

val publishJvmPublicationToSonatypeRepository by tasks.getting
val publishAndroidReleasePublicationToSonatypeRepository by tasks.getting
val publishIosArm64PublicationToSonatypeRepository by tasks.getting
val publishIosX64PublicationToSonatypeRepository by tasks.getting
val publishIosSimulatorArm64PublicationToSonatypeRepository by tasks.getting
val publishMacosArm64PublicationToSonatypeRepository by tasks.getting
val publishMacosX64PublicationToSonatypeRepository by tasks.getting
val publishWinPublicationToSonatypeRepository by tasks.getting
val publishLinuxX64PublicationToSonatypeRepository by tasks.getting
val publishLinuxArm64PublicationToSonatypeRepository by tasks.getting
val publishWasmJsPublicationToSonatypeRepository by tasks.getting
// val publishWasmWasiPublicationToSonatypeRepository by tasks.getting
val publishKotlinMultiplatformPublicationToSonatypeRepository by tasks.getting
val publishAllPublicationsToSonatypeRepository by tasks.getting

val signTasks = listOf(
signJvmPublication, signAndroidReleasePublication,
signIosArm64Publication, signIosSimulatorArm64Publication,
signIosArm64Publication, signIosX64Publication,
signIosSimulatorArm64Publication,
signMacosArm64Publication, signMacosX64Publication,
signWinPublication, signWasmJsPublication, // signWasmWasiPublication,
signWinPublication, signLinuxX64Publication, signLinuxArm64Publication,
signWasmJsPublication, // signWasmWasiPublication,
signKotlinMultiplatformPublication
)

val publishTasks = listOf(
publishJvmPublicationToSonatypeRepository,
publishAndroidReleasePublicationToSonatypeRepository,
publishIosArm64PublicationToSonatypeRepository,
publishIosX64PublicationToSonatypeRepository,
publishIosSimulatorArm64PublicationToSonatypeRepository,
publishMacosArm64PublicationToSonatypeRepository,
publishMacosX64PublicationToSonatypeRepository,
publishWinPublicationToSonatypeRepository,
publishLinuxX64PublicationToSonatypeRepository,
publishLinuxArm64PublicationToSonatypeRepository,
publishWasmJsPublicationToSonatypeRepository,
// publishWasmWasiPublicationToSonatypeRepository,
publishKotlinMultiplatformPublicationToSonatypeRepository,
Expand Down Expand Up @@ -462,12 +512,3 @@ publishing {
}
}
// endregion

//rootProject.the<NodeJsRootExtension>().apply {
// nodeVersion = "21.0.0-v8-canary202309143a48826a08"
// nodeDownloadBaseUrl = "https://nodejs.org/download/v8-canary"
//}
//
//tasks.withType<org.jetbrains.kotlin.gradle.targets.js.npm.tasks.KotlinNpmInstallTask>().configureEach {
// args.add("--ignore-engines")
//}
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip
networkTimeout=10000
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ fun ImageMetadata.convertToPhotoMetadata(

val takenDateMillis = extractTakenDateMillis(this)

val gpsDirectory = findTiffDirectory(TiffConstants.TIFF_GPS)
val gpsDirectory = findTiffDirectory(TiffConstants.TIFF_DIRECTORY_GPS)

val gps = gpsDirectory?.let { GPSInfo.createFrom(it) }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,15 @@ object DngPreviewExtractor : TiffPreviewExtractor {
if (ifd0.getFieldValue(TiffTag.TIFF_TAG_DNG_VERSION, false) == null)
return null

val subIfd1 = tiffContents.directories.find {
it.type == TiffConstants.EXIF_SUB_IFD1
val ifd2 = tiffContents.directories.find {
it.type == TiffConstants.TIFF_DIRECTORY_TYPE_IFD2
} ?: return null

val previewImageStart =
subIfd1.getFieldValue(ExifTag.EXIF_TAG_PREVIEW_IMAGE_START_SUB_IFD1) ?: return null
ifd2.getFieldValue(ExifTag.EXIF_TAG_PREVIEW_IMAGE_START_SUB_IFD1) ?: return null

val previewLength =
subIfd1.getFieldValue(ExifTag.EXIF_TAG_PREVIEW_IMAGE_LENGTH_SUB_IFD1) ?: return null
ifd2.getFieldValue(ExifTag.EXIF_TAG_PREVIEW_IMAGE_LENGTH_SUB_IFD1) ?: return null

if (previewLength == 0)
return null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ object NefPreviewExtractor : TiffPreviewExtractor {
): ByteArray? = tryWithImageReadException {

val ifd1 = tiffContents.directories.find {
it.type == TiffConstants.TIFF_IFD1
it.type == TiffConstants.TIFF_DIRECTORY_TYPE_IFD1
} ?: return null

val previewImageStart =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -242,18 +242,17 @@ class TiffDirectory(
fun description(type: Int): String {
return when (type) {
TiffConstants.DIRECTORY_TYPE_UNKNOWN -> "Unknown"
TiffConstants.DIRECTORY_TYPE_ROOT -> "IFD0"
TiffConstants.DIRECTORY_TYPE_SUB -> "SubIFD"
TiffConstants.TIFF_DIRECTORY_TYPE_IFD0 -> "IFD0"
TiffConstants.TIFF_DIRECTORY_TYPE_IFD1 -> "IFD1"
TiffConstants.EXIF_SUB_IFD1 -> "SubIFD1"
TiffConstants.EXIF_SUB_IFD2 -> "SubIFD2"
TiffConstants.EXIF_SUB_IFD3 -> "SubIFD3"
// TiffConstants.DIRECTORY_TYPE_THUMBNAIL -> "Thumbnail"
TiffConstants.TIFF_EXIF_IFD -> "ExifIFD"
TiffConstants.TIFF_GPS -> "GPS"
TiffConstants.TIFF_INTEROP_IFD -> "InteropIFD"
TiffConstants.TIFF_DIRECTORY_EXIF -> "ExifIFD"
TiffConstants.TIFF_DIRECTORY_GPS -> "GPS"
TiffConstants.TIFF_DIRECTORY_INTEROP -> "InteropIFD"
TiffConstants.TIFF_MAKER_NOTE_CANON -> "MakerNoteCanon"
TiffConstants.TIFF_MAKER_NOTE_NIKON -> "MakerNoteNikon"
else -> "Bad Type"
else -> "Unknown type $type"
}
}

Expand Down
18 changes: 9 additions & 9 deletions src/commonMain/kotlin/com/ashampoo/kim/format/tiff/TiffReader.kt
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ import com.ashampoo.kim.common.toInt
import com.ashampoo.kim.format.ImageFormatMagicNumbers
import com.ashampoo.kim.format.tiff.constant.ExifTag
import com.ashampoo.kim.format.tiff.constant.TiffConstants
import com.ashampoo.kim.format.tiff.constant.TiffConstants.DIRECTORY_TYPE_SUB
import com.ashampoo.kim.format.tiff.constant.TiffConstants.EXIF_SUB_IFD1
import com.ashampoo.kim.format.tiff.constant.TiffConstants.EXIF_SUB_IFD2
import com.ashampoo.kim.format.tiff.constant.TiffConstants.EXIF_SUB_IFD3
import com.ashampoo.kim.format.tiff.constant.TiffConstants.TIFF_DIRECTORY_TYPE_IFD1
import com.ashampoo.kim.format.tiff.constant.TiffTag
import com.ashampoo.kim.format.tiff.fieldtype.FieldType.Companion.getFieldType
import com.ashampoo.kim.format.tiff.taginfo.TagInfoLong
Expand All @@ -48,10 +48,10 @@ object TiffReader {
)

private val directoryTypeMap = mapOf(
ExifTag.EXIF_TAG_EXIF_OFFSET to TiffConstants.TIFF_EXIF_IFD,
ExifTag.EXIF_TAG_GPSINFO to TiffConstants.TIFF_GPS,
ExifTag.EXIF_TAG_INTEROP_OFFSET to TiffConstants.TIFF_INTEROP_IFD,
ExifTag.EXIF_TAG_SUB_IFDS_OFFSET to TiffConstants.DIRECTORY_TYPE_SUB
ExifTag.EXIF_TAG_EXIF_OFFSET to TiffConstants.TIFF_DIRECTORY_EXIF,
ExifTag.EXIF_TAG_GPSINFO to TiffConstants.TIFF_DIRECTORY_GPS,
ExifTag.EXIF_TAG_INTEROP_OFFSET to TiffConstants.TIFF_DIRECTORY_INTEROP,
ExifTag.EXIF_TAG_SUB_IFDS_OFFSET to TiffConstants.TIFF_DIRECTORY_TYPE_IFD1
)

/**
Expand All @@ -73,7 +73,7 @@ object TiffReader {
byteReader = byteReader,
byteOrder = tiffHeader.byteOrder,
directoryOffset = tiffHeader.offsetToFirstIFD,
directoryType = TiffConstants.DIRECTORY_TYPE_ROOT,
directoryType = TiffConstants.TIFF_DIRECTORY_TYPE_IFD0,
visitedOffsets = mutableListOf<Int>(),
addDirectory = {
directories.add(it)
Expand Down Expand Up @@ -159,7 +159,7 @@ object TiffReader {
* Thumbnails are not essential and can be re-created anytime.
*/

val isThumbnailDirectory = directoryType == TiffConstants.TIFF_IFD1
val isThumbnailDirectory = directoryType == TiffConstants.TIFF_DIRECTORY_TYPE_IFD1

if (isThumbnailDirectory)
return true
Expand Down Expand Up @@ -209,7 +209,7 @@ object TiffReader {
1 -> EXIF_SUB_IFD1
2 -> EXIF_SUB_IFD2
3 -> EXIF_SUB_IFD3
else -> DIRECTORY_TYPE_SUB
else -> TIFF_DIRECTORY_TYPE_IFD1
}
else
directoryTypeMap.get(offsetField)!!
Expand Down Expand Up @@ -290,7 +290,7 @@ object TiffReader {
* Except for the GPS directory where GPSVersionID is indeed zero,
* but a valid field. So we shouldn't skip it.
*/
if (tag == 0 && directoryType != TiffConstants.TIFF_GPS)
if (tag == 0 && directoryType != TiffConstants.TIFF_DIRECTORY_GPS)
continue

val fieldType = try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ internal object TiffTags {
*/
@Suppress("UseIfInsteadOfWhen")
val possibleMatches = when (directoryType) {
TiffConstants.TIFF_GPS -> GPS_TAGS_MAP[tag]
TiffConstants.TIFF_DIRECTORY_GPS -> GPS_TAGS_MAP[tag]
TiffConstants.TIFF_MAKER_NOTE_CANON -> CANON_TAGS_MAP[tag]
TiffConstants.TIFF_MAKER_NOTE_NIKON -> NIKON_TAGS_MAP[tag]
else -> TIFF_AND_EXIF_TAGS_MAP[tag]
Expand Down
Loading

0 comments on commit 80028c8

Please sign in to comment.