blob: 5c9c8b6ec6b072478df665f0f81c6c5b2cb18c01 [file] [log] [blame]
Dichen Zhang0d12ba82022-10-19 20:44:51 +00001
2/*
3 * Copyright 2022 The Android Open Source Project
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
Nick Deakinf6bca5a2022-11-04 10:43:43 -040017
18#ifndef ANDROID_JPEGRECOVERYMAP_JPEGDECODER_H
19#define ANDROID_JPEGRECOVERYMAP_JPEGDECODER_H
20
Dichen Zhang0d12ba82022-10-19 20:44:51 +000021// We must include cstdio before jpeglib.h. It is a requirement of libjpeg.
22#include <cstdio>
23extern "C" {
24#include <jerror.h>
25#include <jpeglib.h>
26}
27#include <utils/Errors.h>
28#include <vector>
29namespace android::recoverymap {
30/*
31 * Encapsulates a converter from JPEG to raw image (YUV420planer or grey-scale) format.
32 * This class is not thread-safe.
33 */
34class JpegDecoder {
35public:
36 JpegDecoder();
37 ~JpegDecoder();
38 /*
39 * Decompresses JPEG image to raw image (YUV420planer or grey-scale) format. After calling
40 * this method, call getDecompressedImage() to get the image.
41 * Returns false if decompressing the image fails.
42 */
43 bool decompressImage(const void* image, int length);
44 /*
45 * Returns the decompressed raw image buffer pointer. This method must be called only after
46 * calling decompressImage().
47 */
Nick Deakinf6bca5a2022-11-04 10:43:43 -040048 void* getDecompressedImagePtr();
Dichen Zhang0d12ba82022-10-19 20:44:51 +000049 /*
50 * Returns the decompressed raw image buffer size. This method must be called only after
51 * calling decompressImage().
52 */
53 size_t getDecompressedImageSize();
Nick Deakinf6bca5a2022-11-04 10:43:43 -040054 /*
55 * Returns the image width in pixels. This method must be called only after calling
56 * decompressImage().
57 */
58 size_t getDecompressedImageWidth();
59 /*
60 * Returns the image width in pixels. This method must be called only after calling
61 * decompressImage().
62 */
63 size_t getDecompressedImageHeight();
Fyodor Kyslov1dcc4422022-11-16 01:40:53 +000064 /*
65 * Returns the XMP data from the image.
66 */
67 void* getXMPPtr();
68 /*
69 * Returns the decompressed XMP buffer size. This method must be called only after
70 * calling decompressImage().
71 */
72 size_t getXMPSize();
73
74 bool getCompressedImageParameters(const void* image, int length,
75 size_t* pWidth, size_t* pHeight,
76 std::vector<uint8_t>* &iccData,
77 std::vector<uint8_t>* &exifData);
78
Dichen Zhang0d12ba82022-10-19 20:44:51 +000079private:
80 bool decode(const void* image, int length);
81 // Returns false if errors occur.
82 bool decompress(jpeg_decompress_struct* cinfo, const uint8_t* dest, bool isSingleChannel);
83 bool decompressYUV(jpeg_decompress_struct* cinfo, const uint8_t* dest);
84 bool decompressSingleChannel(jpeg_decompress_struct* cinfo, const uint8_t* dest);
85 // Process 16 lines of Y and 16 lines of U/V each time.
86 // We must pass at least 16 scanlines according to libjpeg documentation.
87 static const int kCompressBatchSize = 16;
Nick Deakinf6bca5a2022-11-04 10:43:43 -040088 // The buffer that holds the decompressed result.
Dichen Zhang0d12ba82022-10-19 20:44:51 +000089 std::vector<JOCTET> mResultBuffer;
Fyodor Kyslov1dcc4422022-11-16 01:40:53 +000090 // The buffer that holds XMP Data.
91 std::vector<JOCTET> mXMPBuffer;
92
Nick Deakinf6bca5a2022-11-04 10:43:43 -040093 // Resolution of the decompressed image.
94 size_t mWidth;
95 size_t mHeight;
Dichen Zhang0d12ba82022-10-19 20:44:51 +000096};
97} /* namespace android */
Nick Deakinf6bca5a2022-11-04 10:43:43 -040098
99#endif // ANDROID_JPEGRECOVERYMAP_JPEGDECODER_H