From a2b2e9c11e1c53eebe41cb8f7eb805e78109b9ab Mon Sep 17 00:00:00 2001 From: Steve Lhomme Date: Tue, 24 Dec 2024 09:58:55 +0100 Subject: [PATCH 01/16] corec: don't support gzip header in zlib We don't need it in Matroska. --- corec/corec/helpers/zlib/CMakeLists.txt | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/corec/corec/helpers/zlib/CMakeLists.txt b/corec/corec/helpers/zlib/CMakeLists.txt index 87d0c9a8..cf048a28 100644 --- a/corec/corec/helpers/zlib/CMakeLists.txt +++ b/corec/corec/helpers/zlib/CMakeLists.txt @@ -22,7 +22,6 @@ if (CONFIG_ZLIB) inffast.c inflate.c inftrees.c - uncompr.c zutil.c compress.c deflate.c @@ -68,14 +67,14 @@ if (CONFIG_ZLIB) endif() endif() endif() - - target_compile_definitions("zlib" PRIVATE FASTEST NO_ERRNO_H) + + target_compile_definitions("zlib" PRIVATE FASTEST NO_ERRNO_H NO_GZIP) # if(WIN32 && DYNAMIC BUILD) # target_compile_definitions("zlib" ZLIB_DLL) # endif(WIN32) target_sources("zlib" PRIVATE ${zlib_group_SOURCES} ${ZLIB_ASM_SOURCES} ${zlib_group_PUBLIC_HEADERS}) target_include_directories("zlib" PUBLIC ".") - set_target_properties("zlib" PROPERTIES + set_target_properties("zlib" PROPERTIES PUBLIC_HEADER "${zlib_group_PUBLIC_HEADERS}" ) endif(CONFIG_ZLIB) From 0569dcdba530bce5c17e70ce7d76966e0412fed7 Mon Sep 17 00:00:00 2001 From: Steve Lhomme Date: Tue, 24 Dec 2024 11:08:57 +0100 Subject: [PATCH 02/16] corec: remove unused SwapSP() --- corec/corec/portab.h | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/corec/corec/portab.h b/corec/corec/portab.h index 63eb2e35..91e8c6ee 100644 --- a/corec/corec/portab.h +++ b/corec/corec/portab.h @@ -1,5 +1,5 @@ /***************************************************************************** - * + * * Copyright (c) 2008-2010, CoreCodec, Inc. * All rights reserved. * @@ -516,22 +516,6 @@ void * __alloca(size_t size); #define alloca(size) __builtin_alloca(size) #endif -#if defined(ARM) -//fixed size stack: -// symbian -// palm os -#define SWAPSP -static INLINE void* SwapSP(void* in) -{ - void* out; - asm volatile( - "mov %0, sp\n\t" - "mov sp, %1\n\t" - : "=&r"(out) : "r"(in) : "cc"); - return out; -} -#endif - #endif /* __GNUC__ */ #if defined(_MSC_VER) && defined(TARGET_WIN) From 2e893d6352447dad034253de1b8193d62fabb96d Mon Sep 17 00:00:00 2001 From: Steve Lhomme Date: Tue, 24 Dec 2024 11:09:33 +0100 Subject: [PATCH 03/16] corec: remove unused plane types --- corec/corec/portab.h | 7 ------- 1 file changed, 7 deletions(-) diff --git a/corec/corec/portab.h b/corec/corec/portab.h index 91e8c6ee..39adfda6 100644 --- a/corec/corec/portab.h +++ b/corec/corec/portab.h @@ -482,13 +482,6 @@ typedef uint16_t utf16_t; #define MAXPATHFULL MAXPATH #endif -#define MAXPLANES 4 -typedef void* planes[MAXPLANES]; -typedef const void* constplanes[MAXPLANES]; -#define CONST_CONSTPLANES(name) const void* const (name)[MAXPLANES] -#define CONSTPLANES(name) const void* (name)[MAXPLANES] -#define CONST_PLANES(name) void* const (name)[MAXPLANES] - #define FOURCCBE(a,b,c,d) \ (((uint8_t)(a) << 24) | ((uint8_t)(b) << 16) | \ ((uint8_t)(c) << 8) | ((uint8_t)(d) << 0)) From ef9118bcb733e73a2c908f891765e8ae8a3c1866 Mon Sep 17 00:00:00 2001 From: Steve Lhomme Date: Mon, 23 Dec 2024 15:46:15 +0100 Subject: [PATCH 04/16] libmatroska2: use MatroskaContentEncodingScope in public API --- libmatroska2/matroska2/matroska.h | 6 +++--- libmatroska2/matroskamain.c | 14 +++++++------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/libmatroska2/matroska2/matroska.h b/libmatroska2/matroska2/matroska.h index 492971d8..f052a2c6 100644 --- a/libmatroska2/matroska2/matroska.h +++ b/libmatroska2/matroska2/matroska.h @@ -49,8 +49,8 @@ #define PROFILE_MATROSKA_V5 (1<<6) #define PROFILE_WEBM (1<<3) #define PROFILE_DIVX (1<<4) -#define PROFILE_MATROSKA_ALL (PROFILE_MATROSKA_V1|PROFILE_MATROSKA_V2|PROFILE_MATROSKA_V3|PROFILE_MATROSKA_V4) -#define PROFILE_MATROSKA_ANY (PROFILE_MATROSKA_ALL|PROFILE_WEBM|PROFILE_DIVX) +#define PROFILE_MATROSKA_ALL (PROFILE_MATROSKA_V1|PROFILE_MATROSKA_V2|PROFILE_MATROSKA_V3|PROFILE_MATROSKA_V4) +#define PROFILE_MATROSKA_ANY (PROFILE_MATROSKA_ALL|PROFILE_WEBM|PROFILE_DIVX) #define MATROSKA_VERSION 2 @@ -120,7 +120,7 @@ MATROSKA_DLL matroska_cuepoint *MATROSKA_CuesGetTimestampStart(const ebml_elemen #if defined(CONFIG_EBML_WRITING) MATROSKA_DLL MatroskaTrackEncodingCompAlgo MATROSKA_TrackGetBlockCompression(const matroska_trackentry *TrackEntry, int ForProfile); -MATROSKA_DLL bool_t MATROSKA_TrackSetCompressionZlib(matroska_trackentry *TrackEntry, int Scope, int ForProfile); +MATROSKA_DLL bool_t MATROSKA_TrackSetCompressionZlib(matroska_trackentry *TrackEntry, MatroskaContentEncodingScope Scope, int ForProfile); MATROSKA_DLL bool_t MATROSKA_TrackSetCompressionHeader(matroska_trackentry *TrackEntry, const uint8_t *Header, size_t HeaderSize, int ForProfile); MATROSKA_DLL bool_t MATROSKA_TrackSetCompressionNone(matroska_trackentry *TrackEntry); #if defined(CONFIG_ZLIB) diff --git a/libmatroska2/matroskamain.c b/libmatroska2/matroskamain.c index 341fa043..8377732b 100644 --- a/libmatroska2/matroskamain.c +++ b/libmatroska2/matroskamain.c @@ -64,7 +64,7 @@ err_t MATROSKA_Init(parsercontext *p) if (!MATROSKA_init_once) { MATROSKA_init_once = 1; - + MATROSKA_InitSemantic(); EBML_SemanticMatroska[0] = (ebml_semantic){1, 0, EBML_getContextHead() ,0}; @@ -645,7 +645,7 @@ bool_t MATROSKA_BlockKeyframe(const matroska_block *Block) if (!EBML_ElementIsType((const ebml_element*)Block, MATROSKA_getContextBlock())) return 0; - + BlockGroup = (ebml_master*)EBML_ElementParent(Block); if (!BlockGroup || !Node_IsPartOf(BlockGroup,MATROSKA_BLOCKGROUP_CLASS)) return 0; @@ -782,7 +782,7 @@ err_t MATROSKA_CuePointUpdate(matroska_cuepoint *Cue, ebml_element *Segment, int if (!TrackNum) return ERR_OUT_OF_MEMORY; EBML_IntegerSetValue(TrackNum, MATROSKA_BlockTrackNum(Cue->Block)); - + PosInCluster = EBML_MasterGetChild((ebml_master*)Elt,MATROSKA_getContextCueClusterPosition(), ForProfile); if (!PosInCluster) return ERR_OUT_OF_MEMORY; @@ -793,7 +793,7 @@ err_t MATROSKA_CuePointUpdate(matroska_cuepoint *Cue, ebml_element *Segment, int return ERR_INVALID_DATA; assert(EBML_ElementPosition(Elt) != INVALID_FILEPOS_T); - + EBML_IntegerSetValue((ebml_integer*)PosInCluster, EBML_ElementPosition(Elt) - EBML_ElementPositionData(Segment)); return ERR_NONE; @@ -1777,7 +1777,7 @@ static err_t RenderBlockData(matroska_block *Element, stream *Output, bool_t bFo Cursor = &BlockHead[2]; BlockHeadSize = 5; } - else + else return ERR_INVALID_DATA; STORE16BE(Cursor,Element->LocalTimestamp); @@ -2174,7 +2174,7 @@ static int CmpAttachedFile(const ebml_master* a,const ebml_master* b) return -1; if (NameA==NULL) return 1; - + EBML_StringGet((ebml_string*)NameA,FilenameA,TSIZEOF(FilenameA)); EBML_StringGet((ebml_string*)NameB,FilenameB,TSIZEOF(FilenameB)); @@ -2391,7 +2391,7 @@ MatroskaTrackEncodingCompAlgo MATROSKA_TrackGetBlockCompression(const matroska_t return (MatroskaTrackEncodingCompAlgo)EBML_IntegerValue((ebml_integer*)Elt2); } -bool_t MATROSKA_TrackSetCompressionZlib(matroska_trackentry *TrackEntry, int Scope, int ForProfile) +bool_t MATROSKA_TrackSetCompressionZlib(matroska_trackentry *TrackEntry, MatroskaContentEncodingScope Scope, int ForProfile) { // force zlib compression bool_t HadEncoding; From 0025e84a8ce53fb5975eb7e5dda3f6e0d6bb201b Mon Sep 17 00:00:00 2001 From: Steve Lhomme Date: Mon, 23 Dec 2024 11:06:15 +0100 Subject: [PATCH 05/16] libmatroska2: allow setting other compression algorithms --- libmatroska2/matroska2/matroska.h | 2 +- libmatroska2/matroskamain.c | 4 ++-- mkclean/mkclean.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/libmatroska2/matroska2/matroska.h b/libmatroska2/matroska2/matroska.h index f052a2c6..fd7bca60 100644 --- a/libmatroska2/matroska2/matroska.h +++ b/libmatroska2/matroska2/matroska.h @@ -120,7 +120,7 @@ MATROSKA_DLL matroska_cuepoint *MATROSKA_CuesGetTimestampStart(const ebml_elemen #if defined(CONFIG_EBML_WRITING) MATROSKA_DLL MatroskaTrackEncodingCompAlgo MATROSKA_TrackGetBlockCompression(const matroska_trackentry *TrackEntry, int ForProfile); -MATROSKA_DLL bool_t MATROSKA_TrackSetCompressionZlib(matroska_trackentry *TrackEntry, MatroskaContentEncodingScope Scope, int ForProfile); +MATROSKA_DLL bool_t MATROSKA_TrackSetCompressionAlgo(matroska_trackentry *TrackEntry, MatroskaContentEncodingScope Scope, int ForProfile, MatroskaTrackEncodingCompAlgo algo); MATROSKA_DLL bool_t MATROSKA_TrackSetCompressionHeader(matroska_trackentry *TrackEntry, const uint8_t *Header, size_t HeaderSize, int ForProfile); MATROSKA_DLL bool_t MATROSKA_TrackSetCompressionNone(matroska_trackentry *TrackEntry); #if defined(CONFIG_ZLIB) diff --git a/libmatroska2/matroskamain.c b/libmatroska2/matroskamain.c index 8377732b..bf315f1b 100644 --- a/libmatroska2/matroskamain.c +++ b/libmatroska2/matroskamain.c @@ -2391,7 +2391,7 @@ MatroskaTrackEncodingCompAlgo MATROSKA_TrackGetBlockCompression(const matroska_t return (MatroskaTrackEncodingCompAlgo)EBML_IntegerValue((ebml_integer*)Elt2); } -bool_t MATROSKA_TrackSetCompressionZlib(matroska_trackentry *TrackEntry, MatroskaContentEncodingScope Scope, int ForProfile) +bool_t MATROSKA_TrackSetCompressionAlgo(matroska_trackentry *TrackEntry, MatroskaContentEncodingScope Scope, int ForProfile, MatroskaTrackEncodingCompAlgo algo) { // force zlib compression bool_t HadEncoding; @@ -2413,7 +2413,7 @@ bool_t MATROSKA_TrackSetCompressionZlib(matroska_trackentry *TrackEntry, Matrosk Elt = EBML_MasterGetChild((ebml_master*)Elt2,MATROSKA_getContextContentCompression(), ForProfile); Elt2 = EBML_MasterGetChild((ebml_master*)Elt,MATROSKA_getContextContentCompAlgo(), ForProfile); - EBML_IntegerSetValue((ebml_integer*)Elt2, MATROSKA_TRACK_ENCODING_COMP_ZLIB); + EBML_IntegerSetValue((ebml_integer*)Elt2, algo); } return HadEncoding; } diff --git a/mkclean/mkclean.c b/mkclean/mkclean.c index bdf1a9cd..913b1ea0 100644 --- a/mkclean/mkclean.c +++ b/mkclean/mkclean.c @@ -2729,7 +2729,7 @@ int main(int argc, const char *argv[]) case MATROSKA_TRACK_ENCODING_COMP_ZLIB: case MATROSKA_TRACK_ENCODING_COMP_BZLIB: // transform bzlib into zlib case MATROSKA_TRACK_ENCODING_COMP_LZO1X: // transform lzo1x into zlib - if (MATROSKA_TrackSetCompressionZlib((matroska_trackentry*)RLevel1, zlib_scope,DstProfile)) + if (MATROSKA_TrackSetCompressionAlgo((matroska_trackentry*)RLevel1, zlib_scope,DstProfile, MATROSKA_TRACK_ENCODING_COMP_ZLIB)) ClustersNeedRead = 1; break; case MATROSKA_TRACK_ENCODING_COMP_HEADERSTRIP: From 3445fc62b5d09fbd58eb3fe13f849611ebc0a531 Mon Sep 17 00:00:00 2001 From: Steve Lhomme Date: Mon, 23 Dec 2024 14:29:19 +0100 Subject: [PATCH 06/16] libmatroska2: simplify compression algorithm checks So it can be used with other algorithms. --- libmatroska2/matroskamain.c | 40 +++++++++++++++++++++++++++---------- 1 file changed, 29 insertions(+), 11 deletions(-) diff --git a/libmatroska2/matroskamain.c b/libmatroska2/matroskamain.c index bf315f1b..06abaf92 100644 --- a/libmatroska2/matroskamain.c +++ b/libmatroska2/matroskamain.c @@ -1685,6 +1685,7 @@ static char GetBestLacingType(const matroska_block *Element, int ForProfile) size_t i; int32_t DataSize; ebml_element *Elt, *Elt2, *Header = NULL; + MatroskaTrackEncodingCompAlgo CompressionAlgo = MATROSKA_TRACK_ENCODING_COMP_NONE; MatroskaContentEncodingScope CompressionScope = MATROSKA_CONTENTENCODINGSCOPE_BLOCK; if (ARRAYCOUNT(Element->SizeList,int32_t) <= 1) @@ -1719,11 +1720,16 @@ static char GetBestLacingType(const matroska_block *Element, int ForProfile) return 0; // TODO: support encryption Header = EBML_MasterGetChild((ebml_master*)Elt, MATROSKA_getContextContentCompAlgo(),ForProfile); + if (Header) + CompressionAlgo = EBML_IntegerValue((ebml_integer*)Header); + bool_t CanCompress = 0; + if (CompressionAlgo == MATROSKA_TRACK_ENCODING_COMP_HEADERSTRIP) + CanCompress = 1; #if defined(CONFIG_ZLIB) - if (EBML_IntegerValue((ebml_integer*)Header)!=MATROSKA_TRACK_ENCODING_COMP_HEADERSTRIP && EBML_IntegerValue((ebml_integer*)Header)!=MATROSKA_TRACK_ENCODING_COMP_ZLIB) -#else - if (EBML_IntegerValue((ebml_integer*)Header)!=MATROSKA_TRACK_ENCODING_COMP_HEADERSTRIP) + else if (CompressionAlgo == MATROSKA_TRACK_ENCODING_COMP_ZLIB) + CanCompress = 1; #endif + if (!CanCompress) return 0; if (EBML_IntegerValue((ebml_integer*)Header)==MATROSKA_TRACK_ENCODING_COMP_HEADERSTRIP) @@ -1762,6 +1768,7 @@ static err_t RenderBlockData(matroska_block *Element, stream *Output, bool_t bFo uint8_t BlockHead[5], *Cursor; size_t ToWrite, Written, BlockHeadSize = 4; ebml_element *Elt, *Elt2, *Header = NULL; + MatroskaTrackEncodingCompAlgo CompressionAlgo = MATROSKA_TRACK_ENCODING_COMP_NONE; MatroskaContentEncodingScope CompressionScope = MATROSKA_CONTENTENCODINGSCOPE_BLOCK; assert(Element->Lacing != LACING_AUTO); @@ -1825,17 +1832,22 @@ static err_t RenderBlockData(matroska_block *Element, stream *Output, bool_t bFo return ERR_INVALID_DATA; // TODO: support encryption Header = EBML_MasterGetChild((ebml_master*)Elt, MATROSKA_getContextContentCompAlgo(),ForProfile); + if (Header) + CompressionAlgo = EBML_IntegerValue((ebml_integer*)Header); + bool_t CanCompress = 0; + if (CompressionAlgo == MATROSKA_TRACK_ENCODING_COMP_HEADERSTRIP) + CanCompress = 1; #if defined(CONFIG_ZLIB) - if (Header == NULL || (EBML_IntegerValue((ebml_integer*)Header)!=MATROSKA_TRACK_ENCODING_COMP_HEADERSTRIP && EBML_IntegerValue((ebml_integer*)Header)!=MATROSKA_TRACK_ENCODING_COMP_ZLIB)) -#else - if (Header == NULL || EBML_IntegerValue((ebml_integer*)Header)!=MATROSKA_TRACK_ENCODING_COMP_HEADERSTRIP) + else if (CompressionAlgo == MATROSKA_TRACK_ENCODING_COMP_ZLIB) + CanCompress = 1; #endif + if (!CanCompress) { Err = ERR_NOT_SUPPORTED; goto failed; } - if (EBML_IntegerValue((ebml_integer*)Header)==MATROSKA_TRACK_ENCODING_COMP_HEADERSTRIP) + if (CompressionAlgo == MATROSKA_TRACK_ENCODING_COMP_HEADERSTRIP) Header = EBML_MasterFindChild((ebml_master*)Elt, MATROSKA_getContextContentCompSettings()); } } @@ -2007,6 +2019,7 @@ static filepos_t UpdateBlockSize(matroska_block *Element, bool_t bWithDefault, b { ebml_element *Header = NULL; #if defined(CONFIG_EBML_WRITING) + MatroskaTrackEncodingCompAlgo CompressionAlgo = MATROSKA_TRACK_ENCODING_COMP_NONE; ebml_element *Elt, *Elt2; if (Element->Lacing == LACING_AUTO) Element->Lacing = GetBestLacingType(Element,ForProfile); @@ -2030,14 +2043,19 @@ static filepos_t UpdateBlockSize(matroska_block *Element, bool_t bWithDefault, b return ERR_INVALID_DATA; // TODO: support encryption Header = EBML_MasterGetChild((ebml_master*)Elt, MATROSKA_getContextContentCompAlgo(),ForProfile); + if (Header) + CompressionAlgo = EBML_IntegerValue((ebml_integer*)Header); + bool_t CanCompress = 0; + if (CompressionAlgo == MATROSKA_TRACK_ENCODING_COMP_HEADERSTRIP) + CanCompress = 1; #if defined(CONFIG_ZLIB) - if (Header == NULL || (EBML_IntegerValue((ebml_integer*)Header)!=MATROSKA_TRACK_ENCODING_COMP_HEADERSTRIP && EBML_IntegerValue((ebml_integer*)Header)!=MATROSKA_TRACK_ENCODING_COMP_ZLIB)) -#else - if (Header == NULL || EBML_IntegerValue((ebml_integer*)Header)!=MATROSKA_TRACK_ENCODING_COMP_HEADERSTRIP) + else if (CompressionAlgo == MATROSKA_TRACK_ENCODING_COMP_ZLIB) + CanCompress = 1; #endif + if (!CanCompress) return ERR_INVALID_DATA; - if (EBML_IntegerValue((ebml_integer*)Header)==MATROSKA_TRACK_ENCODING_COMP_HEADERSTRIP) + if (CompressionAlgo == MATROSKA_TRACK_ENCODING_COMP_HEADERSTRIP) Header = EBML_MasterFindChild((ebml_master*)Elt, MATROSKA_getContextContentCompSettings()); } } From 1fb9162061cae9053bfa7edb26c09fa275dcd41a Mon Sep 17 00:00:00 2001 From: Steve Lhomme Date: Tue, 24 Dec 2024 08:46:17 +0100 Subject: [PATCH 07/16] libmatroska2: simplify decompression algorithm checks --- libmatroska2/matroskamain.c | 38 +++++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/libmatroska2/matroskamain.c b/libmatroska2/matroskamain.c index 06abaf92..eae9071f 100644 --- a/libmatroska2/matroskamain.c +++ b/libmatroska2/matroskamain.c @@ -188,20 +188,23 @@ static err_t CheckCompression(matroska_block *Block, int ForProfile) return ERR_INVALID_DATA; // TODO: support encryption Header = (ebml_master*)EBML_MasterGetChild(Elt, MATROSKA_getContextContentCompAlgo(), ForProfile); -#if defined(CONFIG_ZLIB) || defined(CONFIG_LZO1X) || defined(CONFIG_BZLIB) - if (EBML_IntegerValue((ebml_integer*)Header)!=MATROSKA_TRACK_ENCODING_COMP_HEADERSTRIP) + MatroskaTrackEncodingCompAlgo CompressionAlgo = Header ? EBML_IntegerValue((ebml_integer*)Header) : MATROSKA_TRACK_ENCODING_COMP_NONE; + bool_t CanDecompress = 0; + if (CompressionAlgo == MATROSKA_TRACK_ENCODING_COMP_HEADERSTRIP) + CanDecompress = 1; #if defined(CONFIG_ZLIB) - if (EBML_IntegerValue((ebml_integer*)Header)!=MATROSKA_TRACK_ENCODING_COMP_ZLIB) + else if (CompressionAlgo == MATROSKA_TRACK_ENCODING_COMP_ZLIB) + CanDecompress = 1; #endif #if defined(CONFIG_LZO1X) - if (EBML_IntegerValue((ebml_integer*)Header)!=MATROSKA_TRACK_ENCODING_COMP_LZO1X) + else if (CompressionAlgo == MATROSKA_TRACK_ENCODING_COMP_LZO1X) + CanDecompress = 1; #endif #if defined(CONFIG_BZLIB) - if (EBML_IntegerValue((ebml_integer*)Header)!=MATROSKA_TRACK_ENCODING_COMP_BZLIB) -#endif -#else - if (EBML_IntegerValue((ebml_integer*)Header)!=MATROSKA_TRACK_ENCODING_COMP_HEADERSTRIP) + else if (CompressionAlgo == MATROSKA_TRACK_ENCODING_COMP_BZLIB) + CanDecompress = 1; #endif + if (!CanDecompress) return ERR_INVALID_DATA; if (EBML_IntegerValue((ebml_integer*)Header)==MATROSKA_TRACK_ENCODING_COMP_HEADERSTRIP) @@ -947,20 +950,23 @@ err_t MATROSKA_BlockReadData(matroska_block *Element, stream *Input, int ForProf return ERR_NOT_SUPPORTED; // TODO: support encryption Header = EBML_MasterGetChild((ebml_master*)Elt, MATROSKA_getContextContentCompAlgo(),ForProfile); -#if defined(CONFIG_ZLIB) || defined(CONFIG_LZO1X) || defined(CONFIG_BZLIB) - if (EBML_IntegerValue((ebml_integer*)Header)!=MATROSKA_TRACK_ENCODING_COMP_HEADERSTRIP) + MatroskaTrackEncodingCompAlgo CompressionAlgo = Header ? EBML_IntegerValue((ebml_integer*)Header) : MATROSKA_TRACK_ENCODING_COMP_NONE; + bool_t CanDecompress = 0; + if (CompressionAlgo == MATROSKA_TRACK_ENCODING_COMP_HEADERSTRIP) + CanDecompress = 1; #if defined(CONFIG_ZLIB) - if (EBML_IntegerValue((ebml_integer*)Header)!=MATROSKA_TRACK_ENCODING_COMP_ZLIB) + else if (CompressionAlgo == MATROSKA_TRACK_ENCODING_COMP_ZLIB) + CanDecompress = 1; #endif #if defined(CONFIG_LZO1X) - if (EBML_IntegerValue((ebml_integer*)Header)!=MATROSKA_TRACK_ENCODING_COMP_LZO1X) + else if (CompressionAlgo == MATROSKA_TRACK_ENCODING_COMP_LZO1X) + CanDecompress = 1; #endif #if defined(CONFIG_BZLIB) - if (EBML_IntegerValue((ebml_integer*)Header)!=MATROSKA_TRACK_ENCODING_COMP_BZLIB) -#endif -#else - if (EBML_IntegerValue((ebml_integer*)Header)!=MATROSKA_TRACK_ENCODING_COMP_HEADERSTRIP) + else if (CompressionAlgo == MATROSKA_TRACK_ENCODING_COMP_BZLIB) + CanDecompress = 1; #endif + if (!CanDecompress) return ERR_INVALID_DATA; if (EBML_IntegerValue((ebml_integer*)Header)==MATROSKA_TRACK_ENCODING_COMP_HEADERSTRIP) From 7a4e93914682d74439602ca0136c90c13ad887b7 Mon Sep 17 00:00:00 2001 From: Steve Lhomme Date: Mon, 23 Dec 2024 14:58:14 +0100 Subject: [PATCH 08/16] libmatroska2: keep the current compression format of CodecPrivate --- libmatroska2/matroskamain.c | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/libmatroska2/matroskamain.c b/libmatroska2/matroskamain.c index eae9071f..8e3b3072 100644 --- a/libmatroska2/matroskamain.c +++ b/libmatroska2/matroskamain.c @@ -120,7 +120,7 @@ struct matroska_seekpoint struct matroska_trackentry { ebml_master Base; - bool_t CodecPrivateCompressed; + MatroskaTrackEncodingCompAlgo CodecPrivateCompressionAlgo; }; static err_t BlockTrackChanged(matroska_block *Block) @@ -2297,6 +2297,7 @@ static err_t CreateCluster(matroska_cluster *p) static err_t ReadTrackEntry(matroska_trackentry *Element, stream *Input, const ebml_parser_context *ParserContext, bool_t AllowDummyElt, int Scope, size_t DepthCheckCRC) { + Element->CodecPrivateCompressionAlgo = MATROSKA_TRACK_ENCODING_COMP_NONE; err_t Result = INHERITED(Element,ebml_element_vmt,MATROSKA_TRACKENTRY_CLASS)->ReadData(Element, Input, ParserContext, AllowDummyElt, Scope, DepthCheckCRC); if (Result==ERR_NONE) { @@ -2310,7 +2311,11 @@ static err_t ReadTrackEntry(matroska_trackentry *Element, stream *Input, const e if (Elt) { ebml_integer *EncScope = (ebml_integer*)EBML_MasterFindChild((ebml_master*)Elt2,MATROSKA_getContextContentEncodingScope()); - Element->CodecPrivateCompressed = EncScope && (EBML_IntegerValue(EncScope) & MATROSKA_CONTENTENCODINGSCOPE_PRIVATE)!=0; + if (EncScope && (EBML_IntegerValue(EncScope) & MATROSKA_CONTENTENCODINGSCOPE_PRIVATE)!=0) + { + ebml_element *Header = EBML_MasterGetChild((ebml_master*)Elt, MATROSKA_getContextContentCompAlgo(), EBML_ANY_PROFILE); + Element->CodecPrivateCompressionAlgo = EBML_IntegerValue((ebml_integer*)Header); + } } } } @@ -2321,7 +2326,7 @@ static err_t ReadTrackEntry(matroska_trackentry *Element, stream *Input, const e static filepos_t UpdateDataSizeTrackEntry(matroska_trackentry *Element, bool_t bWithDefault, bool_t bForceWithoutMandatory, int ForProfile) { #if defined(CONFIG_ZLIB) - bool_t CodecPrivateCompressed = 0; + MatroskaTrackEncodingCompAlgo CompressionAlgo = MATROSKA_TRACK_ENCODING_COMP_NONE; ebml_integer *Scope = NULL; ebml_element *Encodings = EBML_MasterFindChild(Element,MATROSKA_getContextContentEncodings()); if (Encodings) @@ -2333,15 +2338,19 @@ static filepos_t UpdateDataSizeTrackEntry(matroska_trackentry *Element, bool_t b if (Elt) { Scope = (ebml_integer*)EBML_MasterFindChild((ebml_master*)Elt2,MATROSKA_getContextContentEncodingScope()); - CodecPrivateCompressed = Scope && (EBML_IntegerValue(Scope) & MATROSKA_CONTENTENCODINGSCOPE_PRIVATE)!=0; + if (Scope && (EBML_IntegerValue(Scope) & MATROSKA_CONTENTENCODINGSCOPE_PRIVATE)!=0) + { + ebml_element *Header = EBML_MasterGetChild((ebml_master*)Elt, MATROSKA_getContextContentCompAlgo(),ForProfile); + CompressionAlgo = EBML_IntegerValue((ebml_integer*)Header); + } } } } - if (CodecPrivateCompressed != Element->CodecPrivateCompressed) + if (CompressionAlgo != Element->CodecPrivateCompressionAlgo) { ebml_binary *CodecPrivate = (ebml_binary*)EBML_MasterFindChild(Element,MATROSKA_getContextCodecPrivate()); - if (!Element->CodecPrivateCompressed) + if (Element->CodecPrivateCompressionAlgo == MATROSKA_TRACK_ENCODING_COMP_NONE) { // compress the codec private if (CodecPrivate) @@ -2351,11 +2360,11 @@ static filepos_t UpdateDataSizeTrackEntry(matroska_trackentry *Element, bool_t b if (CompressFrameZLib(ARRAYBEGIN(CodecPrivate->Data,uint8_t), (size_t)CodecPrivate->Base.DataSize, &Compressed, &CompressedSize)==ERR_NONE) { if (EBML_BinarySetData(CodecPrivate, Compressed, CompressedSize)==ERR_NONE) - Element->CodecPrivateCompressed = 1; + Element->CodecPrivateCompressionAlgo = MATROSKA_TRACK_ENCODING_COMP_ZLIB; } free(Compressed); } - if (!Element->CodecPrivateCompressed) + if (Element->CodecPrivateCompressionAlgo == MATROSKA_TRACK_ENCODING_COMP_NONE) EBML_IntegerSetValue(Scope, EBML_IntegerValue(Scope) ^ MATROSKA_CONTENTENCODINGSCOPE_PRIVATE); } else @@ -2370,13 +2379,13 @@ static filepos_t UpdateDataSizeTrackEntry(matroska_trackentry *Element, bool_t b if (UnCompressFrameZLib(ARRAYBEGIN(CodecPrivate->Data,uint8_t), (size_t)CodecPrivate->Base.DataSize, &Compressed, &CompressedSize, &Offset)==ERR_NONE) { if (EBML_BinarySetData(CodecPrivate, ARRAYBEGIN(Compressed,uint8_t), CompressedSize)==ERR_NONE) - Element->CodecPrivateCompressed = 0; + Element->CodecPrivateCompressionAlgo = MATROSKA_TRACK_ENCODING_COMP_NONE; } ArrayClear(&Compressed); } else - Element->CodecPrivateCompressed = 0; - if (Element->CodecPrivateCompressed) + Element->CodecPrivateCompressionAlgo = MATROSKA_TRACK_ENCODING_COMP_NONE; + if (Element->CodecPrivateCompressionAlgo != MATROSKA_TRACK_ENCODING_COMP_NONE) { // TODO: add in the Compression header that the header is still compressed } @@ -2390,7 +2399,7 @@ static matroska_trackentry *CopyTrackEntry(const matroska_trackentry *Element, c { matroska_trackentry *Result = (matroska_trackentry*)INHERITED(Element,ebml_element_vmt,MATROSKA_TRACKENTRY_CLASS)->Copy(Element, Cookie); if (Result) - Result->CodecPrivateCompressed = Element->CodecPrivateCompressed; + Result->CodecPrivateCompressionAlgo = Element->CodecPrivateCompressionAlgo; return Result; } From 7fc6ceacb3759dccdc778d824a0b5dd38911f955 Mon Sep 17 00:00:00 2001 From: Steve Lhomme Date: Tue, 24 Dec 2024 08:59:33 +0100 Subject: [PATCH 09/16] libmatroska2: pass encoding scope as MatroskaContentEncodingScope --- libmatroska2/matroskamain.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libmatroska2/matroskamain.c b/libmatroska2/matroskamain.c index 8e3b3072..2f51378b 100644 --- a/libmatroska2/matroskamain.c +++ b/libmatroska2/matroskamain.c @@ -1652,7 +1652,7 @@ err_t CompressFrameZLib(const uint8_t *Cursor, size_t CursorSize, uint8_t **OutB #endif // CONFIG_EBML_WRITING #endif // CONFIG_ZLIB -static filepos_t GetBlockFrameSize(const matroska_block *Element, size_t Frame, const ebml_element *Header, int CompScope) +static filepos_t GetBlockFrameSize(const matroska_block *Element, size_t Frame, const ebml_element *Header, MatroskaContentEncodingScope CompScope) { if (Frame >= ARRAYCOUNT(Element->SizeList,int32_t)) return 0; From 2a90347d7201f3da1d59ceda5ba4e34759e0cff5 Mon Sep 17 00:00:00 2001 From: Steve Lhomme Date: Tue, 24 Dec 2024 09:33:16 +0100 Subject: [PATCH 10/16] libmatroska2: don't use zlib (de)compression without CONFIG_ZLIB --- libmatroska2/matroskamain.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/libmatroska2/matroskamain.c b/libmatroska2/matroskamain.c index 2f51378b..dc0e34f6 100644 --- a/libmatroska2/matroskamain.c +++ b/libmatroska2/matroskamain.c @@ -2325,7 +2325,6 @@ static err_t ReadTrackEntry(matroska_trackentry *Element, stream *Input, const e static filepos_t UpdateDataSizeTrackEntry(matroska_trackentry *Element, bool_t bWithDefault, bool_t bForceWithoutMandatory, int ForProfile) { -#if defined(CONFIG_ZLIB) MatroskaTrackEncodingCompAlgo CompressionAlgo = MATROSKA_TRACK_ENCODING_COMP_NONE; ebml_integer *Scope = NULL; ebml_element *Encodings = EBML_MasterFindChild(Element,MATROSKA_getContextContentEncodings()); @@ -2357,11 +2356,14 @@ static filepos_t UpdateDataSizeTrackEntry(matroska_trackentry *Element, bool_t b { size_t CompressedSize = ARRAYCOUNT(CodecPrivate->Data,uint8_t); uint8_t *Compressed = malloc(CompressedSize); - if (CompressFrameZLib(ARRAYBEGIN(CodecPrivate->Data,uint8_t), (size_t)CodecPrivate->Base.DataSize, &Compressed, &CompressedSize)==ERR_NONE) +#if defined(CONFIG_ZLIB) + if (CompressionAlgo == MATROSKA_TRACK_ENCODING_COMP_ZLIB && + CompressFrameZLib(ARRAYBEGIN(CodecPrivate->Data,uint8_t), (size_t)CodecPrivate->Base.DataSize, &Compressed, &CompressedSize)==ERR_NONE) { if (EBML_BinarySetData(CodecPrivate, Compressed, CompressedSize)==ERR_NONE) Element->CodecPrivateCompressionAlgo = MATROSKA_TRACK_ENCODING_COMP_ZLIB; } +#endif free(Compressed); } if (Element->CodecPrivateCompressionAlgo == MATROSKA_TRACK_ENCODING_COMP_NONE) @@ -2376,11 +2378,14 @@ static filepos_t UpdateDataSizeTrackEntry(matroska_trackentry *Element, bool_t b array Compressed; ArrayInit(&Compressed); - if (UnCompressFrameZLib(ARRAYBEGIN(CodecPrivate->Data,uint8_t), (size_t)CodecPrivate->Base.DataSize, &Compressed, &CompressedSize, &Offset)==ERR_NONE) +#if defined(CONFIG_ZLIB) + if (Element->CodecPrivateCompressionAlgo == MATROSKA_TRACK_ENCODING_COMP_ZLIB && + UnCompressFrameZLib(ARRAYBEGIN(CodecPrivate->Data,uint8_t), (size_t)CodecPrivate->Base.DataSize, &Compressed, &CompressedSize, &Offset)==ERR_NONE) { if (EBML_BinarySetData(CodecPrivate, ARRAYBEGIN(Compressed,uint8_t), CompressedSize)==ERR_NONE) Element->CodecPrivateCompressionAlgo = MATROSKA_TRACK_ENCODING_COMP_NONE; } +#endif ArrayClear(&Compressed); } else @@ -2391,7 +2396,6 @@ static filepos_t UpdateDataSizeTrackEntry(matroska_trackentry *Element, bool_t b } } } -#endif return INHERITED(Element,ebml_element_vmt,MATROSKA_TRACKENTRY_CLASS)->UpdateDataSize(Element, bWithDefault, bForceWithoutMandatory, ForProfile); } From a2bf49e72679d5c760614086de641a89402aa7b0 Mon Sep 17 00:00:00 2001 From: Steve Lhomme Date: Tue, 24 Dec 2024 09:44:18 +0100 Subject: [PATCH 11/16] libmatroska2: allow shifting the allocated compressed buffer If the compression algorithm adds a header we don't want. --- libmatroska2/matroskamain.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libmatroska2/matroskamain.c b/libmatroska2/matroskamain.c index dc0e34f6..7ef6dd4d 100644 --- a/libmatroska2/matroskamain.c +++ b/libmatroska2/matroskamain.c @@ -2356,11 +2356,12 @@ static filepos_t UpdateDataSizeTrackEntry(matroska_trackentry *Element, bool_t b { size_t CompressedSize = ARRAYCOUNT(CodecPrivate->Data,uint8_t); uint8_t *Compressed = malloc(CompressedSize); + uint8_t *NewCompressed = Compressed; #if defined(CONFIG_ZLIB) if (CompressionAlgo == MATROSKA_TRACK_ENCODING_COMP_ZLIB && - CompressFrameZLib(ARRAYBEGIN(CodecPrivate->Data,uint8_t), (size_t)CodecPrivate->Base.DataSize, &Compressed, &CompressedSize)==ERR_NONE) + CompressFrameZLib(ARRAYBEGIN(CodecPrivate->Data,uint8_t), (size_t)CodecPrivate->Base.DataSize, &NewCompressed, &CompressedSize)==ERR_NONE) { - if (EBML_BinarySetData(CodecPrivate, Compressed, CompressedSize)==ERR_NONE) + if (EBML_BinarySetData(CodecPrivate, NewCompressed, CompressedSize)==ERR_NONE) Element->CodecPrivateCompressionAlgo = MATROSKA_TRACK_ENCODING_COMP_ZLIB; } #endif From 0a2984e7bef7651b0c7ba76b9b844c95e5dac2d0 Mon Sep 17 00:00:00 2001 From: Steve Lhomme Date: Tue, 24 Dec 2024 09:21:15 +0100 Subject: [PATCH 12/16] libmatroska2: pass the compression algorithm to GetBlockFrameSize() In case it's not zlib. --- libmatroska2/matroskamain.c | 39 ++++++++++++++++++++----------------- 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/libmatroska2/matroskamain.c b/libmatroska2/matroskamain.c index 7ef6dd4d..26987dbb 100644 --- a/libmatroska2/matroskamain.c +++ b/libmatroska2/matroskamain.c @@ -1652,7 +1652,8 @@ err_t CompressFrameZLib(const uint8_t *Cursor, size_t CursorSize, uint8_t **OutB #endif // CONFIG_EBML_WRITING #endif // CONFIG_ZLIB -static filepos_t GetBlockFrameSize(const matroska_block *Element, size_t Frame, const ebml_element *Header, MatroskaContentEncodingScope CompScope) +static filepos_t GetBlockFrameSize(const matroska_block *Element, size_t Frame, const ebml_element *Header, + MatroskaTrackEncodingCompAlgo CompAlgo, MatroskaContentEncodingScope CompScope) { if (Frame >= ARRAYCOUNT(Element->SizeList,int32_t)) return 0; @@ -1673,12 +1674,14 @@ static filepos_t GetBlockFrameSize(const matroska_block *Element, size_t Frame, } OutSize = *Size; assert(Element->Base.Base.bValueIsSet); -#if defined(CONFIG_EBML_WRITING) && defined(CONFIG_ZLIB) - if (!Element->Base.Base.bValueIsSet || CompressFrameZLib(Data,*Size,NULL,&OutSize)!=ERR_NONE) -#else if (!Element->Base.Base.bValueIsSet) -#endif return *Size; // we can't tell the final size without decoding the data +#if defined(CONFIG_EBML_WRITING) +#if defined(CONFIG_ZLIB) + if (CompAlgo == MATROSKA_TRACK_ENCODING_COMP_ZLIB && CompressFrameZLib(Data,*Size,NULL,&OutSize)!=ERR_NONE) + return *Size; // we can't tell the final size without decoding the data +#endif +#endif return OutSize; } return ARRAYBEGIN(Element->SizeList,int32_t)[Frame] - EBML_ElementDataSize(Header, 1); // header stripping @@ -1746,7 +1749,7 @@ static char GetBestLacingType(const matroska_block *Element, int ForProfile) XiphLacingSize = 0; for (i=0;iSizeList,int32_t)-1;++i) { - DataSize = (int32_t)GetBlockFrameSize(Element, i, Header, CompressionScope); + DataSize = (int32_t)GetBlockFrameSize(Element, i, Header, CompressionAlgo, CompressionScope); while (DataSize >= 0xFF) { XiphLacingSize++; @@ -1755,10 +1758,10 @@ static char GetBestLacingType(const matroska_block *Element, int ForProfile) XiphLacingSize++; } - EbmlLacingSize = EBML_CodedSizeLength(GetBlockFrameSize(Element, 0, Header, CompressionScope),0,1); + EbmlLacingSize = EBML_CodedSizeLength(GetBlockFrameSize(Element, 0, Header, CompressionAlgo, CompressionScope),0,1); for (i=1;iSizeList,int32_t)-1;++i) { - DataSize = (int32_t)GetBlockFrameSize(Element, i, Header, CompressionScope) - DataSize; + DataSize = (int32_t)GetBlockFrameSize(Element, i, Header, CompressionAlgo, CompressionScope) - DataSize; EbmlLacingSize += EBML_CodedSizeLengthSigned(DataSize,0); } @@ -1881,12 +1884,12 @@ static err_t RenderBlockData(matroska_block *Element, stream *Output, bool_t bFo LaceHead[0] = (ARRAYCOUNT(Element->SizeList,int32_t)-1) & 0xFF; // number of elements in the lace if (Element->Lacing == LACING_EBML) { - DataSize = (int32_t)GetBlockFrameSize(Element, 0, Header, CompressionScope); + DataSize = (int32_t)GetBlockFrameSize(Element, 0, Header, CompressionAlgo, CompressionScope); LaceSize += EBML_CodedValueLength(DataSize,EBML_CodedSizeLength(DataSize,0,1),LaceHead+LaceSize, 1); for (i=1;iSizeList,int32_t)-1;++i) { PrevSize = DataSize; - DataSize = (int32_t)GetBlockFrameSize(Element, i, Header, CompressionScope); + DataSize = (int32_t)GetBlockFrameSize(Element, i, Header, CompressionAlgo, CompressionScope); LaceSize += EBML_CodedValueLengthSigned(DataSize-PrevSize,EBML_CodedSizeLengthSigned(DataSize-PrevSize,0),LaceHead+LaceSize); } } @@ -1894,7 +1897,7 @@ static err_t RenderBlockData(matroska_block *Element, stream *Output, bool_t bFo { for (i=0;iSizeList,int32_t)-1;++i) { - DataSize = (int32_t)GetBlockFrameSize(Element, i, Header, CompressionScope); + DataSize = (int32_t)GetBlockFrameSize(Element, i, Header, CompressionAlgo, CompressionScope); while (DataSize >= 0xFF) { LaceHead[LaceSize++] = 0xFF; @@ -2072,22 +2075,22 @@ static filepos_t UpdateBlockSize(matroska_block *Element, bool_t bWithDefault, b if (Element->Lacing == LACING_NONE) { assert(ARRAYCOUNT(Element->SizeList,int32_t) == 1); - Element->Base.Base.DataSize = GetBlockHeadSize(Element) + GetBlockFrameSize(Element,0,Header, CompressionScope); + Element->Base.Base.DataSize = GetBlockHeadSize(Element) + GetBlockFrameSize(Element,0,Header, CompressionAlgo, CompressionScope); } else if (Element->Lacing == LACING_EBML) { size_t i; filepos_t PrevSize, Size; filepos_t Result = GetBlockHeadSize(Element) + 1; // 1 for the number of frames - Size = GetBlockFrameSize(Element,0,Header, CompressionScope); + Size = GetBlockFrameSize(Element,0,Header, CompressionAlgo, CompressionScope); Result += EBML_CodedSizeLength(Size,0,1) + Size; for (i=1;iSizeList,int32_t)-1;++i) { PrevSize = Size; - Size = GetBlockFrameSize(Element,i,Header, CompressionScope); + Size = GetBlockFrameSize(Element,i,Header, CompressionAlgo, CompressionScope); Result += Size + EBML_CodedSizeLengthSigned(Size - PrevSize,0); } - Result += GetBlockFrameSize(Element,i,Header, CompressionScope); + Result += GetBlockFrameSize(Element,i,Header, CompressionAlgo, CompressionScope); Element->Base.Base.DataSize = Result; } else if (Element->Lacing == LACING_XIPH) @@ -2097,10 +2100,10 @@ static filepos_t UpdateBlockSize(matroska_block *Element, bool_t bWithDefault, b filepos_t Result = GetBlockHeadSize(Element) + 1; // 1 for the number of frames for (i=0;iSizeList,int32_t)-1;++i) { - Size = GetBlockFrameSize(Element,i,Header, CompressionScope); + Size = GetBlockFrameSize(Element,i,Header, CompressionAlgo, CompressionScope); Result += (Size / 0xFF + 1) + Size; } - Result += GetBlockFrameSize(Element,i,Header, CompressionScope); + Result += GetBlockFrameSize(Element,i,Header, CompressionAlgo, CompressionScope); Element->Base.Base.DataSize = Result; } else if (Element->Lacing == LACING_FIXED) @@ -2108,7 +2111,7 @@ static filepos_t UpdateBlockSize(matroska_block *Element, bool_t bWithDefault, b size_t i; filepos_t Result = GetBlockHeadSize(Element) + 1; // 1 for the number of frames for (i=0;iSizeList,int32_t);++i) - Result += GetBlockFrameSize(Element,i,Header, CompressionScope); + Result += GetBlockFrameSize(Element,i,Header, CompressionAlgo, CompressionScope); Element->Base.Base.DataSize = Result; } #ifdef TODO From c57d58aa9e8e5f5d43be6b8b3d0d0a69b29137c9 Mon Sep 17 00:00:00 2001 From: Steve Lhomme Date: Tue, 24 Dec 2024 10:17:32 +0100 Subject: [PATCH 13/16] libmatroska2: move Zlib compression functions No functional changes. --- libmatroska2/matroskamain.c | 167 ++++++++++++++++++------------------ 1 file changed, 84 insertions(+), 83 deletions(-) diff --git a/libmatroska2/matroskamain.c b/libmatroska2/matroskamain.c index 26987dbb..1101ba20 100644 --- a/libmatroska2/matroskamain.c +++ b/libmatroska2/matroskamain.c @@ -167,6 +167,90 @@ static err_t ClusterTimeChanged(matroska_cluster *Cluster) return ERR_NONE; } +#if defined(CONFIG_ZLIB) +err_t UnCompressFrameZLib(const uint8_t *Cursor, size_t CursorSize, array *OutBuf, size_t *FrameSize, size_t *ArrayOffset) +{ + z_stream stream; + int Res; + err_t Err = ERR_NONE; + + memset(&stream,0,sizeof(stream)); + Res = inflateInit(&stream); + if (Res != Z_OK) + Err = ERR_INVALID_DATA; + else + { + size_t Count; + stream.next_in = (Bytef*)Cursor; + stream.avail_in = CursorSize; + stream.next_out = ARRAYBEGIN(*OutBuf,uint8_t) + *ArrayOffset; + do { + Count = stream.next_out - ARRAYBEGIN(*OutBuf,uint8_t); + if (!ArrayResize(OutBuf, Count + 1024, 0)) + { + Res = Z_MEM_ERROR; + break; + } + stream.avail_out = ARRAYCOUNT(*OutBuf,uint8_t) - Count; + stream.next_out = ARRAYBEGIN(*OutBuf,uint8_t) + Count; + Res = inflate(&stream, Z_NO_FLUSH); + if (Res!=Z_STREAM_END && Res!=Z_OK) + break; + } while (Res!=Z_STREAM_END && stream.avail_in && !stream.avail_out); + *FrameSize = stream.total_out; + *ArrayOffset = *ArrayOffset + stream.total_out; + inflateEnd(&stream); + if (Res != Z_STREAM_END) + Err = ERR_INVALID_DATA; + } + return Err; +} + +#if defined(CONFIG_EBML_WRITING) +err_t CompressFrameZLib(const uint8_t *Cursor, size_t CursorSize, uint8_t **OutBuf, size_t *OutSize) +{ + err_t Err = ERR_NONE; + z_stream stream; + size_t Count; + array TmpBuf; + int Res; + + memset(&stream,0,sizeof(stream)); + if (deflateInit(&stream, 9)!=Z_OK) + return ERR_INVALID_DATA; + stream.next_in = (Bytef*)Cursor; + stream.avail_in = CursorSize; + Count = 0; + ArrayInit(&TmpBuf); + stream.next_out = ARRAYBEGIN(TmpBuf,uint8_t); + do { + Count = stream.next_out - ARRAYBEGIN(TmpBuf,uint8_t); + if (!ArrayResize(&TmpBuf,CursorSize + Count,0)) + { + ArrayClear(&TmpBuf); + Err = ERR_OUT_OF_MEMORY; + break; + } + stream.avail_out = ARRAYCOUNT(TmpBuf,uint8_t) - Count; + stream.next_out = ARRAYBEGIN(TmpBuf,uint8_t) + Count; + Res = deflate(&stream, Z_FINISH); + } while (stream.avail_out==0 && Res!=Z_STREAM_END); + + if (OutBuf && OutSize) + // TODO: write directly in the output buffer + memcpy(*OutBuf, ARRAYBEGIN(TmpBuf,uint8_t), min(*OutSize, stream.total_out)); + ArrayClear(&TmpBuf); + + if (OutSize) + *OutSize = stream.total_out; + + deflateEnd(&stream); + + return Err; +} +#endif // CONFIG_EBML_WRITING +#endif // CONFIG_ZLIB + static err_t CheckCompression(matroska_block *Block, int ForProfile) { ebml_master *Elt, *Header; @@ -1568,89 +1652,6 @@ err_t MATROSKA_BlockAppendFrame(matroska_block *Block, const matroska_frame *Fra return ERR_NONE; } -#if defined(CONFIG_ZLIB) -err_t UnCompressFrameZLib(const uint8_t *Cursor, size_t CursorSize, array *OutBuf, size_t *FrameSize, size_t *ArrayOffset) -{ - z_stream stream; - int Res; - err_t Err = ERR_NONE; - - memset(&stream,0,sizeof(stream)); - Res = inflateInit(&stream); - if (Res != Z_OK) - Err = ERR_INVALID_DATA; - else - { - size_t Count; - stream.next_in = (Bytef*)Cursor; - stream.avail_in = CursorSize; - stream.next_out = ARRAYBEGIN(*OutBuf,uint8_t) + *ArrayOffset; - do { - Count = stream.next_out - ARRAYBEGIN(*OutBuf,uint8_t); - if (!ArrayResize(OutBuf, Count + 1024, 0)) - { - Res = Z_MEM_ERROR; - break; - } - stream.avail_out = ARRAYCOUNT(*OutBuf,uint8_t) - Count; - stream.next_out = ARRAYBEGIN(*OutBuf,uint8_t) + Count; - Res = inflate(&stream, Z_NO_FLUSH); - if (Res!=Z_STREAM_END && Res!=Z_OK) - break; - } while (Res!=Z_STREAM_END && stream.avail_in && !stream.avail_out); - *FrameSize = stream.total_out; - *ArrayOffset = *ArrayOffset + stream.total_out; - inflateEnd(&stream); - if (Res != Z_STREAM_END) - Err = ERR_INVALID_DATA; - } - return Err; -} - -#if defined(CONFIG_EBML_WRITING) -err_t CompressFrameZLib(const uint8_t *Cursor, size_t CursorSize, uint8_t **OutBuf, size_t *OutSize) -{ - err_t Err = ERR_NONE; - z_stream stream; - size_t Count; - array TmpBuf; - int Res; - - memset(&stream,0,sizeof(stream)); - if (deflateInit(&stream, 9)!=Z_OK) - return ERR_INVALID_DATA; - stream.next_in = (Bytef*)Cursor; - stream.avail_in = CursorSize; - Count = 0; - ArrayInit(&TmpBuf); - stream.next_out = ARRAYBEGIN(TmpBuf,uint8_t); - do { - Count = stream.next_out - ARRAYBEGIN(TmpBuf,uint8_t); - if (!ArrayResize(&TmpBuf,CursorSize + Count,0)) - { - ArrayClear(&TmpBuf); - Err = ERR_OUT_OF_MEMORY; - break; - } - stream.avail_out = ARRAYCOUNT(TmpBuf,uint8_t) - Count; - stream.next_out = ARRAYBEGIN(TmpBuf,uint8_t) + Count; - Res = deflate(&stream, Z_FINISH); - } while (stream.avail_out==0 && Res!=Z_STREAM_END); - - if (OutBuf && OutSize) - // TODO: write directly in the output buffer - memcpy(*OutBuf, ARRAYBEGIN(TmpBuf,uint8_t), min(*OutSize, stream.total_out)); - ArrayClear(&TmpBuf); - - if (OutSize) - *OutSize = stream.total_out; - - deflateEnd(&stream); - - return Err; -} -#endif // CONFIG_EBML_WRITING -#endif // CONFIG_ZLIB static filepos_t GetBlockFrameSize(const matroska_block *Element, size_t Frame, const ebml_element *Header, MatroskaTrackEncodingCompAlgo CompAlgo, MatroskaContentEncodingScope CompScope) From 481e0b651a19d3444ca2787ddcf3b9677387b7d9 Mon Sep 17 00:00:00 2001 From: Steve Lhomme Date: Tue, 24 Dec 2024 10:19:08 +0100 Subject: [PATCH 14/16] libmatroska2: use UnCompressFrameZLib() to decompress frames --- libmatroska2/matroskamain.c | 71 +++++++------------------------------ 1 file changed, 12 insertions(+), 59 deletions(-) diff --git a/libmatroska2/matroskamain.c b/libmatroska2/matroskamain.c index 1101ba20..1afa3fc7 100644 --- a/libmatroska2/matroskamain.c +++ b/libmatroska2/matroskamain.c @@ -1091,37 +1091,13 @@ err_t MATROSKA_BlockReadData(matroska_block *Element, stream *Input, int ForProf #if defined(CONFIG_ZLIB) if (EBML_IntegerValue((ebml_integer*)Header)==MATROSKA_TRACK_ENCODING_COMP_ZLIB) { - // get the ouput size, adjust the Element->SizeList value, write in Element->Data - z_stream stream; - int Res; - memset(&stream,0,sizeof(stream)); - Res = inflateInit(&stream); - if (Res != Z_OK) - Err = ERR_INVALID_DATA; - else + size_t UncompressedSize; + size_t Offset = 0; + Err = UnCompressFrameZLib(InBuf, ARRAYBEGIN(Element->SizeList,int32_t)[0], &Element->Data, &UncompressedSize, &Offset); + if (Err == ERR_NONE) { - size_t Count = 0; - stream.next_in = InBuf; - stream.avail_in = ARRAYBEGIN(Element->SizeList,int32_t)[0]; - stream.next_out = ARRAYBEGIN(Element->Data,uint8_t); - do { - Count = stream.next_out - ARRAYBEGIN(Element->Data,uint8_t); - stream.avail_out = 1024; - if (!ArrayResize(&Element->Data, Count + stream.avail_out, 0)) - { - Res = Z_MEM_ERROR; - break; - } - stream.next_out = ARRAYBEGIN(Element->Data,uint8_t) + Count; - Res = inflate(&stream, Z_NO_FLUSH); - if (Res!=Z_STREAM_END && Res!=Z_OK) - break; - } while (Res!=Z_STREAM_END && stream.avail_in && !stream.avail_out); - ArrayResize(&Element->Data, stream.total_out, 0); - ARRAYBEGIN(Element->SizeList,int32_t)[0] = stream.total_out; - inflateEnd(&stream); - if (Res != Z_STREAM_END) - Err = ERR_INVALID_DATA; + ArrayResize(&Element->Data, UncompressedSize, 0); + ARRAYBEGIN(Element->SizeList,int32_t)[0] = UncompressedSize; } } #endif @@ -1258,36 +1234,13 @@ err_t MATROSKA_BlockReadData(matroska_block *Element, stream *Input, int ForProf #if defined(CONFIG_ZLIB) if (EBML_IntegerValue((ebml_integer*)Header)==MATROSKA_TRACK_ENCODING_COMP_ZLIB) { - z_stream stream; - int Res; - memset(&stream,0,sizeof(stream)); - Res = inflateInit(&stream); - if (Res != Z_OK) - Err = ERR_INVALID_DATA; - else + size_t UncompressedSize; + size_t Offset = 0; + Err = UnCompressFrameZLib(InBuf, ARRAYBEGIN(Element->SizeList,int32_t)[NumFrame], &Element->Data, &UncompressedSize, &Offset); + if (Err == ERR_NONE) { - size_t Count; - stream.next_in = InBuf; - stream.avail_in = FrameSize = ARRAYBEGIN(Element->SizeList,int32_t)[NumFrame]; - stream.next_out = ARRAYBEGIN(Element->Data,uint8_t) + OutSize; - do { - Count = stream.next_out - ARRAYBEGIN(Element->Data,uint8_t); - if (!ArrayResize(&Element->Data, Count + 1024, 0)) - { - Res = Z_MEM_ERROR; - break; - } - stream.avail_out = ARRAYCOUNT(Element->Data,uint8_t) - Count; - stream.next_out = ARRAYBEGIN(Element->Data,uint8_t) + Count; - Res = inflate(&stream, Z_NO_FLUSH); - if (Res!=Z_STREAM_END && Res!=Z_OK) - break; - } while (Res!=Z_STREAM_END && stream.avail_in && !stream.avail_out); - ARRAYBEGIN(Element->SizeList,int32_t)[NumFrame] = stream.total_out; - OutSize += stream.total_out; - inflateEnd(&stream); - if (Res != Z_STREAM_END) - Err = ERR_INVALID_DATA; + ArrayResize(&Element->Data, UncompressedSize, 0); + ARRAYBEGIN(Element->SizeList,int32_t)[NumFrame] = UncompressedSize; } } #endif From 7c95b7f220f977b4dabb7ac2b9eb2dfca09b51e6 Mon Sep 17 00:00:00 2001 From: Steve Lhomme Date: Tue, 24 Dec 2024 10:35:48 +0100 Subject: [PATCH 15/16] libmatroska2: only compress with zlib with MATROSKA_TRACK_ENCODING_COMP_ZLIB --- libmatroska2/matroskamain.c | 49 ++++++++++++++++++++----------------- 1 file changed, 26 insertions(+), 23 deletions(-) diff --git a/libmatroska2/matroskamain.c b/libmatroska2/matroskamain.c index 1afa3fc7..37eaa497 100644 --- a/libmatroska2/matroskamain.c +++ b/libmatroska2/matroskamain.c @@ -1881,33 +1881,36 @@ static err_t RenderBlockData(matroska_block *Element, stream *Output, bool_t bFo if (Header && Header->Context==MATROSKA_getContextContentCompAlgo()) { #if defined(CONFIG_ZLIB) - uint8_t *OutBuf; - array TmpBuf; - ArrayInit(&TmpBuf); - for (i=ARRAYBEGIN(Element->SizeList,int32_t);i!=ARRAYEND(Element->SizeList,int32_t);++i) + if (CompressionAlgo == MATROSKA_TRACK_ENCODING_COMP_ZLIB) { - if (!ArrayResize(&TmpBuf,*i + 100,0)) - { - ArrayClear(&TmpBuf); - Err = ERR_OUT_OF_MEMORY; - break; - } - OutBuf = ARRAYBEGIN(TmpBuf,uint8_t); - ToWrite = ARRAYCOUNT(TmpBuf,uint8_t); - if (CompressFrameZLib(Cursor, *i, &OutBuf, &ToWrite) != ERR_NONE) + uint8_t *OutBuf; + array TmpBuf; + ArrayInit(&TmpBuf); + for (i=ARRAYBEGIN(Element->SizeList,int32_t);i!=ARRAYEND(Element->SizeList,int32_t);++i) { + if (!ArrayResize(&TmpBuf,*i + 100,0)) + { + ArrayClear(&TmpBuf); + Err = ERR_OUT_OF_MEMORY; + break; + } + OutBuf = ARRAYBEGIN(TmpBuf,uint8_t); + ToWrite = ARRAYCOUNT(TmpBuf,uint8_t); + if (CompressFrameZLib(Cursor, *i, &OutBuf, &ToWrite) != ERR_NONE) + { + ArrayClear(&TmpBuf); + Err = ERR_OUT_OF_MEMORY; + break; + } + + Err = Stream_Write(Output,OutBuf,ToWrite,&Written); ArrayClear(&TmpBuf); - Err = ERR_OUT_OF_MEMORY; - break; + if (Rendered) + *Rendered += Written; + Cursor += *i; + if (Err!=ERR_NONE) + break; } - - Err = Stream_Write(Output,OutBuf,ToWrite,&Written); - ArrayClear(&TmpBuf); - if (Rendered) - *Rendered += Written; - Cursor += *i; - if (Err!=ERR_NONE) - break; } #endif } From 975f46a503a3d574fed570dae63b3dd34b650f76 Mon Sep 17 00:00:00 2001 From: Steve Lhomme Date: Mon, 23 Dec 2024 11:30:33 +0100 Subject: [PATCH 16/16] mkclean: rename zlib_scope to compress_scope --- mkclean/mkclean.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/mkclean/mkclean.c b/mkclean/mkclean.c index 913b1ea0..335b2647 100644 --- a/mkclean/mkclean.c +++ b/mkclean/mkclean.c @@ -2637,7 +2637,7 @@ int main(int argc, const char *argv[]) if (EBML_ElementIsType((ebml_element*)RLevel1, MATROSKA_getContextTrackEntry())) { MatroskaTrackEncodingCompAlgo encoding = MATROSKA_TRACK_ENCODING_COMP_NONE; - MatroskaContentEncodingScope zlib_scope = MATROSKA_CONTENTENCODINGSCOPE_BLOCK; + MatroskaContentEncodingScope compress_scope = MATROSKA_CONTENTENCODINGSCOPE_BLOCK; Elt2 = EBML_MasterFindChild(RLevel1,MATROSKA_getContextTrackNumber()); if (!Elt2) continue; @@ -2690,7 +2690,7 @@ int main(int argc, const char *argv[]) } } if (encoding == MATROSKA_TRACK_ENCODING_COMP_NONE) - zlib_scope = 0; + compress_scope = 0; else { if (Encodings) @@ -2700,13 +2700,13 @@ int main(int argc, const char *argv[]) { Elt2 = EBML_MasterGetChild((ebml_master*)Elt,MATROSKA_getContextContentEncodingScope(), DstProfile); if (Elt2) - zlib_scope = EBML_IntegerValue((ebml_integer*)Elt2); + compress_scope = EBML_IntegerValue((ebml_integer*)Elt2); } } } // see if we can add CodecPrivate too - if ((Optimize || encoding != MATROSKA_TRACK_ENCODING_COMP_NONE) && encoding != MATROSKA_TRACK_ENCODING_COMP_HEADERSTRIP && zlib_scope != MATROSKA_CONTENTENCODINGSCOPE_PRIVATE) + if ((Optimize || encoding != MATROSKA_TRACK_ENCODING_COMP_NONE) && encoding != MATROSKA_TRACK_ENCODING_COMP_HEADERSTRIP && compress_scope != MATROSKA_CONTENTENCODINGSCOPE_PRIVATE) { if (CodecPrivate!=NULL) { @@ -2718,7 +2718,7 @@ int main(int argc, const char *argv[]) && (CompressedSize + ExtraCompHeaderBytes) < origCompressedSize) { encoding = MATROSKA_TRACK_ENCODING_COMP_ZLIB; - zlib_scope |= MATROSKA_CONTENTENCODINGSCOPE_PRIVATE; + compress_scope |= MATROSKA_CONTENTENCODINGSCOPE_PRIVATE; } free(Compressed); } @@ -2729,7 +2729,7 @@ int main(int argc, const char *argv[]) case MATROSKA_TRACK_ENCODING_COMP_ZLIB: case MATROSKA_TRACK_ENCODING_COMP_BZLIB: // transform bzlib into zlib case MATROSKA_TRACK_ENCODING_COMP_LZO1X: // transform lzo1x into zlib - if (MATROSKA_TrackSetCompressionAlgo((matroska_trackentry*)RLevel1, zlib_scope,DstProfile, MATROSKA_TRACK_ENCODING_COMP_ZLIB)) + if (MATROSKA_TrackSetCompressionAlgo((matroska_trackentry*)RLevel1, compress_scope,DstProfile, MATROSKA_TRACK_ENCODING_COMP_ZLIB)) ClustersNeedRead = 1; break; case MATROSKA_TRACK_ENCODING_COMP_HEADERSTRIP: