1 /*
2 * Copyright (C) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #include "raw_decoder.h"
16
17 #include "buffer_source_stream.h"
18 #include "image_log.h"
19 #include "image_trace.h"
20 #include "jpeg_decoder.h"
21 #include "raw_stream.h"
22
23 #undef LOG_DOMAIN
24 #define LOG_DOMAIN LOG_TAG_DOMAIN_ID_PLUGIN
25
26 #undef LOG_TAG
27 #define LOG_TAG "RawDecoder"
28
29 namespace OHOS {
30 namespace ImagePlugin {
31 using namespace MultimediaPlugin;
32 using namespace Media;
33 namespace {
34 constexpr uint32_t RAW_IMAGE_NUM = 1;
35 }
36
RawDecoder()37 RawDecoder::RawDecoder()
38 {
39 IMAGE_LOGD("create IN");
40
41 IMAGE_LOGD("create OUT");
42 }
43
~RawDecoder()44 RawDecoder::~RawDecoder()
45 {
46 IMAGE_LOGD("release IN");
47
48 Reset();
49
50 IMAGE_LOGD("release OUT");
51 }
52
Reset()53 void RawDecoder::Reset()
54 {
55 IMAGE_LOGD("Reset IN");
56
57 inputStream_ = nullptr;
58 state_ = RawDecodingState::UNDECIDED;
59
60 PixelDecodeOptions opts;
61 opts_ = opts;
62
63 PlImageInfo info;
64 info_ = info;
65
66 rawStream_ = nullptr;
67
68 // PIEX used.
69 jpegStream_ = nullptr;
70 jpegDecoder_ = nullptr;
71
72 IMAGE_LOGD("Reset OUT");
73 }
74
HasProperty(std::string key)75 bool RawDecoder::HasProperty(std::string key)
76 {
77 IMAGE_LOGD("HasProperty IN key=[%{public}s]", key.c_str());
78
79 IMAGE_LOGD("HasProperty OUT");
80 return false;
81 }
82
PromoteIncrementalDecode(uint32_t index,ProgDecodeContext & progContext)83 uint32_t RawDecoder::PromoteIncrementalDecode(uint32_t index, ProgDecodeContext &progContext)
84 {
85 IMAGE_LOGD("PromoteIncrementalDecode index=%{public}u", index);
86 return Media::ERR_IMAGE_DATA_UNSUPPORT;
87 }
88
GetTopLevelImageNum(uint32_t & num)89 uint32_t RawDecoder::GetTopLevelImageNum(uint32_t &num)
90 {
91 num = RAW_IMAGE_NUM;
92 IMAGE_LOGD("GetTopLevelImageNum, num=%{public}u", num);
93 return Media::SUCCESS;
94 }
95
SetSource(InputDataStream & sourceStream)96 void RawDecoder::SetSource(InputDataStream &sourceStream)
97 {
98 IMAGE_LOGD("SetSource IN");
99
100 inputStream_ = &sourceStream;
101 rawStream_ = std::make_unique<RawStream>(sourceStream);
102
103 state_ = RawDecodingState::SOURCE_INITED;
104
105 IMAGE_LOGD("SetSource OUT");
106 }
107
SetDecodeOptions(uint32_t index,const PixelDecodeOptions & opts,PlImageInfo & info)108 uint32_t RawDecoder::SetDecodeOptions(uint32_t index, const PixelDecodeOptions &opts, PlImageInfo &info)
109 {
110 IMAGE_LOGD("SetDecodeOptions IN index=%{public}u", index);
111
112 if (index >= RAW_IMAGE_NUM) {
113 IMAGE_LOGE("[SetDecodeOptions] decode image index[%{public}u], out of range[%{public}u].",
114 index, RAW_IMAGE_NUM);
115 return Media::ERR_IMAGE_INVALID_PARAMETER;
116 }
117
118 IMAGE_LOGD("SetDecodeOptions opts, pixelFormat=%{public}d, alphaType=%{public}d, "
119 "colorSpace=%{public}d, size=(%{public}u, %{public}u), state=%{public}d",
120 static_cast<int32_t>(opts.desiredPixelFormat), static_cast<int32_t>(opts.desireAlphaType),
121 static_cast<int32_t>(opts.desiredColorSpace), opts.desiredSize.width, opts.desiredSize.height, state_);
122
123 if (state_ < RawDecodingState::SOURCE_INITED) {
124 IMAGE_LOGE("[SetDecodeOptions] set decode options failed for state %{public}d.", state_);
125 return Media::ERR_MEDIA_INVALID_OPERATION;
126 }
127
128 if (state_ >= RawDecodingState::IMAGE_DECODING) {
129 state_ = RawDecodingState::SOURCE_INITED;
130 }
131
132 if (state_ < RawDecodingState::BASE_INFO_PARSED) {
133 uint32_t ret = DoDecodeHeader();
134 if (ret != Media::SUCCESS) {
135 state_ = RawDecodingState::BASE_INFO_PARSING;
136 IMAGE_LOGE("[SetDecodeOptions] decode header error on set decode options:%{public}u.", ret);
137 return ret;
138 }
139
140 state_ = RawDecodingState::BASE_INFO_PARSED;
141 }
142
143 // only state RawDecodingState::BASE_INFO_PARSED can go here.
144 uint32_t ret = DoSetDecodeOptions(index, opts, info);
145 if (ret != Media::SUCCESS) {
146 state_ = RawDecodingState::BASE_INFO_PARSING;
147 IMAGE_LOGE("[SetDecodeOptions] do set decode options fail, ret:%{public}u.", ret);
148 return ret;
149 }
150
151 state_ = RawDecodingState::IMAGE_DECODING;
152
153 IMAGE_LOGD("SetDecodeOptions OUT");
154 return Media::SUCCESS;
155 }
156
GetImageSize(uint32_t index,Size & size)157 uint32_t RawDecoder::GetImageSize(uint32_t index, Size &size)
158 {
159 IMAGE_LOGD("GetImageSize IN index=%{public}u", index);
160
161 if (index >= RAW_IMAGE_NUM) {
162 IMAGE_LOGE("[GetImageSize] decode image index[%{public}u], out of range[%{public}u].",
163 index, RAW_IMAGE_NUM);
164 return Media::ERR_IMAGE_INVALID_PARAMETER;
165 }
166
167 if (state_ < RawDecodingState::SOURCE_INITED) {
168 IMAGE_LOGE("[GetImageSize] get image size failed for state %{public}d.", state_);
169 return ERR_MEDIA_INVALID_OPERATION;
170 }
171
172 if (state_ >= RawDecodingState::BASE_INFO_PARSED) {
173 size = info_.size;
174 IMAGE_LOGD("GetImageSize OUT size=(%{public}u, %{public}u)", size.width, size.height);
175 return Media::SUCCESS;
176 }
177
178 // only state RawDecodingState::SOURCE_INITED and RawDecodingState::BASE_INFO_PARSING can go here.
179 uint32_t ret = DoDecodeHeader();
180 if (ret != Media::SUCCESS) {
181 IMAGE_LOGD("[GetImageSize]decode header error on get image size, ret:%{public}u.", ret);
182 state_ = RawDecodingState::BASE_INFO_PARSING;
183 return ret;
184 }
185
186 ret = DoGetImageSize(index, size);
187 if (ret != Media::SUCCESS) {
188 IMAGE_LOGE("[GetImageSize]do get image size failed, ret:%{public}u.", ret);
189 state_ = RawDecodingState::BASE_INFO_PARSING;
190 return ret;
191 }
192
193 state_ = RawDecodingState::BASE_INFO_PARSED;
194
195 IMAGE_LOGD("GetImageSize OUT size=(%{public}u, %{public}u)", size.width, size.height);
196 return Media::SUCCESS;
197 }
198
Decode(uint32_t index,DecodeContext & context)199 uint32_t RawDecoder::Decode(uint32_t index, DecodeContext &context)
200 {
201 ImageTrace imageTrace("RawDecoder::Decode, index:%u", index);
202 IMAGE_LOGD("Decode IN index=%{public}u", index);
203
204 if (index >= RAW_IMAGE_NUM) {
205 IMAGE_LOGE("[Decode] decode image index:[%{public}u] out of range:[%{public}u].",
206 index, RAW_IMAGE_NUM);
207 return Media::ERR_IMAGE_INVALID_PARAMETER;
208 }
209 if (state_ < RawDecodingState::IMAGE_DECODING) {
210 IMAGE_LOGE("[Decode] decode failed for state %{public}d.", state_);
211 return Media::ERR_MEDIA_INVALID_OPERATION;
212 }
213
214 uint32_t ret = DoDecode(index, context);
215 if (ret == Media::SUCCESS) {
216 state_ = RawDecodingState::IMAGE_DECODED;
217 IMAGE_LOGI("[Decode] success.");
218 } else {
219 state_ = RawDecodingState::IMAGE_ERROR;
220 IMAGE_LOGE("[Decode] fail, ret=%{public}u", ret);
221 }
222
223 IMAGE_LOGD("Decode OUT");
224 return ret;
225 }
226
DoDecodeHeader()227 uint32_t RawDecoder::DoDecodeHeader()
228 {
229 IMAGE_LOGD("DoDecodeHeader IN");
230
231 if (piex::IsRaw(rawStream_.get())) {
232 jpegDecoder_ = nullptr;
233 jpegStream_ = nullptr;
234 uint32_t ret = DoDecodeHeaderByPiex();
235 if (ret != Media::SUCCESS) {
236 IMAGE_LOGE("DoDecodeHeader piex header decode fail.");
237 return ret;
238 }
239
240 if (jpegDecoder_ != nullptr) {
241 IMAGE_LOGI("DoDecodeHeader piex header decode success.");
242 return Media::SUCCESS;
243 }
244 }
245
246 uint32_t ret = Media::ERR_IMAGE_DATA_UNSUPPORT;
247 IMAGE_LOGD("DoDecodeHeader header decode fail, ret=[%{public}u]", ret);
248
249 IMAGE_LOGD("DoDecodeHeader OUT");
250 return ret;
251 }
252
DoDecodeHeaderByPiex()253 uint32_t RawDecoder::DoDecodeHeaderByPiex()
254 {
255 IMAGE_LOGD("DoDecodeHeaderByPiex IN");
256
257 piex::PreviewImageData imageData;
258 piex::Error error = piex::GetPreviewImageData(rawStream_.get(), &imageData);
259 if (error == piex::Error::kFail) {
260 IMAGE_LOGE("DoDecodeHeaderByPiex get preview fail");
261 return Media::ERR_IMAGE_DATA_ABNORMAL;
262 }
263
264 piex::Image piexImage;
265 bool hasImage = false;
266 if (error == piex::Error::kOk) {
267 if ((imageData.preview.format == piex::Image::kJpegCompressed) && (imageData.preview.length > 0)) {
268 piexImage = imageData.preview;
269 hasImage = true;
270 }
271 }
272
273 if (!hasImage) {
274 IMAGE_LOGD("DoDecodeHeaderByPiex OUT 2");
275 return Media::SUCCESS;
276 }
277
278 uint32_t size = piexImage.length;
279 std::unique_ptr<uint8_t[]> data = std::make_unique<uint8_t[]>(size);
280 error = rawStream_->GetData(piexImage.offset, size, data.get());
281 if (error != piex::Error::kOk) {
282 IMAGE_LOGE("DoDecodeHeaderByPiex getdata fail");
283 return Media::ERR_IMAGE_MALLOC_ABNORMAL;
284 }
285
286 jpegStream_ = BufferSourceStream::CreateSourceStream(data.get(), size);
287 if (!jpegStream_) {
288 IMAGE_LOGE("DoDecodeHeaderByPiex create sourcestream fail");
289 return Media::ERR_IMAGE_MALLOC_ABNORMAL;
290 }
291
292 data = nullptr;
293 jpegDecoder_ = std::make_unique<JpegDecoder>();
294 jpegDecoder_->SetSource(*(jpegStream_.get()));
295
296 IMAGE_LOGD("DoDecodeHeaderByPiex OUT");
297 return Media::SUCCESS;
298 }
299
DoSetDecodeOptions(uint32_t index,const PixelDecodeOptions & opts,PlImageInfo & info)300 uint32_t RawDecoder::DoSetDecodeOptions(uint32_t index, const PixelDecodeOptions &opts, PlImageInfo &info)
301 {
302 IMAGE_LOGD("DoSetDecodeOptions IN index=%{public}u", index);
303 uint32_t ret;
304 opts_ = opts;
305 if (jpegDecoder_ != nullptr) {
306 IMAGE_LOGI("DoSetDecodeOptions, set decode options for JpegDecoder");
307 ret = jpegDecoder_->SetDecodeOptions(index, opts_, info_);
308 } else {
309 IMAGE_LOGE("DoSetDecodeOptions, unsupport");
310 ret = Media::ERR_IMAGE_DATA_UNSUPPORT;
311 }
312 info = info_;
313
314 if (ret == Media::SUCCESS) {
315 IMAGE_LOGI("DoSetDecodeOptions set decode options success.");
316 } else {
317 IMAGE_LOGE("DoSetDecodeOptions set decode options fail, ret=[%{public}u]", ret);
318 }
319
320 IMAGE_LOGD("DoSetDecodeOptions OUT pixelFormat=%{public}d, alphaType=%{public}d, "
321 "colorSpace=%{public}d, size=(%{public}u, %{public}u)",
322 static_cast<int32_t>(info.pixelFormat), static_cast<int32_t>(info.alphaType),
323 static_cast<int32_t>(info.colorSpace), info.size.width, info.size.height);
324 return ret;
325 }
326
DoGetImageSize(uint32_t index,Size & size)327 uint32_t RawDecoder::DoGetImageSize(uint32_t index, Size &size)
328 {
329 IMAGE_LOGD("DoGetImageSize IN index=%{public}u", index);
330 uint32_t ret;
331
332 if (jpegDecoder_ != nullptr) {
333 IMAGE_LOGI("DoGetImageSize, get image size for JpegDecoder");
334 ret = jpegDecoder_->GetImageSize(index, info_.size);
335 } else {
336 IMAGE_LOGE("DoGetImageSize, unsupport");
337 ret = Media::ERR_IMAGE_DATA_UNSUPPORT;
338 }
339 size = info_.size;
340
341 if (ret == Media::SUCCESS) {
342 IMAGE_LOGI("DoGetImageSize, get image size success.");
343 } else {
344 IMAGE_LOGE("DoGetImageSize, get image size fail, ret=[%{public}u]", ret);
345 }
346
347 IMAGE_LOGD("DoGetImageSize OUT size=(%{public}u, %{public}u)", size.width, size.height);
348 return ret;
349 }
350
DoDecode(uint32_t index,DecodeContext & context)351 uint32_t RawDecoder::DoDecode(uint32_t index, DecodeContext &context)
352 {
353 IMAGE_LOGD("DoDecode IN index=%{public}u", index);
354 uint32_t ret;
355
356 if (jpegDecoder_ != nullptr) {
357 IMAGE_LOGI("DoDecode decode by JpegDecoder.");
358 ret = jpegDecoder_->Decode(index, context);
359 } else {
360 IMAGE_LOGE("DoDecode decode unsupport.");
361 ret = Media::ERR_IMAGE_DATA_UNSUPPORT;
362 }
363
364 if (ret == Media::SUCCESS) {
365 IMAGE_LOGI("DoDecode decode success.");
366 } else {
367 IMAGE_LOGE("DoDecode decode fail, ret=%{public}u", ret);
368 }
369
370 IMAGE_LOGD("DoDecode OUT ret=%{public}u", ret);
371 return ret;
372 }
373 } // namespace ImagePlugin
374 } // namespace OHOS
375