{"id":9766,"url":"https://patchwork.libcamera.org/api/patches/9766/?format=json","web_url":"https://patchwork.libcamera.org/patch/9766/","project":{"id":1,"url":"https://patchwork.libcamera.org/api/projects/1/?format=json","name":"libcamera","link_name":"libcamera","list_id":"libcamera_core","list_email":"libcamera-devel@lists.libcamera.org","web_url":"","scm_url":"","webscm_url":""},"msgid":"<20200923191731.11433-1-email@uajain.com>","date":"2020-09-23T19:17:31","name":"[libcamera-devel,RFC,v2] android: jpeg: exif: Set timezone information","commit_ref":null,"pull_url":null,"state":"accepted","archived":false,"hash":"1b395dc486dfea79b513d79366e09dcbd1f3ed6c","submitter":{"id":1,"url":"https://patchwork.libcamera.org/api/people/1/?format=json","name":"Umang Jain","email":"email@uajain.com"},"delegate":null,"mbox":"https://patchwork.libcamera.org/patch/9766/mbox/","series":[{"id":1315,"url":"https://patchwork.libcamera.org/api/series/1315/?format=json","web_url":"https://patchwork.libcamera.org/project/libcamera/list/?series=1315","date":"2020-09-23T19:17:31","name":"[libcamera-devel,RFC,v2] android: jpeg: exif: Set timezone information","version":2,"mbox":"https://patchwork.libcamera.org/series/1315/mbox/"}],"comments":"https://patchwork.libcamera.org/api/patches/9766/comments/","check":"pending","checks":"https://patchwork.libcamera.org/api/patches/9766/checks/","tags":{},"headers":{"Return-Path":"<libcamera-devel-bounces@lists.libcamera.org>","X-Original-To":"parsemail@patchwork.libcamera.org","Delivered-To":"parsemail@patchwork.libcamera.org","Received":["from lancelot.ideasonboard.com (lancelot.ideasonboard.com\n\t[92.243.16.209])\n\tby patchwork.libcamera.org (Postfix) with ESMTPS id 84DD6C3B5B\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed, 23 Sep 2020 19:17:40 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id CE43762FE3;\n\tWed, 23 Sep 2020 21:17:39 +0200 (CEST)","from mail.uajain.com (static.126.159.217.95.clients.your-server.de\n\t[95.217.159.126])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 3CF5060576\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 23 Sep 2020 21:17:37 +0200 (CEST)"],"Authentication-Results":"lancelot.ideasonboard.com;\n\tdkim=fail reason=\"signature verification failed\" (2048-bit key;\n\tunprotected) header.d=uajain.com header.i=@uajain.com\n\theader.b=\"fS3IpHlx\"; dkim-atps=neutral","From":"Umang Jain <email@uajain.com>","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=uajain.com; s=mail;\n\tt=1600888656; bh=3VfsXSLSqom5fJbAEwHjTM0UvOegq6nooHOy3QIgMzg=;\n\th=From:To:Cc:Subject:In-Reply-To:References;\n\tb=fS3IpHlxs8q0gJcXnI+DGnn3PqRCrn5ETqKdRsIwHUDNR1kdfS+3uHCcb3apYSh6f\n\tFaRnjOFIsyLaUndRpYouidTZlBxud7lyFyOUwjKQ8MkeeOmLfBmsxCwX/6AgoVkREm\n\tDnrlalaa5OSzMRnAbawgxmBmxrVRyHCcwdxRF2aQkRuOqGhgjBTBziJSUj2EzGFCo2\n\tnI1MvahRrK5vKxwQXt+ONOf579gCq1SJqk21xBkwjp2Oihkc1kVri429uccyXQwEG+\n\ti/icu8d+g9Ti+mdFVwlpwspzwsxAhRZODzy8hBpOw/18bV12Ps2NTZ7G5y6y6+79QO\n\t+9gVM+8tIjlew==","To":"libcamera-devel@lists.libcamera.org","Date":"Thu, 24 Sep 2020 00:47:31 +0530","Message-Id":"<20200923191731.11433-1-email@uajain.com>","In-Reply-To":"<20200909153206.7700-1-email@uajain.com>","References":"<20200909153206.7700-1-email@uajain.com>","Mime-Version":"1.0","Subject":"[libcamera-devel] [RFC PATCH v2] android: jpeg: exif: Set timezone\n\tinformation","X-BeenThere":"libcamera-devel@lists.libcamera.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<libcamera-devel.lists.libcamera.org>","List-Unsubscribe":"<https://lists.libcamera.org/options/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=unsubscribe>","List-Archive":"<https://lists.libcamera.org/pipermail/libcamera-devel/>","List-Post":"<mailto:libcamera-devel@lists.libcamera.org>","List-Help":"<mailto:libcamera-devel-request@lists.libcamera.org?subject=help>","List-Subscribe":"<https://lists.libcamera.org/listinfo/libcamera-devel>,\n\t<mailto:libcamera-devel-request@lists.libcamera.org?subject=subscribe>","Content-Type":"text/plain; charset=\"us-ascii\"","Content-Transfer-Encoding":"7bit","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"},"content":"Hi,\n\nAgain posting as a RFC but the patch is now functional as expected.\nTested with few range of values (+ -) and didn't see a problem.\n\nLet me know what you think.\n---\n\nGet timezone information from the timestamp, although the resolution\nfor EXIF_TAG_TIME_ZONE_OFFSET is fairly limited (per-hour only).\n\nThis commit also introduces a special case handling for this tag.\nIn course of development, it was found that libexif does not\nsupport this tag practically but still carries it among its\nheader files. The manual patching here turned out to be a small\ndetail that can conveniently be removed as and when libexif's\nsupport for timezone information improves.\n\nThe EXIF specification defines three other tags (OffsetTime,\nOffsetTimeOriginal, OffsetTimeDigitized), in the EXIF IFD.\nThese are not supported by libexif yet.\n\nSigned-off-by: Umang Jain <email@uajain.com>\n---\n src/android/jpeg/exif.cpp | 44 +++++++++++++++++++++++++++++++++++++++\n src/android/jpeg/exif.h   |  1 +\n 2 files changed, 45 insertions(+)","diff":"diff --git a/src/android/jpeg/exif.cpp b/src/android/jpeg/exif.cpp\nindex c0dbfcc..27d8fde 100644\n--- a/src/android/jpeg/exif.cpp\n+++ b/src/android/jpeg/exif.cpp\n@@ -7,6 +7,8 @@\n \n #include \"exif.h\"\n \n+#include <stdlib.h>\n+\n #include \"libcamera/internal/log.h\"\n \n using namespace libcamera;\n@@ -135,6 +137,29 @@ void Exif::setShort(ExifIfd ifd, ExifTag tag, uint16_t item)\n \texif_entry_unref(entry);\n }\n \n+void Exif::setSShort(ExifIfd ifd, ExifTag tag, int16_t item)\n+{\n+\tExifEntry *entry;\n+\t/*\n+\t * Special case handling for EXIF_TAG_TIME_ZONE_OFFSET. We need to\n+\t * manually create and initialize an ExifEntry for this tag, since\n+\t * the intialization support is missing from libexif's function\n+\t * exif_entry_initialize().\n+\t *\n+\t * \\todo: Remove this special case when the above issue is fixed in\n+\t * libexif.\n+\t */\n+\tif (tag == EXIF_TAG_TIME_ZONE_OFFSET)\n+\t\tentry = createEntry (ifd, tag, EXIF_FORMAT_SSHORT, 1, 2);\n+\telse\n+\t\tentry = createEntry(ifd, tag);\n+\tif (!entry)\n+\t\treturn;\n+\n+\texif_set_sshort(entry->data, EXIF_BYTE_ORDER_INTEL, item);\n+\texif_entry_unref(entry);\n+}\n+\n void Exif::setLong(ExifIfd ifd, ExifTag tag, uint32_t item)\n {\n \tExifEntry *entry = createEntry(ifd, tag);\n@@ -196,6 +221,25 @@ void Exif::setTimestamp(time_t timestamp)\n \tsetString(EXIF_IFD_0, EXIF_TAG_DATE_TIME, EXIF_FORMAT_ASCII, ts);\n \tsetString(EXIF_IFD_EXIF, EXIF_TAG_DATE_TIME_ORIGINAL, EXIF_FORMAT_ASCII, ts);\n \tsetString(EXIF_IFD_EXIF, EXIF_TAG_DATE_TIME_DIGITIZED, EXIF_FORMAT_ASCII, ts);\n+\n+\t/*\n+\t * If possible, query and set timezone information via\n+\t * EXIF_TAG_TIME_ZONE_OFFSET. There is only per-hour resolution for tag\n+\t * hence, round up hours if minutes >= 30.\n+\t */\n+\tint r = strftime(str, sizeof(str), \"%z\", &tm);\n+\tif (r > 0) {\n+\t\tint16_t timezone = atoi(str);\n+\t\tint16_t hour = timezone / 100;\n+\t\tint16_t min = timezone % 100;\n+\n+\t\tif (min <= -30)\n+\t\t\thour--;\n+\t\telse if (min >= 30)\n+\t\t\thour++;\n+\n+\t\tsetSShort(EXIF_IFD_0, EXIF_TAG_TIME_ZONE_OFFSET, hour);\n+\t}\n }\n \n void Exif::setOrientation(int orientation)\ndiff --git a/src/android/jpeg/exif.h b/src/android/jpeg/exif.h\nindex f04cefc..9c9cc3b 100644\n--- a/src/android/jpeg/exif.h\n+++ b/src/android/jpeg/exif.h\n@@ -37,6 +37,7 @@ private:\n \t\t\t       unsigned long components, unsigned int size);\n \n \tvoid setShort(ExifIfd ifd, ExifTag tag, uint16_t item);\n+\tvoid setSShort(ExifIfd ifd, ExifTag tag, int16_t item);\n \tvoid setLong(ExifIfd ifd, ExifTag tag, uint32_t item);\n \tvoid setString(ExifIfd ifd, ExifTag tag, ExifFormat format,\n \t\t       const std::string &item);\n","prefixes":["libcamera-devel","RFC","v2"]}