[{"id":13524,"web_url":"https://patchwork.libcamera.org/comment/13524/","msgid":"<20201028012954.GJ3967@pendragon.ideasonboard.com>","date":"2020-10-28T01:29:54","subject":"Re: [libcamera-devel] [PATCH v2 3/3] android: jpeg:\n\tpost_processor_jpeg: Embed thumbnail into Exif metadata","submitter":{"id":2,"url":"https://patchwork.libcamera.org/api/people/2/","name":"Laurent Pinchart","email":"laurent.pinchart@ideasonboard.com"},"content":"Hi Umang,\n\nThank you for the patch.\n\nOn Wed, Oct 28, 2020 at 02:54:47AM +0530, Umang Jain wrote:\n> Embed a Jpeg-encoded thumbnail into Exif metadata using the Thumbnailer\n> class that got introduced.\n> \n> Introduce a helper function in Exif class for setting the thumbnail\n> data. Set the EXIF_TAG_COMPRESSION to '6' to denote that the thumbnail\n> is jpeg-compressed, as mentioned in Exif v2.31.\n> \n> Signed-off-by: Umang Jain <email@uajain.com>\n> ---\n>  src/android/jpeg/exif.cpp                | 24 ++++++++++++++++-\n>  src/android/jpeg/exif.h                  |  2 ++\n>  src/android/jpeg/post_processor_jpeg.cpp | 34 ++++++++++++++++++++++++\n>  src/android/jpeg/post_processor_jpeg.h   |  8 +++++-\n>  4 files changed, 66 insertions(+), 2 deletions(-)\n> \n> diff --git a/src/android/jpeg/exif.cpp b/src/android/jpeg/exif.cpp\n> index d21534a..6ac52c6 100644\n> --- a/src/android/jpeg/exif.cpp\n> +++ b/src/android/jpeg/exif.cpp\n> @@ -75,8 +75,16 @@ Exif::~Exif()\n>  \tif (exifData_)\n>  \t\tfree(exifData_);\n>  \n> -\tif (data_)\n> +\tif (data_) {\n> +\t\t/*\n> +\t\t * Reset thumbnail data to avoid getting double-freed by\n> +\t\t * libexif. It is owned by the caller (i.e. PostProcessorJpeg).\n> +\t\t */\n> +\t\tdata_->data = nullptr;\n> +\t\tdata_->size = 0;\n> +\n>  \t\texif_data_unref(data_);\n> +\t}\n>  \n>  \tif (mem_)\n>  \t\texif_mem_unref(mem_);\n> @@ -268,6 +276,20 @@ void Exif::setOrientation(int orientation)\n>  \tsetShort(EXIF_IFD_0, EXIF_TAG_ORIENTATION, value);\n>  }\n>  \n> +/*\n> + * The thumbnail data should remain valid until the Exif object is destroyed.\n> + * Failing to do so, might result in no thumbnail data being set even after a\n> + * call to Exif::setThumbnail().\n> + */\n> +void Exif::setThumbnail(Span<const unsigned char> thumbnail,\n> +\t\t\tuint16_t compression)\n> +{\n> +\tdata_->data = const_cast<unsigned char *>(thumbnail.data());\n> +\tdata_->size = thumbnail.size();\n> +\n> +\tsetShort(EXIF_IFD_0, EXIF_TAG_COMPRESSION, compression);\n> +}\n> +\n>  [[nodiscard]] int Exif::generate()\n>  {\n>  \tif (exifData_) {\n> diff --git a/src/android/jpeg/exif.h b/src/android/jpeg/exif.h\n> index 12c27b6..6987b31 100644\n> --- a/src/android/jpeg/exif.h\n> +++ b/src/android/jpeg/exif.h\n> @@ -26,6 +26,8 @@ public:\n>  \n>  \tvoid setOrientation(int orientation);\n>  \tvoid setSize(const libcamera::Size &size);\n> +\tvoid setThumbnail(libcamera::Span<const unsigned char> thumbnail,\n> +\t\t\t  uint16_t compression);\n>  \tvoid setTimestamp(time_t timestamp);\n>  \n>  \tlibcamera::Span<const uint8_t> data() const { return { exifData_, size_ }; }\n> diff --git a/src/android/jpeg/post_processor_jpeg.cpp b/src/android/jpeg/post_processor_jpeg.cpp\n> index c56f1b2..a0db793 100644\n> --- a/src/android/jpeg/post_processor_jpeg.cpp\n> +++ b/src/android/jpeg/post_processor_jpeg.cpp\n> @@ -39,11 +39,41 @@ int PostProcessorJpeg::configure(const StreamConfiguration &inCfg,\n>  \t}\n>  \n>  \tstreamSize_ = outCfg.size;\n> +\n> +\tthumbnailer_.configure(inCfg.size, inCfg.pixelFormat);\n> +\tStreamConfiguration thCfg = inCfg;\n> +\tthCfg.size = thumbnailer_.size();\n> +\tif (thumbnailEncoder_.configure(thCfg) != 0) {\n> +\t\tLOG(JPEG, Error) << \"Failed to configure thumbnail encoder\";\n> +\t\treturn -EINVAL;\n> +\t}\n> +\n>  \tencoder_ = std::make_unique<EncoderLibJpeg>();\n>  \n>  \treturn encoder_->configure(inCfg);\n>  }\n>  \n> +void PostProcessorJpeg::generateThumbnail(const FrameBuffer &source,\n> +\t\t\t\t\t  std::vector<unsigned char> *thumbnail)\n> +{\n> +\t/* Stores the raw scaled-down thumbnail bytes. */\n> +\tstd::vector<unsigned char> rawThumbnail;\n> +\n> +\tthumbnailer_.createThumbnail(source, &rawThumbnail);\n> +\n> +\tif (!rawThumbnail.empty()) {\n> +\t\tthumbnail->resize(rawThumbnail.size());\n\nThis will zero the contents of the vector, which isn't required. Let's\nleave it as-is for now, but record the issue:\n\n\t\t/*\n\t\t * \\todo Avoid value-initialization of all elements of the\n\t\t * vector.\n\t\t */\n\n> +\n> +\t\tint jpeg_size = thumbnailEncoder_.encode(rawThumbnail,\n> +\t\t\t\t\t\t\t *thumbnail, { });\n> +\t\tthumbnail->resize(jpeg_size);\n> +\n> +\t\tLOG(JPEG, Debug)\n> +\t\t\t<< \"Thumbnail compress returned \"\n> +\t\t\t<< jpeg_size << \" bytes\";\n> +\t}\n> +}\n> +\n>  int PostProcessorJpeg::process(const FrameBuffer &source,\n>  \t\t\t       Span<uint8_t> destination,\n>  \t\t\t       CameraMetadata *metadata)\n> @@ -64,6 +94,10 @@ int PostProcessorJpeg::process(const FrameBuffer &source,\n>  \t * second, it is good enough.\n>  \t */\n>  \texif.setTimestamp(std::time(nullptr));\n> +\tstd::vector<unsigned char> thumbnail;\n> +\tgenerateThumbnail(source, &thumbnail);\n\nI think we could return the vector from generateThumbnail() instead of\npassing it from the caller, but that's also not something that needs to\nbe addressed now.\n\n> +\tif(!thumbnail.empty())\n> +\t\texif.setThumbnail(thumbnail, 6);\n\nThe magic value isn't very nice. How about turning the parameter to a\n'bool compressed', or, better, to an enum declared in the Exif class\n\n\tenum class Compression {\n\t\tNone = 1,\n\t\tJPEG = 6,\n\t};\n\nand turning setThumbnail() into\n\n\tvoid setThumbnail(libcamera::Span<const unsigned char> thumbnail,\n\t\t\t  Compression compression);\n\nApart from that the patch looks good to me.\n\nReviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n\nI'll let Kieran have a look too, but I think these small issues could be\nfixed while applying (unless he would prefer you to test them first).\n\n>  \tif (exif.generate() != 0)\n>  \t\tLOG(JPEG, Error) << \"Failed to generate valid EXIF data\";\n>  \n> diff --git a/src/android/jpeg/post_processor_jpeg.h b/src/android/jpeg/post_processor_jpeg.h\n> index 3706cec..5afa831 100644\n> --- a/src/android/jpeg/post_processor_jpeg.h\n> +++ b/src/android/jpeg/post_processor_jpeg.h\n> @@ -8,12 +8,13 @@\n>  #define __ANDROID_POST_PROCESSOR_JPEG_H__\n>  \n>  #include \"../post_processor.h\"\n> +#include \"encoder_libjpeg.h\"\n> +#include \"thumbnailer.h\"\n>  \n>  #include <libcamera/geometry.h>\n>  \n>  #include \"libcamera/internal/buffer.h\"\n>  \n> -class Encoder;\n>  class CameraDevice;\n>  \n>  class PostProcessorJpeg : public PostProcessor\n> @@ -28,9 +29,14 @@ public:\n>  \t\t    CameraMetadata *metadata) override;\n>  \n>  private:\n> +\tvoid generateThumbnail(const libcamera::FrameBuffer &source,\n> +\t\t\t       std::vector<unsigned char> *thumbnail);\n> +\n>  \tCameraDevice *const cameraDevice_;\n>  \tstd::unique_ptr<Encoder> encoder_;\n>  \tlibcamera::Size streamSize_;\n> +\tEncoderLibJpeg thumbnailEncoder_;\n> +\tThumbnailer thumbnailer_;\n>  };\n>  \n>  #endif /* __ANDROID_POST_PROCESSOR_JPEG_H__ */","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 526FABDB1E\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed, 28 Oct 2020 01:30:45 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id C76546223C;\n\tWed, 28 Oct 2020 02:30:44 +0100 (CET)","from perceval.ideasonboard.com (perceval.ideasonboard.com\n\t[IPv6:2001:4b98:dc2:55:216:3eff:fef7:d647])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTPS id 48CFE6034B\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 28 Oct 2020 02:30:43 +0100 (CET)","from pendragon.ideasonboard.com (62-78-145-57.bb.dnainternet.fi\n\t[62.78.145.57])\n\tby perceval.ideasonboard.com (Postfix) with ESMTPSA id B7BAB99A;\n\tWed, 28 Oct 2020 02:30:42 +0100 (CET)"],"Authentication-Results":"lancelot.ideasonboard.com;\n\tdkim=fail reason=\"signature verification failed\" (1024-bit key;\n\tunprotected) header.d=ideasonboard.com header.i=@ideasonboard.com\n\theader.b=\"EKIYxAhU\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com;\n\ts=mail; t=1603848642;\n\tbh=rXMnUO3XDar2me7WuwBujR8/TK12XXVSAgnPz8mrSHw=;\n\th=Date:From:To:Cc:Subject:References:In-Reply-To:From;\n\tb=EKIYxAhU2M9ckHlBbxdI2TdoinxYzEXUdIwRjIfrqVTxDhq6Dj8LzEorgFJp1nqlB\n\tmzgNGtLGNGrLY5a/6d9ti1fD6cWvLVWvXP5xdwVFzIwUcYqXZRuWcsNEFK7P7otV9W\n\tQcHD45wY+2pOfFlklnQR5YJFMBRDSe3eDtazCQrc=","Date":"Wed, 28 Oct 2020 03:29:54 +0200","From":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","To":"Umang Jain <email@uajain.com>","Message-ID":"<20201028012954.GJ3967@pendragon.ideasonboard.com>","References":"<20201027212447.131431-1-email@uajain.com>\n\t<20201027212447.131431-4-email@uajain.com>","MIME-Version":"1.0","Content-Disposition":"inline","In-Reply-To":"<20201027212447.131431-4-email@uajain.com>","Subject":"Re: [libcamera-devel] [PATCH v2 3/3] android: jpeg:\n\tpost_processor_jpeg: Embed thumbnail into Exif metadata","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>","Cc":"libcamera-devel@lists.libcamera.org","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>"}},{"id":13527,"web_url":"https://patchwork.libcamera.org/comment/13527/","msgid":"<ceec69d2-3385-2dd3-5eda-1870b3810417@uajain.com>","date":"2020-10-28T06:00:16","subject":"Re: [libcamera-devel] [PATCH v2 3/3] android: jpeg:\n\tpost_processor_jpeg: Embed thumbnail into Exif metadata","submitter":{"id":1,"url":"https://patchwork.libcamera.org/api/people/1/","name":"Umang Jain","email":"email@uajain.com"},"content":"Hi Laurent,\n\nThanks for the review.\n\nOn 10/28/20 6:59 AM, Laurent Pinchart wrote:\n> Hi Umang,\n>\n> Thank you for the patch.\n>\n> On Wed, Oct 28, 2020 at 02:54:47AM +0530, Umang Jain wrote:\n>> Embed a Jpeg-encoded thumbnail into Exif metadata using the Thumbnailer\n>> class that got introduced.\n>>\n>> Introduce a helper function in Exif class for setting the thumbnail\n>> data. Set the EXIF_TAG_COMPRESSION to '6' to denote that the thumbnail\n>> is jpeg-compressed, as mentioned in Exif v2.31.\n>>\n>> Signed-off-by: Umang Jain <email@uajain.com>\n>> ---\n>>   src/android/jpeg/exif.cpp                | 24 ++++++++++++++++-\n>>   src/android/jpeg/exif.h                  |  2 ++\n>>   src/android/jpeg/post_processor_jpeg.cpp | 34 ++++++++++++++++++++++++\n>>   src/android/jpeg/post_processor_jpeg.h   |  8 +++++-\n>>   4 files changed, 66 insertions(+), 2 deletions(-)\n>>\n>> diff --git a/src/android/jpeg/exif.cpp b/src/android/jpeg/exif.cpp\n>> index d21534a..6ac52c6 100644\n>> --- a/src/android/jpeg/exif.cpp\n>> +++ b/src/android/jpeg/exif.cpp\n>> @@ -75,8 +75,16 @@ Exif::~Exif()\n>>   \tif (exifData_)\n>>   \t\tfree(exifData_);\n>>   \n>> -\tif (data_)\n>> +\tif (data_) {\n>> +\t\t/*\n>> +\t\t * Reset thumbnail data to avoid getting double-freed by\n>> +\t\t * libexif. It is owned by the caller (i.e. PostProcessorJpeg).\n>> +\t\t */\n>> +\t\tdata_->data = nullptr;\n>> +\t\tdata_->size = 0;\n>> +\n>>   \t\texif_data_unref(data_);\n>> +\t}\n>>   \n>>   \tif (mem_)\n>>   \t\texif_mem_unref(mem_);\n>> @@ -268,6 +276,20 @@ void Exif::setOrientation(int orientation)\n>>   \tsetShort(EXIF_IFD_0, EXIF_TAG_ORIENTATION, value);\n>>   }\n>>   \n>> +/*\n>> + * The thumbnail data should remain valid until the Exif object is destroyed.\n>> + * Failing to do so, might result in no thumbnail data being set even after a\n>> + * call to Exif::setThumbnail().\n>> + */\n>> +void Exif::setThumbnail(Span<const unsigned char> thumbnail,\n>> +\t\t\tuint16_t compression)\n>> +{\n>> +\tdata_->data = const_cast<unsigned char *>(thumbnail.data());\n>> +\tdata_->size = thumbnail.size();\n>> +\n>> +\tsetShort(EXIF_IFD_0, EXIF_TAG_COMPRESSION, compression);\n>> +}\n>> +\n>>   [[nodiscard]] int Exif::generate()\n>>   {\n>>   \tif (exifData_) {\n>> diff --git a/src/android/jpeg/exif.h b/src/android/jpeg/exif.h\n>> index 12c27b6..6987b31 100644\n>> --- a/src/android/jpeg/exif.h\n>> +++ b/src/android/jpeg/exif.h\n>> @@ -26,6 +26,8 @@ public:\n>>   \n>>   \tvoid setOrientation(int orientation);\n>>   \tvoid setSize(const libcamera::Size &size);\n>> +\tvoid setThumbnail(libcamera::Span<const unsigned char> thumbnail,\n>> +\t\t\t  uint16_t compression);\n>>   \tvoid setTimestamp(time_t timestamp);\n>>   \n>>   \tlibcamera::Span<const uint8_t> data() const { return { exifData_, size_ }; }\n>> diff --git a/src/android/jpeg/post_processor_jpeg.cpp b/src/android/jpeg/post_processor_jpeg.cpp\n>> index c56f1b2..a0db793 100644\n>> --- a/src/android/jpeg/post_processor_jpeg.cpp\n>> +++ b/src/android/jpeg/post_processor_jpeg.cpp\n>> @@ -39,11 +39,41 @@ int PostProcessorJpeg::configure(const StreamConfiguration &inCfg,\n>>   \t}\n>>   \n>>   \tstreamSize_ = outCfg.size;\n>> +\n>> +\tthumbnailer_.configure(inCfg.size, inCfg.pixelFormat);\n>> +\tStreamConfiguration thCfg = inCfg;\n>> +\tthCfg.size = thumbnailer_.size();\n>> +\tif (thumbnailEncoder_.configure(thCfg) != 0) {\n>> +\t\tLOG(JPEG, Error) << \"Failed to configure thumbnail encoder\";\n>> +\t\treturn -EINVAL;\n>> +\t}\n>> +\n>>   \tencoder_ = std::make_unique<EncoderLibJpeg>();\n>>   \n>>   \treturn encoder_->configure(inCfg);\n>>   }\n>>   \n>> +void PostProcessorJpeg::generateThumbnail(const FrameBuffer &source,\n>> +\t\t\t\t\t  std::vector<unsigned char> *thumbnail)\n>> +{\n>> +\t/* Stores the raw scaled-down thumbnail bytes. */\n>> +\tstd::vector<unsigned char> rawThumbnail;\n>> +\n>> +\tthumbnailer_.createThumbnail(source, &rawThumbnail);\n>> +\n>> +\tif (!rawThumbnail.empty()) {\n>> +\t\tthumbnail->resize(rawThumbnail.size());\n> This will zero the contents of the vector, which isn't required. Let's\n> leave it as-is for now, but record the issue:\n>\n> \t\t/*\n> \t\t * \\todo Avoid value-initialization of all elements of the\n> \t\t * vector.\n> \t\t */\n>\n>> +\n>> +\t\tint jpeg_size = thumbnailEncoder_.encode(rawThumbnail,\n>> +\t\t\t\t\t\t\t *thumbnail, { });\n>> +\t\tthumbnail->resize(jpeg_size);\n>> +\n>> +\t\tLOG(JPEG, Debug)\n>> +\t\t\t<< \"Thumbnail compress returned \"\n>> +\t\t\t<< jpeg_size << \" bytes\";\n>> +\t}\n>> +}\n>> +\n>>   int PostProcessorJpeg::process(const FrameBuffer &source,\n>>   \t\t\t       Span<uint8_t> destination,\n>>   \t\t\t       CameraMetadata *metadata)\n>> @@ -64,6 +94,10 @@ int PostProcessorJpeg::process(const FrameBuffer &source,\n>>   \t * second, it is good enough.\n>>   \t */\n>>   \texif.setTimestamp(std::time(nullptr));\n>> +\tstd::vector<unsigned char> thumbnail;\n>> +\tgenerateThumbnail(source, &thumbnail);\n> I think we could return the vector from generateThumbnail() instead of\n> passing it from the caller, but that's also not something that needs to\n> be addressed now.\n>\n>> +\tif(!thumbnail.empty())\n>> +\t\texif.setThumbnail(thumbnail, 6);\n> The magic value isn't very nice. How about turning the parameter to a\n> 'bool compressed', or, better, to an enum declared in the Exif class\n>\n> \tenum class Compression {\n> \t\tNone = 1,\n> \t\tJPEG = 6,\n> \t};\n>\n> and turning setThumbnail() into\n>\n> \tvoid setThumbnail(libcamera::Span<const unsigned char> thumbnail,\n> \t\t\t  Compression compression);\n>\n> Apart from that the patch looks good to me.\n>\n> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>\n>\n> I'll let Kieran have a look too, but I think these small issues could be\n> fixed while applying (unless he would prefer you to test them first).\nI have applied the changes locally, however I will wait a bit if more \nreviews comments flow in, before send another/final version. I can test \nthe patches too with the cam-file-sink branch, however upto Kieran if he \nwants to give quick go at the actual CrOS before pushing.\n>\n>>   \tif (exif.generate() != 0)\n>>   \t\tLOG(JPEG, Error) << \"Failed to generate valid EXIF data\";\n>>   \n>> diff --git a/src/android/jpeg/post_processor_jpeg.h b/src/android/jpeg/post_processor_jpeg.h\n>> index 3706cec..5afa831 100644\n>> --- a/src/android/jpeg/post_processor_jpeg.h\n>> +++ b/src/android/jpeg/post_processor_jpeg.h\n>> @@ -8,12 +8,13 @@\n>>   #define __ANDROID_POST_PROCESSOR_JPEG_H__\n>>   \n>>   #include \"../post_processor.h\"\n>> +#include \"encoder_libjpeg.h\"\n>> +#include \"thumbnailer.h\"\n>>   \n>>   #include <libcamera/geometry.h>\n>>   \n>>   #include \"libcamera/internal/buffer.h\"\n>>   \n>> -class Encoder;\n>>   class CameraDevice;\n>>   \n>>   class PostProcessorJpeg : public PostProcessor\n>> @@ -28,9 +29,14 @@ public:\n>>   \t\t    CameraMetadata *metadata) override;\n>>   \n>>   private:\n>> +\tvoid generateThumbnail(const libcamera::FrameBuffer &source,\n>> +\t\t\t       std::vector<unsigned char> *thumbnail);\n>> +\n>>   \tCameraDevice *const cameraDevice_;\n>>   \tstd::unique_ptr<Encoder> encoder_;\n>>   \tlibcamera::Size streamSize_;\n>> +\tEncoderLibJpeg thumbnailEncoder_;\n>> +\tThumbnailer thumbnailer_;\n>>   };\n>>   \n>>   #endif /* __ANDROID_POST_PROCESSOR_JPEG_H__ */","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 87B98BDB1E\n\tfor <parsemail@patchwork.libcamera.org>;\n\tWed, 28 Oct 2020 06:00:26 +0000 (UTC)","from lancelot.ideasonboard.com (localhost [IPv6:::1])\n\tby lancelot.ideasonboard.com (Postfix) with ESMTP id 0F4B762230;\n\tWed, 28 Oct 2020 07:00:26 +0100 (CET)","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 94B4162034\n\tfor <libcamera-devel@lists.libcamera.org>;\n\tWed, 28 Oct 2020 07:00:23 +0100 (CET)"],"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=\"Qy000TPv\"; dkim-atps=neutral","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/simple; d=uajain.com; s=mail;\n\tt=1603864822; bh=TD3DY/weJj5FKbhWHG/GOCikZXvOQU0nYSfOo3uMHOc=;\n\th=Subject:To:Cc:References:From:In-Reply-To;\n\tb=Qy000TPvv0kQC/na1gtrMLYmX3v+DjK4ATsK5waKM3g4lIjEvC6br0f3NRhQeqk5+\n\tf7Vc9Grq+8nH5TgBbOCvJLdUCNRE79gntt9u8xKOoWHxopUXnOAqoPGa8ejNBOiiXe\n\tqfXlWolvFEUjPIIWTTJa1hjQ/udh2uGq3iCrBEFZvOB1/1lgx4rGBf4UhfuCNXRY63\n\tYJX6wRLiBjtTRSC6odxj6nGfKUJokdMevLKvnlr7izUldLk0j6KmkqoXMNUmh8V2Ki\n\tjmvl4y9UOUuIX78lB6V6EyO1USy90oHLlOT+2q+qTKlkYwOVy/7/DCqo2R3hBn9Mme\n\tG/zx/t5IgW7rg==","To":"Laurent Pinchart <laurent.pinchart@ideasonboard.com>","References":"<20201027212447.131431-1-email@uajain.com>\n\t<20201027212447.131431-4-email@uajain.com>\n\t<20201028012954.GJ3967@pendragon.ideasonboard.com>","From":"Umang Jain <email@uajain.com>","Message-ID":"<ceec69d2-3385-2dd3-5eda-1870b3810417@uajain.com>","Date":"Wed, 28 Oct 2020 11:30:16 +0530","Mime-Version":"1.0","In-Reply-To":"<20201028012954.GJ3967@pendragon.ideasonboard.com>","Content-Language":"en-US","Subject":"Re: [libcamera-devel] [PATCH v2 3/3] android: jpeg:\n\tpost_processor_jpeg: Embed thumbnail into Exif metadata","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>","Cc":"libcamera-devel@lists.libcamera.org","Content-Transfer-Encoding":"7bit","Content-Type":"text/plain; charset=\"us-ascii\"; Format=\"flowed\"","Errors-To":"libcamera-devel-bounces@lists.libcamera.org","Sender":"\"libcamera-devel\" <libcamera-devel-bounces@lists.libcamera.org>"}}]