Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f6bca5a5 authored by Nick Deakin's avatar Nick Deakin
Browse files

jpegrecoverymap: add initial recovery map calculations.

This change adds the starting point for generating and applying the
recovery map. A follow-up change will add more robust tests for this
update (eg. unit testing color conversions).

There are a few other known TODOs remaining for these map operations:
  * Clean up handling around hdr_ratio (ie. utilizing XMP)
  * Add color space information for inputs and utilize it for ICC data
  * Add handling for PQ encode/decode

No-Typo-Check: Lint suggesting typo in code as if it's a comment
Test: build
Bug: b/252835416
Change-Id: I2f6a1bf3b046036292afe46bbd2396a87cdc5164
parent dc6e0d37
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -30,10 +30,12 @@ cc_library_static {

    srcs: [
        "recoverymap.cpp",
        "recoverymapmath.cpp",
    ],

    shared_libs: [
        "libimage_io",
        "libjpeg",
        "libutils",
    ],
}
+21 −2
Original line number Diff line number Diff line
@@ -14,6 +14,10 @@
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef ANDROID_JPEGRECOVERYMAP_JPEGDECODER_H
#define ANDROID_JPEGRECOVERYMAP_JPEGDECODER_H

// We must include cstdio before jpeglib.h. It is a requirement of libjpeg.
#include <cstdio>
extern "C" {
@@ -41,12 +45,22 @@ public:
     * Returns the decompressed raw image buffer pointer. This method must be called only after
     * calling decompressImage().
     */
    const void* getDecompressedImagePtr();
    void* getDecompressedImagePtr();
    /*
     * Returns the decompressed raw image buffer size. This method must be called only after
     * calling decompressImage().
     */
    size_t getDecompressedImageSize();
    /*
     * Returns the image width in pixels. This method must be called only after calling
     * decompressImage().
     */
    size_t getDecompressedImageWidth();
    /*
     * Returns the image width in pixels. This method must be called only after calling
     * decompressImage().
     */
    size_t getDecompressedImageHeight();
private:
    bool decode(const void* image, int length);
    // Returns false if errors occur.
@@ -56,7 +70,12 @@ private:
    // Process 16 lines of Y and 16 lines of U/V each time.
    // We must pass at least 16 scanlines according to libjpeg documentation.
    static const int kCompressBatchSize = 16;
    // The buffer that holds the compressed result.
    // The buffer that holds the decompressed result.
    std::vector<JOCTET> mResultBuffer;
    // Resolution of the decompressed image.
    size_t mWidth;
    size_t mHeight;
};
} /* namespace android  */

#endif // ANDROID_JPEGRECOVERYMAP_JPEGDECODER_H
+7 −2
Original line number Diff line number Diff line
@@ -14,6 +14,9 @@
 * limitations under the License.
 */

#ifndef ANDROID_JPEGRECOVERYMAP_JPEGENCODER_H
#define ANDROID_JPEGRECOVERYMAP_JPEGENCODER_H

// We must include cstdio before jpeglib.h. It is a requirement of libjpeg.
#include <cstdio>

@@ -50,7 +53,7 @@ public:
     * Returns the compressed JPEG buffer pointer. This method must be called only after calling
     * compressImage().
     */
    const void* getCompressedImagePtr();
    void* getCompressedImagePtr();

    /*
     * Returns the compressed JPEG buffer size. This method must be called only after calling
@@ -88,3 +91,5 @@ private:
};

} /* namespace android  */

