1 /* 2 * Copyright 2017 The Chromium OS Authors. All rights reserved. 3 * Use of this source code is governed by a BSD-style license that can be 4 * found in the LICENSE file. 5 */ 6 7 #ifndef INCLUDE_ARC_EXIF_UTILS_H_ 8 #define INCLUDE_ARC_EXIF_UTILS_H_ 9 10 #include <cstddef> 11 #include <memory> 12 #include <string> 13 #include <utility> 14 #include <vector> 15 16 extern "C" { 17 #include <libexif/exif-data.h> 18 } 19 20 #include "arc/jpeg_compressor.h" 21 22 namespace arc { 23 24 // ExifUtils can generate APP1 segment with tags which caller set. ExifUtils can 25 // also add a thumbnail in the APP1 segment if thumbnail size is specified. 26 // ExifUtils can be reused with different images by calling initialize(). 27 // 28 // Example of using this class : 29 // ExifUtils utils; 30 // utils.initialize(inputYU12Buffer, inputWidth, inputHeight, 31 // outputJpegQuality); 32 // ... 33 // // Call ExifUtils functions to set Exif tags. 34 // ... 35 // utils.generateApp1(); 36 // unsigned int app1Length = utils.getApp1Length(); 37 // uint8_t* app1Buffer = new uint8_t[app1Length]; 38 // memcpy(app1Buffer, utils.getApp1Buffer(), app1Length); 39 class ExifUtils { 40 public: 41 ExifUtils(); 42 ~ExifUtils(); 43 44 // Sets input YU12 image |buffer| with |width| x |height|. |quality| is the 45 // compressed JPEG image quality. The caller should not release |buffer| until 46 // generateApp1() or the destructor is called. initialize() can be called 47 // multiple times. The setting of Exif tags will be cleared. 48 bool Initialize(const uint8_t* buffer, uint16_t width, uint16_t height, 49 int quality); 50 51 // Sets the manufacturer of camera. 52 // Returns false if memory allocation fails. 53 bool SetMaker(const std::string& maker); 54 55 // Sets the model number of camera. 56 // Returns false if memory allocation fails. 57 bool SetModel(const std::string& model); 58 59 // Sets the date and time of image last modified. It takes local time. The 60 // name of the tag is DateTime in IFD0. 61 // Returns false if memory allocation fails. 62 bool SetDateTime(const struct tm& t); 63 64 // Sets the focal length of lens used to take the image in millimeters. 65 // Returns false if memory allocation fails. 66 bool SetFocalLength(uint32_t numerator, uint32_t denominator); 67 68 // Sets the latitude with degrees minutes seconds format. 69 // Returns false if memory allocation fails. 70 bool SetGpsLatitude(double latitude); 71 72 // Sets the longitude with degrees minutes seconds format. 73 // Returns false if memory allocation fails. 74 bool SetGpsLongitude(double longitude); 75 76 // Sets the altitude in meters. 77 // Returns false if memory allocation fails. 78 bool SetGpsAltitude(double altitude); 79 80 // Sets GPS date stamp and time stamp (atomic clock). It takes UTC time. 81 // Returns false if memory allocation fails. 82 bool SetGpsTimestamp(const struct tm& t); 83 84 // Sets GPS processing method. 85 // Returns false if memory allocation fails. 86 bool SetGpsProcessingMethod(const std::string& method); 87 88 // Since the size of APP1 segment is limited, it is recommended the 89 // resolution of thumbnail is equal to or smaller than 640x480. If the 90 // thumbnail is too big, generateApp1() will return false. 91 // Returns false if |width| or |height| is not even. 92 bool SetThumbnailSize(uint16_t width, uint16_t height); 93 94 // Sets image orientation. 95 // Returns false if memory allocation fails. 96 bool SetOrientation(uint16_t orientation); 97 98 // Generates APP1 segment. 99 // Returns false if generating APP1 segment fails. 100 bool GenerateApp1(); 101 102 // Gets buffer of APP1 segment. This method must be called only after calling 103 // generateAPP1(). 104 const uint8_t* GetApp1Buffer(); 105 106 // Gets length of APP1 segment. This method must be called only after calling 107 // generateAPP1(). 108 unsigned int GetApp1Length(); 109 110 private: 111 // Resets the pointers and memories. 112 void Reset(); 113 114 // Adds a variable length tag to |exif_data_|. It will remove the original one 115 // if the tag exists. 116 // Returns the entry of the tag. The reference count of returned ExifEntry is 117 // two. 118 std::unique_ptr<ExifEntry> AddVariableLengthEntry(ExifIfd ifd, ExifTag tag, 119 ExifFormat format, 120 uint64_t components, 121 unsigned int size); 122 123 // Adds a entry of |tag| in |exif_data_|. It won't remove the original one if 124 // the tag exists. 125 // Returns the entry of the tag. It adds one reference count to returned 126 // ExifEntry. 127 std::unique_ptr<ExifEntry> AddEntry(ExifIfd ifd, ExifTag tag); 128 129 // Sets the width (number of columes) of main image. 130 // Returns false if memory allocation fails. 131 bool SetImageWidth(uint16_t width); 132 133 // Sets the length (number of rows) of main image. 134 // Returns false if memory allocation fails. 135 bool SetImageLength(uint16_t length); 136 137 // Generates a thumbnail. Calls compressor_.getCompressedImagePtr() to get the 138 // result image. 139 // Returns false if failed. 140 bool GenerateThumbnail(); 141 142 // Resizes the thumbnail yuv image to |thumbnail_width_| x |thumbnail_height_| 143 // and stores in |scaled_buffer|. 144 // Returns false if scale image failed. 145 bool GenerateYuvThumbnail(std::vector<uint8_t>* scaled_buffer); 146 147 // Destroys the buffer of APP1 segment if exists. 148 void DestroyApp1(); 149 150 // The buffer pointer of yuv image (YU12). Not owned by this class. 151 const uint8_t* yu12_buffer_; 152 // The size of yuv image. 153 uint16_t yu12_width_; 154 uint16_t yu12_height_; 155 156 // The size of thumbnail. 157 uint16_t thumbnail_width_; 158 uint16_t thumbnail_height_; 159 160 // The Exif data (APP1). Owned by this class. 161 ExifData* exif_data_; 162 // The raw data of APP1 segment. It's allocated by ExifMem in |exif_data_| but 163 // owned by this class. 164 uint8_t* app1_buffer_; 165 // The length of |app1_buffer_|. 166 unsigned int app1_length_; 167 // The quality of compressed thumbnail image. The size of EXIF thumbnail has 168 // to be smaller than 64KB. If quality is 100, the size may be bigger than 169 // 64KB. 170 int thumbnail_jpeg_quality_; 171 172 // The YU12 to Jpeg compressor. 173 JpegCompressor compressor_; 174 }; 175 176 } // namespace arc 177 178 #endif // INCLUDE_ARC_EXIF_UTILS_H_ 179