Home | History | Annotate | Download | only in arc
      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