• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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 "directory_ex.h"
17 #include "file_source_stream.h"
18 #include "image_log.h"
19 #include "image_utils.h"
20 #include "media_errors.h"
21 
22 namespace OHOS {
23 namespace Media {
24 using namespace OHOS::HiviewDFX;
25 using namespace std;
26 using namespace ImagePlugin;
27 
FileSourceStream(std::FILE * file,size_t size,size_t offset,size_t original)28 FileSourceStream::FileSourceStream(std::FILE *file, size_t size, size_t offset, size_t original)
29     : filePtr_(file), fileSize_(size), fileOffset_(offset), fileOriginalOffset_(original)
30 {}
31 
~FileSourceStream()32 FileSourceStream::~FileSourceStream()
33 {
34     fclose(filePtr_);
35     ResetReadBuffer();
36 }
37 
CreateSourceStream(const string & pathName)38 unique_ptr<FileSourceStream> FileSourceStream::CreateSourceStream(const string &pathName)
39 {
40     string realPath;
41     if (!PathToRealPath(pathName, realPath)) {
42         IMAGE_LOGE("[FileSourceStream]input the file path exception.");
43         return nullptr;
44     }
45     size_t size = 0;
46     if (!ImageUtils::GetFileSize(realPath, size)) {
47         IMAGE_LOGE("[FileSourceStream]get the file size fail.");
48         return nullptr;
49     }
50     FILE *filePtr = fopen(realPath.c_str(), "rb");
51     if (filePtr == nullptr) {
52         IMAGE_LOGE("[FileSourceStream]open file fail.");
53         return nullptr;
54     }
55     long offset = ftell(filePtr);
56     if (offset < 0) {
57         IMAGE_LOGE("[FileSourceStream]get the position fail.");
58         fclose(filePtr);
59         return nullptr;
60     }
61     return (unique_ptr<FileSourceStream>(new FileSourceStream(filePtr, size, offset, offset)));
62 }
CreateSourceStream(const int fd)63 unique_ptr<FileSourceStream> FileSourceStream::CreateSourceStream(const int fd)
64 {
65     size_t size = 0;
66     if (!ImageUtils::GetFileSize(fd, size)) {
67         IMAGE_LOGE("[FileSourceStream]get the file size fail.");
68         return nullptr;
69     }
70     FILE *filePtr = fdopen(fd, "rb");
71     if (filePtr == nullptr) {
72         IMAGE_LOGE("[FileSourceStream]open file fail.");
73         return nullptr;
74     }
75     long offset = ftell(filePtr);
76     if (offset < 0) {
77         IMAGE_LOGE("[FileSourceStream]get the position fail.");
78         fclose(filePtr);
79         return nullptr;
80     }
81     return (unique_ptr<FileSourceStream>(new FileSourceStream(filePtr, size, offset, offset)));
82 }
83 
Read(uint32_t desiredSize,DataStreamBuffer & outData)84 bool FileSourceStream::Read(uint32_t desiredSize, DataStreamBuffer &outData)
85 {
86     if (desiredSize == 0 || filePtr_ == nullptr) {
87         IMAGE_LOGE("[FileSourceStream]read stream input parameter exception.");
88         return false;
89     }
90     if (!GetData(desiredSize, outData)) {
91         IMAGE_LOGE("[FileSourceStream]read fail.");
92         return false;
93     }
94     fileOffset_ += outData.dataSize;
95     return true;
96 }
97 
Peek(uint32_t desiredSize,DataStreamBuffer & outData)98 bool FileSourceStream::Peek(uint32_t desiredSize, DataStreamBuffer &outData)
99 {
100     if (desiredSize == 0 || filePtr_ == nullptr) {
101         IMAGE_LOGE("[FileSourceStream]peek stream input parameter exception.");
102         return false;
103     }
104     if (!GetData(desiredSize, outData)) {
105         IMAGE_LOGE("[FileSourceStream]peek fail.");
106         return false;
107     }
108     int ret = fseek(filePtr_, fileOffset_, SEEK_SET);
109     if (ret != 0) {
110         IMAGE_LOGE("[FileSourceStream]go to original position fail, ret:%{public}d.", ret);
111         return false;
112     }
113     return true;
114 }
115 
Read(uint32_t desiredSize,uint8_t * outBuffer,uint32_t bufferSize,uint32_t & readSize)116 bool FileSourceStream::Read(uint32_t desiredSize, uint8_t *outBuffer, uint32_t bufferSize, uint32_t &readSize)
117 {
118     if (desiredSize == 0 || outBuffer == nullptr || desiredSize > bufferSize || desiredSize > fileSize_) {
119         IMAGE_LOGE("[FileSourceStream]input parameter exception, desiredSize:%{public}u, bufferSize:%{public}u,\
120                    fileSize_:%{public}zu.",
121                    desiredSize, bufferSize, fileSize_);
122         return false;
123     }
124     if (!GetData(desiredSize, outBuffer, bufferSize, readSize)) {
125         IMAGE_LOGE("[FileSourceStream]read fail.");
126         return false;
127     }
128     fileOffset_ += readSize;
129     return true;
130 }
131 
Peek(uint32_t desiredSize,uint8_t * outBuffer,uint32_t bufferSize,uint32_t & readSize)132 bool FileSourceStream::Peek(uint32_t desiredSize, uint8_t *outBuffer, uint32_t bufferSize, uint32_t &readSize)
133 {
134     if (desiredSize == 0 || outBuffer == nullptr || desiredSize > bufferSize || desiredSize > fileSize_) {
135         IMAGE_LOGE("[FileSourceStream]input parameter exception, desiredSize:%{public}u, bufferSize:%{public}u,\
136                    fileSize_:%{public}zu.",
137                    desiredSize, bufferSize, fileSize_);
138         return false;
139     }
140     if (!GetData(desiredSize, outBuffer, bufferSize, readSize)) {
141         IMAGE_LOGE("[FileSourceStream]peek fail.");
142         return false;
143     }
144     int ret = fseek(filePtr_, fileOffset_, SEEK_SET);
145     if (ret != 0) {
146         IMAGE_LOGE("[FileSourceStream]go to original position fail, ret:%{public}d.", ret);
147         return false;
148     }
149     return true;
150 }
151 
Seek(uint32_t position)152 bool FileSourceStream::Seek(uint32_t position)
153 {
154     if (position > fileSize_) {
155         IMAGE_LOGE("[FileSourceStream]Seek the position greater than the file size, position:%{public}u.", position);
156         return false;
157     }
158     size_t targetPosition = position + fileOriginalOffset_;
159     fileOffset_ = ((targetPosition < fileSize_) ? targetPosition : fileSize_);
160     int ret = fseek(filePtr_, fileOffset_, SEEK_SET);
161     if (ret != 0) {
162         IMAGE_LOGE("[FileSourceStream]go to offset position fail, ret:%{public}d.", ret);
163         return false;
164     }
165     return true;
166 }
167 
Tell()168 uint32_t FileSourceStream::Tell()
169 {
170     return fileOffset_;
171 }
172 
GetData(uint32_t desiredSize,uint8_t * outBuffer,uint32_t bufferSize,uint32_t & readSize)173 bool FileSourceStream::GetData(uint32_t desiredSize, uint8_t *outBuffer, uint32_t bufferSize, uint32_t &readSize)
174 {
175     if (fileSize_ == fileOffset_) {
176         IMAGE_LOGE("[FileSourceStream]read finish, offset:%{public}zu ,dataSize%{public}zu.", fileOffset_, fileSize_);
177         return false;
178     }
179     if (desiredSize > (fileSize_ - fileOffset_)) {
180         desiredSize = fileSize_ - fileOffset_;
181     }
182     size_t bytesRead = fread(outBuffer, sizeof(outBuffer[0]), desiredSize, filePtr_);
183     if (bytesRead < desiredSize) {
184         IMAGE_LOGE("[FileSourceStream]read fail, bytesRead:%{public}zu", bytesRead);
185         return false;
186     }
187     readSize = desiredSize;
188     return true;
189 }
190 
GetData(uint32_t desiredSize,DataStreamBuffer & outData)191 bool FileSourceStream::GetData(uint32_t desiredSize, DataStreamBuffer &outData)
192 {
193     if (fileSize_ == fileOffset_) {
194         IMAGE_LOGE("[FileSourceStream]read finish, offset:%{public}zu ,dataSize%{public}zu.", fileOffset_, fileSize_);
195         return false;
196     }
197 
198     if (desiredSize == 0 || desiredSize > MALLOC_MAX_LENTH) {
199         IMAGE_LOGE("[FileSourceStream]Invalid value, desiredSize out of size.");
200         return false;
201     }
202 
203     ResetReadBuffer();
204     readBuffer_ = static_cast<uint8_t *>(malloc(desiredSize));
205     if (readBuffer_ == nullptr) {
206         IMAGE_LOGE("[FileSourceStream]malloc the desiredSize fail.");
207         return false;
208     }
209     outData.bufferSize = desiredSize;
210     if (desiredSize > (fileSize_ - fileOffset_)) {
211         desiredSize = fileSize_ - fileOffset_;
212     }
213     size_t bytesRead = fread(readBuffer_, sizeof(uint8_t), desiredSize, filePtr_);
214     if (bytesRead < desiredSize) {
215         IMAGE_LOGE("[FileSourceStream]read fail, bytesRead:%{public}zu", bytesRead);
216         return false;
217     }
218     outData.inputStreamBuffer = static_cast<uint8_t *>(readBuffer_);
219     outData.dataSize = desiredSize;
220     return true;
221 }
222 
GetStreamSize()223 size_t FileSourceStream::GetStreamSize()
224 {
225     return fileSize_;
226 }
227 
GetDataPtr()228 uint8_t *FileSourceStream::GetDataPtr()
229 {
230     return nullptr;
231 }
232 
GetStreamType()233 uint32_t FileSourceStream::GetStreamType()
234 {
235     return ImagePlugin::FILE_STREAM_TYPE;
236 }
237 
ResetReadBuffer()238 void FileSourceStream::ResetReadBuffer()
239 {
240     if (readBuffer_ != nullptr) {
241         free(readBuffer_);
242         readBuffer_ = nullptr;
243     }
244 }
245 } // namespace Media
246 } // namespace OHOS