179 lines
6.0 KiB
C++
179 lines
6.0 KiB
C++
/*
|
|
* Copyright 2017 The Chromium OS Authors. All rights reserved.
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
* found in the LICENSE file.
|
|
*/
|
|
|
|
#ifndef INCLUDE_ARC_EXIF_UTILS_H_
|
|
#define INCLUDE_ARC_EXIF_UTILS_H_
|
|
|
|
#include <cstddef>
|
|
#include <memory>
|
|
#include <string>
|
|
#include <utility>
|
|
#include <vector>
|
|
|
|
extern "C" {
|
|
#include <libexif/exif-data.h>
|
|
}
|
|
|
|
#include "arc/jpeg_compressor.h"
|
|
|
|
namespace arc {
|
|
|
|
// ExifUtils can generate APP1 segment with tags which caller set. ExifUtils can
|
|
// also add a thumbnail in the APP1 segment if thumbnail size is specified.
|
|
// ExifUtils can be reused with different images by calling initialize().
|
|
//
|
|
// Example of using this class :
|
|
// ExifUtils utils;
|
|
// utils.initialize(inputYU12Buffer, inputWidth, inputHeight,
|
|
// outputJpegQuality);
|
|
// ...
|
|
// // Call ExifUtils functions to set Exif tags.
|
|
// ...
|
|
// utils.generateApp1();
|
|
// unsigned int app1Length = utils.getApp1Length();
|
|
// uint8_t* app1Buffer = new uint8_t[app1Length];
|
|
// memcpy(app1Buffer, utils.getApp1Buffer(), app1Length);
|
|
class ExifUtils {
|
|
public:
|
|
ExifUtils();
|
|
~ExifUtils();
|
|
|
|
// Sets input YU12 image |buffer| with |width| x |height|. |quality| is the
|
|
// compressed JPEG image quality. The caller should not release |buffer| until
|
|
// generateApp1() or the destructor is called. initialize() can be called
|
|
// multiple times. The setting of Exif tags will be cleared.
|
|
bool Initialize(const uint8_t* buffer, uint16_t width, uint16_t height,
|
|
int quality);
|
|
|
|
// Sets the manufacturer of camera.
|
|
// Returns false if memory allocation fails.
|
|
bool SetMaker(const std::string& maker);
|
|
|
|
// Sets the model number of camera.
|
|
// Returns false if memory allocation fails.
|
|
bool SetModel(const std::string& model);
|
|
|
|
// Sets the date and time of image last modified. It takes local time. The
|
|
// name of the tag is DateTime in IFD0.
|
|
// Returns false if memory allocation fails.
|
|
bool SetDateTime(const struct tm& t);
|
|
|
|
// Sets the focal length of lens used to take the image in millimeters.
|
|
// Returns false if memory allocation fails.
|
|
bool SetFocalLength(uint32_t numerator, uint32_t denominator);
|
|
|
|
// Sets the latitude with degrees minutes seconds format.
|
|
// Returns false if memory allocation fails.
|
|
bool SetGpsLatitude(double latitude);
|
|
|
|
// Sets the longitude with degrees minutes seconds format.
|
|
// Returns false if memory allocation fails.
|
|
bool SetGpsLongitude(double longitude);
|
|
|
|
// Sets the altitude in meters.
|
|
// Returns false if memory allocation fails.
|
|
bool SetGpsAltitude(double altitude);
|
|
|
|
// Sets GPS date stamp and time stamp (atomic clock). It takes UTC time.
|
|
// Returns false if memory allocation fails.
|
|
bool SetGpsTimestamp(const struct tm& t);
|
|
|
|
// Sets GPS processing method.
|
|
// Returns false if memory allocation fails.
|
|
bool SetGpsProcessingMethod(const std::string& method);
|
|
|
|
// Since the size of APP1 segment is limited, it is recommended the
|
|
// resolution of thumbnail is equal to or smaller than 640x480. If the
|
|
// thumbnail is too big, generateApp1() will return false.
|
|
// Returns false if |width| or |height| is not even.
|
|
bool SetThumbnailSize(uint16_t width, uint16_t height);
|
|
|
|
// Sets image orientation.
|
|
// Returns false if memory allocation fails.
|
|
bool SetOrientation(uint16_t orientation);
|
|
|
|
// Generates APP1 segment.
|
|
// Returns false if generating APP1 segment fails.
|
|
bool GenerateApp1();
|
|
|
|
// Gets buffer of APP1 segment. This method must be called only after calling
|
|
// generateAPP1().
|
|
const uint8_t* GetApp1Buffer();
|
|
|
|
// Gets length of APP1 segment. This method must be called only after calling
|
|
// generateAPP1().
|
|
unsigned int GetApp1Length();
|
|
|
|
private:
|
|
// Resets the pointers and memories.
|
|
void Reset();
|
|
|
|
// Adds a variable length tag to |exif_data_|. It will remove the original one
|
|
// if the tag exists.
|
|
// Returns the entry of the tag. The reference count of returned ExifEntry is
|
|
// two.
|
|
std::unique_ptr<ExifEntry> AddVariableLengthEntry(ExifIfd ifd, ExifTag tag,
|
|
ExifFormat format,
|
|
uint64_t components,
|
|
unsigned int size);
|
|
|
|
// Adds a entry of |tag| in |exif_data_|. It won't remove the original one if
|
|
// the tag exists.
|
|
// Returns the entry of the tag. It adds one reference count to returned
|
|
// ExifEntry.
|
|
std::unique_ptr<ExifEntry> AddEntry(ExifIfd ifd, ExifTag tag);
|
|
|
|
// Sets the width (number of columes) of main image.
|
|
// Returns false if memory allocation fails.
|
|
bool SetImageWidth(uint16_t width);
|
|
|
|
// Sets the length (number of rows) of main image.
|
|
// Returns false if memory allocation fails.
|
|
bool SetImageLength(uint16_t length);
|
|
|
|
// Generates a thumbnail. Calls compressor_.getCompressedImagePtr() to get the
|
|
// result image.
|
|
// Returns false if failed.
|
|
bool GenerateThumbnail();
|
|
|
|
// Resizes the thumbnail yuv image to |thumbnail_width_| x |thumbnail_height_|
|
|
// and stores in |scaled_buffer|.
|
|
// Returns false if scale image failed.
|
|
bool GenerateYuvThumbnail(std::vector<uint8_t>* scaled_buffer);
|
|
|
|
// Destroys the buffer of APP1 segment if exists.
|
|
void DestroyApp1();
|
|
|
|
// The buffer pointer of yuv image (YU12). Not owned by this class.
|
|
const uint8_t* yu12_buffer_;
|
|
// The size of yuv image.
|
|
uint16_t yu12_width_;
|
|
uint16_t yu12_height_;
|
|
|
|
// The size of thumbnail.
|
|
uint16_t thumbnail_width_;
|
|
uint16_t thumbnail_height_;
|
|
|
|
// The Exif data (APP1). Owned by this class.
|
|
ExifData* exif_data_;
|
|
// The raw data of APP1 segment. It's allocated by ExifMem in |exif_data_| but
|
|
// owned by this class.
|
|
uint8_t* app1_buffer_;
|
|
// The length of |app1_buffer_|.
|
|
unsigned int app1_length_;
|
|
// The quality of compressed thumbnail image. The size of EXIF thumbnail has
|
|
// to be smaller than 64KB. If quality is 100, the size may be bigger than
|
|
// 64KB.
|
|
int thumbnail_jpeg_quality_;
|
|
|
|
// The YU12 to Jpeg compressor.
|
|
JpegCompressor compressor_;
|
|
};
|
|
|
|
} // namespace arc
|
|
|
|
#endif // INCLUDE_ARC_EXIF_UTILS_H_
|