Coverage Report

Created: 2025-08-28 07:25

/src/libultrahdr/lib/include/ultrahdr/jpegdecoderhelper.h
Line
Count
Source (jump to first uncovered line)
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 ULTRAHDR_JPEGDECODERHELPER_H
18
#define ULTRAHDR_JPEGDECODERHELPER_H
19
20
#include <stdio.h>  // For jpeglib.h.
21
22
// C++ build requires extern C for jpeg internals.
23
#ifdef __cplusplus
24
extern "C" {
25
#endif
26
27
#include <jerror.h>
28
#include <jpeglib.h>
29
30
#ifdef __cplusplus
31
}  // extern "C"
32
#endif
33
34
#include <cstdint>
35
#include <memory>
36
#include <vector>
37
38
#include "ultrahdr_api.h"
39
40
namespace ultrahdr {
41
42
/*!\brief List of supported operations */
43
typedef enum {
44
  PARSE_STREAM = (1 << 0),   /**< Parse jpeg header, APPn markers (Exif, Icc, Xmp, Iso) */
45
  DECODE_STREAM = (1 << 16), /**< Single channel images are decoded to Grayscale format and multi
46
                                channel images are decoded to RGB format */
47
  DECODE_TO_YCBCR_CS = (1 << 17), /**< Decode image to YCbCr Color Space  */
48
  DECODE_TO_RGB_CS = (1 << 18),   /**< Decode image to RGB Color Space  */
49
} decode_mode_t;
50
51
/*!\brief Encapsulates a converter from JPEG to raw image format. This class is not thread-safe */
52
class JpegDecoderHelper {
53
 public:
54
50.9k
  JpegDecoderHelper() = default;
55
50.9k
  ~JpegDecoderHelper() = default;
56
57
  /*!\brief This function decodes the bitstream that is passed to it to the desired format and
58
   * stores the results internally. The result is accessible via getter functions.
59
   *
60
   * \param[in]  image    pointer to compressed image
61
   * \param[in]  length   length of compressed image
62
   * \param[in]  mode     output decode format
63
   *
64
   * \return uhdr_error_info_t #UHDR_CODEC_OK if operation succeeds, uhdr_codec_err_t otherwise.
65
   */
66
  uhdr_error_info_t decompressImage(const void* image, size_t length,
67
                                    decode_mode_t mode = DECODE_TO_YCBCR_CS);
68
69
  /*!\brief This function parses the bitstream that is passed to it and makes image information
70
   * available to the client via getter() functions. It does not decompress the image. That is done
71
   * by decompressImage().
72
   *
73
   * \param[in]  image    pointer to compressed image
74
   * \param[in]  length   length of compressed image
75
   *
76
   * \return uhdr_error_info_t #UHDR_CODEC_OK if operation succeeds, uhdr_codec_err_t otherwise.
77
   */
78
39.7k
  uhdr_error_info_t parseImage(const void* image, size_t length) {
79
39.7k
    return decompressImage(image, length, PARSE_STREAM);
80
39.7k
  }
81
82
  /*! Below public methods are only effective if a call to decompressImage() is made and it returned
83
   * true. */
84
85
  /*!\brief returns decompressed image descriptor */
86
  uhdr_raw_image_t getDecompressedImage();
87
88
  /*!\brief returns pointer to decompressed image
89
   * \deprecated This function is deprecated instead use getDecompressedImage().
90
   */
91
0
  void* getDecompressedImagePtr() { return mResultBuffer.data(); }
92
93
  /*!\brief returns size of decompressed image
94
   * \deprecated This function is deprecated instead use getDecompressedImage().
95
   */
96
0
  size_t getDecompressedImageSize() { return mResultBuffer.size(); }
97
98
  /*! Below public methods are only effective if a call to parseImage() or decompressImage() is made
99
   * and it returned true. */
100
101
  /*!\brief returns image width */
102
36.9k
  unsigned int getDecompressedImageWidth() { return mPlaneWidth[0]; }
103
104
  /*!\brief returns image height */
105
36.9k
  unsigned int getDecompressedImageHeight() { return mPlaneHeight[0]; }
106
107
  /*!\brief returns number of components in image */
108
36.9k
  unsigned int getNumComponentsInImage() { return mNumComponents; }
109
110
  /*!\brief returns pointer to xmp block present in input image */
111
8.86k
  void* getXMPPtr() { return mXMPBuffer.data(); }
112
113
  /*!\brief returns size of xmp block */
114
51.7k
  size_t getXMPSize() { return mXMPBuffer.size(); }
115
116
  /*!\brief returns pointer to exif block present in input image */
117
112
  void* getEXIFPtr() { return mEXIFBuffer.data(); }
118
119
  /*!\brief returns size of exif block */
120
37.1k
  size_t getEXIFSize() { return mEXIFBuffer.size(); }
121
122
  /*!\brief returns pointer to icc block present in input image */
123
9.63k
  void* getICCPtr() { return mICCBuffer.data(); }
124
125
  /*!\brief returns size of icc block */
126
48.6k
  size_t getICCSize() { return mICCBuffer.size(); }
127
128
  /*!\brief returns pointer to iso block present in input image */
129
30.8k
  void* getIsoMetadataPtr() { return mIsoMetadataBuffer.data(); }
130
131
  /*!\brief returns size of iso block */
132
95.5k
  size_t getIsoMetadataSize() { return mIsoMetadataBuffer.size(); }
133
134
  /*!\brief returns the offset of exif data payload with reference to 'image' address that is passed
135
   * via parseImage()/decompressImage() call. Note this does not include jpeg marker (0xffe1) and
136
   * the next 2 bytes indicating the size of the payload. If exif block is not present in the image
137
   * passed, then it returns -1. */
138
0
  long getEXIFPos() { return mExifPayLoadOffset; }
139
140
 private:
141
  // max number of components supported
142
  static constexpr int kMaxNumComponents = 3;
143
144
  uhdr_error_info_t decode(const void* image, size_t length, decode_mode_t mode);
145
  uhdr_error_info_t decode(jpeg_decompress_struct* cinfo, uint8_t* dest);
146
  uhdr_error_info_t decodeToCSYCbCr(jpeg_decompress_struct* cinfo, uint8_t* dest);
147
  uhdr_error_info_t decodeToCSRGB(jpeg_decompress_struct* cinfo, uint8_t* dest);
148
149
  // temporary storage
150
  std::unique_ptr<uint8_t[]> mPlanesMCURow[kMaxNumComponents];
151
152
  std::vector<JOCTET> mResultBuffer;       // buffer to store decoded data
153
  std::vector<JOCTET> mXMPBuffer;          // buffer to store xmp data
154
  std::vector<JOCTET> mEXIFBuffer;         // buffer to store exif data
155
  std::vector<JOCTET> mICCBuffer;          // buffer to store icc data
156
  std::vector<JOCTET> mIsoMetadataBuffer;  // buffer to store iso data
157
158
  // image attributes
159
  uhdr_img_fmt_t mOutFormat;
160
  unsigned int mNumComponents;
161
  unsigned int mPlaneWidth[kMaxNumComponents];
162
  unsigned int mPlaneHeight[kMaxNumComponents];
163
  unsigned int mPlaneHStride[kMaxNumComponents];
164
  unsigned int mPlaneVStride[kMaxNumComponents];
165
166
  long mExifPayLoadOffset;  // Position of EXIF package, default value is -1 which means no EXIF
167
                            // package appears.
168
};
169
170
} /* namespace ultrahdr  */
171
172
#endif  // ULTRAHDR_JPEGDECODERHELPER_H