1 /*
2  * Copyright 2017 The Chromium OS Authors. All rights reserved.
3  * Use of this source code is governed by a BSD-style license that can be
4  * found in the LICENSE file.
5  */
6 
7 #ifndef INCLUDE_ARC_JPEG_COMPRESSOR_H_
8 #define INCLUDE_ARC_JPEG_COMPRESSOR_H_
9 
10 // We must include cstdio before jpeglib.h. It is a requirement of libjpeg.
11 #include <cstdio>
12 #include <vector>
13 
14 extern "C" {
15 #include <jerror.h>
16 #include <jpeglib.h>
17 }
18 
19 namespace arc {
20 
21 // Encapsulates a converter from YU12 to JPEG format. This class is not
22 // thread-safe.
23 class JpegCompressor {
24  public:
25   JpegCompressor();
26   ~JpegCompressor();
27 
28   // Compresses YU12 image to JPEG format. After calling this method, call
29   // GetCompressedImagePtr() to get the image. |quality| is the resulted jpeg
30   // image quality. It ranges from 1 (poorest quality) to 100 (highest quality).
31   // |app1Buffer| is the buffer of APP1 segment (exif) which will be added to
32   // the compressed image. Returns false if errors occur during compression.
33   bool CompressImage(const void* image, int width, int height, int quality,
34                      const void* app1Buffer, unsigned int app1Size);
35 
36   // Returns the compressed JPEG buffer pointer. This method must be called only
37   // after calling CompressImage().
38   const void* GetCompressedImagePtr();
39 
40   // Returns the compressed JPEG buffer size. This method must be called only
41   // after calling CompressImage().
42   size_t GetCompressedImageSize();
43 
44  private:
45   // InitDestination(), EmptyOutputBuffer() and TerminateDestination() are
46   // callback functions to be passed into jpeg library.
47   static void InitDestination(j_compress_ptr cinfo);
48   static boolean EmptyOutputBuffer(j_compress_ptr cinfo);
49   static void TerminateDestination(j_compress_ptr cinfo);
50   static void OutputErrorMessage(j_common_ptr cinfo);
51 
52   // Returns false if errors occur.
53   bool Encode(const void* inYuv, int width, int height, int jpegQuality,
54               const void* app1Buffer, unsigned int app1Size);
55   void SetJpegDestination(jpeg_compress_struct* cinfo);
56   void SetJpegCompressStruct(int width, int height, int quality,
57                              jpeg_compress_struct* cinfo);
58   // Returns false if errors occur.
59   bool Compress(jpeg_compress_struct* cinfo, const uint8_t* yuv);
60 
61   // The block size for encoded jpeg image buffer.
62   static const int kBlockSize = 16384;
63   // Process 16 lines of Y and 16 lines of U/V each time.
64   // We must pass at least 16 scanlines according to libjpeg documentation.
65   static const int kCompressBatchSize = 16;
66 
67   // The buffer that holds the compressed result.
68   std::vector<JOCTET> result_buffer_;
69 };
70 
71 }  // namespace arc
72 
73 #endif  // INCLUDE_ARC_JPEG_COMPRESSOR_H_
74