Skip to content

Commit

Permalink
v2.0 -- transcoding layer
Browse files Browse the repository at this point in the history
  • Loading branch information
DichenZhang1 committed Apr 11, 2024
1 parent 75e3a91 commit c82e44a
Show file tree
Hide file tree
Showing 14 changed files with 1,913 additions and 41 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,7 @@ set_property(DIRECTORY PROPERTY ADDITIONAL_MAKE_CLEAN_FILES
# File Lists
###########################################################
file(GLOB UHDR_CORE_SRCS_LIST "${SOURCE_DIR}/src/*.cpp")
file(GLOB UHDR_TEST_SRCS_LIST "${TESTS_DIR}/*.cpp")
file(GLOB UHDR_TEST_SRCS_LIST "${TESTS_DIR}/ultrahdr_test.cpp")
file(GLOB UHDR_BM_SRCS_LIST "${BENCHMARK_DIR}/*.cpp")
file(GLOB IMAGE_IO_SRCS_LIST "${THIRD_PARTY_DIR}/image_io/src/**/*.cc")

Expand Down
23 changes: 23 additions & 0 deletions lib/include/ultrahdr/editorhelper.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,26 @@ typedef enum {
ULTRAHDR_MIRROR_HORIZONTAL,
} ultrahdr_mirroring_direction;

typedef struct ultrahdr_crop_effect_struct : ultrahdr_effect {
int left;
int right;
int top;
int bottom;
} ultrahdr_crop_effect;

typedef struct ultrahdr_mirror_effect_struct : ultrahdr_effect {
ultrahdr_mirroring_direction mirror_dir;
} ultrahdr_mirror_effect;

typedef struct ultrahdr_rotate_effect_struct : ultrahdr_effect {
int clockwise_degree;
} ultrahdr_rotate_effect;

typedef struct ultrahdr_resize_effect_struct : ultrahdr_effect {
int new_width;
int new_height;
} ultrahdr_resize_effect;

status_t crop(uhdr_uncompressed_ptr const in_img,
int left, int right, int top, int bottom, uhdr_uncompressed_ptr out_img);

Expand All @@ -39,6 +59,9 @@ status_t rotate(uhdr_uncompressed_ptr const in_img, int clockwise_degree,
status_t resize(uhdr_uncompressed_ptr const in_img, int out_width, int out_height,
uhdr_uncompressed_ptr out_img);

status_t addEffects(uhdr_uncompressed_ptr const in_img, std::vector<ultrahdr_effect*>& effects,
uhdr_uncompressed_ptr out_image);

} // namespace ultrahdr

#endif // ULTRAHDR_EDITORHELPER_H
54 changes: 27 additions & 27 deletions lib/include/ultrahdr/heifr.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ class MemoryWriter {
size_t capacity_;
};

class HeifR : public UltraHdr{
class HeifR : public UltraHdr {
public:
/*
* Experimental only
Expand Down Expand Up @@ -127,6 +127,32 @@ class HeifR : public UltraHdr{
ultrahdr_codec codec,
uhdr_exif_ptr exif);

/*
* Encode API-x
* Compress HEIFR image from SDR YUV and raw gain map.
*
* This method is only used for transcoding case.
*
* @param yuv420_image_ptr uncompressed SDR image in YUV_420 color format
* @param gainmap_image_ptr uncompressed gain map image in Y single channel color format
* @param metadata gain map metadata to be written in the primary image
* @param dest destination of the compressed HEIFR image. Please note that {@code maxLength}
* represents the maximum available size of the desitination buffer, and it must be
* set before calling this method. If the encoded HEIFR size exceeds
* {@code maxLength}, this method will return {@code ERROR_JPEGR_BUFFER_TOO_SMALL}.
* @param quality target quality of the JPEG encoding, must be in range of 0-100 where 100 is
* the highest quality
* @param exif pointer to the exif metadata.
* @param codec target output image codec (HEIC for HEVC codec, AVIF for AV1 codec)
* @return NO_ERROR if encoding succeeds, error code if error occurs.
*/
status_t encodeHeifWithGainMap(uhdr_uncompressed_ptr yuv420_image_ptr,
uhdr_uncompressed_ptr gainmap_image_ptr,
ultrahdr_metadata_ptr metadata,
uhdr_compressed_ptr dest, int quality,
ultrahdr_codec codec,
uhdr_exif_ptr exif);

/*
* Decode API
* Decompress HEIFR image.
Expand Down Expand Up @@ -175,32 +201,6 @@ class HeifR : public UltraHdr{
ultrahdr_output_format output_format = ULTRAHDR_OUTPUT_HDR_LINEAR,
uhdr_uncompressed_ptr gainmap_image_ptr = nullptr,
ultrahdr_metadata_ptr metadata = nullptr);
protected:
/*
* Encode API-x
* Compress HEIFR image from SDR YUV and raw gain map.
*
* This method is only used for transcoding case.
*
* @param yuv420_image_ptr uncompressed SDR image in YUV_420 color format
* @param gainmap_image_ptr uncompressed gain map image in Y single channel color format
* @param metadata gain map metadata to be written in the primary image
* @param dest destination of the compressed HEIFR image. Please note that {@code maxLength}
* represents the maximum available size of the desitination buffer, and it must be
* set before calling this method. If the encoded HEIFR size exceeds
* {@code maxLength}, this method will return {@code ERROR_JPEGR_BUFFER_TOO_SMALL}.
* @param quality target quality of the JPEG encoding, must be in range of 0-100 where 100 is
* the highest quality
* @param exif pointer to the exif metadata.
* @param codec target output image codec (HEIC for HEVC codec, AVIF for AV1 codec)
* @return NO_ERROR if encoding succeeds, error code if error occurs.
*/
status_t encodeHeifWithGainMap(uhdr_uncompressed_ptr yuv420_image_ptr,
uhdr_uncompressed_ptr gainmap_image_ptr,
ultrahdr_metadata_ptr metadata,
uhdr_compressed_ptr dest, int quality,
ultrahdr_codec codec,
uhdr_exif_ptr exif);
};
} // namespace ultrahdr

Expand Down
46 changes: 34 additions & 12 deletions lib/include/ultrahdr/jpegr.h
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,40 @@ class JpegR : public UltraHdr {
*/
status_t getJPEGRInfo(uhdr_compressed_ptr jpegr_image_ptr, uhdr_info_ptr jpeg_image_info_ptr);

/*
* This method is called to separate primary image and gain map image from JPEGR
*
* @param jpegr_image_ptr pointer to compressed JPEGR image.
* @param primary_jpg_image_ptr destination of primary image
* @param gainmap_jpg_image_ptr destination of compressed gain map image
* @return NO_ERROR if calculation succeeds, error code if error occurs.
*/
static status_t extractPrimaryImageAndGainMap(uhdr_compressed_ptr jpegr_image_ptr,
uhdr_compressed_ptr primary_jpg_image_ptr,
uhdr_compressed_ptr gainmap_jpg_image_ptr);

/*
* Encode API-x
* Compress JPEGR image from SDR YUV and raw gain map.
*
* This method is only used for transcoding case.
*
* @param yuv420_image_ptr uncompressed SDR image in YUV_420 color format
* @param gainmap_image_ptr uncompressed gain map image in Y single channel color format
* @param metadata metadata to be written in XMP of the primary jpeg
* @param dest destination of the compressed JPEGR image. Please note that {@code maxLength}
* represents the maximum available size of the desitination buffer, and it must be
* set before calling this method. If the encoded JPEGR size exceeds
* {@code maxLength}, this method will return {@code ERROR_JPEGR_BUFFER_TOO_SMALL}.
* @param quality target quality of the JPEG encoding, must be in range of 0-100 where 100 is
* the highest quality
* @param exif pointer to the exif metadata.
* @return NO_ERROR if encoding succeeds, error code if error occurs.
*/
status_t encodeJPEGR(uhdr_uncompressed_ptr yuv420_image_ptr, uhdr_uncompressed_ptr gainmap_image_ptr,
ultrahdr_metadata_ptr metadata, uhdr_compressed_ptr dest, int quality,
uhdr_exif_ptr exif);

private:
/*
* This method is called in the encoding pipeline. It will encode the gain map.
Expand All @@ -241,18 +275,6 @@ class JpegR : public UltraHdr {
status_t compressGainMap(uhdr_uncompressed_ptr gainmap_image_ptr,
JpegEncoderHelper* jpeg_enc_obj_ptr);

/*
* This method is called to separate primary image and gain map image from JPEGR
*
* @param jpegr_image_ptr pointer to compressed JPEGR image.
* @param primary_jpg_image_ptr destination of primary image
* @param gainmap_jpg_image_ptr destination of compressed gain map image
* @return NO_ERROR if calculation succeeds, error code if error occurs.
*/
status_t extractPrimaryImageAndGainMap(uhdr_compressed_ptr jpegr_image_ptr,
uhdr_compressed_ptr primary_jpg_image_ptr,
uhdr_compressed_ptr gainmap_jpg_image_ptr);

/*
* Gets Info from JPEG image without decoding it.
*
Expand Down
164 changes: 163 additions & 1 deletion lib/include/ultrahdr/ultrahdr.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@
#ifndef ULTRAHDR_ULTRAHDR_H
#define ULTRAHDR_ULTRAHDR_H

#include <memory>
#include <string>
#include <vector>

#define WITH_EXPERIMENTAL_GAIN_MAP 1

Expand Down Expand Up @@ -57,7 +59,8 @@ typedef enum {
ULTRAHDR_OUTPUT_HDR_LINEAR, // HDR in F16 color format (linear)
ULTRAHDR_OUTPUT_HDR_PQ, // HDR in RGBA_1010102 color format (PQ transfer function)
ULTRAHDR_OUTPUT_HDR_HLG, // HDR in RGBA_1010102 color format (HLG transfer function)
ULTRAHDR_OUTPUT_MAX = ULTRAHDR_OUTPUT_HDR_HLG,
ULTRAHDR_OUTPUT_HDR_LINEAR_RGB_10BIT,
ULTRAHDR_OUTPUT_MAX = ULTRAHDR_OUTPUT_HDR_LINEAR_RGB_10BIT,
} ultrahdr_output_format;

// Supported pixel format
Expand Down Expand Up @@ -111,6 +114,7 @@ typedef enum {
ERROR_ULTRAHDR_NO_IMAGES_FOUND = ULTRAHDR_RUNTIME_ERROR_BASE - 6,
ERROR_ULTRAHDR_MULTIPLE_EXIFS_RECEIVED = ULTRAHDR_RUNTIME_ERROR_BASE - 7,
ERROR_ULTRAHDR_UNSUPPORTED_MAP_SCALE_FACTOR = ULTRAHDR_RUNTIME_ERROR_BASE - 8,
ERROR_ULTRAHDR_INSUFFICIENT_RESOURCE = ULTRAHDR_RUNTIME_ERROR_BASE - 9,

ERROR_ULTRAHDR_UNSUPPORTED_FEATURE = -30000,
} status_t;
Expand Down Expand Up @@ -208,7 +212,124 @@ static const char* const kGainMapVersion = "1.0";
// Map is quarter res / sixteenth size
static const size_t kMapDimensionScaleFactor = 4;

typedef struct ultrahdr_effect_struct {
virtual ~ultrahdr_effect_struct() = default;
} ultrahdr_effect;

/**
* Holds configuration information.
*/
typedef struct ultrahdr_configuration_struct {
// The encoding quality of the primary image for encoding, or the output image for
// transcoding, in the range of 0~100.
int quality;
// The encoding quality of the gain map, in the range of 0~100.
// TODO:
// int gain_map_quality;
// Color gamut.
ultrahdr_color_gamut colorGamut;
// HDR transfer function
ultrahdr_transfer_function transferFunction;
// The codec for the output image
ultrahdr_codec outputCodec;
// Pixel format
ultrahdr_pixel_format pixelFormat;
// Editing effects
std::vector<ultrahdr_effect*> effects;
//
float maxDisplayBoost;
} ultrahdr_configuration;

class UltraHdr {
public:
/**
* Adding input image to the library.
*
* @param image input image.
*
* @return NO_ERROR if encoding succeeds, error code if error occurs.
*/
status_t addImage(ultrahdr_compressed_struct* image);

/**
* Adding input image to the library.
*
* @param image input image.
*
* @return NO_ERROR if encoding succeeds, error code if error occurs.
*/
status_t addImage(ultrahdr_uncompressed_struct* image);

/**
* Adding input gain map to the library.
* (Gain map image and metadata may be calculated from outside this library)
*
* @param gainMapImage input gain map image.
* @param gainMapMetadata input gain map metadata.
*
* @return NO_ERROR if encoding succeeds, error code if error occurs.
*/
status_t addGainMap(ultrahdr_compressed_struct* gainMapImage,
ultrahdr_metadata_struct* gainMapMetadata);

/**
* Adding EXIF metadata to the library.
*
* @param exif EXIF metadata.
*
* @return NO_ERROR if encoding succeeds, error code if error occurs.
*/
status_t addExif(ultrahdr_exif_struct* exif);

/**
* Extracts the EXIF metadata from the input image.
*
* @param dest destination of the EXIF.
*
* @return NO_ERROR if encoding succeeds, error code if error occurs.
*/
status_t getExif(ultrahdr_exif_struct*& dest);

/**
* Extracts the gain map from the input image.
*
* @param dest destination of the gain map.
*
* @return NO_ERROR if encoding succeeds, error code if error occurs.
*/
status_t getGainMap(ultrahdr_uncompressed_struct*& dest);

/**
* Extracts the gain map related metadata from the input image.
*
* @param dest destination of the metadata.
*
* @return NO_ERROR if encoding succeeds, error code if error occurs.
*/
status_t getGainMapMetadata(ultrahdr_metadata_ptr& metadata);

/**
* API-1
* Converts the input image(s) to target format.
*
* @param config configure from user.
* @param dest destination of the output image.
*
* @return NO_ERROR if encoding succeeds, error code if error occurs.
*/
status_t convert(ultrahdr_configuration* config, uhdr_compressed_ptr& dest);

/**
* API-2
* Converts the input image(s) to target format.
*
* @param config configure from user.
* @param dest destination of the output image.
*
* @return NO_ERROR if encoding succeeds, error code if error occurs.
*/
status_t convert(ultrahdr_configuration* config, uhdr_uncompressed_ptr& dest);

protected:
/*
* This method is called in the encoding pipeline. It will take the uncompressed 8-bit and
Expand Down Expand Up @@ -258,6 +379,47 @@ class UltraHdr {
* @param dest pointer to store tonemapped SDR image
*/
status_t toneMap(uhdr_uncompressed_ptr src, uhdr_uncompressed_ptr dest);

private:
/**
* When {@code sdr_jpeg_img} is available but {@code sdr_raw_img} is empty, decode the SDR JPEG
* image and extract the EXIF.
*
* @return NO_ERROR if encoding succeeds, error code if error occurs.
*/
status_t maybeDecodeJpegSdr();

/**
* When {@code hdr_raw_img} is available but {@code sdr_raw_img} is empty, tone map the raw HDR
* image.
*
* @return NO_ERROR if encoding succeeds, error code if error occurs.
*/
status_t maybeToneMapRawHdr();

void createOutputMemory(int size, void*& dest);

std::shared_ptr<ultrahdr_uncompressed_struct> sdr_raw_img = nullptr;
std::shared_ptr<ultrahdr_uncompressed_struct> hdr_raw_img = nullptr;
std::shared_ptr<ultrahdr_uncompressed_struct> gain_map_raw_img = nullptr;
std::shared_ptr<ultrahdr_exif_struct> exif = nullptr;
std::shared_ptr<ultrahdr_compressed_struct> sdr_jpeg_img = nullptr;
std::shared_ptr<ultrahdr_compressed_struct> sdr_heif_img = nullptr;
std::shared_ptr<ultrahdr_compressed_struct> gain_map_jpeg_img = nullptr;
std::shared_ptr<ultrahdr_metadata_struct> gain_map_metadata = nullptr;


// shared_ptr<ultrahdr_uncompressed_image> recon_hdr_img = nullptr; // linear RGBA1010102 color space

std::shared_ptr<uint8_t[]> sdr_raw_img_data = nullptr;
std::shared_ptr<uint8_t[]> hdr_raw_img_data = nullptr;
std::shared_ptr<uint8_t[]> gain_map_raw_img_data = nullptr;
std::shared_ptr<uint8_t[]> exif_data = nullptr;
std::shared_ptr<uint8_t[]> sdr_jpeg_img_data = nullptr;
std::shared_ptr<uint8_t[]> sdr_heif_img_data = nullptr;
std::shared_ptr<uint8_t[]> gain_map_jpeg_img_data = nullptr;

std::vector<std::shared_ptr<uint8_t[]>> shared_output_data;
};


Expand Down
Loading

0 comments on commit c82e44a

Please sign in to comment.