[libcamera-devel,v3] qcam: dng_writer: Record creation time in the EXIF directory

Message ID 20200615155143.2609284-1-niklas.soderlund@ragnatech.se
State Accepted
Headers show
Series
  • [libcamera-devel,v3] qcam: dng_writer: Record creation time in the EXIF directory
Related show

Commit Message

Niklas Söderlund June 15, 2020, 3:51 p.m. UTC
If the EXIF directory is empty due to no metadata being available tools
such as tiffinfo complains that the directory is malformed.

    TIFFFetchDirectory: Sanity check on directory count failed, this is probably not a valid IFD offset.
    TIFFReadCustomDirectory: Failed to read custom directory at offset 0.

Always record the creation time in the EXIF directory instead of adding
complexity to skip creating the EXIF directory if there is no metadata
to record. This ensures there are at least some entries in the EXIF
directory and that makes tiffinfo happy.

Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
---
* Changes since v1
- Also set EXIFTAG_DATETIMEORIGINAL
* Changes since v2
- Add todo to not forget to add OffsetTimeOriginal and
  OffsetTimeDigitized once libtff learns about them.
---
 src/qcam/dng_writer.cpp | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

Comments

Laurent Pinchart June 16, 2020, 2:30 a.m. UTC | #1
Hi Niklas,

Thank you for the patch.

On Mon, Jun 15, 2020 at 05:51:43PM +0200, Niklas Söderlund wrote:
> If the EXIF directory is empty due to no metadata being available tools
> such as tiffinfo complains that the directory is malformed.
> 
>     TIFFFetchDirectory: Sanity check on directory count failed, this is probably not a valid IFD offset.
>     TIFFReadCustomDirectory: Failed to read custom directory at offset 0.
> 
> Always record the creation time in the EXIF directory instead of adding
> complexity to skip creating the EXIF directory if there is no metadata
> to record. This ensures there are at least some entries in the EXIF
> directory and that makes tiffinfo happy.
> 
> Signed-off-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
> ---
> * Changes since v1
> - Also set EXIFTAG_DATETIMEORIGINAL
> * Changes since v2
> - Add todo to not forget to add OffsetTimeOriginal and
>   OffsetTimeDigitized once libtff learns about them.
> ---
>  src/qcam/dng_writer.cpp | 17 +++++++++++++++++
>  1 file changed, 17 insertions(+)
> 
> diff --git a/src/qcam/dng_writer.cpp b/src/qcam/dng_writer.cpp
> index 8470908816e3e408..d5667c863cada250 100644
> --- a/src/qcam/dng_writer.cpp
> +++ b/src/qcam/dng_writer.cpp
> @@ -427,6 +427,23 @@ int DNGWriter::write(const char *filename, const Camera *camera,
>  	/* Create a new IFD for the EXIF data and fill it. */
>  	TIFFCreateEXIFDirectory(tif);
>  
> +	/* Store creation time. */
> +	time_t rawtime;
> +	struct tm *timeinfo;
> +	char strTime[20];
> +
> +	time(&rawtime);
> +	timeinfo = localtime(&rawtime);
> +	strftime(strTime, 20, "%Y:%m:%d %H:%M:%S", timeinfo);
> +
> +	/*
> +	 * \todo Handle timezone information by setting OffsetTimeOriginal and
> +	 * OffsetTimeDigitized once libtiff catches up to the specification and
> +	 * have EXIFTAG_ defines to handle them.

s/have/has/

Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

> +	 */
> +	TIFFSetField(tif, EXIFTAG_DATETIMEORIGINAL, strTime);
> +	TIFFSetField(tif, EXIFTAG_DATETIMEDIGITIZED, strTime);
> +
>  	if (metadata.contains(controls::AnalogueGain)) {
>  		float gain = metadata.get(controls::AnalogueGain);
>  		uint16_t iso = std::min(std::max(gain * 100, 0.0f), 65535.0f);

Patch

diff --git a/src/qcam/dng_writer.cpp b/src/qcam/dng_writer.cpp
index 8470908816e3e408..d5667c863cada250 100644
--- a/src/qcam/dng_writer.cpp
+++ b/src/qcam/dng_writer.cpp
@@ -427,6 +427,23 @@  int DNGWriter::write(const char *filename, const Camera *camera,
 	/* Create a new IFD for the EXIF data and fill it. */
 	TIFFCreateEXIFDirectory(tif);
 
+	/* Store creation time. */
+	time_t rawtime;
+	struct tm *timeinfo;
+	char strTime[20];
+
+	time(&rawtime);
+	timeinfo = localtime(&rawtime);
+	strftime(strTime, 20, "%Y:%m:%d %H:%M:%S", timeinfo);
+
+	/*
+	 * \todo Handle timezone information by setting OffsetTimeOriginal and
+	 * OffsetTimeDigitized once libtiff catches up to the specification and
+	 * have EXIFTAG_ defines to handle them.
+	 */
+	TIFFSetField(tif, EXIFTAG_DATETIMEORIGINAL, strTime);
+	TIFFSetField(tif, EXIFTAG_DATETIMEDIGITIZED, strTime);
+
 	if (metadata.contains(controls::AnalogueGain)) {
 		float gain = metadata.get(controls::AnalogueGain);
 		uint16_t iso = std::min(std::max(gain * 100, 0.0f), 65535.0f);