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