Skip to content

Commit

Permalink
Support for ISO Base Media File Format (ISOBMFF) (#53)
Browse files Browse the repository at this point in the history
  • Loading branch information
StefanOltmann authored Jan 7, 2024
1 parent f53bb87 commit 37960e5
Show file tree
Hide file tree
Showing 256 changed files with 2,532 additions and 491 deletions.
133 changes: 0 additions & 133 deletions .idea/inspectionProfiles/Project_Default.xml

Large diffs are not rendered by default.

12 changes: 8 additions & 4 deletions NOTICE.txt
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
Ashampoo Kim - Kotlin Image Metadata
Copyright 2023 Ashampoo GmbH & Co. KG
Copyright 2024 Ashampoo GmbH & Co. KG

This product includes a modified portion of 'Apache Commons Imaging'
developed by the Apache Software Foundation (https://www.apache.org/).
The metadata handling logic, originally implemented in Java, has been rewritten in Kotlin.
Copyright 2007-2023 The Apache Software Foundation

Logic for reading ISOBMFF containers was derived from 'metadata-extractor'
developed by Drew Noakes (https://github.com/drewnoakes/metadata-extractor).
Copyright 2002-2023 Drew Noakes and contributors

This product includes images from Unplash provided under
the Unsplash license (https://unsplash.com/license).
These files are used as test data.

The sample images photo_62.nef, photo_63.arw, photo_64.rw2 and photo_56.orf are
taken from https://github.com/drewnoakes/metadata-extractor-images under the note
"You are free to use these media files however you wish.".
The sample images photo_62.nef, photo_63.arw, photo_64.rw2, photo_56.orf and
photo_72.hif are taken from https://github.com/drewnoakes/metadata-extractor-images
under the note "You are free to use these media files however you wish".
19 changes: 18 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ It's part of [Ashampoo Photos](https://ashampoo.com/photos).
* JPG: Read & Write EXIF, IPTC & XMP
* PNG: Read & Write `eXIf` chunk & XMP
+ Also read non-standard EXIF & IPTC from `tEXt`/`zTXt` chunk
* ISOBMFF (like HEIC & JXL): Read EXIF & XMP
+ Somewhat experimental as only tested for iPhone HEIC files so far
* TIFF / DNG / RAW: Read EXIF & XMP
+ Good support for Canon CR2, Fujifilm RAF & Adobe DNG
+ Experimental support for NEF, ARW, RW2 & ORF with known issues
Expand All @@ -33,7 +35,7 @@ of Ashampoo Photos, which, in turn, is driven by user community feedback.
## Installation

```
implementation("com.ashampoo:kim:0.8.3")
implementation("com.ashampoo:kim:0.9")
```

## Sample usages
Expand Down Expand Up @@ -138,6 +140,21 @@ val newBytes = Kim.updateThumbnail(
## Limitations

* Inability to update EXIF, IPTC and XMP in JPG files simultaneously.
* HEIC files are only tested for iPhone SE 3.

## Regarding HEIC patents

When handling ISO base media file format (ISOBMFF) files like HEIC,
our adherence to the EIC/ISO 14496-12 specification ensures freedom
from patent issues, as the relevant patents for ISOBMFF have expired
(older than 20 years), making the format public domain.

For example we intentionally omit certain features specified in the HEIC
standard, such as image size ("ispe") and rotation ("irot"), to steer clear
of potential legal complications.

In future updates, we plan to integrate special values from other
patent-free ISOBMFF-based formats as we broaden support for additional file types.

## Contributions

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2023 Ashampoo GmbH & Co. KG
* Copyright 2024 Ashampoo GmbH & Co. KG
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2023 Ashampoo GmbH & Co. KG
* Copyright 2024 Ashampoo GmbH & Co. KG
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2023 Ashampoo GmbH & Co. KG
* Copyright 2024 Ashampoo GmbH & Co. KG
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2023 Ashampoo GmbH & Co. KG
* Copyright 2024 Ashampoo GmbH & Co. KG
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2023 Ashampoo GmbH & Co. KG
* Copyright 2024 Ashampoo GmbH & Co. KG
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down
2 changes: 1 addition & 1 deletion src/commonMain/kotlin/com/ashampoo/kim/Kim.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2023 Ashampoo GmbH & Co. KG
* Copyright 2024 Ashampoo GmbH & Co. KG
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2023 Ashampoo GmbH & Co. KG
* Copyright 2024 Ashampoo GmbH & Co. KG
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2023 Ashampoo GmbH & Co. KG
* Copyright 2024 Ashampoo GmbH & Co. KG
* Copyright 2007-2023 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
Expand Down
2 changes: 1 addition & 1 deletion src/commonMain/kotlin/com/ashampoo/kim/common/ByteOrder.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2023 Ashampoo GmbH & Co. KG
* Copyright 2024 Ashampoo GmbH & Co. KG
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2023 Ashampoo GmbH & Co. KG
* Copyright 2024 Ashampoo GmbH & Co. KG
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down
2 changes: 1 addition & 1 deletion src/commonMain/kotlin/com/ashampoo/kim/common/ExifUtil.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2023 Ashampoo GmbH & Co. KG
* Copyright 2024 Ashampoo GmbH & Co. KG
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down
34 changes: 34 additions & 0 deletions src/commonMain/kotlin/com/ashampoo/kim/common/FourCC.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Copyright 2024 Ashampoo GmbH & Co. KG
*
* 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 com.ashampoo.kim.common

/**
* See https://en.wikipedia.org/wiki/FourCC
*
* PNG Chunks and HEIC boxes share the concept where the four
* type bytes of a chunk/box translate to human readable strings
* like "IHDR" & "IDAT" for PNG and "FTYP" & "META" for HEIC.
*
* This excension function converts an int to such an type string.
*/
@Suppress("MagicNumber")
fun Int.toFourCCTypeString(): String =
charArrayOf(
(0xFF and (this shr 24)).toChar(),
(0xFF and (this shr 16)).toChar(),
(0xFF and (this shr 8)).toChar(),
(0xFF and (this shr 0)).toChar()
).concatToString()
2 changes: 1 addition & 1 deletion src/commonMain/kotlin/com/ashampoo/kim/common/GpsUtil.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2023 Ashampoo GmbH & Co. KG
* Copyright 2024 Ashampoo GmbH & Co. KG
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2023 Ashampoo GmbH & Co. KG
* Copyright 2024 Ashampoo GmbH & Co. KG
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2023 Ashampoo GmbH & Co. KG
* Copyright 2024 Ashampoo GmbH & Co. KG
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2023 Ashampoo GmbH & Co. KG
* Copyright 2024 Ashampoo GmbH & Co. KG
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2023 Ashampoo GmbH & Co. KG
* Copyright 2024 Ashampoo GmbH & Co. KG
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2023 Ashampoo GmbH & Co. KG
* Copyright 2024 Ashampoo GmbH & Co. KG
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2023 Ashampoo GmbH & Co. KG
* Copyright 2024 Ashampoo GmbH & Co. KG
* Copyright 2007-2023 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
Expand Down
2 changes: 1 addition & 1 deletion src/commonMain/kotlin/com/ashampoo/kim/common/ZLib.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2023 Ashampoo GmbH & Co. KG
* Copyright 2024 Ashampoo GmbH & Co. KG
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2023 Ashampoo GmbH & Co. KG
* Copyright 2024 Ashampoo GmbH & Co. KG
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -80,6 +80,36 @@ object ImageFormatMagicNumbers {
0x52, 0x49, 0x46, 0x46, null, null, null, null, 0x57, 0x45, 0x42, 0x50
)

/* 4 bytes + "ftypheic" */
val heic: List<Byte?> = byteListOf(
null, null, null, null
).plus("ftypheic".encodeToByteArray().toList())

/* A HEIC brand */
val mif1: List<Byte?> = byteListOf(
null, null, null, null
).plus("ftypmif1".encodeToByteArray().toList())

/* A HEIC brand */
val msf1: List<Byte?> = byteListOf(
null, null, null, null
).plus("ftypmsf1".encodeToByteArray().toList())

/* A HEIC brand */
val heix: List<Byte?> = byteListOf(
null, null, null, null
).plus("ftypheix".encodeToByteArray().toList())

/* A HEIC brand */
val hevc: List<Byte?> = byteListOf(
null, null, null, null
).plus("ftyphevc".encodeToByteArray().toList())

/* A HEIC brand */
val hevx: List<Byte?> = byteListOf(
null, null, null, null
).plus("ftyphevx".encodeToByteArray().toList())

private fun byteListOf(vararg ints: Int?): List<Byte?> =
ints.map { it?.toByte() }

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2023 Ashampoo GmbH & Co. KG
* Copyright 2024 Ashampoo GmbH & Co. KG
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down
6 changes: 4 additions & 2 deletions src/commonMain/kotlin/com/ashampoo/kim/format/ImageParser.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
/*
* Copyright 2023 Ashampoo GmbH & Co. KG
* Copyright 2007-2023 The Apache Software Foundation
* Copyright 2024 Ashampoo GmbH & Co. KG
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -17,6 +16,7 @@
package com.ashampoo.kim.format

import com.ashampoo.kim.common.ImageReadException
import com.ashampoo.kim.format.isobmff.ISOBMFFImageParser
import com.ashampoo.kim.format.jpeg.JpegImageParser
import com.ashampoo.kim.format.png.PngImageParser
import com.ashampoo.kim.format.raf.RafImageParser
Expand Down Expand Up @@ -47,6 +47,8 @@ fun interface ImageParser {

ImageFormat.RAF -> RafImageParser

ImageFormat.HEIC -> ISOBMFFImageParser

else -> null
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2023 Ashampoo GmbH & Co. KG
* Copyright 2024 Ashampoo GmbH & Co. KG
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2023 Ashampoo GmbH & Co. KG
* Copyright 2024 Ashampoo GmbH & Co. KG
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2023 Ashampoo GmbH & Co. KG
* Copyright 2024 Ashampoo GmbH & Co. KG
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
/*
* Copyright 2023 Ashampoo GmbH & Co. KG
* Copyright 2007-2023 The Apache Software Foundation
* Copyright 2024 Ashampoo GmbH & Co. KG
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -42,7 +41,7 @@ object ArwPreviewExtractor : TiffPreviewExtractor {
if (previewLength == 0)
return null

randomAccessByteReader.skipTo(previewImageStart)
randomAccessByteReader.moveTo(previewImageStart)

val previewBytes = randomAccessByteReader.readBytes(previewLength)

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
/*
* Copyright 2023 Ashampoo GmbH & Co. KG
* Copyright 2007-2023 The Apache Software Foundation
* Copyright 2024 Ashampoo GmbH & Co. KG
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -42,7 +41,7 @@ object Cr2PreviewExtractor : TiffPreviewExtractor {
if (previewLength == 0)
return null

randomAccessByteReader.skipTo(previewImageStart)
randomAccessByteReader.moveTo(previewImageStart)

val previewBytes = randomAccessByteReader.readBytes(previewLength)

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
/*
* Copyright 2023 Ashampoo GmbH & Co. KG
* Copyright 2007-2023 The Apache Software Foundation
* Copyright 2024 Ashampoo GmbH & Co. KG
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -52,7 +51,7 @@ object DngPreviewExtractor : TiffPreviewExtractor {
if (previewLength == 0)
return null

randomAccessByteReader.skipTo(previewImageStart)
randomAccessByteReader.moveTo(previewImageStart)

val previewBytes = randomAccessByteReader.readBytes(previewLength)

Expand Down
Loading

0 comments on commit 37960e5

Please sign in to comment.