#endif // ANDROID_JPEGRECOVERYMAP_JPEGENCODER_H
+3 −1
Original line number Diff line number Diff line
@@ -35,6 +35,8 @@ enum {
    ERROR_JPEGR_INVALID_INPUT_TYPE      = JPEGR_IO_ERROR_BASE,
    ERROR_JPEGR_INVALID_OUTPUT_TYPE     = JPEGR_IO_ERROR_BASE - 1,
    ERROR_JPEGR_INVALID_NULL_PTR        = JPEGR_IO_ERROR_BASE - 2,
    ERROR_JPEGR_RESOLUTION_MISMATCH     = JPEGR_IO_ERROR_BASE - 3,
    ERROR_JPEGR_BUFFER_TOO_SMALL        = JPEGR_IO_ERROR_BASE - 4,

    JPEGR_RUNTIME_ERROR_BASE            = -20000,
    ERROR_JPEGR_ENCODE_ERROR            = JPEGR_RUNTIME_ERROR_BASE - 1,
+24 −16
Original line number Diff line number Diff line
@@ -14,6 +14,9 @@
 * limitations under the License.
 */

#ifndef ANDROID_JPEGRECOVERYMAP_RECOVERYMAP_H
#define ANDROID_JPEGRECOVERYMAP_RECOVERYMAP_H

#include "jpegrerrorcode.h"

namespace android::recoverymap {
@@ -71,7 +74,8 @@ public:
     * Compress JPEGR image from 10-bit HDR YUV and 8-bit SDR YUV.
     *
     * Generate recovery map from the HDR and SDR inputs, compress SDR YUV to 8-bit JPEG and append
     * the recovery map to the end of the compressed JPEG.
     * the recovery map to the end of the compressed JPEG. HDR and SDR inputs must be the same
     * resolution and color space.
     * @param uncompressed_p010_image uncompressed HDR image in P010 color format
     * @param uncompressed_yuv_420_image uncompressed SDR image in YUV_420 color format
     * @param dest destination of the compressed JPEGR image
@@ -84,7 +88,7 @@ public:
     */
    status_t encodeJPEGR(jr_uncompressed_ptr uncompressed_p010_image,
                         jr_uncompressed_ptr uncompressed_yuv_420_image,
                         void* dest,
                         jr_compressed_ptr dest,
                         int quality,
                         jr_exif_ptr exif,
                         float hdr_ratio = 0.0f);
@@ -95,7 +99,7 @@ public:
     * This method requires HAL Hardware JPEG encoder.
     *
     * Generate recovery map from the HDR and SDR inputs, append the recovery map to the end of the
     * compressed JPEG.
     * compressed JPEG. HDR and SDR inputs must be the same resolution and color space.
     * @param uncompressed_p010_image uncompressed HDR image in P010 color format
     * @param uncompressed_yuv_420_image uncompressed SDR image in YUV_420 color format
     * @param compressed_jpeg_image compressed 8-bit JPEG image
@@ -106,8 +110,8 @@ public:
     */
    status_t encodeJPEGR(jr_uncompressed_ptr uncompressed_p010_image,
                         jr_uncompressed_ptr uncompressed_yuv_420_image,
                         void* compressed_jpeg_image,
                         void* dest,
                         jr_compressed_ptr compressed_jpeg_image,
                         jr_compressed_ptr dest,
                         float hdr_ratio = 0.0f);

    /*
@@ -116,7 +120,8 @@ public:
     * This method requires HAL Hardware JPEG encoder.
     *
     * Decode the compressed 8-bit JPEG image to YUV SDR, generate recovery map from the HDR input
     * and the decoded SDR result, append the recovery map to the end of the compressed JPEG.
     * and the decoded SDR result, append the recovery map to the end of the compressed JPEG. HDR
     * and SDR inputs must be the same resolution and color space.
     * @param uncompressed_p010_image uncompressed HDR image in P010 color format
     * @param compressed_jpeg_image compressed 8-bit JPEG image
     * @param dest destination of the compressed JPEGR image
@@ -125,8 +130,8 @@ public:
     * @return NO_ERROR if encoding succeeds, error code if error occurs.
     */
    status_t encodeJPEGR(jr_uncompressed_ptr uncompressed_p010_image,
                         void* compressed_jpeg_image,
                         void* dest,
                         jr_compressed_ptr compressed_jpeg_image,
                         jr_compressed_ptr dest,
                         float hdr_ratio = 0.0f);

    /*
@@ -147,7 +152,7 @@ public:
     *                    |       SDR      |     false     |          SDR         |
     * @return NO_ERROR if decoding succeeds, error code if error occurs.
     */
    status_t decodeJPEGR(void* compressed_jpegr_image,
    status_t decodeJPEGR(jr_compressed_ptr compressed_jpegr_image,
                         jr_uncompressed_ptr dest,
                         jr_exif_ptr exif = nullptr,
                         bool request_sdr = false);
@@ -159,7 +164,7 @@ private:
     * @param dest decoded recover map
     * @return NO_ERROR if decoding succeeds, error code if error occurs.
     */
    status_t decodeRecoveryMap(jr_compressed_ptr compressed_recovery_map,
    status_t decompressRecoveryMap(jr_compressed_ptr compressed_recovery_map,
                               jr_uncompressed_ptr dest);

    /*
@@ -169,16 +174,17 @@ private:
     * @param dest encoded recover map
     * @return NO_ERROR if encoding succeeds, error code if error occurs.
     */
    status_t encodeRecoveryMap(jr_uncompressed_ptr uncompressed_recovery_map,
    status_t compressRecoveryMap(jr_uncompressed_ptr uncompressed_recovery_map,
                               jr_compressed_ptr dest);

    /*
     * This method is called in the encoding pipeline. It will take the uncompressed 8-bit and
     * 10-bit yuv images as input, and calculate the uncompressed recovery map.
     * 10-bit yuv images as input, and calculate the uncompressed recovery map. The input images
     * must be the same resolution.
     *
     * @param uncompressed_yuv_420_image uncompressed SDR image in YUV_420 color format
     * @param uncompressed_p010_image uncompressed HDR image in P010 color format
     * @param dest recover map
     * @param dest recovery map; caller responsible for memory of data
     * @return NO_ERROR if calculation succeeds, error code if error occurs.
     */
    status_t generateRecoveryMap(jr_uncompressed_ptr uncompressed_yuv_420_image,
@@ -207,7 +213,7 @@ private:
     * @param dest destination of compressed recovery map
     * @return NO_ERROR if calculation succeeds, error code if error occurs.
     */
    status_t extractRecoveryMap(void* compressed_jpegr_image, jr_compressed_ptr dest);
    status_t extractRecoveryMap(jr_compressed_ptr compressed_jpegr_image, jr_compressed_ptr dest);

    /*
     * This method is called in the encoding pipeline. It will take the standard 8-bit JPEG image
@@ -219,9 +225,9 @@ private:
     * @param dest compressed JPEGR image
     * @return NO_ERROR if calculation succeeds, error code if error occurs.
     */
    status_t appendRecoveryMap(void* compressed_jpeg_image,
    status_t appendRecoveryMap(jr_compressed_ptr compressed_jpeg_image,
                               jr_compressed_ptr compressed_recovery_map,
                               void* dest);
                               jr_compressed_ptr dest);

    /*
     * This method generates XMP metadata.
@@ -266,3 +272,5 @@ private:
};

} // namespace android::recoverymap

#endif // ANDROID_JPEGRECOVERYMAP_RECOVERYMAP_H
Loading