xref: /aosp_15_r20/external/libaom/third_party/libwebm/mkvparser/mkvreader.cc (revision 77c1e3ccc04c968bd2bc212e87364f250e820521)
1*77c1e3ccSAndroid Build Coastguard Worker // Copyright (c) 2010 The WebM project authors. All Rights Reserved.
2*77c1e3ccSAndroid Build Coastguard Worker //
3*77c1e3ccSAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license
4*77c1e3ccSAndroid Build Coastguard Worker // that can be found in the LICENSE file in the root of the source
5*77c1e3ccSAndroid Build Coastguard Worker // tree. An additional intellectual property rights grant can be found
6*77c1e3ccSAndroid Build Coastguard Worker // in the file PATENTS.  All contributing project authors may
7*77c1e3ccSAndroid Build Coastguard Worker // be found in the AUTHORS file in the root of the source tree.
8*77c1e3ccSAndroid Build Coastguard Worker #include "mkvparser/mkvreader.h"
9*77c1e3ccSAndroid Build Coastguard Worker 
10*77c1e3ccSAndroid Build Coastguard Worker #include <sys/types.h>
11*77c1e3ccSAndroid Build Coastguard Worker 
12*77c1e3ccSAndroid Build Coastguard Worker #include <cassert>
13*77c1e3ccSAndroid Build Coastguard Worker 
14*77c1e3ccSAndroid Build Coastguard Worker namespace mkvparser {
15*77c1e3ccSAndroid Build Coastguard Worker 
MkvReader()16*77c1e3ccSAndroid Build Coastguard Worker MkvReader::MkvReader() : m_file(NULL), reader_owns_file_(true) {}
17*77c1e3ccSAndroid Build Coastguard Worker 
MkvReader(FILE * fp)18*77c1e3ccSAndroid Build Coastguard Worker MkvReader::MkvReader(FILE* fp) : m_file(fp), reader_owns_file_(false) {
19*77c1e3ccSAndroid Build Coastguard Worker   GetFileSize();
20*77c1e3ccSAndroid Build Coastguard Worker }
21*77c1e3ccSAndroid Build Coastguard Worker 
~MkvReader()22*77c1e3ccSAndroid Build Coastguard Worker MkvReader::~MkvReader() {
23*77c1e3ccSAndroid Build Coastguard Worker   if (reader_owns_file_)
24*77c1e3ccSAndroid Build Coastguard Worker     Close();
25*77c1e3ccSAndroid Build Coastguard Worker   m_file = NULL;
26*77c1e3ccSAndroid Build Coastguard Worker }
27*77c1e3ccSAndroid Build Coastguard Worker 
Open(const char * fileName)28*77c1e3ccSAndroid Build Coastguard Worker int MkvReader::Open(const char* fileName) {
29*77c1e3ccSAndroid Build Coastguard Worker   if (fileName == NULL)
30*77c1e3ccSAndroid Build Coastguard Worker     return -1;
31*77c1e3ccSAndroid Build Coastguard Worker 
32*77c1e3ccSAndroid Build Coastguard Worker   if (m_file)
33*77c1e3ccSAndroid Build Coastguard Worker     return -1;
34*77c1e3ccSAndroid Build Coastguard Worker 
35*77c1e3ccSAndroid Build Coastguard Worker #ifdef _MSC_VER
36*77c1e3ccSAndroid Build Coastguard Worker   const errno_t e = fopen_s(&m_file, fileName, "rb");
37*77c1e3ccSAndroid Build Coastguard Worker 
38*77c1e3ccSAndroid Build Coastguard Worker   if (e)
39*77c1e3ccSAndroid Build Coastguard Worker     return -1;  // error
40*77c1e3ccSAndroid Build Coastguard Worker #else
41*77c1e3ccSAndroid Build Coastguard Worker   m_file = fopen(fileName, "rb");
42*77c1e3ccSAndroid Build Coastguard Worker 
43*77c1e3ccSAndroid Build Coastguard Worker   if (m_file == NULL)
44*77c1e3ccSAndroid Build Coastguard Worker     return -1;
45*77c1e3ccSAndroid Build Coastguard Worker #endif
46*77c1e3ccSAndroid Build Coastguard Worker   return !GetFileSize();
47*77c1e3ccSAndroid Build Coastguard Worker }
48*77c1e3ccSAndroid Build Coastguard Worker 
GetFileSize()49*77c1e3ccSAndroid Build Coastguard Worker bool MkvReader::GetFileSize() {
50*77c1e3ccSAndroid Build Coastguard Worker   if (m_file == NULL)
51*77c1e3ccSAndroid Build Coastguard Worker     return false;
52*77c1e3ccSAndroid Build Coastguard Worker #ifdef _MSC_VER
53*77c1e3ccSAndroid Build Coastguard Worker   int status = _fseeki64(m_file, 0L, SEEK_END);
54*77c1e3ccSAndroid Build Coastguard Worker 
55*77c1e3ccSAndroid Build Coastguard Worker   if (status)
56*77c1e3ccSAndroid Build Coastguard Worker     return false;  // error
57*77c1e3ccSAndroid Build Coastguard Worker 
58*77c1e3ccSAndroid Build Coastguard Worker   m_length = _ftelli64(m_file);
59*77c1e3ccSAndroid Build Coastguard Worker #else
60*77c1e3ccSAndroid Build Coastguard Worker   fseek(m_file, 0L, SEEK_END);
61*77c1e3ccSAndroid Build Coastguard Worker   m_length = ftell(m_file);
62*77c1e3ccSAndroid Build Coastguard Worker #endif
63*77c1e3ccSAndroid Build Coastguard Worker   assert(m_length >= 0);
64*77c1e3ccSAndroid Build Coastguard Worker 
65*77c1e3ccSAndroid Build Coastguard Worker   if (m_length < 0)
66*77c1e3ccSAndroid Build Coastguard Worker     return false;
67*77c1e3ccSAndroid Build Coastguard Worker 
68*77c1e3ccSAndroid Build Coastguard Worker #ifdef _MSC_VER
69*77c1e3ccSAndroid Build Coastguard Worker   status = _fseeki64(m_file, 0L, SEEK_SET);
70*77c1e3ccSAndroid Build Coastguard Worker 
71*77c1e3ccSAndroid Build Coastguard Worker   if (status)
72*77c1e3ccSAndroid Build Coastguard Worker     return false;  // error
73*77c1e3ccSAndroid Build Coastguard Worker #else
74*77c1e3ccSAndroid Build Coastguard Worker   fseek(m_file, 0L, SEEK_SET);
75*77c1e3ccSAndroid Build Coastguard Worker #endif
76*77c1e3ccSAndroid Build Coastguard Worker 
77*77c1e3ccSAndroid Build Coastguard Worker   return true;
78*77c1e3ccSAndroid Build Coastguard Worker }
79*77c1e3ccSAndroid Build Coastguard Worker 
Close()80*77c1e3ccSAndroid Build Coastguard Worker void MkvReader::Close() {
81*77c1e3ccSAndroid Build Coastguard Worker   if (m_file != NULL) {
82*77c1e3ccSAndroid Build Coastguard Worker     fclose(m_file);
83*77c1e3ccSAndroid Build Coastguard Worker     m_file = NULL;
84*77c1e3ccSAndroid Build Coastguard Worker   }
85*77c1e3ccSAndroid Build Coastguard Worker }
86*77c1e3ccSAndroid Build Coastguard Worker 
Length(long long * total,long long * available)87*77c1e3ccSAndroid Build Coastguard Worker int MkvReader::Length(long long* total, long long* available) {
88*77c1e3ccSAndroid Build Coastguard Worker   if (m_file == NULL)
89*77c1e3ccSAndroid Build Coastguard Worker     return -1;
90*77c1e3ccSAndroid Build Coastguard Worker 
91*77c1e3ccSAndroid Build Coastguard Worker   if (total)
92*77c1e3ccSAndroid Build Coastguard Worker     *total = m_length;
93*77c1e3ccSAndroid Build Coastguard Worker 
94*77c1e3ccSAndroid Build Coastguard Worker   if (available)
95*77c1e3ccSAndroid Build Coastguard Worker     *available = m_length;
96*77c1e3ccSAndroid Build Coastguard Worker 
97*77c1e3ccSAndroid Build Coastguard Worker   return 0;
98*77c1e3ccSAndroid Build Coastguard Worker }
99*77c1e3ccSAndroid Build Coastguard Worker 
Read(long long offset,long len,unsigned char * buffer)100*77c1e3ccSAndroid Build Coastguard Worker int MkvReader::Read(long long offset, long len, unsigned char* buffer) {
101*77c1e3ccSAndroid Build Coastguard Worker   if (m_file == NULL)
102*77c1e3ccSAndroid Build Coastguard Worker     return -1;
103*77c1e3ccSAndroid Build Coastguard Worker 
104*77c1e3ccSAndroid Build Coastguard Worker   if (offset < 0)
105*77c1e3ccSAndroid Build Coastguard Worker     return -1;
106*77c1e3ccSAndroid Build Coastguard Worker 
107*77c1e3ccSAndroid Build Coastguard Worker   if (len < 0)
108*77c1e3ccSAndroid Build Coastguard Worker     return -1;
109*77c1e3ccSAndroid Build Coastguard Worker 
110*77c1e3ccSAndroid Build Coastguard Worker   if (len == 0)
111*77c1e3ccSAndroid Build Coastguard Worker     return 0;
112*77c1e3ccSAndroid Build Coastguard Worker 
113*77c1e3ccSAndroid Build Coastguard Worker   if (offset >= m_length)
114*77c1e3ccSAndroid Build Coastguard Worker     return -1;
115*77c1e3ccSAndroid Build Coastguard Worker 
116*77c1e3ccSAndroid Build Coastguard Worker #ifdef _MSC_VER
117*77c1e3ccSAndroid Build Coastguard Worker   const int status = _fseeki64(m_file, offset, SEEK_SET);
118*77c1e3ccSAndroid Build Coastguard Worker 
119*77c1e3ccSAndroid Build Coastguard Worker   if (status)
120*77c1e3ccSAndroid Build Coastguard Worker     return -1;  // error
121*77c1e3ccSAndroid Build Coastguard Worker #elif defined(_WIN32)
122*77c1e3ccSAndroid Build Coastguard Worker   fseeko64(m_file, static_cast<off_t>(offset), SEEK_SET);
123*77c1e3ccSAndroid Build Coastguard Worker #elif !(defined(__ANDROID__) && __ANDROID_API__ < 24 && !defined(__LP64__) && \
124*77c1e3ccSAndroid Build Coastguard Worker         defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS == 64)
125*77c1e3ccSAndroid Build Coastguard Worker   // POSIX.1 has fseeko and ftello. fseeko and ftello are not available before
126*77c1e3ccSAndroid Build Coastguard Worker   // Android API level 24. See
127*77c1e3ccSAndroid Build Coastguard Worker   // https://android.googlesource.com/platform/bionic/+/main/docs/32-bit-abi.md
128*77c1e3ccSAndroid Build Coastguard Worker   fseeko(m_file, static_cast<off_t>(offset), SEEK_SET);
129*77c1e3ccSAndroid Build Coastguard Worker #else
130*77c1e3ccSAndroid Build Coastguard Worker   fseek(m_file, static_cast<long>(offset), SEEK_SET);
131*77c1e3ccSAndroid Build Coastguard Worker #endif
132*77c1e3ccSAndroid Build Coastguard Worker 
133*77c1e3ccSAndroid Build Coastguard Worker   const size_t size = fread(buffer, 1, len, m_file);
134*77c1e3ccSAndroid Build Coastguard Worker 
135*77c1e3ccSAndroid Build Coastguard Worker   if (size < size_t(len))
136*77c1e3ccSAndroid Build Coastguard Worker     return -1;  // error
137*77c1e3ccSAndroid Build Coastguard Worker 
138*77c1e3ccSAndroid Build Coastguard Worker   return 0;  // success
139*77c1e3ccSAndroid Build Coastguard Worker }
140*77c1e3ccSAndroid Build Coastguard Worker 
141*77c1e3ccSAndroid Build Coastguard Worker }  // namespace mkvparser
142