From af6a1e4ef13dcf5811ccd9eb6b63d21bdc88dc70 Mon Sep 17 00:00:00 2001 From: jhurst Date: Wed, 7 Oct 2015 16:41:23 +0000 Subject: [PATCH] o Moved personal dev environment from older gcc to newer clang. Many small changes were made to satisfy the new compiler: - Altered many printf format codes to use the correct type for the given integer type - Parenthesized some expressions to clarify previously ambiguous expectations of precedence - Created macro KM_MACOSX for use in OS-specific code selection - Removed last uses of the old C-language abs(), now using Kumu::xabs() - Removed last uses of the old C-language atoi() o Added platform-independent call Kumu::GetExecutablePath() (test with win32) o Fixed a bug that was causing Array properties to be written without the (count, length) header (from PAL) o Fixed Win32 build (from Crowe) o Added imlementation of SMPTE ST 2092-1 pink noise generator o Added pinkwave CLI utility o Added font support to the IMF timed-text wrapper --- src/AS_02_PCM.cpp | 2 + src/AS_02_TimedText.cpp | 14 +- src/AS_DCP_JP2K.cpp | 32 ++--- src/AS_DCP_MPEG2.cpp | 2 +- src/Index.cpp | 8 +- src/JP2K.cpp | 4 +- src/KM_fileio.h | 4 +- src/KM_platform.h | 16 ++- src/KM_util.cpp | 12 +- src/KM_util.h | 2 +- src/KM_xml.cpp | 42 +++--- src/MXF.h | 4 +- src/MXFTypes.h | 141 ++++++++++++++++---- src/Makefile.am | 24 +++- src/ST2052_TextParser.cpp | 92 ++++++++++--- src/as-02-unwrap.cpp | 12 +- src/as-02-wrap.cpp | 18 +-- src/asdcp-info.cpp | 2 +- src/asdcp-test.cpp | 12 +- src/asdcp-unwrap.cpp | 12 +- src/asdcp-wrap.cpp | 8 +- src/blackwave.cpp | 2 +- src/h__02_Reader.cpp | 2 +- src/klvsplit.cpp | 2 +- src/kmfilegen.cpp | 17 +-- src/kmrandgen.cpp | 2 +- src/phdr-unwrap.cpp | 10 +- src/phdr-wrap.cpp | 18 +-- src/pinkwave.cpp | 269 ++++++++++++++++++++++++++++++++++++++ src/wavesplit.cpp | 4 +- 30 files changed, 616 insertions(+), 173 deletions(-) create mode 100644 src/pinkwave.cpp diff --git a/src/AS_02_PCM.cpp b/src/AS_02_PCM.cpp index f62dcc3..183f424 100644 --- a/src/AS_02_PCM.cpp +++ b/src/AS_02_PCM.cpp @@ -25,6 +25,8 @@ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + /*! \file AS_02_PCM.cpp \version $Id$ \brief AS-02 library, PCM essence reader and writer implementation diff --git a/src/AS_02_TimedText.cpp b/src/AS_02_TimedText.cpp index 47d3566..bd85737 100644 --- a/src/AS_02_TimedText.cpp +++ b/src/AS_02_TimedText.cpp @@ -114,13 +114,17 @@ AS_02::TimedText::MXFReader::h__Reader::MD_to_TimedText_TDesc(TimedTextDescripto if ( DescObject->MIMEMediaType.find("application/x-font-opentype") != std::string::npos || DescObject->MIMEMediaType.find("application/x-opentype") != std::string::npos || DescObject->MIMEMediaType.find("font/opentype") != std::string::npos ) - TmpResource.Type = ASDCP::TimedText::MT_OPENTYPE; - + { + TmpResource.Type = ASDCP::TimedText::MT_OPENTYPE; + } else if ( DescObject->MIMEMediaType.find("image/png") != std::string::npos ) - TmpResource.Type = ASDCP::TimedText::MT_PNG; - + { + TmpResource.Type = ASDCP::TimedText::MT_PNG; + } else - TmpResource.Type = ASDCP::TimedText::MT_BIN; + { + TmpResource.Type = ASDCP::TimedText::MT_BIN; + } TDesc.ResourceList.push_back(TmpResource); m_ResourceMap.insert(ResourceMap_t::value_type(DescObject->AncillaryResourceID, *sdi)); diff --git a/src/AS_DCP_JP2K.cpp b/src/AS_DCP_JP2K.cpp index a1bc499..35929c6 100755 --- a/src/AS_DCP_JP2K.cpp +++ b/src/AS_DCP_JP2K.cpp @@ -163,17 +163,17 @@ ASDCP::JP2K::PictureDescriptorDump(const PictureDescriptor& PDesc, FILE* stream) ); } - fprintf(stream, " Scod: %hd\n", PDesc.CodingStyleDefault.Scod); - fprintf(stream, " ProgressionOrder: %hd\n", PDesc.CodingStyleDefault.SGcod.ProgressionOrder); + fprintf(stream, " Scod: %hhu\n", PDesc.CodingStyleDefault.Scod); + fprintf(stream, " ProgressionOrder: %hhu\n", PDesc.CodingStyleDefault.SGcod.ProgressionOrder); fprintf(stream, " NumberOfLayers: %hd\n", KM_i16_BE(Kumu::cp2i(PDesc.CodingStyleDefault.SGcod.NumberOfLayers))); - fprintf(stream, " MultiCompTransform: %hd\n", PDesc.CodingStyleDefault.SGcod.MultiCompTransform); - fprintf(stream, "DecompositionLevels: %hd\n", PDesc.CodingStyleDefault.SPcod.DecompositionLevels); - fprintf(stream, " CodeblockWidth: %hd\n", PDesc.CodingStyleDefault.SPcod.CodeblockWidth); - fprintf(stream, " CodeblockHeight: %hd\n", PDesc.CodingStyleDefault.SPcod.CodeblockHeight); - fprintf(stream, " CodeblockStyle: %hd\n", PDesc.CodingStyleDefault.SPcod.CodeblockStyle); - fprintf(stream, " Transformation: %hd\n", PDesc.CodingStyleDefault.SPcod.Transformation); + fprintf(stream, " MultiCompTransform: %hhu\n", PDesc.CodingStyleDefault.SGcod.MultiCompTransform); + fprintf(stream, "DecompositionLevels: %hhu\n", PDesc.CodingStyleDefault.SPcod.DecompositionLevels); + fprintf(stream, " CodeblockWidth: %hhu\n", PDesc.CodingStyleDefault.SPcod.CodeblockWidth); + fprintf(stream, " CodeblockHeight: %hhu\n", PDesc.CodingStyleDefault.SPcod.CodeblockHeight); + fprintf(stream, " CodeblockStyle: %hhu\n", PDesc.CodingStyleDefault.SPcod.CodeblockStyle); + fprintf(stream, " Transformation: %hhu\n", PDesc.CodingStyleDefault.SPcod.Transformation); ui32_t precinct_set_size = 0; @@ -181,7 +181,7 @@ ASDCP::JP2K::PictureDescriptorDump(const PictureDescriptor& PDesc, FILE* stream) for ( i = 0; PDesc.CodingStyleDefault.SPcod.PrecinctSize[i] != 0 && i < MaxPrecincts; ++i ) precinct_set_size++; - fprintf(stream, " Precincts: %hd\n", precinct_set_size); + fprintf(stream, " Precincts: %u\n", precinct_set_size); fprintf(stream, "precinct dimensions:\n"); for ( i = 0; i < precinct_set_size && i < MaxPrecincts; i++ ) @@ -190,7 +190,7 @@ ASDCP::JP2K::PictureDescriptorDump(const PictureDescriptor& PDesc, FILE* stream) s_exp_lookup[(PDesc.CodingStyleDefault.SPcod.PrecinctSize[i]>>4)&0x0f] ); - fprintf(stream, " Sqcd: %hd\n", PDesc.QuantizationDefault.Sqcd); + fprintf(stream, " Sqcd: %hhu\n", PDesc.QuantizationDefault.Sqcd); char tmp_buf[MaxDefaults*2]; fprintf(stream, " SPqcd: %s\n", @@ -392,12 +392,12 @@ lh__Reader::OpenRead(const std::string& filename, EssenceType_t type) DefaultLogSink().Warn("EditRate and SampleRate do not match (%.03f, %.03f).\n", m_EditRate.Quotient(), m_SampleRate.Quotient()); - if ( m_EditRate == EditRate_24 && m_SampleRate == EditRate_48 || - m_EditRate == EditRate_25 && m_SampleRate == EditRate_50 || - m_EditRate == EditRate_30 && m_SampleRate == EditRate_60 || - m_EditRate == EditRate_48 && m_SampleRate == EditRate_96 || - m_EditRate == EditRate_50 && m_SampleRate == EditRate_100 || - m_EditRate == EditRate_60 && m_SampleRate == EditRate_120 ) + if ( ( m_EditRate == EditRate_24 && m_SampleRate == EditRate_48 ) + || ( m_EditRate == EditRate_25 && m_SampleRate == EditRate_50 ) + || ( m_EditRate == EditRate_30 && m_SampleRate == EditRate_60 ) + || ( m_EditRate == EditRate_48 && m_SampleRate == EditRate_96 ) + || ( m_EditRate == EditRate_50 && m_SampleRate == EditRate_100 ) + || ( m_EditRate == EditRate_60 && m_SampleRate == EditRate_120 ) ) { DefaultLogSink().Debug("File may contain JPEG Interop stereoscopic images.\n"); return RESULT_SFORMAT; diff --git a/src/AS_DCP_MPEG2.cpp b/src/AS_DCP_MPEG2.cpp index ef82c2c..b7877b5 100755 --- a/src/AS_DCP_MPEG2.cpp +++ b/src/AS_DCP_MPEG2.cpp @@ -308,7 +308,7 @@ ASDCP::MPEG2::FrameBuffer::Dump(FILE* stream, ui32_t dump_len) const if ( stream == 0 ) stream = stderr; - fprintf(stream, "Frame: %06u, %c%-2hu, %7u bytes", + fprintf(stream, "Frame: %06u, %c%-2hhu, %7u bytes", m_FrameNumber, FrameTypeChar(m_FrameType), m_TemporalOffset, m_Size); if ( m_GOPStart ) diff --git a/src/Index.cpp b/src/Index.cpp index b7796bc..f996339 100755 --- a/src/Index.cpp +++ b/src/Index.cpp @@ -131,8 +131,8 @@ ASDCP::MXF::IndexTableSegment::Dump(FILE* stream) fprintf(stream, " EditUnitByteCount = %u\n", EditUnitByteCount); fprintf(stream, " IndexSID = %u\n", IndexSID); fprintf(stream, " BodySID = %u\n", BodySID); - fprintf(stream, " SliceCount = %hu\n", SliceCount); - fprintf(stream, " PosTableCount = %hu\n", PosTableCount); + fprintf(stream, " SliceCount = %hhu\n", SliceCount); + fprintf(stream, " PosTableCount = %hhu\n", PosTableCount); fprintf(stream, " DeltaEntryArray:\n"); DeltaEntryArray.Dump(stream); @@ -154,7 +154,7 @@ ASDCP::MXF::IndexTableSegment::Dump(FILE* stream) const char* ASDCP::MXF::IndexTableSegment::DeltaEntry::EncodeString(char* str_buf, ui32_t buf_len) const { - snprintf(str_buf, buf_len, "%3d %-3hu %-3u", PosTableIndex, Slice, ElementData); + snprintf(str_buf, buf_len, "%3d %-3hhu %-3u", PosTableIndex, Slice, ElementData); return str_buf; } @@ -207,7 +207,7 @@ ASDCP::MXF::IndexTableSegment::IndexEntry::EncodeString(char* str_buf, ui32_t bu txt_flags[4] = ( (Flags & 0x0f) == 3 ) ? 'B' : ( (Flags & 0x0f) == 2 ) ? 'P' : 'I'; txt_flags[5] = 0; - snprintf(str_buf, buf_len, "%3i %-3hu %s %s", + snprintf(str_buf, buf_len, "%3i %-3hhu %s %s", TemporalOffset, KeyFrameOffset, txt_flags, i64sz(StreamOffset, intbuf)); diff --git a/src/JP2K.cpp b/src/JP2K.cpp index 0066f22..a0f2a8a 100755 --- a/src/JP2K.cpp +++ b/src/JP2K.cpp @@ -172,7 +172,7 @@ ASDCP::JP2K::Accessor::COD::Dump(FILE* stream) const fprintf(stream, " ProgOrder: %s\n", prog_order_str); fprintf(stream, " Layers: %hu\n", Layers()); - fprintf(stream, " DecompLevels: %hu\n", DecompLevels()); + fprintf(stream, " DecompLevels: %hhu\n", DecompLevels()); fprintf(stream, " CodeBlockWidth: %d\n", 1 << CodeBlockWidth()); fprintf(stream, "CodeBlockHeight: %d\n", 1 << CodeBlockHeight()); fprintf(stream, " CodeBlockStyle: %d\n", CodeBlockStyle()); @@ -203,7 +203,7 @@ ASDCP::JP2K::Accessor::QCD::Dump(FILE* stream) const fprintf(stream, "QCD: \n"); fprintf(stream, "QuantizationType: %s\n", GetQuantizationTypeString(QuantizationType())); fprintf(stream, " GuardBits: %d\n", GuardBits()); - fprintf(stream, " SPqcd:\n", GuardBits()); + fprintf(stream, " SPqcd: %d\n", GuardBits()); Kumu::hexdump(m_MarkerData, m_DataSize, stream); } diff --git a/src/KM_fileio.h b/src/KM_fileio.h index a6970bf..18dcf0e 100755 --- a/src/KM_fileio.h +++ b/src/KM_fileio.h @@ -220,7 +220,7 @@ namespace Kumu { public: virtual ~PathMatchAny() {} - inline bool Match(const std::string& s) const { return true; } + inline bool Match(const std::string&) const { return true; } }; #ifndef KM_WIN32 @@ -261,6 +261,8 @@ namespace Kumu PathList_t& FindInPaths(const IPathMatch& Pattern, const PathList_t& SearchPaths, PathList_t& FoundPaths, bool one_shot = false, char separator = '/'); + std::string GetExecutablePath(const std::string& default_path); + //------------------------------------------------------------------------------------------ // Directory Manipulation //------------------------------------------------------------------------------------------ diff --git a/src/KM_platform.h b/src/KM_platform.h index 578f545..defcd8a 100644 --- a/src/KM_platform.h +++ b/src/KM_platform.h @@ -1,5 +1,5 @@ /* -Copyright (c) 2004-2012, John Hurst +Copyright (c) 2004-2015, John Hurst All rights reserved. Redistribution and use in source and binary forms, with or without @@ -32,7 +32,8 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #ifndef _KM_PLATFORM_H_ # define _KM_PLATFORM_H_ -# ifdef __APPLE__ +#if defined(__APPLE__) && defined(__MACH__) +# define KM_MACOSX # ifdef __BIG_ENDIAN__ # define KM_BIG_ENDIAN # endif @@ -120,11 +121,17 @@ namespace Kumu // template inline T xclamp(T v, T l, T h) { - if ( v < l ) return l; - if ( v > h ) return h; + if ( v < l ) { return l; } + if ( v > h ) { return h; } return v; } + // + template + inline T xabs(T n) { + if ( n < 0 ) { return -n; } + return n; + } // read an integer from byte-structured storage template @@ -134,6 +141,7 @@ namespace Kumu template inline void i2p(T i, byte_t* p) { *(T*)p = i; } + # ifdef KM_BIG_ENDIAN # define KM_i16_LE(i) Kumu::Swap2(i) # define KM_i32_LE(i) Kumu::Swap4(i) diff --git a/src/KM_util.cpp b/src/KM_util.cpp index 29c3802..2ccf9e9 100755 --- a/src/KM_util.cpp +++ b/src/KM_util.cpp @@ -796,8 +796,8 @@ Kumu::Timestamp::EncodeString(char* str_buf, ui32_t buf_len) const tmp_t.AddMinutes(m_TZOffsetMinutes); tmp_t.GetComponents(year, month, day, hour, minute, second); - ofst_hours = abs(m_TZOffsetMinutes) / 60; - ofst_minutes = abs(m_TZOffsetMinutes) % 60; + ofst_hours = Kumu::xabs(m_TZOffsetMinutes) / 60; + ofst_minutes = Kumu::xabs(m_TZOffsetMinutes) % 60; if ( m_TZOffsetMinutes < 0 ) direction = '-'; @@ -805,7 +805,7 @@ Kumu::Timestamp::EncodeString(char* str_buf, ui32_t buf_len) const // 2004-05-01T13:20:00+00:00 snprintf(str_buf, buf_len, - "%04hu-%02hu-%02huT%02hu:%02hu:%02hu%c%02hu:%02hu", + "%04hu-%02hhu-%02hhuT%02hhu:%02hhu:%02hhu%c%02u:%02u", year, month, day, hour, minute, second, direction, ofst_hours, ofst_minutes); @@ -1185,11 +1185,7 @@ Kumu::km_token_split(const std::string& str, const std::string& separator) r = strstr(pstr, separator.c_str()); } - if ( strlen(pstr) >= 0 ) - { - components.push_back(std::string(pstr)); - } - + components.push_back(std::string(pstr)); return components; } diff --git a/src/KM_util.h b/src/KM_util.h index 2ca1793..51334de 100755 --- a/src/KM_util.h +++ b/src/KM_util.h @@ -531,7 +531,7 @@ namespace Kumu }; inline void hexdump(const ByteString& buf, FILE* stream = 0) { - hexdump(buf.RoData(), buf.Length()); + hexdump(buf.RoData(), buf.Length(), stream); } // Locates the first occurrence of the null-terminated string s2 in the string s1, where not more diff --git a/src/KM_xml.cpp b/src/KM_xml.cpp index 2fe4e33..8345630 100644 --- a/src/KM_xml.cpp +++ b/src/KM_xml.cpp @@ -61,13 +61,13 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. XERCES_CPP_NAMESPACE_USE -namespace Kumu { - void init_xml_dom(); - typedef std::basic_string XercesString; - bool UTF_8_to_XercesString(const std::string& in_str, XercesString& out_str); - bool UTF_8_to_XercesString(const char* in_str, XercesString& out_str); - bool XercesString_to_UTF_8(const XercesString& in_str, std::string& out_str); - bool XercesString_to_UTF_8(const XMLCh* in_str, std::string& out_str); +extern "C" +{ + void kumu_init_xml_dom(); + bool kumu_UTF_8_to_XercesString(const std::string& in_str, std::basic_string& out_str); + bool kumu_UTF_8_to_XercesString_p(const char* in_str, std::basic_string& out_str); + bool kumu_XercesString_to_UTF_8(const std::basic_string& in_str, std::string& out_str); + bool kumu_XercesString_to_UTF_8_p(const XMLCh* in_str, std::string& out_str); } #endif @@ -651,7 +651,7 @@ static const XMLCh sg_label_UTF_8[] = { chLatin_U, chLatin_T, chLatin_F, // void -Kumu::init_xml_dom() +kumu_init_xml_dom() { if ( ! sg_xml_init ) { @@ -691,13 +691,13 @@ Kumu::init_xml_dom() // bool -Kumu::XercesString_to_UTF_8(const Kumu::XercesString& in_str, std::string& out_str) { - return XercesString_to_UTF_8(in_str.c_str(), out_str); +kumu_XercesString_to_UTF_8(const std::basic_string& in_str, std::string& out_str) { + return kumu_XercesString_to_UTF_8_p(in_str.c_str(), out_str); } // bool -Kumu::XercesString_to_UTF_8(const XMLCh* in_str, std::string& out_str) +kumu_XercesString_to_UTF_8_p(const XMLCh* in_str, std::string& out_str) { assert(in_str); assert(sg_xml_init); @@ -734,13 +734,13 @@ Kumu::XercesString_to_UTF_8(const XMLCh* in_str, std::string& out_str) // bool -Kumu::UTF_8_to_XercesString(const std::string& in_str, Kumu::XercesString& out_str) { - return UTF_8_to_XercesString(in_str.c_str(), out_str); +kumu_UTF_8_to_XercesString(const std::string& in_str, std::basic_string& out_str) { + return kumu_UTF_8_to_XercesString_p(in_str.c_str(), out_str); } // bool -Kumu::UTF_8_to_XercesString(const char* in_str, Kumu::XercesString& out_str) +kumu_UTF_8_to_XercesString_p(const char* in_str, std::basic_string& out_str) { assert(in_str); assert(sg_xml_init); @@ -848,7 +848,7 @@ public: assert(x_name); std::string tx_name; - if ( ! XercesString_to_UTF_8(x_name, tx_name) ) + if ( ! kumu_XercesString_to_UTF_8(x_name, tx_name) ) m_HasEncodeErrors = true; const char* name = tx_name.c_str(); @@ -878,10 +878,10 @@ public: for ( ui32_t i = 0; i < a_len; i++) { std::string aname, value; - if ( ! XercesString_to_UTF_8(attributes.getName(i), aname) ) + if ( ! kumu_XercesString_to_UTF_8(attributes.getName(i), aname) ) m_HasEncodeErrors = true; - if ( ! XercesString_to_UTF_8(attributes.getValue(i), value) ) + if ( ! kumu_XercesString_to_UTF_8(attributes.getValue(i), value) ) m_HasEncodeErrors = true; const char* x_aname = aname.c_str(); @@ -917,7 +917,7 @@ public: if ( length > 0 ) { std::string tmp; - if ( ! XercesString_to_UTF_8(chars, tmp) ) + if ( ! kumu_XercesString_to_UTF_8(chars, tmp) ) m_HasEncodeErrors = true; m_Scope.top()->AppendBody(tmp); @@ -934,7 +934,7 @@ Kumu::XMLElement::ParseString(const char* document, ui32_t doc_len) return false; } - init_xml_dom(); + kumu_init_xml_dom(); int errorCount = 0; SAXParser* parser = new SAXParser(); @@ -992,8 +992,8 @@ Kumu::XMLElement::ParseFirstFromString(const char* document, ui32_t doc_len) return false; } - init_xml_dom(); - + kumu_init_xml_dom(); + int errorCount = 0; SAXParser* parser = new SAXParser(); diff --git a/src/MXF.h b/src/MXF.h index 6041772..391e0cc 100755 --- a/src/MXF.h +++ b/src/MXF.h @@ -1,5 +1,5 @@ /* -Copyright (c) 2005-2014, John Hurst +Copyright (c) 2005-2015, John Hurst All rights reserved. Redistribution and use in source and binary forms, with or without @@ -99,7 +99,7 @@ namespace ASDCP }; const Dictionary*& m_Dict; - Array PairArray; + HeadlessArray PairArray; RIP(const Dictionary*& d) : m_Dict(d) {} virtual ~RIP() {} diff --git a/src/MXFTypes.h b/src/MXFTypes.h index 77c0f5f..f49ef8b 100755 --- a/src/MXFTypes.h +++ b/src/MXFTypes.h @@ -103,39 +103,105 @@ namespace ASDCP Batch() {} virtual ~Batch() {} + inline virtual bool HasValue() const { return ! this->empty(); } + + virtual ui32_t ArchiveLength() const { + ui32_t arch_size = sizeof(ui32_t) * 2; + typename std::vector::const_iterator i; + + for ( i = this->begin(); i != this->end(); ++i ) + { + arch_size += i->ArchiveLength(); + } + + return arch_size; + } + + // + virtual bool Archive(Kumu::MemIOWriter* Writer) const { + if ( ! Writer->WriteUi32BE(this->size()) ) return false; + byte_t* p = Writer->CurrentData(); + + if ( ! Writer->WriteUi32BE(0) ) return false; + if ( this->empty() ) return true; + + typename std::vector::const_iterator i = this->begin(); + assert(i != this->end()); + + ui32_t ItemSize = Writer->Remainder(); + if ( ! i->Archive(Writer) ) return false; + ItemSize -= Writer->Remainder(); + Kumu::i2p(KM_i32_BE(ItemSize), p); + ++i; + + bool result = true; + for ( ; i != this->end() && result; ++i ) + { + result = i->Archive(Writer); + } + + return result; + } + // virtual bool Unarchive(Kumu::MemIOReader* Reader) { - ui32_t ItemCount, ItemSize; - if ( ! Reader->ReadUi32BE(&ItemCount) ) return false; - if ( ! Reader->ReadUi32BE(&ItemSize) ) return false; + ui32_t item_count, item_size; + if ( ! Reader->ReadUi32BE(&item_count) ) return false; + if ( ! Reader->ReadUi32BE(&item_size) ) return false; - if ( ( ItemCount > 65536 ) || ( ItemSize > 1024 ) ) - return false; + if ( ( item_count > 65536 ) || ( item_size > 1024 ) ) + { + return false; + } bool result = true; - for ( ui32_t i = 0; i < ItemCount && result; i++ ) + for ( ui32_t i = 0; i < item_count && result; ++i ) { T Tmp; result = Tmp.Unarchive(Reader); if ( result ) - this->push_back(Tmp); + { + this->push_back(Tmp); + } } return result; } + // + void Dump(FILE* stream = 0, ui32_t depth = 0) + { + char identbuf[IdentBufferLen]; + + if ( stream == 0 ) + stream = stderr; + + typename std::vector::iterator i = this->begin(); + for ( ; i != this->end(); i++ ) + fprintf(stream, " %s\n", (*i).EncodeString(identbuf, IdentBufferLen)); + } + }; + + // + template + class Array : public std::list, public Kumu::IArchive + { + public: + Array() {} + virtual ~Array() {} + inline virtual bool HasValue() const { return ! this->empty(); } virtual ui32_t ArchiveLength() const { - ui32_t arch_size = sizeof(ui32_t)*2; + ui32_t arch_size = sizeof(ui32_t) * 2; + typename std::list::const_iterator i; - typename std::vector::const_iterator l_i = this->begin(); - assert(l_i != this->end()); + for ( i = this->begin(); i != this->end(); ++i ) + { + arch_size += i->ArchiveLength(); + } - for ( ; l_i != this->end(); l_i++ ) - arch_size += l_i->ArchiveLength(); - return arch_size; } @@ -147,21 +213,50 @@ namespace ASDCP if ( ! Writer->WriteUi32BE(0) ) return false; if ( this->empty() ) return true; - typename std::vector::const_iterator l_i = this->begin(); - assert(l_i != this->end()); + typename std::list::const_iterator i = this->begin(); + assert(i != this->end()); ui32_t ItemSize = Writer->Remainder(); - if ( ! (*l_i).Archive(Writer) ) return false; + if ( ! i->Archive(Writer) ) return false; ItemSize -= Writer->Remainder(); Kumu::i2p(KM_i32_BE(ItemSize), p); - l_i++; + ++i; bool result = true; - for ( ; l_i != this->end() && result; l_i++ ) - result = (*l_i).Archive(Writer); + for ( ; i != this->end() && result; ++i ) + { + result = i->Archive(Writer); + } + + return result; + } + + // + virtual bool Unarchive(Kumu::MemIOReader* Reader) { + ui32_t item_count, item_size; + if ( ! Reader->ReadUi32BE(&item_count) ) return false; + if ( ! Reader->ReadUi32BE(&item_size) ) return false; + + if ( ( item_count > 65536 ) || ( item_size > 1024 ) ) + { + return false; + } + + bool result = true; + for ( ui32_t i = 0; i < item_count && result; ++i ) + { + T Tmp; + result = Tmp.Unarchive(Reader); + + if ( result ) + { + this->push_back(Tmp); + } + } return result; } + // void Dump(FILE* stream = 0, ui32_t depth = 0) @@ -171,7 +266,7 @@ namespace ASDCP if ( stream == 0 ) stream = stderr; - typename std::vector::iterator i = this->begin(); + typename std::list::iterator i = this->begin(); for ( ; i != this->end(); i++ ) fprintf(stream, " %s\n", (*i).EncodeString(identbuf, IdentBufferLen)); } @@ -179,11 +274,11 @@ namespace ASDCP // template - class Array : public std::list, public Kumu::IArchive + class HeadlessArray : public std::list, public Kumu::IArchive { public: - Array() {} - virtual ~Array() {} + HeadlessArray() {} + virtual ~HeadlessArray() {} // virtual bool Unarchive(Kumu::MemIOReader* Reader) diff --git a/src/Makefile.am b/src/Makefile.am index a1f28f5..2f84f6e 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -58,6 +58,7 @@ include_HEADERS = \ if DEV_HEADERS include_HEADERS += \ S12MTimecode.h \ + ST2095_PinkNoise.h \ MDD.h \ Metadata.h \ KLV.h \ @@ -124,7 +125,8 @@ libasdcp_la_SOURCES = MPEG2_Parser.cpp MPEG.cpp JP2K_Codestream_Parser.cpp \ AtmosSyncChannel_Mixer.cpp AtmosSyncChannel_Mixer.h \ PCMDataProviders.cpp PCMDataProviders.h \ SyncEncoder.c SyncEncoder.h SyncCommon.h CRC16.c CRC16.h \ - UUIDInformation.c UUIDInformation.h + UUIDInformation.c UUIDInformation.h \ + ST2095_PinkNoise.cpp libasdcp_la_LDFLAGS = -release @VERSION@ @@ -207,9 +209,20 @@ endif # list of programs to be built and installed bin_PROGRAMS = \ - asdcp-wrap asdcp-unwrap asdcp-util asdcp-info asdcp-test \ - j2c-test blackwave klvwalk wavesplit klvsplit \ - kmfilegen kmrandgen kmuuidgen + asdcp-wrap \ + asdcp-unwrap \ + asdcp-util \ + asdcp-info \ + asdcp-test \ + j2c-test \ + blackwave \ + pinkwave \ + klvwalk \ + wavesplit \ + klvsplit \ + kmfilegen \ + kmrandgen \ + kmuuidgen if USE_AS_02 bin_PROGRAMS += \ @@ -251,6 +264,9 @@ kmuuidgen_LDADD = libkumu.la blackwave_SOURCES = blackwave.cpp blackwave_LDADD = libasdcp.la libkumu.la +pinkwave_SOURCES = pinkwave.cpp +pinkwave_LDADD = libasdcp.la libkumu.la + klvwalk_SOURCES = klvwalk.cpp klvwalk_LDADD = libasdcp.la libkumu.la diff --git a/src/ST2052_TextParser.cpp b/src/ST2052_TextParser.cpp index b00ebe6..0637875 100644 --- a/src/ST2052_TextParser.cpp +++ b/src/ST2052_TextParser.cpp @@ -45,22 +45,32 @@ const char* c_tt_namespace_name = "http://www.smpte-ra.org/schemas/2052-1/2010/s //------------------------------------------------------------------------------------------ // +int const NS_ID_LENGTH = 16; + // -static byte_t s_id_prefix[16] = { +static byte_t s_png_id_prefix[NS_ID_LENGTH] = { // RFC 4122 type 5 - // 2067-2 5.4.5 + // 2067-2 5.4.5 / RFC4122 Appendix C 0x6b, 0xa7, 0xb8, 0x11, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8 }; // -void -gen_png_name_id(const std::string& image_name, UUID& asset_id) +static byte_t s_font_id_prefix[NS_ID_LENGTH] = { + // RFC 4122 type 5 + // 2067-2 5.4.6 + 0xb6, 0xcc, 0x57, 0xa0, 0x87, 0xe7, 0x4e, 0x75, + 0xb1, 0xc3, 0x33, 0x59, 0xf3, 0xae, 0x88, 0x17 +}; + +// +static Kumu::UUID +create_4122_type5_id(const std::string& subject_name, const byte_t* ns_id) { SHA_CTX ctx; SHA1_Init(&ctx); - SHA1_Update(&ctx, s_id_prefix, 16); - SHA1_Update(&ctx, (byte_t*)image_name.c_str(), image_name.length()); + SHA1_Update(&ctx, ns_id, NS_ID_LENGTH); + SHA1_Update(&ctx, (byte_t*)subject_name.c_str(), subject_name.size()); const ui32_t sha_len = 20; byte_t bin_buf[sha_len]; @@ -73,7 +83,21 @@ gen_png_name_id(const std::string& image_name, UUID& asset_id) buf[6] |= 0x50; // set UUID version 'digest' buf[8] &= 0x3f; // clear bits 6&7 buf[8] |= 0x80; // set bit 7 - asset_id.Set(buf); + return Kumu::UUID(buf); +} + +// +static Kumu::UUID +create_png_name_id(const std::string& image_name) +{ + return create_4122_type5_id(image_name, s_png_id_prefix); +} + +// +static Kumu::UUID +create_font_name_id(const std::string& font_name) +{ + return create_4122_type5_id(font_name, s_font_id_prefix); } //------------------------------------------------------------------------------------------ @@ -101,7 +125,9 @@ AS_02::TimedText::Type5UUIDFilenameResolver::OpenRead(const std::string& dirname abs_dirname = "."; } - if ( KM_SUCCESS(dir_reader.Open(abs_dirname.c_str())) ) + Result_t result = dir_reader.Open(abs_dirname); + + if ( KM_SUCCESS(result) ) { while ( KM_SUCCESS(dir_reader.GetNext(next_item, ft)) ) { @@ -111,26 +137,35 @@ AS_02::TimedText::Type5UUIDFilenameResolver::OpenRead(const std::string& dirname if ( ft == DET_FILE ) { FileReader reader; - Result_t result = reader.OpenRead(tmp_path); + Result_t read_result = reader.OpenRead(tmp_path); - if ( KM_SUCCESS(result) ) + if ( KM_SUCCESS(read_result) ) { - result = reader.Read(read_buffer, 16); + read_result = reader.Read(read_buffer, 16); } - if ( KM_SUCCESS(result) ) + if ( KM_SUCCESS(read_result) ) { // is it PNG? if ( memcmp(read_buffer, PNGMagic, sizeof(PNGMagic)) == 0 ) { - UUID asset_id; - gen_png_name_id(next_item, asset_id); + UUID asset_id = create_png_name_id(next_item); + m_ResourceMap.insert(ResourceMap::value_type(asset_id, next_item)); + } + // is it a font? + else if ( memcmp(read_buffer, OpenTypeMagic, sizeof(OpenTypeMagic)) == 0 + || memcmp(read_buffer, TrueTypeMagic, sizeof(TrueTypeMagic)) == 0 ) + { + fprintf(stderr, "wrap font!\n"); + UUID asset_id = create_font_name_id(next_item); m_ResourceMap.insert(ResourceMap::value_type(asset_id, next_item)); } } } } } + + return result; } // @@ -144,6 +179,7 @@ AS_02::TimedText::Type5UUIDFilenameResolver::ResolveRID(const byte_t* uuid, ASDC if ( i == m_ResourceMap.end() ) { + DefaultLogSink().Debug("Missing timed-text resource \"%s\"\n", tmp_id.EncodeHex(buf, 64)); return RESULT_NOT_FOUND; } @@ -315,13 +351,27 @@ AS_02::TimedText::ST2052_TextParser::h__TextParser::OpenRead() for ( i = png_visitor.value_list.begin(); i != png_visitor.value_list.end(); ++i ) { - UUID asset_id; - gen_png_name_id(*i, asset_id); - TimedTextResourceDescriptor TmpResource; - memcpy(TmpResource.ResourceID, asset_id.Value(), UUIDlen); - TmpResource.Type = ASDCP::TimedText::MT_PNG; - m_TDesc.ResourceList.push_back(TmpResource); - m_ResourceTypes.insert(ResourceTypeMap_t::value_type(UUID(TmpResource.ResourceID), ASDCP::TimedText::MT_PNG)); + UUID asset_id = create_png_name_id(*i); + TimedTextResourceDescriptor png_resource; + memcpy(png_resource.ResourceID, asset_id.Value(), UUIDlen); + png_resource.Type = ASDCP::TimedText::MT_PNG; + m_TDesc.ResourceList.push_back(png_resource); + m_ResourceTypes.insert(ResourceTypeMap_t::value_type(UUID(png_resource.ResourceID), + ASDCP::TimedText::MT_PNG)); + } + + AttributeVisitor font_visitor("fontFamily"); + apply_visitor(m_Root, font_visitor); + + for ( i = font_visitor.value_list.begin(); i != font_visitor.value_list.end(); ++i ) + { + UUID font_id = create_font_name_id(*i); + TimedTextResourceDescriptor font_resource; + memcpy(font_resource.ResourceID, font_id.Value(), UUIDlen); + font_resource.Type = ASDCP::TimedText::MT_OPENTYPE; + m_TDesc.ResourceList.push_back(font_resource); + m_ResourceTypes.insert(ResourceTypeMap_t::value_type(UUID(font_resource.ResourceID), + ASDCP::TimedText::MT_OPENTYPE)); } return RESULT_OK; diff --git a/src/as-02-unwrap.cpp b/src/as-02-unwrap.cpp index 37b458b..688656b 100755 --- a/src/as-02-unwrap.cpp +++ b/src/as-02-unwrap.cpp @@ -178,7 +178,7 @@ public: case 'b': TEST_EXTRA_ARG(i, 'b'); - fb_size = abs(atoi(argv[i])); + fb_size = Kumu::xabs(strtol(argv[i], 0, 10)); if ( verbose_flag ) fprintf(stderr, "Frame Buffer size: %u bytes.\n", fb_size); @@ -188,12 +188,12 @@ public: case 'd': TEST_EXTRA_ARG(i, 'd'); duration_flag = true; - duration = abs(atoi(argv[i])); + duration = Kumu::xabs(strtol(argv[i], 0, 10)); break; case 'f': TEST_EXTRA_ARG(i, 'f'); - start_frame = abs(atoi(argv[i])); + start_frame = Kumu::xabs(strtol(argv[i], 0, 10)); break; case 'h': help_flag = true; break; @@ -201,12 +201,12 @@ public: case 'p': TEST_EXTRA_ARG(i, 'p'); - picture_rate = abs(atoi(argv[i])); + picture_rate = Kumu::xabs(strtol(argv[i], 0, 10)); break; case 's': TEST_EXTRA_ARG(i, 's'); - fb_dump_size = abs(atoi(argv[i])); + fb_dump_size = Kumu::xabs(strtol(argv[i], 0, 10)); break; case 'V': version_flag = true; break; @@ -215,7 +215,7 @@ public: case 'w': TEST_EXTRA_ARG(i, 'w'); - number_width = abs(atoi(argv[i])); + number_width = Kumu::xabs(strtol(argv[i], 0, 10)); break; case 'Z': j2c_pedantic = false; break; diff --git a/src/as-02-wrap.cpp b/src/as-02-wrap.cpp index 982397a..09abd98 100755 --- a/src/as-02-wrap.cpp +++ b/src/as-02-wrap.cpp @@ -283,7 +283,7 @@ public: case 'b': TEST_EXTRA_ARG(i, 'b'); - fb_size = abs(atoi(argv[i])); + fb_size = Kumu::xabs(strtol(argv[i], 0, 10)); if ( verbose_flag ) fprintf(stderr, "Frame Buffer size: %u bytes.\n", fb_size); @@ -301,12 +301,12 @@ public: case 'D': TEST_EXTRA_ARG(i, 'D'); - component_depth = abs(atoi(argv[i])); + component_depth = Kumu::xabs(strtol(argv[i], 0, 10)); break; case 'd': TEST_EXTRA_ARG(i, 'd'); - duration = abs(atoi(argv[i])); + duration = Kumu::xabs(strtol(argv[i], 0, 10)); break; case 'E': encrypt_header_flag = false; break; @@ -314,7 +314,7 @@ public: case 'F': TEST_EXTRA_ARG(i, 'F'); - field_dominance = abs(atoi(argv[i])); + field_dominance = Kumu::xabs(strtol(argv[i], 0, 10)); if ( field_dominance > 1 ) { fprintf(stderr, "Field dominance value must be \"0\" or \"1\"\n"); @@ -388,17 +388,17 @@ public: case 's': TEST_EXTRA_ARG(i, 's'); - partition_space = abs(atoi(argv[i])); + partition_space = Kumu::xabs(strtol(argv[i], 0, 10)); break; case 't': TEST_EXTRA_ARG(i, 't'); - rgba_MinRef = abs(atoi(argv[i])); + rgba_MinRef = Kumu::xabs(strtol(argv[i], 0, 10)); break; case 'T': TEST_EXTRA_ARG(i, 'T'); - rgba_MaxRef = abs(atoi(argv[i])); + rgba_MaxRef = Kumu::xabs(strtol(argv[i], 0, 10)); break; case 'u': show_ul_values_flag = true; break; @@ -408,12 +408,12 @@ public: case 'x': TEST_EXTRA_ARG(i, 'x'); - horizontal_subsampling = abs(atoi(argv[i])); + horizontal_subsampling = Kumu::xabs(strtol(argv[i], 0, 10)); break; case 'X': TEST_EXTRA_ARG(i, 'X'); - vertical_subsampling = abs(atoi(argv[i])); + vertical_subsampling = Kumu::xabs(strtol(argv[i], 0, 10)); break; case 'Y': diff --git a/src/asdcp-info.cpp b/src/asdcp-info.cpp index 9b3ea40..b8876fe 100755 --- a/src/asdcp-info.cpp +++ b/src/asdcp-info.cpp @@ -164,7 +164,7 @@ public: case 't': TEST_EXTRA_ARG(i, 't'); - max_bitrate = abs(atoi(argv[i])); + max_bitrate = Kumu::xabs(strtol(argv[i], 0, 10)); max_bitrate_flag = true; break; diff --git a/src/asdcp-test.cpp b/src/asdcp-test.cpp index c0ccaa1..1b491b0 100755 --- a/src/asdcp-test.cpp +++ b/src/asdcp-test.cpp @@ -379,7 +379,7 @@ public: case 'b': TEST_EXTRA_ARG(i, 'b'); - fb_size = abs(atoi(argv[i])); + fb_size = Kumu::xabs(strtol(argv[i], 0, 10)); if ( verbose_flag ) fprintf(stderr, "Frame Buffer size: %u bytes.\n", fb_size); @@ -395,7 +395,7 @@ public: case 'd': TEST_EXTRA_ARG(i, 'd'); duration_flag = true; - duration = abs(atoi(argv[i])); + duration = Kumu::xabs(strtol(argv[i], 0, 10)); break; case 'E': encrypt_header_flag = false; break; @@ -403,7 +403,7 @@ public: case 'f': TEST_EXTRA_ARG(i, 'f'); - start_frame = abs(atoi(argv[i])); + start_frame = Kumu::xabs(strtol(argv[i], 0, 10)); break; case 'G': mode = MMT_GOP_START; break; @@ -452,7 +452,7 @@ public: case 'p': TEST_EXTRA_ARG(i, 'p'); - picture_rate = abs(atoi(argv[i])); + picture_rate = Kumu::xabs(strtol(argv[i], 0, 10)); break; case 'R': do_repeat = true; break; @@ -460,7 +460,7 @@ public: case 's': TEST_EXTRA_ARG(i, 's'); - fb_dump_size = abs(atoi(argv[i])); + fb_dump_size = Kumu::xabs(strtol(argv[i], 0, 10)); break; case 't': mode = MMT_DIGEST; break; @@ -472,7 +472,7 @@ public: case 'w': TEST_EXTRA_ARG(i, 'w'); - number_width = abs(atoi(argv[i])); + number_width = Kumu::xabs(strtol(argv[i], 0, 10)); break; case 'x': diff --git a/src/asdcp-unwrap.cpp b/src/asdcp-unwrap.cpp index 1f7e8d2..1d27a52 100755 --- a/src/asdcp-unwrap.cpp +++ b/src/asdcp-unwrap.cpp @@ -209,13 +209,13 @@ public: case 'b': TEST_EXTRA_ARG(i, 'b'); - fb_size = abs(atoi(argv[i])); + fb_size = Kumu::xabs(strtol(argv[i], 0, 10)); break; case 'd': TEST_EXTRA_ARG(i, 'd'); duration_flag = true; - duration = abs(atoi(argv[i])); + duration = Kumu::xabs(strtol(argv[i], 0, 10)); break; case 'e': @@ -225,7 +225,7 @@ public: case 'f': TEST_EXTRA_ARG(i, 'f'); - start_frame = abs(atoi(argv[i])); + start_frame = Kumu::xabs(strtol(argv[i], 0, 10)); break; case 'G': mode = MMT_GOP_START; break; @@ -249,12 +249,12 @@ public: case 'p': TEST_EXTRA_ARG(i, 'p'); - picture_rate = abs(atoi(argv[i])); + picture_rate = Kumu::xabs(strtol(argv[i], 0, 10)); break; case 's': TEST_EXTRA_ARG(i, 's'); - fb_dump_size = abs(atoi(argv[i])); + fb_dump_size = Kumu::xabs(strtol(argv[i], 0, 10)); break; case 'V': version_flag = true; break; @@ -263,7 +263,7 @@ public: case 'w': TEST_EXTRA_ARG(i, 'w'); - number_width = abs(atoi(argv[i])); + number_width = Kumu::xabs(strtol(argv[i], 0, 10)); break; case 'Z': j2c_pedantic = false; break; diff --git a/src/asdcp-wrap.cpp b/src/asdcp-wrap.cpp index 8d54772..a12f79e 100755 --- a/src/asdcp-wrap.cpp +++ b/src/asdcp-wrap.cpp @@ -347,7 +347,7 @@ public: case 'b': TEST_EXTRA_ARG(i, 'b'); - fb_size = abs(atoi(argv[i])); + fb_size = Kumu::xabs(strtol(argv[i], 0, 10)); if ( verbose_flag ) fprintf(stderr, "Frame Buffer size: %u bytes.\n", fb_size); @@ -365,7 +365,7 @@ public: case 'd': TEST_EXTRA_ARG(i, 'd'); - duration = abs(atoi(argv[i])); + duration = Kumu::xabs(strtol(argv[i], 0, 10)); break; case 'E': encrypt_header_flag = false; break; @@ -373,7 +373,7 @@ public: case 'f': TEST_EXTRA_ARG(i, 'f'); - start_frame = abs(atoi(argv[i])); + start_frame = Kumu::xabs(strtol(argv[i], 0, 10)); break; case 'g': write_partial_pcm_flag = true; break; @@ -434,7 +434,7 @@ public: case 'p': TEST_EXTRA_ARG(i, 'p'); - picture_rate = abs(atoi(argv[i])); + picture_rate = Kumu::xabs(strtol(argv[i], 0, 10)); break; case 's': dolby_atmos_sync_flag = true; break; diff --git a/src/blackwave.cpp b/src/blackwave.cpp index ac8fea2..501f96a 100644 --- a/src/blackwave.cpp +++ b/src/blackwave.cpp @@ -175,7 +175,7 @@ make_black_wav_file(CommandOptions& Options) if ( Options.verbose_flag ) { - fprintf(stderr, "%s kHz PCM Audio, %s fps (%u spf)\n", "24", + fprintf(stderr, "%s kHz PCM Audio, 24 fps (%u spf)\n", (Options.s96_flag?"96":"48"), PCM::CalcSamplesPerFrame(ADesc)); fputs("AudioDescriptor:\n", stderr); PCM::AudioDescriptorDump(ADesc); diff --git a/src/h__02_Reader.cpp b/src/h__02_Reader.cpp index 1d5feb2..dd85330 100644 --- a/src/h__02_Reader.cpp +++ b/src/h__02_Reader.cpp @@ -65,7 +65,7 @@ AS_02::default_md_object_init() AS_02::MXF::AS02IndexReader::AS02IndexReader(const ASDCP::Dictionary*& d) : m_Duration(0), m_BytesPerEditUnit(0), - ASDCP::MXF::Partition(m_Dict), m_Dict(d) {} + ASDCP::MXF::Partition(d), m_Dict(d) {} AS_02::MXF::AS02IndexReader::~AS02IndexReader() {} diff --git a/src/klvsplit.cpp b/src/klvsplit.cpp index 5dcd8ed..20f9e57 100755 --- a/src/klvsplit.cpp +++ b/src/klvsplit.cpp @@ -136,7 +136,7 @@ USAGE: %s [-l ] [-p ] [-s ] [-u|-U] [-v] \n\ case 'l': TEST_EXTRA_ARG(i, 'l'); - extract_limit = abs(strtoll(argv[i], 0, 10)); + extract_limit = Kumu::xabs(strtoll(argv[i], 0, 10)); break; case 'p': diff --git a/src/kmfilegen.cpp b/src/kmfilegen.cpp index 6f798cc..9ba816e 100755 --- a/src/kmfilegen.cpp +++ b/src/kmfilegen.cpp @@ -123,15 +123,16 @@ public: bool verbose_flag; // true if the verbose option was selected bool version_flag; // true if the version display option was selected bool help_flag; // true if the help display option was selected - const char* filename; // filename to be processed - const char* write_filename; // filename to write with val_write_flag + std::string filename; // filename to be processed + std::string write_filename; // filename to write with val_write_flag ui32_t chunk_count; MajorMode_t mode; // MajorMode selector // CommandOptions(int argc, const char** argv) : - error_flag(true), order(""), verbose_flag(false), version_flag(false), help_flag(false), - filename(""), write_filename(""), chunk_count(0), mode(MMT_VALIDATE) + error_flag(true), order(""), verbose_flag(false), + version_flag(false), help_flag(false), + chunk_count(0), mode(MMT_VALIDATE) { // order = "rand"; @@ -187,7 +188,7 @@ public: { if (argv[i][0] != '-' ) { - if ( filename != "" ) + if ( ! filename.empty() ) { fprintf(stderr, "Extra filename found: %s\n", argv[i]); return; @@ -206,7 +207,7 @@ public: if ( help_flag || version_flag ) return; - if ( strlen ( filename ) == 0 ) + if ( filename.empty() ) { fprintf(stderr, "Filename required.\n"); return; @@ -221,7 +222,7 @@ public: if ( strcmp(order, "") == 0 ) order = "rand"; - if ( strcmp ( filename, write_filename ) == 0 ) + if ( filename == write_filename ) { fprintf(stderr, "Output and input files must be different.\n"); return; @@ -382,7 +383,7 @@ randomize_list(read_list_t* read_list, ui32_t check_total) Result_t ReadValidateWriteLargeFile(CommandOptions& Options) { - assert(Options.write_filename); + assert(!Options.write_filename.empty()); ui32_t check_total = 0; ui32_t write_total = 0; ui32_t read_count = 0; diff --git a/src/kmrandgen.cpp b/src/kmrandgen.cpp index c641e6b..c39eeb0 100644 --- a/src/kmrandgen.cpp +++ b/src/kmrandgen.cpp @@ -133,7 +133,7 @@ public: case 's': TEST_EXTRA_ARG(i, 's'); - request_size = abs(atoi(argv[i])); + request_size = Kumu::xabs(strtol(argv[i], 0, 10)); break; case 'v': verbose_flag = true; break; diff --git a/src/phdr-unwrap.cpp b/src/phdr-unwrap.cpp index b759cd7..c6669e9 100755 --- a/src/phdr-unwrap.cpp +++ b/src/phdr-unwrap.cpp @@ -154,7 +154,7 @@ public: { case 'b': TEST_EXTRA_ARG(i, 'b'); - fb_size = abs(atoi(argv[i])); + fb_size = Kumu::xabs(strtol(argv[i], 0, 10)); if ( verbose_flag ) fprintf(stderr, "Frame Buffer size: %u bytes.\n", fb_size); @@ -164,12 +164,12 @@ public: case 'd': TEST_EXTRA_ARG(i, 'd'); duration_flag = true; - duration = abs(atoi(argv[i])); + duration = Kumu::xabs(strtol(argv[i], 0, 10)); break; case 'f': TEST_EXTRA_ARG(i, 'f'); - start_frame = abs(atoi(argv[i])); + start_frame = Kumu::xabs(strtol(argv[i], 0, 10)); break; case 'h': help_flag = true; break; @@ -177,7 +177,7 @@ public: case 's': TEST_EXTRA_ARG(i, 's'); - fb_dump_size = abs(atoi(argv[i])); + fb_dump_size = Kumu::xabs(strtol(argv[i], 0, 10)); break; case 'V': version_flag = true; break; @@ -186,7 +186,7 @@ public: case 'w': TEST_EXTRA_ARG(i, 'w'); - number_width = abs(atoi(argv[i])); + number_width = Kumu::xabs(strtol(argv[i], 0, 10)); break; default: diff --git a/src/phdr-wrap.cpp b/src/phdr-wrap.cpp index b7ef2d2..9cdc346 100755 --- a/src/phdr-wrap.cpp +++ b/src/phdr-wrap.cpp @@ -266,7 +266,7 @@ public: case 'b': TEST_EXTRA_ARG(i, 'b'); - fb_size = abs(atoi(argv[i])); + fb_size = Kumu::xabs(strtol(argv[i], 0, 10)); if ( verbose_flag ) fprintf(stderr, "Frame Buffer size: %u bytes.\n", fb_size); @@ -275,12 +275,12 @@ public: case 'D': TEST_EXTRA_ARG(i, 'D'); - component_depth = abs(atoi(argv[i])); + component_depth = Kumu::xabs(strtol(argv[i], 0, 10)); break; case 'd': TEST_EXTRA_ARG(i, 'd'); - duration = abs(atoi(argv[i])); + duration = Kumu::xabs(strtol(argv[i], 0, 10)); break; case 'E': encrypt_header_flag = false; break; @@ -288,7 +288,7 @@ public: case 'F': TEST_EXTRA_ARG(i, 'F'); - field_dominance = abs(atoi(argv[i])); + field_dominance = Kumu::xabs(strtol(argv[i], 0, 10)); if ( field_dominance > 1 ) { fprintf(stderr, "Field dominance value must be \"0\" or \"1\"\n"); @@ -363,17 +363,17 @@ public: case 's': TEST_EXTRA_ARG(i, 's'); - partition_space = abs(atoi(argv[i])); + partition_space = Kumu::xabs(strtol(argv[i], 0, 10)); break; case 't': TEST_EXTRA_ARG(i, 't'); - rgba_MinRef = abs(atoi(argv[i])); + rgba_MinRef = Kumu::xabs(strtol(argv[i], 0, 10)); break; case 'T': TEST_EXTRA_ARG(i, 'T'); - rgba_MaxRef = abs(atoi(argv[i])); + rgba_MaxRef = Kumu::xabs(strtol(argv[i], 0, 10)); break; case 'u': show_ul_values_flag = true; break; @@ -383,12 +383,12 @@ public: case 'x': TEST_EXTRA_ARG(i, 'x'); - horizontal_subsampling = abs(atoi(argv[i])); + horizontal_subsampling = Kumu::xabs(strtol(argv[i], 0, 10)); break; case 'X': TEST_EXTRA_ARG(i, 'X'); - vertical_subsampling = abs(atoi(argv[i])); + vertical_subsampling = Kumu::xabs(strtol(argv[i], 0, 10)); break; case 'Y': diff --git a/src/pinkwave.cpp b/src/pinkwave.cpp new file mode 100644 index 0000000..293d033 --- /dev/null +++ b/src/pinkwave.cpp @@ -0,0 +1,269 @@ +/* +Copyright (c) 2015, John Hurst +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +/*! \file wavsplit.cpp + \version $Id$ + \brief Black WAV file generator +*/ + +#include "Wav.h" +#include "ST2095_PinkNoise.h" +#include + +using namespace ASDCP; + +//------------------------------------------------------------------------------------------ +// +// command line option parser class + +static const char* PROGRAM_NAME = "pinkwave"; // program name for messages + +// Macros used to test command option data state. + +// Increment the iterator, test for an additional non-option command line argument. +// Causes the caller to return if there are no remaining arguments or if the next +// argument begins with '-'. +#define TEST_EXTRA_ARG(i,c) if ( ++i >= argc || argv[(i)][0] == '-' ) \ + { \ + fprintf(stderr, "Argument not found for option %c.\n", (c)); \ + return; \ + } +// +void +banner(FILE* stream = stderr) +{ + fprintf(stream, "\n\ +%s (asdcplib %s)\n\n\ +Copyright (c) 2015 John Hurst\n\n\ +%s is part of asdcplib.\n\ +asdcplib may be copied only under the terms of the license found at\n\ +the top of every file in the asdcplib distribution kit.\n\n\ +Specify the -h (help) option for further information about %s\n\n", + PROGRAM_NAME, ASDCP::Version(), PROGRAM_NAME, PROGRAM_NAME); +} + +// +void +usage(FILE* stream = stderr) +{ + fprintf(stream, "\ +USAGE: %s [-v|-h[-d]] \n\ +\n\ + -V - Show version\n\ + -h - Show help\n\ + -d - Number of edit units to process, default 1440\n\ + -9 - Make a 96 kHz file (default 48 kHz)\n\ +\n\ +Other Options:\n\ + -v - Verbose, show extra detail during run\n\ +\n\ + NOTES: o There is no option grouping, all options must be distinct arguments.\n\ + o All option arguments must be separated from the option by whitespace.\n\ +\n", PROGRAM_NAME); +} + +// +// +class CommandOptions +{ + CommandOptions(); + +public: + bool error_flag; // true if the given options are in error or not complete + bool verbose_flag; // true if the verbose option was selected + bool version_flag; // true if the version display option was selected + bool help_flag; // true if the help display option was selected + bool s96_flag; // true if the samples should be at 96 kHz + ui32_t duration; // number of frames to be processed + float HpFc; // Highpass filter cutoff frequency in Hz + float LpFc; // Lowpass filter cutoff frequency in Hz + const char* filename; // + + CommandOptions(int argc, const char** argv) : + error_flag(true), verbose_flag(false), version_flag(false), help_flag(false), s96_flag(false), + duration(1440), HpFc(PinkFilterHighPassConstant), LpFc(PinkFilterLowPassConstant), filename(0) + { + for ( int i = 1; i < argc; i++ ) + { + if ( argv[i][0] == '-' && ( isalpha(argv[i][1]) || isdigit(argv[i][1]) ) && argv[i][2] == 0 ) + { + switch ( argv[i][1] ) + { + case 'V': version_flag = true; break; + case 'h': help_flag = true; break; + case 'v': verbose_flag = true; break; + + case 'd': + TEST_EXTRA_ARG(i, 'd'); + duration = Kumu::xabs(strtol(argv[i], 0, 10)); + break; + + case '9': + s96_flag = true; + break; + + default: + fprintf(stderr, "Unrecognized option: %c\n", argv[i][1]); + return; + } + } + else + { + if ( filename ) + { + fprintf(stderr, "Unexpected extra filename.\n"); + return; + } + + filename = argv[i]; + } + } + + if ( filename == 0 ) + { + fputs("Output filename required.\n", stderr); + return; + } + + error_flag = false; + } +}; + +// +// +Result_t +make_pink_wav_file(CommandOptions& Options) +{ + PCM::FrameBuffer FrameBuffer; + PCM::AudioDescriptor ADesc; + + ADesc.EditRate = Rational(24,1); + ADesc.AudioSamplingRate = Options.s96_flag ? ASDCP::SampleRate_96k : ASDCP::SampleRate_48k; + ADesc.Locked = 0; + ADesc.ChannelCount = 1; + ADesc.QuantizationBits = 24; + ADesc.BlockAlign = 3; + ADesc.AvgBps = ADesc.BlockAlign * ADesc.AudioSamplingRate.Quotient(); + ADesc.LinkedTrackID = 1; + ADesc.ContainerDuration = Options.duration; + + // set up LCG and pink filter + PinkFilter pink_filter(Options.s96_flag ? ASDCP::SampleRate_96k.Numerator : ASDCP::SampleRate_48k.Numerator, + Options.HpFc, Options.LpFc); + + LinearCongruentialGenerator lcg(Options.s96_flag ? ASDCP::SampleRate_96k.Numerator : ASDCP::SampleRate_48k.Numerator); + + + FrameBuffer.Capacity(PCM::CalcFrameBufferSize(ADesc)); + FrameBuffer.Size(FrameBuffer.Capacity()); + ui32_t samples_per_frame = PCM::CalcSamplesPerFrame(ADesc); + + if ( Options.verbose_flag ) + { + fprintf(stderr, "%s kHz PCM Audio, 24 fps (%u spf)\n", + (Options.s96_flag?"96":"48"), samples_per_frame); + fputs("AudioDescriptor:\n", stderr); + PCM::AudioDescriptorDump(ADesc); + } + + // set up output file + Kumu::FileWriter OutFile; + Result_t result = OutFile.OpenWrite(Options.filename); + + if ( ASDCP_SUCCESS(result) ) + { + RF64::SimpleRF64Header WavHeader(ADesc); + result = WavHeader.WriteToFile(OutFile); + } + + if ( ASDCP_SUCCESS(result) ) + { + ui32_t write_count = 0; + ui32_t duration = 0; + byte_t scaled_pink[sizeof(ui32_t)]; + + while ( ASDCP_SUCCESS(result) && (duration++ < Options.duration) ) + { + // fill the frame buffer with a frame of pink noise + byte_t *p = FrameBuffer.Data(); + + for ( int i = 0; i < samples_per_frame; ++i ) + { + float pink_sample = pink_filter.GetNextSample(lcg.GetNextSample()); + ScalePackSample(pink_sample, p, ADesc.BlockAlign); + p += ADesc.BlockAlign; + } + + result = OutFile.Write(FrameBuffer.RoData(), FrameBuffer.Size(), &write_count); + } + } + + return result; +} + + +// +int +main(int argc, const char** argv) +{ + Result_t result = RESULT_OK; + CommandOptions Options(argc, argv); + + if ( Options.help_flag ) + { + usage(); + return 0; + } + + if ( Options.error_flag ) + return 3; + + if ( Options.version_flag ) + banner(); + + else + result = make_pink_wav_file(Options); + + if ( result != RESULT_OK ) + { + fputs("Program stopped on error.\n", stderr); + + if ( result != RESULT_FAIL ) + { + fputs(result, stderr); + fputc('\n', stderr); + } + + return 1; + } + + return 0; +} + + +// +// end pinkwave.cpp +// diff --git a/src/wavesplit.cpp b/src/wavesplit.cpp index 3fc6899..71448ce 100755 --- a/src/wavesplit.cpp +++ b/src/wavesplit.cpp @@ -138,12 +138,12 @@ public: case 'd': TEST_EXTRA_ARG(i, 'd'); - duration = abs(strtol(argv[i], 0, 10)); + duration = Kumu::xabs(strtol(argv[i], 0, 10)); break; case 'f': TEST_EXTRA_ARG(i, 'f'); - start_frame = abs(strtol(argv[i], 0, 10)); + start_frame = Kumu::xabs(strtol(argv[i], 0, 10)); break; case 'h': help_flag = true; break; -- 2.30.2