1 #ifndef _ANDROID_GRAPHICS_YUV_TO_JPEG_ENCODER_H_
2 #define _ANDROID_GRAPHICS_YUV_TO_JPEG_ENCODER_H_
3 
4 #include "SkTypes.h"
5 #include "SkStream.h"
6 extern "C" {
7     #include "jpeglib.h"
8     #include "jerror.h"
9 }
10 
11 class YuvToJpegEncoder {
12 public:
13     /** Create an encoder based on the YUV format.
14      *
15      *  @param pixelFormat The yuv pixel format as defined in ui/PixelFormat.h.
16      *  @param strides The number of row bytes in each image plane.
17      *  @return an encoder based on the pixelFormat.
18      */
19     static YuvToJpegEncoder* create(int pixelFormat, int* strides);
20 
21     YuvToJpegEncoder(int* strides);
22 
23     /** Encode YUV data to jpeg,  which is output to a stream.
24      *
25      *  @param stream The jpeg output stream.
26      *  @param inYuv The input yuv data.
27      *  @param width Width of the the Yuv data in terms of pixels.
28      *  @param height Height of the Yuv data in terms of pixels.
29      *  @param offsets The offsets in each image plane with respect to inYuv.
30      *  @param jpegQuality Picture quality in [0, 100].
31      *  @return true if successfully compressed the stream.
32      */
33     bool encode(SkWStream* stream,  void* inYuv, int width,
34            int height, int* offsets, int jpegQuality);
35 
~YuvToJpegEncoder()36     virtual ~YuvToJpegEncoder() {}
37 
38 protected:
39     int fNumPlanes;
40     int* fStrides;
41     void setJpegCompressStruct(jpeg_compress_struct* cinfo, int width,
42             int height, int quality);
43     virtual void configSamplingFactors(jpeg_compress_struct* cinfo) = 0;
44     virtual void compress(jpeg_compress_struct* cinfo,
45             uint8_t* yuv, int* offsets) = 0;
46 };
47 
48 class Yuv420SpToJpegEncoder : public YuvToJpegEncoder {
49 public:
50     Yuv420SpToJpegEncoder(int* strides);
~Yuv420SpToJpegEncoder()51     virtual ~Yuv420SpToJpegEncoder() {}
52 
53 private:
54     void configSamplingFactors(jpeg_compress_struct* cinfo);
55     void deinterleaveYuv(uint8_t* yuv, int width, int height,
56             uint8_t*& yPlanar, uint8_t*& uPlanar, uint8_t*& vPlanar);
57     void deinterleave(uint8_t* vuPlanar, uint8_t* uRows, uint8_t* vRows,
58             int rowIndex, int width, int height);
59     void compress(jpeg_compress_struct* cinfo, uint8_t* yuv, int* offsets);
60 };
61 
62 class Yuv422IToJpegEncoder : public YuvToJpegEncoder {
63 public:
64     Yuv422IToJpegEncoder(int* strides);
~Yuv422IToJpegEncoder()65     virtual ~Yuv422IToJpegEncoder() {}
66 
67 private:
68     void configSamplingFactors(jpeg_compress_struct* cinfo);
69     void compress(jpeg_compress_struct* cinfo, uint8_t* yuv, int* offsets);
70     void deinterleave(uint8_t* yuv, uint8_t* yRows, uint8_t* uRows,
71             uint8_t* vRows, int rowIndex, int width, int height);
72 };
73 
74 #endif  // _ANDROID_GRAPHICS_YUV_TO_JPEG_ENCODER_H_
75