{"id":20556104,"url":"https://github.com/irrational-encoding-wizardry/descale","last_synced_at":"2025-09-01T20:11:03.189Z","repository":{"id":79365421,"uuid":"90077564","full_name":"Irrational-Encoding-Wizardry/descale","owner":"Irrational-Encoding-Wizardry","description":"VapourSynth plugin to undo upscaling","archived":false,"fork":false,"pushed_at":"2023-05-09T12:34:51.000Z","size":100,"stargazers_count":73,"open_issues_count":3,"forks_count":16,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-04-21T13:54:09.776Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Irrational-Encoding-Wizardry.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-05-02T21:00:46.000Z","updated_at":"2025-02-20T06:03:05.000Z","dependencies_parsed_at":null,"dependency_job_id":"85ff5cb7-5681-49e1-9794-20a3626b1dcb","html_url":"https://github.com/Irrational-Encoding-Wizardry/descale","commit_stats":null,"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"purl":"pkg:github/Irrational-Encoding-Wizardry/descale","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Irrational-Encoding-Wizardry%2Fdescale","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Irrational-Encoding-Wizardry%2Fdescale/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Irrational-Encoding-Wizardry%2Fdescale/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Irrational-Encoding-Wizardry%2Fdescale/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Irrational-Encoding-Wizardry","download_url":"https://codeload.github.com/Irrational-Encoding-Wizardry/descale/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Irrational-Encoding-Wizardry%2Fdescale/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":273183228,"owners_count":25059812,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-01T02:00:09.058Z","response_time":120,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-16T03:24:44.418Z","updated_at":"2025-09-01T20:11:03.149Z","avatar_url":"https://github.com/Irrational-Encoding-Wizardry.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Descale\n\nVideo/Image filter to undo upscaling.\n\nIncludes a VapourSynth and AviSynth+ plugin\n\n## Usage\n\nThe VapourSynth plugin itself supports every constant input format. If the format is subsampled, left-aligned chroma planes are always assumed.\nThe included python wrapper, contrary to using the plugin directly, doesn't descale the chroma planes but scales them normally with `Spline36`.\n\n```\ndescale.Debilinear(clip src, int width, int height, float src_left=0.0, float src_top=0.0, float src_width=width, float src_height=height, int border_handling=0, bool force=false, bool force_h=false, bool force_v=false, int opt=0)\n\ndescale.Debicubic(clip src, int width, int height, float b=0.0, float c=0.5, float src_left=0.0, float src_top=0.0, float src_width=width, float src_height=height, int border_handling=0, bool force=false, bool force_h=false, bool force_v=false, int opt=0)\n\ndescale.Delanczos(clip src, int width, int height, int taps=3, float src_left=0.0, float src_top=0.0, float src_width=width, float src_height=height, int border_handling=0, bool force=false, bool force_h=false, bool force_v=false, int opt=0)\n\ndescale.Despline16(clip src, int width, int height, float src_left=0.0, float src_top=0.0, float src_width=width, float src_height=height, int border_handling=0, bool force=false, bool force_h=false, bool force_v=false, int opt=0)\n\ndescale.Despline36(clip src, int width, int height, float src_left=0.0, float src_top=0.0, float src_width=width, float src_height=height, int border_handling=0, bool force=false, bool force_h=false, bool force_v=false, int opt=0)\n\ndescale.Despline64(clip src, int width, int height, float src_left=0.0, float src_top=0.0, float src_width=width, float src_height=height, int border_handling=0, bool force=false, bool force_h=false, bool force_v=false, int opt=0)\n\ndescale.Descale(clip src, int width, int height, str kernel, func custom_kernel, int taps=3, float b=0.0, float c=0.0, float src_left=0.0, float src_top=0.0, float src_width=width, float src_height=height, int border_handling=0, bool force=false, bool force_h=false, bool force_v=false, int opt=0)\n```\n\nThe AviSynth+ plugin is used similarly, but without the `descale` namespace.\nCustom kernels are only supported in the VapourSynth plugin.\n\n### Custom kernels\n\n```python\n# Debilinear\ncore.descale.Descale(src, w, h, custom_kernel=lambda x: 1.0 - x, taps=1)\n\n# Delanczos\nimport math\ndef sinc(x):\n    return 1.0 if x == 0 else math.sin(x * math.pi) / (x * math.pi)\ntaps = 3\ncore.descale.Descale(src, w, h, custom_kernel=lambda x: sinc(x) * sinc(x / taps), taps=taps)\n\n# You can also use the python wrapper instead of calling the plugin functions directly\nimport descale\ndescale.Decustom(src, w, h, lambda x: 1.0 - x, taps=1)\n```\n\n## How does this work?\n\nResampling can be described as `A x = b`.\n\nA is an n x m matrix with `m` being the input dimension and `n` the output dimension. `x` is the original vector with `m` elements, `b` is the vector after resampling with `n` elements. We want to solve this equation for `x`.\n\nTo do this, we extend the equation with the transpose of A: `A' A x = A' b`.\n\n`A' A` is now a banded symmetrical m x m matrix and `A' b` is a vector with `m` elements.\n\nThis enables us to use LDLT decomposition on `A' A` to get `LD L' = A' A`. `LD` and `L` are both triangular matrices.\n\nThen we solve `LD y = A' b` with forward substitution, and finally `L' x = y` with back substitution.\n\nWe now have the original vector `x`.\n\n\n## Compilation\n\nBy default only the VapourSynth plugin is compiled.\nTo build the AviSynth+ plugin, add `-Dlibtype=avisynth` or `-Dlibtype=both` to the meson command below.\n\n### Linux\n\n```\n$ meson build\n$ ninja -C build\n```\n\n### Cross-compilation for Windows\n```\n$ meson build --cross-file cross-mingw-x86_64.txt\n$ ninja -C build\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Firrational-encoding-wizardry%2Fdescale","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Firrational-encoding-wizardry%2Fdescale","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Firrational-encoding-wizardry%2Fdescale/lists"}