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