| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This works in practice but is explicitly forbidden in C99, C11 and C17 alike:
> 7.20.5/7.22.5 Searching and sorting utilities
>
> [...] Where an argument declared as size_t nmemb specifies the length
> of the array for a function, nmemb can have the value zero on a call to
> that function; the comparison function is not called, [...] and sorting
> performs no rearrangement. Pointer arguments on such a call shall still
> have valid values, as described in 7.1.4.
> 7.1.4 Use of library functions
>
> [...] If an argument to a function has an invalid value (such as [...]
> a null pointer [...]) [...], the behavior is undefined. If a function
> argument is described as being an array, the pointer actually passed
> to the function shall have a value such that all address computations
> and accesses to objects (that would be valid if the pointer did point
> to the first element of such an array) are in fact valid.
In contrast, qsort_s explicitly allows the array pointer argument to be
NULL when nmemb == 0 (see C11/C17 K.3.6.3 Searching and sorting utilities).
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
|
|
|
| |
Also remove unneeded event arg
|
| |
|
| |
|
|
|
|
|
|
|
|
|
| |
GitHub changed how step otputs are to be set, see
https://github.blog/changelog/2022-10-11-github-actions-deprecating-save-state-and-set-output-commands/
For our docker containers we need to forward the GITHUB_OUTPUT
environment var. The same applies to some other currently unused
env vars. To reduce copy-paste create a proxy-shell script.
|
|
|
|
|
|
| |
MSYS2 already defines a $MINGW_PACKAGE_PREFIX environment variable
making it superfluous to explicit track the matching prefix ourselves.
The local $pre variable is kept to make the package list more readable.
|
|
|
|
|
|
|
|
|
|
|
|
| |
It turns out, the undefined behaviour we detected was not in our own
code, but in the inline isnan() function from MinGW-w64's headers.
A patch has been submitted to and merged by MinGW-w64:
https://sourceforge.net/p/mingw-w64/mailman/mingw-w64-public/thread/20221109020507.1704-1-chortos@inbox.lv/
Until a version containing the fix is available in MSYS2, we
can avoid problematic inlines by defining __CRT__NO_INLINE.
Closes: https://github.com/libass/libass/issues/639
|
|
|
|
|
| |
This was confirmed on Cyberbeing/xy-VSFilter, xy-VSFilter from CCCP
and pinterf/XySubFilter + madVR.
|
|
|
|
|
|
|
|
| |
I misunderstood what MPC-HC's ColorConvTable::NONE (not used for
"YCbCr Matrix: None"!) does and I'm not sure why I thought empty
headers would rely on resolution-based guessing.
After bringing up support for "None" in MPC-HC ISR with clsid2,
it was explained to me that ::NONE is currently equal to BT.601.
|
|
|
|
|
|
| |
If static libass is linked into a binary defining functions
of the same name there will be issues. To avoid this ensure
our non-static functions are all prefixed with 'ass_'.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
If static libass is linked into a binary defining functions
of the same name there will be issues. To avoid this use an
ass_ prefix for namespacing.
Before this commit we already did this for most but not yet
all internal API.
read_file is renamed to ass_load_file as ass_read_file
already exists as a public API function. All other functions
are simply prefixed with ass_.
Fixes: https://github.com/libass/libass/issues/222
Fixes: https://github.com/libass/libass/issues/654
|
|
|
|
|
|
| |
They are both used only once outside of ass_parse.c
to apply fade, so instead export one function handling
VSFilter-compatible fade application.
|
|
|
|
| |
They are used in multiple files but short enough to inline.
|
|
|
|
|
|
| |
Although declared and defined in ass_utils.{h,c},
those functions are only used in one other file
and aren't useful at other places.
|
| |
|
|
|
|
| |
It has not been used since 7af78014635dbe81c3328405aa68dd2cfef94bc4.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
VSFilter uses it for Dialogue lines and Style lines
not preceeded by a styles section header.
libass requires section headers to parse styles,
but this still helps for files without a Styles
section (placed before the Events section) and
also makes our legacy-FFmpeg detection more accurate.
In fact, VSFilter takes _only_ the ScriptType
header into account for Dialogue lines and keeps
a separate version for styles which is also affected
by style section headers.
This dual versioning is not implemented by this commit and the
lack of any issue reports about it suggests such files may not
exist in practice. If however it turned out they do, an additional
version variable can be added to parser_priv and we need to decide
which one to present to API users.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
\kt allows to set the karaoke timing offset to a value other than the
sum of preceeding karaoke durations. Notably this means multiple karaoke
sequences of one Event can be ative at the same time.
Like in VSFilter, \kt is available regardless of the format version.
Using \kt after a karaoke tag in the same override sequence
always makes the preceeding karaoke act as if already completed.
Using \kt within a run resets timing for the next karaoke run.
Addresses part of https://github.com/libass/libass/issues/461.
Further support for v4++ requires at least an ABI break.
|
|
|
|
|
|
|
|
|
|
|
| |
Procesing of the actual style field emulates VSFilter's behaviour
by parsing the inputs the same way and always using 0x80 for shadows.
For user supplied style overrides the field is accepted for all
script versions and the provided alpha value is applied to all colours,
continuing the existing practice of override tags not caring for
version-dependent quirks and limitations.
Fixes: https://github.com/libass/libass/issues/40
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
VSFilter uses the same GetInt method used for colour values
also for all other integer headers and Style or Dialogue
integer fields. This method accepts hexadecimal with a
case-insensitive '&H' or '0x' prefix.
GetInt is practically unchanged from its initial form
in 2003's revision 8 of guliverkli to today's xy*.
(MPC-HC'S ISR changed it more but it still behaves the same wrt to hex)
The previously used atoi never accepts hexadecimal input
and is now only used for the ReadOrder pseudo-field which
isn't parsed by VSFilter.
This relies on uint32_t <-> int32_t conversions just keeping the
bitpattern unchanged (as do many other places in libass) and
mystrtou32_modulo taking sign prefixes into account rather than
rejecting non-positive input.
|
| |
|
|
|
|
|
|
|
| |
This undoes a change which slipped in with
d8f056158abe9d671c53f430ecd21022cc983d47 and caused
PAR to default to a value derived from PlayRes* and
the content area of the rendering frame instead of 1.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
They cannot possibly produce any rendering output,
so there's no benefit in keeping them around. On the
contrary, keeping them around can significantly slow down
processing of fuzzing samples as discovered by OSS-Fuzz.
For its sample, there's one valid event with a large Text entry
(516503 bytes) and 9786 invalid events.
Processing just the one valid events takes a few seconds, which
isn't fast but still bearable and given the large amount of text being
parsed, shaped and rendered not too surprising.
If now the invalid events are kept around, processing the sample still
wasn't finished after 5 minutes. While processing of invalid events ends
early in ass_render_event and they won't create any output themselves,
their time overlaps with the costly, valid event. Meaning this costly
event now get's rendered thousands of times and processing cost is
amplified via just a few bytes being added by the fuzzing engine.
We already do a similar discarding for Styles in process_style().
Unlike the former, process_event_tail() doesn't allocate the new
event itself, so discarding is instead done by its callers.
Fixes: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=47952
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Discovered by OSS-Fuzz.
For sufficiently large valued or numerous karaoke tags
the addition to effect_skip_timing can overflow.
Since the operands were signed, this was undefined behaviour.
For utmost VSFilter compatibility, we'd like to ideally emulate its
effective wraparound behaviour. Although the exact order pf calculation
differs, merely ensuring our values safely wraparound too should yield
the same end result.
To that end, we first change the types of the relevant members to
int32_t guaranteeing the same size as in VSFilter and complement-of-two
representation and then also cast one operand to uint32_t.
Through integer promotion both operands will be treated as unsigned,
so any overflow will be (perfectly defined) unsigend overflow.
The final implicit cast back to int32_t is technically implementation
defined and may raise an "implementation-defined signal", but due to
the complement-of-two semantics in pratice we just get a wraparound
matching the wraparaound expected for the original signed
complement-of-two overflow, but while avoiding UB.
Compilers appear to emit the same machine code on x86 with or without
the uint32_t cast, if any optimisations are enabled and otherwise
at most minor differences.
Fixes: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=47993
|
|
|
|
|
|
|
|
|
|
|
| |
Trailing "\N " no longer produces an empty line.
This matches VSFilter.
Use a pointer to one past the last character rather than to the last
character itself to avoid decrementing the pointer when it points
to the first character, which has undefined behavior.
Resolves: https://github.com/libass/libass/pull/47
|
|
|
|
|
|
| |
If state.effect_timing is zero adding it does nothing.
Also checking for zero and branching is likely at least
as costly as adding zero.
|
|
|
|
|
|
| |
Omission in 85c8c6d7be14cc2602b92ec715834b9c1069a325.
Of course, the same reasoning as in the mentioned commit
also applies to (at least) all other karaoke tags.
|
|
|
|
|
|
| |
Better explained what and why and remove confusing comment about
"None" supposedly being for "exact colour doesn't matter" as
there's no evidence of anyone actually using it like this.
|
|
|
|
|
|
|
|
|
|
|
| |
font_scale_x is a PAR factor and applies to more than just font glyphs,
so par_scale_x is a more accurate and natural name.
orig_{width,height} can easily be confused with the video's
original (storage) resolution, when in fact it is the rendering
resolution (after any anamorphic desqueezing and other scaling etc)
of the video content area of the whole frame.
Thus rename to frame_content_*.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
VSFilter scales several features based on width/PlayResX
but libass until now didn't. This affects:
- explicit vector drawing coordinates
- font spacing
- borders
- shadows
This list was obtained by checking against Cyberbeing/xy-VSFilter
code and searching forevery occurence of m_scalex.
This m_scalex factor is also used for the Banner effect,
to make the delay PlayRes-relative, but in libass the value
is PlayRes-relative by default without needing to be scaled.
Additionally, libass neglected to compensate anamorphic stretching
for some features which is also being fixed now.
Both omissions combined actually happened to cancel each other out
for some PlayRes-relative feature in specific but not unusual cases.
If subs for an anamorphic video use isotropically scaled storage
resolution as PlayRes, libass already rendered e.g. vector drawings
correctly. However, other features like e.g. \xshad used to only render
correctly if isotropically scaled display res was used. Thus, more
complex typesetting actually was never rendered correctly on anamorphic
video before this change.
Fixes https://github.com/libass/libass/issues/171.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
When storage size is not set, we currently use PlayRes
as a fallback hoping it matches the original storage res.
We know this is flawed, but even if PlayRes relates to a
dimension of the source video, in case of anamorphic video
either the native display width or storage width may have
been used. We always want the latter, so if PAR information
was supplied, try to ensure we get something in the storage
aspect ratio.
Note, that this could actually also worsen the rendering for
unknown storage res cases eg if PlayRes already was the original
storage size but the subs got repurposed for a non-anamorphic
(re)encode. Though, such reused subs won't render correctly in VSFilter
too anyway, so we probably don't need to worry to much about this.
|
|
|
|
|
| |
We often only check for != 0, later on, with zero being "unset",
but negative values would obviously be bogus here.
|
|
|
|
|
|
|
|
| |
This won't change the movement speed, as the total movement
is recalculated every frame, so this shouldn't negatively affect
VSFilter compatibility; if anything this should slightly improve
compatibility since VSFilter works in a supersampled space.
In any case, it does improves visual quality.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Usually the delay parameter of legacy effects is scaled
to be relative to the PlayRes canvas. This happens explicitly
in VSFilter and automatically in libass.
However, this scaling in VSFilter happens _before_ applying
max(delay, 1) which means, if e.g. delay=0 it ends up as
1 ms per _storage pixel_. To get the same effect in libass we
must explicitly "unscale" the fallback for small or negative delays.
VSFilter also casts the scaled delay value to int afterwards,
which can lead to not |