• 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_JPEGDECODERHELPER_H
18 #define ANDROID_ULTRAHDR_JPEGDECODERHELPER_H
19 
20 // We must include cstdio before jpeglib.h. It is a requirement of libjpeg.
21 #include <cstdio>
22 extern "C" {
23 #include <jerror.h>
24 #include <jpeglib.h>
25 }
26 #include <utils/Errors.h>
27 #include <vector>
28 
29 static const int kMaxWidth = 8192;
30 static const int kMaxHeight = 8192;
31 
32 namespace android::ultrahdr {
33 /*
34  * Encapsulates a converter from JPEG to raw image (YUV420planer or grey-scale) format.
35  * This class is not thread-safe.
36  */
37 class JpegDecoderHelper {
38 public:
39     JpegDecoderHelper();
40     ~JpegDecoderHelper();
41     /*
42      * Decompresses JPEG image to raw image (YUV420planer, grey-scale or RGBA) format. After
43      * calling this method, call getDecompressedImage() to get the image.
44      * Returns false if decompressing the image fails.
45      */
46     bool decompressImage(const void* image, int length, bool decodeToRGBA = false);
47     /*
48      * Returns the decompressed raw image buffer pointer. This method must be called only after
49      * calling decompressImage().
50      */
51     void* getDecompressedImagePtr();
52     /*
53      * Returns the decompressed raw image buffer size. This method must be called only after
54      * calling decompressImage().
55      */
56     size_t getDecompressedImageSize();
57     /*
58      * Returns the image width in pixels. This method must be called only after calling
59      * decompressImage().
60      */
61     size_t getDecompressedImageWidth();
62     /*
63      * Returns the image width in pixels. This method must be called only after calling
64      * decompressImage().
65      */
66     size_t getDecompressedImageHeight();
67     /*
68      * Returns the XMP data from the image.
69      */
70     void* getXMPPtr();
71     /*
72      * Returns the decompressed XMP buffer size. This method must be called only after
73      * calling decompressImage() or getCompressedImageParameters().
74      */
75     size_t getXMPSize();
76     /*
77      * Returns the EXIF data from the image.
78      */
79     void* getEXIFPtr();
80     /*
81      * Returns the decompressed EXIF buffer size. This method must be called only after
82      * calling decompressImage() or getCompressedImageParameters().
83      */
84     size_t getEXIFSize();
85     /*
86      * Returns the ICC data from the image.
87      */
88     void* getICCPtr();
89     /*
90      * Returns the decompressed ICC buffer size. This method must be called only after
91      * calling decompressImage() or getCompressedImageParameters().
92      */
93     size_t getICCSize();
94     /*
95      * Decompresses metadata of the image. All vectors are owned by the caller.
96      */
97     bool getCompressedImageParameters(const void* image, int length,
98                                       size_t* pWidth, size_t* pHeight,
99                                       std::vector<uint8_t>* iccData,
100                                       std::vector<uint8_t>* exifData);
101 
102 private:
103     bool decode(const void* image, int length, bool decodeToRGBA);
104     // Returns false if errors occur.
105     bool decompress(jpeg_decompress_struct* cinfo, const uint8_t* dest, bool isSingleChannel);
106     bool decompressYUV(jpeg_decompress_struct* cinfo, const uint8_t* dest);
107     bool decompressRGBA(jpeg_decompress_struct* cinfo, const uint8_t* dest);
108     bool decompressSingleChannel(jpeg_decompress_struct* cinfo, const uint8_t* dest);
109     // Process 16 lines of Y and 16 lines of U/V each time.
110     // We must pass at least 16 scanlines according to libjpeg documentation.
111     static const int kCompressBatchSize = 16;
112     // The buffer that holds the decompressed result.
113     std::vector<JOCTET> mResultBuffer;
114     // The buffer that holds XMP Data.
115     std::vector<JOCTET> mXMPBuffer;
116     // The buffer that holds EXIF Data.
117     std::vector<JOCTET> mEXIFBuffer;
118     // The buffer that holds ICC Data.
119     std::vector<JOCTET> mICCBuffer;
120 
121     // Resolution of the decompressed image.
122     size_t mWidth;
123     size_t mHeight;
124 };
125 } /* namespace android::ultrahdr  */
126 
127 #endif // ANDROID_ULTRAHDR_JPEGDECODERHELPER_H
128