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