• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include "image_io/base/istream_ref_data_source.h"
2 
3 #include "image_io/base/data_destination.h"
4 #include "image_io/base/data_segment.h"
5 
6 namespace photos_editing_formats {
7 namespace image_io {
8 
Reset()9 void IStreamRefDataSource::Reset() {
10   istream_ref_.clear();
11   istream_ref_.seekg(0);
12   current_data_segment_.reset();
13 }
14 
GetDataSegment(size_t begin,size_t min_size)15 std::shared_ptr<DataSegment> IStreamRefDataSource::GetDataSegment(
16     size_t begin, size_t min_size) {
17   if (current_data_segment_ && current_data_segment_->Contains(begin)) {
18     return current_data_segment_;
19   }
20   current_data_segment_ = Read(begin, min_size);
21   return current_data_segment_;
22 }
23 
TransferData(const DataRange & data_range,size_t best_size,DataDestination * data_destination)24 DataSource::TransferDataResult IStreamRefDataSource::TransferData(
25     const DataRange &data_range, size_t best_size,
26     DataDestination *data_destination) {
27   bool data_transferred = false;
28   DataDestination::TransferStatus status = DataDestination::kTransferDone;
29   if (data_destination && data_range.IsValid()) {
30     size_t min_size = std::min(data_range.GetLength(), best_size);
31     if (current_data_segment_ &&
32         current_data_segment_->GetLength() >= min_size &&
33         current_data_segment_->GetDataRange().Contains(data_range)) {
34       status = data_destination->Transfer(data_range, *current_data_segment_);
35       data_transferred = true;
36     } else {
37       istream_ref_.clear();
38       size_t chunk_size = min_size;
39       for (size_t begin = data_range.GetBegin(); begin < data_range.GetEnd();
40            begin += chunk_size) {
41         size_t segment_length = 0;
42         size_t end = std::min(data_range.GetEnd(), begin + chunk_size);
43         std::shared_ptr<DataSegment> data_segment = Read(begin, end - begin);
44         if (data_segment) {
45           segment_length = data_segment->GetLength();
46           if (segment_length) {
47             status = data_destination->Transfer(data_segment->GetDataRange(),
48                                                 *data_segment);
49             data_transferred = true;
50           }
51         }
52         if (status != DataDestination::kTransferOk || segment_length == 0) {
53           break;
54         }
55       }
56     }
57   }
58   if (data_transferred) {
59     return status == DataDestination::kTransferError ? kTransferDataError
60                                                      : kTransferDataSuccess;
61   } else {
62     return data_destination ? kTransferDataNone : kTransferDataError;
63   }
64 }
65 
Read(size_t begin,size_t count)66 std::shared_ptr<DataSegment> IStreamRefDataSource::Read(size_t begin,
67                                                         size_t count) {
68   std::shared_ptr<DataSegment> shared_data_segment;
69   istream_ref_.seekg(begin);
70   if (istream_ref_.rdstate() == std::ios_base::goodbit) {
71     Byte *buffer = new Byte[count];
72     istream_ref_.read(reinterpret_cast<char *>(buffer), count);
73     size_t bytes_read = istream_ref_.gcount();
74     shared_data_segment =
75         DataSegment::Create(DataRange(begin, begin + bytes_read), buffer);
76   }
77   return shared_data_segment;
78 }
79 
80 }  // namespace image_io
81 }  // namespace photos_editing_formats
82