Andreas Gampe | ed6b9df | 2014-11-20 22:02:20 -0800 | [diff] [blame] | 1 | #ifndef _ANDROID_GRAPHICS_YUV_TO_JPEG_ENCODER_H_ |
| 2 | #define _ANDROID_GRAPHICS_YUV_TO_JPEG_ENCODER_H_ |
Wei-Ta Chen | bca2d61 | 2009-11-30 17:52:05 +0800 | [diff] [blame] | 3 | |
Dichen Zhang | 3b2c0ce | 2022-12-14 19:58:55 +0000 | [diff] [blame] | 4 | #include <android/data_space.h> |
Dichen Zhang | bfd2380 | 2023-10-26 01:29:19 +0000 | [diff] [blame] | 5 | #include <nativehelper/ScopedPrimitiveArray.h> |
Dichen Zhang | 7087aaf | 2023-04-14 19:01:05 +0000 | [diff] [blame] | 6 | #include <ultrahdr/jpegr.h> |
Dichen Zhang | 3b2c0ce | 2022-12-14 19:58:55 +0000 | [diff] [blame] | 7 | |
Wei-Ta Chen | bca2d61 | 2009-11-30 17:52:05 +0800 | [diff] [blame] | 8 | extern "C" { |
| 9 | #include "jpeglib.h" |
| 10 | #include "jerror.h" |
| 11 | } |
| 12 | |
Kevin Lubick | 1175dc0 | 2022-02-28 12:41:27 -0500 | [diff] [blame] | 13 | class SkWStream; |
| 14 | |
Wei-Ta Chen | bca2d61 | 2009-11-30 17:52:05 +0800 | [diff] [blame] | 15 | class YuvToJpegEncoder { |
| 16 | public: |
| 17 | /** Create an encoder based on the YUV format. |
| 18 | * |
| 19 | * @param pixelFormat The yuv pixel format as defined in ui/PixelFormat.h. |
| 20 | * @param strides The number of row bytes in each image plane. |
| 21 | * @return an encoder based on the pixelFormat. |
| 22 | */ |
| 23 | static YuvToJpegEncoder* create(int pixelFormat, int* strides); |
| 24 | |
Chih-Hung Hsieh | a654328 | 2016-08-29 14:46:35 -0700 | [diff] [blame] | 25 | explicit YuvToJpegEncoder(int* strides); |
Wei-Ta Chen | bca2d61 | 2009-11-30 17:52:05 +0800 | [diff] [blame] | 26 | |
| 27 | /** Encode YUV data to jpeg, which is output to a stream. |
| 28 | * |
| 29 | * @param stream The jpeg output stream. |
| 30 | * @param inYuv The input yuv data. |
Dichen Zhang | 3b2c0ce | 2022-12-14 19:58:55 +0000 | [diff] [blame] | 31 | * @param width Width of the Yuv data in terms of pixels. |
Wei-Ta Chen | bca2d61 | 2009-11-30 17:52:05 +0800 | [diff] [blame] | 32 | * @param height Height of the Yuv data in terms of pixels. |
| 33 | * @param offsets The offsets in each image plane with respect to inYuv. |
| 34 | * @param jpegQuality Picture quality in [0, 100]. |
| 35 | * @return true if successfully compressed the stream. |
| 36 | */ |
| 37 | bool encode(SkWStream* stream, void* inYuv, int width, |
| 38 | int height, int* offsets, int jpegQuality); |
| 39 | |
| 40 | virtual ~YuvToJpegEncoder() {} |
| 41 | |
| 42 | protected: |
| 43 | int fNumPlanes; |
| 44 | int* fStrides; |
| 45 | void setJpegCompressStruct(jpeg_compress_struct* cinfo, int width, |
| 46 | int height, int quality); |
| 47 | virtual void configSamplingFactors(jpeg_compress_struct* cinfo) = 0; |
| 48 | virtual void compress(jpeg_compress_struct* cinfo, |
| 49 | uint8_t* yuv, int* offsets) = 0; |
| 50 | }; |
| 51 | |
| 52 | class Yuv420SpToJpegEncoder : public YuvToJpegEncoder { |
| 53 | public: |
Chih-Hung Hsieh | a654328 | 2016-08-29 14:46:35 -0700 | [diff] [blame] | 54 | explicit Yuv420SpToJpegEncoder(int* strides); |
Andreas Gampe | ed6b9df | 2014-11-20 22:02:20 -0800 | [diff] [blame] | 55 | virtual ~Yuv420SpToJpegEncoder() {} |
Wei-Ta Chen | bca2d61 | 2009-11-30 17:52:05 +0800 | [diff] [blame] | 56 | |
| 57 | private: |
Andreas Gampe | ed6b9df | 2014-11-20 22:02:20 -0800 | [diff] [blame] | 58 | void configSamplingFactors(jpeg_compress_struct* cinfo); |
| 59 | void deinterleaveYuv(uint8_t* yuv, int width, int height, |
Wei-Ta Chen | bca2d61 | 2009-11-30 17:52:05 +0800 | [diff] [blame] | 60 | uint8_t*& yPlanar, uint8_t*& uPlanar, uint8_t*& vPlanar); |
Andreas Gampe | ed6b9df | 2014-11-20 22:02:20 -0800 | [diff] [blame] | 61 | void deinterleave(uint8_t* vuPlanar, uint8_t* uRows, uint8_t* vRows, |
| 62 | int rowIndex, int width, int height); |
| 63 | void compress(jpeg_compress_struct* cinfo, uint8_t* yuv, int* offsets); |
Wei-Ta Chen | bca2d61 | 2009-11-30 17:52:05 +0800 | [diff] [blame] | 64 | }; |
| 65 | |
| 66 | class Yuv422IToJpegEncoder : public YuvToJpegEncoder { |
| 67 | public: |
Chih-Hung Hsieh | a654328 | 2016-08-29 14:46:35 -0700 | [diff] [blame] | 68 | explicit Yuv422IToJpegEncoder(int* strides); |
Wei-Ta Chen | bca2d61 | 2009-11-30 17:52:05 +0800 | [diff] [blame] | 69 | virtual ~Yuv422IToJpegEncoder() {} |
| 70 | |
| 71 | private: |
| 72 | void configSamplingFactors(jpeg_compress_struct* cinfo); |
| 73 | void compress(jpeg_compress_struct* cinfo, uint8_t* yuv, int* offsets); |
| 74 | void deinterleave(uint8_t* yuv, uint8_t* yRows, uint8_t* uRows, |
| 75 | uint8_t* vRows, int rowIndex, int width, int height); |
| 76 | }; |
| 77 | |
Dichen Zhang | 3b2c0ce | 2022-12-14 19:58:55 +0000 | [diff] [blame] | 78 | class P010Yuv420ToJpegREncoder { |
| 79 | public: |
| 80 | /** Encode YUV data to jpeg/r, which is output to a stream. |
Dichen Zhang | f84ed40 | 2023-02-10 22:41:46 +0000 | [diff] [blame] | 81 | * This method will call JpegR::EncodeJPEGR() method. If encoding failed, |
Dichen Zhang | 3b2c0ce | 2022-12-14 19:58:55 +0000 | [diff] [blame] | 82 | * Corresponding error code (defined in jpegrerrorcode.h) will be printed and this |
| 83 | * method will be terminated and return false. |
| 84 | * |
| 85 | * @param env JNI environment. |
| 86 | * @param stream The jpeg output stream. |
| 87 | * @param hdr The input yuv data (p010 format). |
| 88 | * @param hdrColorSpaceId color space id for the input hdr. |
| 89 | * @param sdr The input yuv data (yuv420p format). |
| 90 | * @param sdrColorSpaceId color space id for the input sdr. |
| 91 | * @param width Width of the Yuv data in terms of pixels. |
| 92 | * @param height Height of the Yuv data in terms of pixels. |
| 93 | * @param jpegQuality Picture quality in [0, 100]. |
Dichen Zhang | bfd2380 | 2023-10-26 01:29:19 +0000 | [diff] [blame] | 94 | * @param exif Buffer holds EXIF package. |
Dichen Zhang | 843f1bd | 2023-10-26 02:38:21 +0000 | [diff] [blame] | 95 | * @param hdrStrides The number of row bytes in each image plane of the HDR input. |
| 96 | * @param sdrStrides The number of row bytes in each image plane of the SDR input. |
Dichen Zhang | 3b2c0ce | 2022-12-14 19:58:55 +0000 | [diff] [blame] | 97 | * @return true if successfully compressed the stream. |
| 98 | */ |
| 99 | bool encode(JNIEnv* env, |
| 100 | SkWStream* stream, void* hdr, int hdrColorSpace, void* sdr, int sdrColorSpace, |
Dichen Zhang | 843f1bd | 2023-10-26 02:38:21 +0000 | [diff] [blame] | 101 | int width, int height, int jpegQuality, ScopedByteArrayRO* exif, |
| 102 | ScopedIntArrayRO* hdrStrides, ScopedIntArrayRO* sdrStrides); |
Dichen Zhang | 3b2c0ce | 2022-12-14 19:58:55 +0000 | [diff] [blame] | 103 | |
| 104 | /** Map data space (defined in DataSpace.java and data_space.h) to the color gamut |
| 105 | * used in JPEG/R |
| 106 | * |
| 107 | * @param env JNI environment. |
| 108 | * @param aDataSpace data space defined in data_space.h. |
| 109 | * @return color gamut for JPEG/R. |
| 110 | */ |
Harish Mahendrakar | 6b09b82 | 2023-10-12 20:45:45 +0000 | [diff] [blame] | 111 | static ultrahdr::ultrahdr_color_gamut findColorGamut(JNIEnv* env, int aDataSpace); |
Dichen Zhang | 3b2c0ce | 2022-12-14 19:58:55 +0000 | [diff] [blame] | 112 | |
| 113 | /** Map data space (defined in DataSpace.java and data_space.h) to the transfer function |
| 114 | * used in JPEG/R |
| 115 | * |
| 116 | * @param env JNI environment. |
| 117 | * @param aDataSpace data space defined in data_space.h. |
| 118 | * @return color gamut for JPEG/R. |
| 119 | */ |
Harish Mahendrakar | 6b09b82 | 2023-10-12 20:45:45 +0000 | [diff] [blame] | 120 | static ultrahdr::ultrahdr_transfer_function findHdrTransferFunction(JNIEnv* env, |
| 121 | int aDataSpace); |
Dichen Zhang | 3b2c0ce | 2022-12-14 19:58:55 +0000 | [diff] [blame] | 122 | }; |
| 123 | |
Andreas Gampe | ed6b9df | 2014-11-20 22:02:20 -0800 | [diff] [blame] | 124 | #endif // _ANDROID_GRAPHICS_YUV_TO_JPEG_ENCODER_H_ |