Commit a bunch of portability fixes (64- vs. 32-bit types).
[asdcplib.git] / src / JP2K_Sequence_Parser.cpp
1 /*
2 Copyright (c) 2004-2005, John Hurst
3 All rights reserved.
4
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions
7 are met:
8 1. Redistributions of source code must retain the above copyright
9    notice, this list of conditions and the following disclaimer.
10 2. Redistributions in binary form must reproduce the above copyright
11    notice, this list of conditions and the following disclaimer in the
12    documentation and/or other materials provided with the distribution.
13 3. The name of the author may not be used to endorse or promote products
14    derived from this software without specific prior written permission.
15
16 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27 /*! \file    JP2K_Sequence_Parser.cpp
28     \version $Id$
29     \brief   AS-DCP library, JPEG 2000 codestream essence reader implementation
30 */
31
32 #include <AS_DCP.h>
33 #include <KM_fileio.h>
34 #include <list>
35 #include <string>
36 #include <algorithm>
37 #include <string.h>
38 #include <assert.h>
39
40 using namespace ASDCP;
41
42
43 //------------------------------------------------------------------------------------------
44   
45 class FileList : public std::list<std::string>
46 {
47   std::string m_DirName;
48
49 public:
50   FileList() {}
51   ~FileList() {}
52
53   //
54   Result_t InitFromDirectory(const char* path)
55   {
56     char next_file[Kumu::MaxFilePath];
57     Kumu::DirScanner Scanner;
58
59     Result_t result = Scanner.Open(path);
60
61     if ( ASDCP_SUCCESS(result) )
62       {
63         m_DirName = path;
64
65         while ( ASDCP_SUCCESS(Scanner.GetNext(next_file)) )
66           {
67             if ( next_file[0] == '.' ) // no hidden files or internal links
68               continue;
69
70             std::string Str(m_DirName);
71             Str += "/";
72             Str += next_file;
73             push_back(Str);
74           }
75
76         sort();
77       }
78
79     return result;
80   }
81 };
82
83 //------------------------------------------------------------------------------------------
84
85 class ASDCP::JP2K::SequenceParser::h__SequenceParser
86 {
87   ui32_t             m_FramesRead;
88   Rational           m_PictureRate;
89   FileList           m_FileList;
90   FileList::iterator m_CurrentFile;
91   CodestreamParser   m_Parser;
92
93   ASDCP_NO_COPY_CONSTRUCT(h__SequenceParser);
94
95 public:
96   PictureDescriptor  m_PDesc;
97
98   h__SequenceParser() : m_FramesRead(0)
99   {
100     memset(&m_PDesc, 0, sizeof(m_PDesc));
101     m_PDesc.EditRate = Rational(24,1); 
102   }
103
104   ~h__SequenceParser()
105   {
106     Close();
107   }
108
109   Result_t OpenRead(const char* filename);
110   void     Close() {}
111
112   Result_t Reset()
113   {
114     m_FramesRead = 0;
115     m_CurrentFile = m_FileList.begin();
116     return RESULT_OK;
117   }
118
119   Result_t ReadFrame(FrameBuffer&);
120 };
121
122
123 //
124 ASDCP::Result_t
125 ASDCP::JP2K::SequenceParser::h__SequenceParser::OpenRead(const char* filename)
126 {
127   ASDCP_TEST_NULL_STR(filename);
128
129   Result_t result = m_FileList.InitFromDirectory(filename);
130
131   if ( m_FileList.empty() )
132     return RESULT_ENDOFFILE;
133
134   if ( ASDCP_SUCCESS(result) )
135     {
136       m_CurrentFile = m_FileList.begin();
137
138       CodestreamParser Parser;
139       FrameBuffer TmpBuffer;
140
141       Kumu::fsize_t file_size = Kumu::FileSize((*m_CurrentFile).c_str());
142
143       if ( file_size == 0 )
144         result = RESULT_NOT_FOUND;
145
146       if ( ASDCP_SUCCESS(result) )
147         {
148           assert(file_size <= 0xFFFFFFFFL);
149           result = TmpBuffer.Capacity((ui32_t) file_size);
150         }
151
152       if ( ASDCP_SUCCESS(result) )
153         result = Parser.OpenReadFrame((*m_CurrentFile).c_str(), TmpBuffer);
154       
155       if ( ASDCP_SUCCESS(result) )
156         result = Parser.FillPictureDescriptor(m_PDesc);
157
158       // how big is it?
159       if ( ASDCP_SUCCESS(result) )
160         m_PDesc.ContainerDuration = m_FileList.size();
161     }
162
163   return result;
164 }
165
166 //
167 //
168 ASDCP::Result_t
169 ASDCP::JP2K::SequenceParser::h__SequenceParser::ReadFrame(FrameBuffer& FB)
170 {
171   if ( m_CurrentFile == m_FileList.end() )
172     return RESULT_ENDOFFILE;
173
174   // open the file
175   Result_t result = m_Parser.OpenReadFrame((*m_CurrentFile).c_str(), FB);
176
177   if ( ASDCP_SUCCESS(result) )
178     {
179       FB.FrameNumber(m_FramesRead++);
180       m_CurrentFile++;
181     }
182
183   return result;
184 }
185
186
187 //------------------------------------------------------------------------------------------
188
189 ASDCP::JP2K::SequenceParser::SequenceParser()
190 {
191 }
192
193 ASDCP::JP2K::SequenceParser::~SequenceParser()
194 {
195 }
196
197 // Opens the stream for reading, parses enough data to provide a complete
198 // set of stream metadata for the MXFWriter below.
199 ASDCP::Result_t
200 ASDCP::JP2K::SequenceParser::OpenRead(const char* filename, bool pedantic) const
201 {
202   const_cast<ASDCP::JP2K::SequenceParser*>(this)->m_Parser = new h__SequenceParser;
203
204   Result_t result = m_Parser->OpenRead(filename);
205
206   if ( ASDCP_FAILURE(result) )
207     const_cast<ASDCP::JP2K::SequenceParser*>(this)->m_Parser.release();
208
209   return result;
210 }
211
212 // Rewinds the stream to the beginning.
213 ASDCP::Result_t
214 ASDCP::JP2K::SequenceParser::Reset() const
215 {
216   if ( m_Parser.empty() )
217     return RESULT_INIT;
218
219   return m_Parser->Reset();
220 }
221
222 // Places a frame of data in the frame buffer. Fails if the buffer is too small
223 // or the stream is empty.
224 ASDCP::Result_t
225 ASDCP::JP2K::SequenceParser::ReadFrame(FrameBuffer& FB) const
226 {
227   if ( m_Parser.empty() )
228     return RESULT_INIT;
229
230   return m_Parser->ReadFrame(FB);
231 }
232
233 ASDCP::Result_t
234 ASDCP::JP2K::SequenceParser::FillPictureDescriptor(PictureDescriptor& PDesc) const
235 {
236   if ( m_Parser.empty() )
237     return RESULT_INIT;
238
239   PDesc = m_Parser->m_PDesc;
240   return RESULT_OK;
241 }
242
243
244 //
245 // end JP2K_Sequence_Parser.cpp
246 //