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"
6extern "C" {
7    #include "jpeglib.h"
8    #include "jerror.h"
9}
10
11class YuvToJpegEncoder {
12public:
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
36    virtual ~YuvToJpegEncoder() {}
37
38protected:
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
48class Yuv420SpToJpegEncoder : public YuvToJpegEncoder {
49public:
50    Yuv420SpToJpegEncoder(int* strides);
51    virtual ~Yuv420SpToJpegEncoder() {}
52
53private:
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
62class Yuv422IToJpegEncoder : public YuvToJpegEncoder {
63public:
64    Yuv422IToJpegEncoder(int* strides);
65    virtual ~Yuv422IToJpegEncoder() {}
66
67private:
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