• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2022 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef ANDROID_ULTRAHDR_JPEGENCODERHELPER_H
18 #define ANDROID_ULTRAHDR_JPEGENCODERHELPER_H
19 
20 // We must include cstdio before jpeglib.h. It is a requirement of libjpeg.
21 #include <cstdio>
22 
23 extern "C" {
24 #include <jerror.h>
25 #include <jpeglib.h>
26 }
27 
28 #include <utils/Errors.h>
29 #include <vector>
30 
31 namespace android::ultrahdr {
32 
33 /*
34  * Encapsulates a converter from raw image (YUV420planer or grey-scale) to JPEG format.
35  * This class is not thread-safe.
36  */
37 class JpegEncoderHelper {
38 public:
39     JpegEncoderHelper();
40     ~JpegEncoderHelper();
41 
42     /*
43      * Compresses YUV420Planer image to JPEG format. After calling this method, call
44      * getCompressedImage() to get the image. |quality| is the jpeg image quality parameter to use.
45      * It ranges from 1 (poorest quality) to 100 (highest quality). |iccBuffer| is the buffer of
46      * ICC segment which will be added to the compressed image.
47      * Returns false if errors occur during compression.
48      */
49     bool compressImage(const void* image, int width, int height, int quality,
50                        const void* iccBuffer, unsigned int iccSize, bool isSingleChannel = false);
51 
52     /*
53      * Returns the compressed JPEG buffer pointer. This method must be called only after calling
54      * compressImage().
55      */
56     void* getCompressedImagePtr();
57 
58     /*
59      * Returns the compressed JPEG buffer size. This method must be called only after calling
60      * compressImage().
61      */
62     size_t getCompressedImageSize();
63 
64     /*
65      * Process 16 lines of Y and 16 lines of U/V each time.
66      * We must pass at least 16 scanlines according to libjpeg documentation.
67      */
68     static const int kCompressBatchSize = 16;
69 private:
70     // initDestination(), emptyOutputBuffer() and emptyOutputBuffer() are callback functions to be
71     // passed into jpeg library.
72     static void initDestination(j_compress_ptr cinfo);
73     static boolean emptyOutputBuffer(j_compress_ptr cinfo);
74     static void terminateDestination(j_compress_ptr cinfo);
75     static void outputErrorMessage(j_common_ptr cinfo);
76 
77     // Returns false if errors occur.
78     bool encode(const void* inYuv, int width, int height, int jpegQuality,
79                 const void* iccBuffer, unsigned int iccSize, bool isSingleChannel);
80     void setJpegDestination(jpeg_compress_struct* cinfo);
81     void setJpegCompressStruct(int width, int height, int quality, jpeg_compress_struct* cinfo,
82                                bool isSingleChannel);
83     // Returns false if errors occur.
84     bool compress(jpeg_compress_struct* cinfo, const uint8_t* image, bool isSingleChannel);
85     bool compressYuv(jpeg_compress_struct* cinfo, const uint8_t* yuv);
86     bool compressSingleChannel(jpeg_compress_struct* cinfo, const uint8_t* image);
87 
88     // The block size for encoded jpeg image buffer.
89     static const int kBlockSize = 16384;
90 
91     // The buffer that holds the compressed result.
92     std::vector<JOCTET> mResultBuffer;
93 };
94 
95 } /* namespace android::ultrahdr  */
96 
97 #endif // ANDROID_ULTRAHDR_JPEGENCODERHELPER_H
98