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