1 #ifndef _ANDROID_GRAPHICS_YUV_TO_JPEG_ENCODER_H_
2 #define _ANDROID_GRAPHICS_YUV_TO_JPEG_ENCODER_H_
3 
4 #include <android/data_space.h>
5 #include <nativehelper/ScopedPrimitiveArray.h>
6 #include <ultrahdr/jpegr.h>
7 
8 extern "C" {
9     #include "jpeglib.h"
10     #include "jerror.h"
11 }
12 
13 class SkWStream;
14 
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 
25     explicit YuvToJpegEncoder(int* strides);
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.
31      *  @param width Width of the Yuv data in terms of pixels.
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 
~YuvToJpegEncoder()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:
54     explicit Yuv420SpToJpegEncoder(int* strides);
~Yuv420SpToJpegEncoder()55     virtual ~Yuv420SpToJpegEncoder() {}
56 
57 private:
58     void configSamplingFactors(jpeg_compress_struct* cinfo);
59     void deinterleaveYuv(uint8_t* yuv, int width, int height,
60             uint8_t*& yPlanar, uint8_t*& uPlanar, uint8_t*& vPlanar);
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);
64 };
65 
66 class Yuv422IToJpegEncoder : public YuvToJpegEncoder {
67 public:
68     explicit Yuv422IToJpegEncoder(int* strides);
~Yuv422IToJpegEncoder()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 
78 class P010Yuv420ToJpegREncoder {
79 public:
80     /** Encode YUV data to jpeg/r,  which is output to a stream.
81      *  This method will call JpegR::EncodeJPEGR() method. If encoding failed,
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].
94      *  @param exif Buffer holds EXIF package.
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.
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,
101             int width, int height, int jpegQuality, ScopedByteArrayRO* exif,
102             ScopedIntArrayRO* hdrStrides, ScopedIntArrayRO* sdrStrides);
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      */
111     static ultrahdr::ultrahdr_color_gamut findColorGamut(JNIEnv* env, int aDataSpace);
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      */
120     static ultrahdr::ultrahdr_transfer_function findHdrTransferFunction(JNIEnv* env,
121                                                                         int aDataSpace);
122 };
123 
124 #endif  // _ANDROID_GRAPHICS_YUV_TO_JPEG_ENCODER_H_
125