There is a pending German patent application with the application number 10 2023 125 012.4. In
order to use the TREND watermarker Software in the form published here, a patent license is
required in addition to the license for the Software. See LICENSE
for more information. In case of any questions or uncertainties, please contact us at
trend@isst.fraunhofer.de.
This documentation is in a pretty early stage and updated continuously. Watch it!
Concepts
Overview
Kotlin Multiplatform
Our library is developed as Kotlin Multiplatform Library with support for Kotlin, Java, and JavaScript. This allows the library to be used in any JVM compatible language ( e.g., Java, Kotlin), Node.js, and in plain JavaScript (e.g., browsers).
In some cases, different code is required for different platforms. In such cases the expect
and
actual
feature of Kotlin is used, or some features (like operating on files) are only available on some
platforms. Because of this, code in the same package can be in different paths, depending on the
compilation target. For this reason the following refers to packages instead of paths.
- Example: when compiling for JVM, the package
de.fraunhofer.isst.trend.watermarker.files
contains*.kt
files fromsrc/commonMain/kotlin/files
andsrc/jvmMain/kotlin/files
.
Code Base
The watermarker library offers two main functionalities:
- Insert and extract watermarks: insert and extract additional information into/from files/data.
- Generate and parse watermarks: generate and parse information that are used as watermarks.
These tasks seem similar but are very independent of each other. The only requirement they share is the data format: the library inserts and extracts bytes as watermarks, therefore the generate and parse watermarks task must be able to generate and parse bytes.
The classes
Watermarker
and
JvmWatermarker
are designed to offer an easy entry point for users to insert and extract watermarks from all
supported file types without requiring any additional configuration. Only users with special
requirements should have to familiarize themselves with the individual classes.
Error Handling
We handle errors (and warnings) as values, not as exceptions. Our library
should not throw any exceptions, instead functions which can fail should return a Status
or a
Result
if they return a value. See Error Handling for details.
Insert and Extract Watermarks
The code in the package de.fraunhofer.isst.trend.watermarker.files
is responsible to parse and
generate supported file types in memory:
- all classes adding support for a file type must implement the interface
WatermarkableFile
- the classes should offer functions to modify the contents of the file when possible
- Example:
ZipFile
offers functions to add/remove extra fields into the header section of zip files
- Example:
- if the class allows customizing its behavior, a builder class should be implemented which allows
generating an instance with default settings as well as specifying all its customization options.
- Example:
TextWatermarkerBuilder
(from a different package but the concept is the same)
- Example:
The code in the package de.fraunhofer.isst.trend.watermarker.fileWatermarker
is responsible to
insert and extract watermarks into
WatermarkableFile
s:
- for each instance of
WatermarkableFile
, a class implementingFileWatermarker
for that specific instance should exist (e.g.,ZipWatermarker
forZipFile
) which is responsible to insert, extract and remove watermarks into/from thatWatermarkableFile
while maintaining a valid file. - if the class allows customizing its behavior, a builder class should be implemented which allows
generating an instance with default settings as well as specifying all its customization options.
- Example:
TextWatermarkerBuilder
- Example:
Generate and Parse Watermarks
The code in the package de.fraunhofer.isst.trend.watermarker.watermarks
is responsible for
generating watermarks and parsing extracted watermarks:
- The class
Watermark
is the most basic watermark that offers very limited functionality but is used as a base class for many functions that expect a watermark as parameter and for more sophisticated watermarks. All watermarks should directly or indirectly inherit from this class. - The class
Trendmark
implements a watermark scheme that uses the first byte of the watermark as tag to identify the format of the watermark. The format defines if additional information about the watermark (e.g., size, checksums, or hashes) are included in the watermark. The format of the content itself is not defined in detail (e.g., text, certificate, image, ...), but general information about the content are defined (currently only whether the content is compressed). For more details see the Trendmark documentation section. This implies that a user extracting aTrendmark
must know the type of content but not the format used to store the content.- To offer convenient functions to generate, modify, and parse
Trendmark
s with specific content (e.g., text, certificate, ...) the interfaceTrendmarkBuilder
can be used to implement a class with a builder-like pattern (e.g.,TextWatermark
).
- To offer convenient functions to generate, modify, and parse
Error Handling
We handle errors (and warnings) as values, not as exceptions. Our library
should not throw any exceptions, instead functions which can fail should return a
Status
or a
Result
if they return a value. This allows us to provide detailed reports what happened during the
execution of a function, including warnings and custom success messages holding additional
information, like the exact source of the message. Furthermore, this approach enforces explicit
error handling, even if the dev decides to ignore the error, before accessing the return value of a
function (because the type is different). To see an example how you can handle such return values
see the
CLI
tool.
For more advanced usages see
Trendmark
or
TextWatermark
.
Status
A
Status
represents the outcome of a function, without a return value, that is not guaranteed to
succeed. To be able to report any issues (or just additional information) that occurred during the
execution of a function, the class
Status
contains a list of Event
s that occurred during the execution. A
Status
that represents a success might not contain an
Event
.
Multiple Status
objects can be combined to propagate the reports.
Event
An
Event
represents different kinds of events that can occur during the execution of a function. There are 3
base variants:
The variants
Warning
and
Error
are abstract: For each event that can occur, a unique class must be created that overrides the
function getMessage(): String
to explain the event. If a success message with additional
information is required, a new class inheriting from
Success
can be created. All variants, but the default
Success
variant, require a source
string which should explain the origin of the event (e.g.,
className.functionName
).
Result
A
Result
represents the outcome of a function, with a return value, that is not guaranteed to
succeed. It functions like a
Status
(it uses a
Status
internally) but also has a generic member value
that can contain the return value. When the
Status
is in success or warning state it must contain a value, otherwise it should not
contain a value.