summaryrefslogtreecommitdiffstats
Commit message (Collapse)AuthorAgeFilesLines
* compare: don't call qsort on NULL arraycoverity_scanOleg Oshmyan2022-11-161-1/+2
| | | | | | | | | | | | | | | | | | | | | | | | 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).
* ass_font: remove unused functionrcombs2022-11-152-14/+0
|
* ass_render: set user_override_style.Name during initrcombs2022-11-151-2/+2
|
* ass_render: mover rasterizer into RenderContextrcombs2022-11-154-13/+18
|
* ass_fontselect: take const ASS_Font*rcombs2022-11-152-2/+2
|
* ass_fontselect: fail on allocation failuresrcombs2022-11-151-0/+19
|
* ass_render: move shaper member to RenderContextrcombs2022-11-152-13/+13
|
* ass_render: add setup_shaper() functionrcombs2022-11-151-9/+16
|
* ass_render: add text_info_done functionrcombs2022-11-151-5/+10
|
* ass_render: add text_info_init functionrcombs2022-11-151-11/+20
|
* ass_shaper: move cache ownership to the rendererrcombs2022-11-155-16/+12
|
* ass_render: take RenderContext* in render_and_combine_glyphs()rcombs2022-11-151-15/+20
|
* ass_render: take RenderContext* in ass_render_event()rcombs2022-11-151-3/+3
|
* ass_render: get text_info from statercombs2022-11-151-1/+1
|
* ass_render: take RenderContext* in init_render_context()rcombs2022-11-151-36/+38
|
* ass_render: setup renderer/text_info on RenderContext in ass_renderer_initrcombs2022-11-151-2/+3
|
* ass_render: take RenderContext* in parse_events()rcombs2022-11-151-4/+4
|
* ass_render: use state local in parse_events()rcombs2022-11-151-36/+36
|
* ass_render: take RenderContext* in split_style_runs()rcombs2022-11-151-7/+8
|
* ass_render: take RenderContext* in retrieve_glyphs()rcombs2022-11-151-8/+9
|
* ass_render: take RenderContext* in preliminary_layout()rcombs2022-11-151-5/+5
|
* ass_render: take RenderContext* in wrap_lines_smart()rcombs2022-11-151-34/+39
|
* ass_render: take RenderContext* in reorder_text()rcombs2022-11-151-4/+5
|
* ass_render: take RenderContext* in align_lines()rcombs2022-11-151-6/+6
|
* ass_render: take RenderContext* in apply_baseline_shear()rcombs2022-11-151-3/+4
|
* ass_render: take RenderContext* in calculate_rotation_params()rcombs2022-11-151-9/+10
|
* ass_render: take RenderContext* in add_background()rcombs2022-11-151-7/+8
|
* ass_render: take RenderContext* in render_text()rcombs2022-11-151-31/+35
|
* ass_render: take RenderContext* in [xy]2scr(_(left|right|top|sub))rcombs2022-11-151-19/+24
|
* ass_render: replace render_priv->state with statercombs2022-11-151-53/+53
|
* ass_parse: take RenderContext* in parse_vector_clip()rcombs2022-11-151-6/+6
|
* ass_parse: take RenderContext* in process_karaoke_effects()rcombs2022-11-153-11/+13
|
* ass_parse: take RenderContext* in parse_tags()rcombs2022-11-153-188/+188
|
* ass_render: take RenderContext* in reset_render_context()rcombs2022-11-153-35/+35
|
* ass_render: take RenderContext* in init_font_scale()rcombs2022-11-151-16/+17
|
* ass_render: move (font|border|blur)_scale to RenderContextrcombs2022-11-152-38/+39
|
* ass_render: take RenderContext* in handle_selective_style_overrides()rcombs2022-11-151-8/+9
|
* ass_render: take RenderContext* in free_render_contextrcombs2022-11-151-14/+15
|
* ass_render: add text_info member to RenderContextrcombs2022-11-152-0/+2
|
* ass_parse: take RenderContext* in get_next_char()rcombs2022-11-153-4/+5
|
* ass_parse: take RenderContext* in apply_transition_effects()rcombs2022-11-153-18/+20
| | | | Also remove unneeded event arg
* ass_parse: take RenderContext in update_font()rcombs2022-11-153-11/+14
|
* ass_render: add renderer pointer to RenderContextrcombs2022-11-152-0/+3
|
* ci/gha: replace deprecated set-outputOneric2022-11-121-3/+18
| | | | | | | | | 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.
* ci/gha: replace matrix.package_prefixOneric2022-11-111-3/+1
| | | | | | 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.
* ci/gha: reenable sanitisers for 64-bit WindowsOneric2022-11-101-4/+7
| | | | | | | | | | | | 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
* doc: document xy* not mangling colours on RGB videoOneric2022-11-021-1/+5
| | | | | This was confirmed on Cyberbeing/xy-VSFilter, xy-VSFilter from CCCP and pinterf/XySubFilter + madVR.
* doc: fix description of MPC-HC ISR's colour manglingOneric2022-11-021-3/+3
| | | | | | | | 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.
* ci/gha: ensure internal API is namespacedOneric2022-10-221-0/+22
| | | | | | 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_'.
* refactor: prefix all internal API with ass_Oneric2022-10-2222-210/+210
| | | | | | | | | | | | | | | 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
* parse: replace mult_alpha and change_alpha exportsOneric2022-10-223-8/+11
| | | | | | They are both used only once outside of ass_parse.c to apply fade, so instead export one function handling VSFilter-compatible fade application.
* refactor/utils: turn some functions into static inlinesOneric2022-10-222-42/+39
| | | | They are used in multiple files but short enough to inline.
* refactor: move and static'fy some internal functionsOneric2022-10-227-208/+200
| | | | | | 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.
* refactor: static'fy functions only used in one fileOneric2022-10-213-32/+29
|
* parse: remove unused functionOneric2022-10-212-11/+0
| | | | It has not been used since 7af78014635dbe81c3328405aa68dd2cfef94bc4.
* Parse ScriptType headerOneric2022-10-142-3/+26
| | | | | | | | | | | | | | | | | | | 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.
* Implement v4++'s \kt tagOneric2022-10-143-1/+25
| | | | | | | | | | | | | | \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.
* Support SSA's AlphaLevel style fieldOneric2022-10-141-0/+20
| | | | | | | | | | | 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
* Accept hexadecimal for all non-inline int valuesOneric2022-10-143-11/+18
| | | | | | | | | | | | | | | | | | | 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.
* cosmetic: indent postprocessing of parsed valuesOneric2022-10-141-11/+11
|
* render: do not default PAR based on PlayResOneric2022-10-071-1/+2
| | | | | | | 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.
* ass: discard invalid events earlyOneric2022-09-291-2/+9
| | | | | | | | | | | | | | | | | | | | | | | | | 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
* parse: avoid signed overflow for effect_skip_timingOneric2022-09-292-10/+10
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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
* Trim trailing whitespace from Dialogue lines earlyOleg Oshmyan2022-09-291-4/+4
| | | | | | | | | | | 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
* parse: remove useless branchOneric2022-09-251-6/+3
| | | | | | 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.
* parse: avoid more UB on double to integer castsOneric2022-09-251-2/+2
| | | | | | Omission in 85c8c6d7be14cc2602b92ec715834b9c1069a325. Of course, the same reasoning as in the mentioned commit also applies to (at least) all other karaoke tags.
* doc: improve colour matrix descriptionOneric2022-09-251-29/+54
| | | | | | 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.
* Rename orig_{width,height} and font_scale_xOneric2022-09-243-40/+40
| | | | | | | | | | | 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_*.
* Fix scaling in x directionOleg Oshmyan2022-09-242-34/+53
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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.
* render: improve storage res fallback when PAR is setOneric2022-09-241-1/+15
| | | | | | | | | | | | | | | | | 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.
* render_api: sanitise user-supplied values earlyOneric2022-09-151-0/+5
| | | | | We often only check for != 0, later on, with zero being "unset", but negative values would obviously be bogus here.
* Allow subpixel movement for legacy effectsOneric2022-09-151-1/+1
| | | | | | | | 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.
* Fix legacy effect's delay scaling and precisionOneric2022-09-151-6/+20
| | | | | | | | | | | | | | | | | | | | | 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