2 Copyright (c) 2004-2009, John Hurst
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions
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.
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.
27 /*! \file Codestream_Parser.cpp
28 \version $Id: JP2K_Codestream_Parser.cpp,v 1.7 2009/04/09 19:16:49 msheby Exp $
29 \brief AS-DCP library, JPEG 2000 codestream essence reader implementation
32 #include <KM_fileio.h>
37 using Kumu::DefaultLogSink;
39 //------------------------------------------------------------------------------------------
41 class ASDCP::JP2K::CodestreamParser::h__CodestreamParser
43 ASDCP_NO_COPY_CONSTRUCT(h__CodestreamParser);
46 PictureDescriptor m_PDesc;
47 Kumu::FileReader m_File;
51 memset(&m_PDesc, 0, sizeof(m_PDesc));
52 m_PDesc.EditRate = Rational(24,1);
53 m_PDesc.SampleRate = m_PDesc.EditRate;
56 ~h__CodestreamParser() {}
58 Result_t OpenReadFrame(const char* filename, FrameBuffer& FB)
60 ASDCP_TEST_NULL_STR(filename);
62 Result_t result = m_File.OpenRead(filename);
64 if ( ASDCP_SUCCESS(result) )
66 Kumu::fsize_t file_size = m_File.Size();
68 if ( FB.Capacity() < file_size )
70 DefaultLogSink().Error("FrameBuf.Capacity: %u frame length: %u\n", FB.Capacity(), (ui32_t)file_size);
71 return RESULT_SMALLBUF;
77 if ( ASDCP_SUCCESS(result) )
78 result = m_File.Read(FB.Data(), FB.Capacity(), &read_count);
80 if ( ASDCP_SUCCESS(result) )
83 if ( ASDCP_SUCCESS(result) )
85 byte_t start_of_data = 0; // out param
86 result = ParseMetadataIntoDesc(FB, m_PDesc, &start_of_data);
88 if ( ASDCP_SUCCESS(result) )
89 FB.PlaintextOffset(start_of_data);
95 Result_t OpenReadFrame(const unsigned char * data, unsigned int size, FrameBuffer& FB)
97 if ( FB.Capacity() < size )
99 DefaultLogSink().Error("FrameBuf.Capacity: %u frame length: %u\n", FB.Capacity(), (ui32_t) size);
100 return RESULT_SMALLBUF;
103 memcpy (FB.Data(), data, size);
106 byte_t start_of_data = 0; // out param
107 const Result_t result = ParseMetadataIntoDesc(FB, m_PDesc, &start_of_data);
109 if ( ASDCP_SUCCESS(result) )
110 FB.PlaintextOffset(start_of_data);
117 ASDCP::JP2K::ParseMetadataIntoDesc(const FrameBuffer& FB, PictureDescriptor& PDesc, byte_t* start_of_data)
119 Result_t result = RESULT_OK;
122 const byte_t* p = FB.RoData();
123 const byte_t* end_p = p + FB.Size();
125 while ( p < end_p && ASDCP_SUCCESS(result) )
127 result = GetNextMarker(&p, NextMarker);
129 if ( ASDCP_FAILURE(result) )
131 result = RESULT_RAW_ESS;
135 switch ( NextMarker.m_Type )
138 if ( start_of_data != 0 )
139 *start_of_data = p - FB.RoData();
146 Accessor::SIZ SIZ_(NextMarker);
147 PDesc.StoredWidth = SIZ_.Xsize();
148 PDesc.StoredHeight = SIZ_.Ysize();
149 PDesc.AspectRatio = Rational(SIZ_.Xsize(), SIZ_.Ysize());
150 PDesc.Rsize = SIZ_.Rsize();
151 PDesc.Xsize = SIZ_.Xsize();
152 PDesc.Ysize = SIZ_.Ysize();
153 PDesc.XOsize = SIZ_.XOsize();
154 PDesc.YOsize = SIZ_.YOsize();
155 PDesc.XTsize = SIZ_.XTsize();
156 PDesc.YTsize = SIZ_.YTsize();
157 PDesc.XTOsize = SIZ_.XTOsize();
158 PDesc.YTOsize = SIZ_.YTOsize();
159 PDesc.Csize = SIZ_.Csize();
161 if ( PDesc.Csize != 3 )
163 DefaultLogSink().Error("Unexpected number of components: %u\n", PDesc.Csize);
164 return RESULT_RAW_FORMAT;
167 for ( i = 0; i < PDesc.Csize; i++ )
168 SIZ_.ReadComponent(i, PDesc.ImageComponents[i]);
173 memset(&PDesc.CodingStyleDefault, 0, sizeof(CodingStyleDefault_t));
175 if ( NextMarker.m_DataSize > sizeof(CodingStyleDefault_t) )
177 DefaultLogSink().Error("Unexpectedly large CodingStyle data: %u\n", NextMarker.m_DataSize);
178 return RESULT_RAW_FORMAT;
181 memcpy(&PDesc.CodingStyleDefault, NextMarker.m_Data, NextMarker.m_DataSize);
185 memset(&PDesc.QuantizationDefault, 0, sizeof(QuantizationDefault_t));
187 if ( NextMarker.m_DataSize < 16 )
189 DefaultLogSink().Error("No quantization signaled\n");
190 return RESULT_RAW_FORMAT;
193 if ( NextMarker.m_DataSize > MaxDefaults )
195 DefaultLogSink().Error("Quantization Default length exceeds maximum %d\n", NextMarker.m_DataSize);
196 return RESULT_RAW_FORMAT;
199 memcpy(&PDesc.QuantizationDefault, NextMarker.m_Data, NextMarker.m_DataSize);
200 PDesc.QuantizationDefault.SPqcdLength = NextMarker.m_DataSize - 1;
228 //------------------------------------------------------------------------------------------
230 ASDCP::JP2K::CodestreamParser::CodestreamParser()
234 ASDCP::JP2K::CodestreamParser::~CodestreamParser()
238 // Opens the stream for reading, parses enough data to provide a complete
239 // set of stream metadata for the MXFWriter below.
241 ASDCP::JP2K::CodestreamParser::OpenReadFrame(const char* filename, FrameBuffer& FB) const
243 const_cast<ASDCP::JP2K::CodestreamParser*>(this)->m_Parser = new h__CodestreamParser;
244 return m_Parser->OpenReadFrame(filename, FB);
247 // Opens the stream for reading, parses enough data to provide a complete
248 // set of stream metadata for the MXFWriter below.
250 ASDCP::JP2K::CodestreamParser::OpenReadFrame(const unsigned char* data, unsigned int size, FrameBuffer& FB) const
252 const_cast<ASDCP::JP2K::CodestreamParser*>(this)->m_Parser = new h__CodestreamParser;
253 return m_Parser->OpenReadFrame(data, size, FB);
258 ASDCP::JP2K::CodestreamParser::FillPictureDescriptor(PictureDescriptor& PDesc) const
260 if ( m_Parser.empty() )
263 PDesc = m_Parser->m_PDesc;
269 // end Codestream_Parser.cpp