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
16 #include "istream_source_stream.h"
17
18 #include "image_log.h"
19 #include "image_utils.h"
20
21 #undef LOG_DOMAIN
22 #define LOG_DOMAIN LOG_TAG_DOMAIN_ID_IMAGE
23
24 #undef LOG_TAG
25 #define LOG_TAG "IstreamSourceStream"
26
27 namespace OHOS {
28 namespace Media {
29 using namespace std;
30 using namespace ImagePlugin;
31
IstreamSourceStream(unique_ptr<istream> inputStream,size_t size,size_t original,size_t offset)32 IstreamSourceStream::IstreamSourceStream(unique_ptr<istream> inputStream, size_t size, size_t original, size_t offset)
33 : inputStream_(move(inputStream)), streamSize_(size), streamOriginalOffset_(original), streamOffset_(offset)
34 {}
35
~IstreamSourceStream()36 IstreamSourceStream::~IstreamSourceStream()
37 {
38 ResetReadBuffer();
39 }
40
CreateSourceStream(unique_ptr<istream> inputStream)41 std::unique_ptr<IstreamSourceStream> IstreamSourceStream::CreateSourceStream(unique_ptr<istream> inputStream)
42 {
43 if ((inputStream == nullptr) || (inputStream->rdbuf() == nullptr) ||
44 inputStream.get() == nullptr) {
45 IMAGE_LOGE("[IstreamSourceStream]input parameter exception.");
46 return nullptr;
47 }
48 size_t streamSize = 0;
49 if (!ImageUtils::GetInputStreamSize(*(inputStream.get()), streamSize)) {
50 IMAGE_LOGE("[IstreamSourceStream]Get the input stream exception.");
51 return nullptr;
52 }
53 if (streamSize == 0) {
54 IMAGE_LOGE("[IstreamSourceStream]input stream size exception.");
55 return nullptr;
56 }
57 size_t original = inputStream->tellg();
58 size_t offset = original;
59 return make_unique<IstreamSourceStream>(move(inputStream), streamSize, original, offset);
60 }
61
Read(uint32_t desiredSize,DataStreamBuffer & outData)62 bool IstreamSourceStream::Read(uint32_t desiredSize, DataStreamBuffer &outData)
63 {
64 if (desiredSize == 0) {
65 IMAGE_LOGE("[IstreamSourceStream]read stream input parameter exception.");
66 return false;
67 }
68 if (!GetData(desiredSize, outData)) {
69 IMAGE_LOGE("[IstreamSourceStream]read fail.");
70 return false;
71 }
72 streamOffset_ += outData.dataSize;
73 return true;
74 }
75
Peek(uint32_t desiredSize,DataStreamBuffer & outData)76 bool IstreamSourceStream::Peek(uint32_t desiredSize, DataStreamBuffer &outData)
77 {
78 if (desiredSize == 0) {
79 IMAGE_LOGE("[IstreamSourceStream]peek stream input parameter exception.");
80 return false;
81 }
82 if (!GetData(desiredSize, outData)) {
83 IMAGE_LOGE("[IstreamSourceStream]peek fail.");
84 return false;
85 }
86 inputStream_->seekg(streamOffset_);
87 return true;
88 }
89
Read(uint32_t desiredSize,uint8_t * outBuffer,uint32_t bufferSize,uint32_t & readSize)90 bool IstreamSourceStream::Read(uint32_t desiredSize, uint8_t *outBuffer, uint32_t bufferSize, uint32_t &readSize)
91 {
92 if (desiredSize == 0 || outBuffer == nullptr || desiredSize > bufferSize) {
93 IMAGE_LOGE("[IstreamSourceStream]input the parameter exception, desiredSize:%{public}u,"
94 "bufferSize:%{public}u.", desiredSize, bufferSize);
95 return false;
96 }
97 if (!GetData(desiredSize, outBuffer, bufferSize, readSize)) {
98 IMAGE_LOGE("[IstreamSourceStream]read fail.");
99 return false;
100 }
101 streamOffset_ += readSize;
102 return true;
103 }
104
Peek(uint32_t desiredSize,uint8_t * outBuffer,uint32_t bufferSize,uint32_t & readSize)105 bool IstreamSourceStream::Peek(uint32_t desiredSize, uint8_t *outBuffer, uint32_t bufferSize, uint32_t &readSize)
106 {
107 if (desiredSize == 0 || outBuffer == nullptr || desiredSize > bufferSize) {
108 IMAGE_LOGE("[IstreamSourceStream]input the parameter exception, desiredSize:%{public}u,"
109 "bufferSize:%{public}u.", desiredSize, bufferSize);
110 return false;
111 }
112 if (!GetData(desiredSize, outBuffer, bufferSize, readSize)) {
113 IMAGE_LOGE("[IstreamSourceStream]peek fail.");
114 return false;
115 }
116 inputStream_->seekg(streamOffset_);
117 return true;
118 }
119
Seek(uint32_t position)120 bool IstreamSourceStream::Seek(uint32_t position)
121 {
122 if (position > streamSize_) {
123 IMAGE_LOGE("[IstreamSourceStream]Seek the position error, position:%{public}u,"
124 "streamSize_:%{public}zu.", position, streamSize_);
125 return false;
126 }
127 size_t targetPosition = position + streamOriginalOffset_;
128 streamOffset_ = ((targetPosition < streamSize_) ? targetPosition : streamSize_);
129 inputStream_->seekg(streamOffset_);
130 return true;
131 }
132
Tell()133 uint32_t IstreamSourceStream::Tell()
134 {
135 return streamOffset_;
136 }
137
GetData(uint32_t desiredSize,uint8_t * outBuffer,uint32_t bufferSize,uint32_t & readSize)138 bool IstreamSourceStream::GetData(uint32_t desiredSize, uint8_t *outBuffer, uint32_t bufferSize, uint32_t &readSize)
139 {
140 if (streamSize_ == 0 || streamOffset_ >= streamSize_) {
141 IMAGE_LOGE("[IstreamSourceStream]get source data fail. streamSize:%{public}zu,"
142 "streamOffset:%{public}zu.", streamSize_, streamOffset_);
143 return false;
144 }
145 if (desiredSize > (streamSize_ - streamOffset_)) {
146 desiredSize = (streamSize_ - streamOffset_);
147 }
148 if (!inputStream_->read(reinterpret_cast<char *>(outBuffer), desiredSize)) {
149 IMAGE_LOGE("[IstreamSourceStream]read the inputstream fail.");
150 return false;
151 }
152 readSize = desiredSize;
153 return true;
154 }
155
GetData(uint32_t desiredSize,DataStreamBuffer & outData)156 bool IstreamSourceStream::GetData(uint32_t desiredSize, DataStreamBuffer &outData)
157 {
158 if (streamSize_ == 0 || streamOffset_ >= streamSize_) {
159 IMAGE_LOGE("[IstreamSourceStream]get source data fail. streamSize:%{public}zu,"
160 "streamOffset:%{public}zu.", streamSize_, streamOffset_);
161 return false;
162 }
163
164 if (desiredSize == 0 || desiredSize > MALLOC_MAX_LENTH) {
165 IMAGE_LOGE("IstreamSourceStream]Invalid value, desiredSize out of size.");
166 return false;
167 }
168 ResetReadBuffer();
169 databuffer_ = static_cast<uint8_t *>(malloc(desiredSize));
170 if (databuffer_ == nullptr) {
171 IMAGE_LOGE("[IstreamSourceStream]malloc the output data buffer fail.");
172 return false;
173 }
174 outData.bufferSize = desiredSize;
175 if (desiredSize > (streamSize_ - streamOffset_)) {
176 desiredSize = (streamSize_ - streamOffset_);
177 }
178 inputStream_->seekg(streamOffset_);
179 if (!inputStream_->read(reinterpret_cast<char *>(databuffer_), desiredSize)) {
180 IMAGE_LOGE("[IstreamSourceStream]read the inputstream fail.");
181 free(databuffer_);
182 databuffer_ = nullptr;
183 return false;
184 }
185 outData.inputStreamBuffer = databuffer_;
186 outData.dataSize = desiredSize;
187 return true;
188 }
189
GetStreamSize()190 size_t IstreamSourceStream::GetStreamSize()
191 {
192 return streamSize_;
193 }
194
GetDataPtr()195 uint8_t *IstreamSourceStream::GetDataPtr()
196 {
197 return nullptr;
198 }
199
GetStreamType()200 uint32_t IstreamSourceStream::GetStreamType()
201 {
202 return ImagePlugin::INPUT_STREAM_TYPE;
203 }
204
ResetReadBuffer()205 void IstreamSourceStream::ResetReadBuffer()
206 {
207 if (databuffer_ != nullptr) {
208 free(databuffer_);
209 databuffer_ = nullptr;
210 }
211 }
212 } // namespace Media
213 } // namespace OHOS
214