{"id":13546482,"url":"https://github.com/avaneev/avir","last_synced_at":"2025-04-02T18:30:55.994Z","repository":{"id":41413353,"uuid":"42787820","full_name":"avaneev/avir","owner":"avaneev","description":"High-quality pro HDR image resizing / scaling C++ library, including a very fast, precise, SIMD Lanczos resizer (header-only C++)","archived":false,"fork":false,"pushed_at":"2025-03-24T13:59:53.000Z","size":17283,"stargazers_count":431,"open_issues_count":1,"forks_count":44,"subscribers_count":23,"default_branch":"master","last_synced_at":"2025-03-24T14:41:40.408Z","etag":null,"topics":["bitmap","hdr-image","image-manipulation","image-processing","image-resizer","image-resolution","image-scaling","image-upscaling","image-upsizing","lanczos","resample","resampling","resize-images","resizer-image","upscaler","upscaling"],"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/avaneev.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":"2015-09-19T20:04:39.000Z","updated_at":"2025-03-24T14:00:01.000Z","dependencies_parsed_at":"2024-01-18T11:56:55.038Z","dependency_job_id":"54afd7d9-b94e-480a-ba0c-69a9c8872f7c","html_url":"https://github.com/avaneev/avir","commit_stats":null,"previous_names":[],"tags_count":19,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/avaneev%2Favir","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/avaneev%2Favir/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/avaneev%2Favir/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/avaneev%2Favir/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/avaneev","download_url":"https://codeload.github.com/avaneev/avir/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246869687,"owners_count":20847176,"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","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":["bitmap","hdr-image","image-manipulation","image-processing","image-resizer","image-resolution","image-scaling","image-upscaling","image-upsizing","lanczos","resample","resampling","resize-images","resizer-image","upscaler","upscaling"],"created_at":"2024-08-01T12:00:38.699Z","updated_at":"2025-04-02T18:30:55.980Z","avatar_url":"https://github.com/avaneev.png","language":"C++","readme":"# AVIR - Image Resizing Algorithm (in C++)\r\n\r\n## Introduction\r\n\r\nMe, Aleksey Vaneev, is happy to offer you an open source image resizing /\r\nscaling library which has reached a production level of quality, and is\r\nready to be incorporated into any project. This library features routines\r\nfor both down- and upsizing of 8- and 16-bit, 1 to 4-channel images. Image\r\nresizing routines were implemented in a portable, cross-platform, header-only\r\nC++ code, and have a high level of optimality. Beside resizing, this library\r\noffers a sub-pixel shift operation. Built-in sRGB gamma correction is\r\navailable.\r\n\r\nThe resizing algorithm at first produces 2X upsized image (relative to the\r\nsource image size, or relative to the destination image size if downsizing is\r\nperformed) and then performs interpolation using a bank of sinc function-based\r\nfractional delay filters. At the last stage a correction filter is applied\r\nwhich fixes smoothing introduced at previous steps.\r\n\r\nThe resizing algorithm was designed to provide the best visual quality. The\r\nauthor even believes this algorithm provides the \"ultimate\" level of\r\nquality (for an orthogonal, non neural-network, resizing) which cannot be\r\nincreased further: no math exists to provide a better frequency response,\r\nbetter anti-aliasing quality and at the same time having less ringing\r\nartifacts: these are 3 elements that define any resizing algorithm's quality;\r\nin AVIR practice these elements have a high correlation to each other, so they\r\ncan be represented by a single parameter (AVIR offers several parameter sets\r\nwith varying quality). Algorithm's time performance turned out to be very good\r\nas well (for the \"ultimate\" image quality).\r\n\r\nAn important element utilized by this algorithm is the so called Peaked Cosine\r\nwindow function, which is applied over sinc function in all filters. Please\r\nconsult the documentation for more details.\r\n\r\nNote that since AVIR implements orthogonal resizing, it may exhibit diagonal\r\naliasing artifacts. These artifacts are usually suppressed by EWA or radial\r\nfiltering techniques. EWA-like technique is not implemented in AVIR, because\r\nit requires considerably more computing resources and may produce a blurred\r\nimage.\r\n\r\nAs a bonus, a much faster `LANCIR` image resizing algorithm is also offered as\r\na part of this library. But the main focus of this documentation is the\r\noriginal AVIR image resizing algorithm.\r\n\r\n*AVIR is dedicated to women. Your digital photos can look good at any size!*\r\n\r\nP.S. Please credit the author of this library in your documentation in the\r\nfollowing way: \"AVIR image resizing algorithm designed by Aleksey Vaneev\".\r\n\r\n## Affine and Non-Linear Transformations\r\n\r\nAVIR does not offer affine and non-linear image transformations \"out of the\r\nbox\". Since upsizing is a relatively fast operation in AVIR (required time\r\nscales linearly with the output image area), affine and non-linear\r\ntransformations can be implemented in steps: 4- to 8-times upsizing,\r\ntransformation via bilinear interpolation, downsizing (linear proportional\r\naffine transformations can probably skip the downsizing step). This should not\r\ncompromise the transformation quality much as bilinear interpolation's\r\nproblems will mostly reside in spectral area without useful signal, with a\r\nmaximum of 0.7 dB high-frequency attenuation for 4-times upsizing, and 0.17 dB\r\nattenuation for 8-times upsizing. This approach is probably as time efficient\r\nas performing a high-quality transform over the input image directly (the only\r\nserious drawback is the increased memory requirement). Note that affine\r\ntransformations that change image proportions should first apply proportion\r\nchange during upsizing.\r\n\r\n## Requirements\r\n\r\nC++ compiler and system with efficient \"float\" floating-point (24-bit\r\nmantissa) type support. This library can also internally use the \"double\" and\r\nSIMD floating-point types during resizing if needed. This library does not\r\nhave dependencies beside the standard C library.\r\n\r\n## Usage Information\r\n\r\nThe image resizer is represented by the `avir::CImageResizer\u003c\u003e` class, which\r\nis a single front-end class for the whole library. Basically, you do not need\r\nto use nor understand any other classes beside this class.\r\n\r\n* [Documentation](https://www.voxengo.com/public/avir/Documentation/)\r\n\r\nThe code of the library resides in the \"avir\" C++ namespace, effectively\r\nisolating it from all other code. The code is thread-safe. You need just\r\na single resizer object per running application, at any time, even when\r\nresizing images concurrently.\r\n\r\nTo resize images in your application, simply add 3 lines of code (note that\r\nyou may need to change `ImageResizer( 8 )` here, to specify your image's true\r\nbit resolution, which may be 10 or even 16):\r\n\r\n```c++\r\n#include \"avir.h\"\r\navir :: CImageResizer\u003c\u003e ImageResizer( 8 );\r\nImageResizer.resizeImage( InBuf, 640, 480, 0, OutBuf, 1024, 768, 3, 0 );\r\n(multi-threaded operation requires additional coding, see the documentation)\r\n```\r\n\r\nAVIR works with header-less \"raw\" image buffers. If you are not too familiar\r\nwith the low-level \"packed interleaved\" image storage format, the `InBuf` is\r\nexpected to be `w*h*c` elements in size, where `w` and `h` is the width and\r\nthe height of the image in pixels, respectively, and `c` is the number of\r\ncolor channels in the image. In the example above, the size of the `InBuf` is\r\n`640*480*3=921600` elements. If you are working with 8-bit images, the buffer\r\nand the elements should have the `uint8_t*` type; if you are working with\r\n16-bit images, they should have the `uint16_t*` type. Note that when\r\nprocessing 16-bit images, the value of `16` should be used in resizer's\r\nconstructor. AVIR's algorithm does not discern between channel packing order\r\n(`RGBA`, `ARGB`, `BGRA`, etc.), so if the `BGRA` ordered elements were passed\r\nto it, the result will be also `BGRA`.\r\n\r\nIf the graphics library you are using returns a `uint32_t*` pointer to a raw\r\n4-channel packed pixel data, you will need to cast both the input and output\r\npointers to the `uint8_t*` type when supplying them to the resizing function,\r\nand set the ElCount to 4.\r\n\r\nFor low-ringing performance:\r\n\r\n```c++\r\navir :: CImageResizer\u003c\u003e ImageResizer( 8, 0, avir :: CImageResizerParamsLR() );\r\n```\r\n\r\nTo use the built-in gamma correction, which is disabled by default, an object\r\nof the `avir::CImageResizerVars` class with its variable `UseSRGBGamma` set to\r\n`true` should be supplied to the `resizeImage()` function. Note that, when\r\nenabled, the gamma correction is applied to all channels (e.g. alpha-channel)\r\nin the current implementation.\r\n\r\n```c++\r\navir :: CImageResizerVars Vars;\r\nVars.UseSRGBGamma = true;\r\n```\r\n\r\nDithering (error-diffusion dither which is perceptually good) can be enabled\r\nthis way:\r\n\r\n```c++\r\ntypedef avir :: fpclass_def\u003c float, float,\r\n    avir :: CImageResizerDithererErrdINL\u003c float \u003e \u003e fpclass_dith;\r\navir :: CImageResizer\u003c fpclass_dith \u003e ImageResizer( 8 );\r\n```\r\n\r\nThe library is able to process images of any bit depth: this includes 8-bit,\r\n16-bit, float and double types. Larger integer and signed integer types are\r\nnot supported. Supported source and destination image sizes are only limited\r\nby the available system memory. Note that the resizing function applies\r\nclipping to integer output only; floating-point output will not be clipped to\r\n[0; 1] range.\r\n\r\nThe code of this library was commented in the [Doxygen](http://www.doxygen.org/)\r\nstyle. To generate the documentation locally you may run the\r\n`doxygen ./other/avirdoxy.txt` command from the library's directory. Note that\r\nthe code was suitably documented allowing you to make modifications, and to\r\ngain full understanding of the algorithm.\r\n\r\nPreliminary tests show that this library (compiled with Intel C++ Compiler\r\n18.2 with AVX2 instructions enabled, without explicit SIMD resizing code) can\r\nresize 8-bit RGB 5184x3456 (17.9 Mpixel) 3-channel image down to 1920x1280\r\n(2.5 Mpixel) image in 245 milliseconds, utilizing a single thread, on Intel\r\nCore i7-7700K processor-based system without overclocking. This scales down to\r\n74 milliseconds if 8 threads are utilized.\r\n\r\nMulti-threaded operation is not provided by this library \"out of the box\".\r\nThe multi-threaded (horizontally-threaded) infrastructure is available, but\r\nrequires additional system-specific interfacing code for engagement.\r\n\r\n## SIMD Usage Information\r\n\r\nThis library is capable of using SIMD floating-point types for internal\r\nvariables. This means that up to 4 color channels can be processed in\r\nparallel. Since the default interleaved processing algorithm itself remains\r\nnon-SIMD, the use of SIMD internal types is not practical for 1- and 2-channel\r\nimage resizing (due to overhead). SIMD internal type can be used this way:\r\n\r\n```c++\r\n#include \"avir_float4_sse.h\"\r\navir :: CImageResizer\u003c avir :: fpclass_float4 \u003e ImageResizer( 8 );\r\n```\r\n\r\nFor 1-channel and 2-channel image resizing when AVX instructions are allowed\r\nit may be reasonable to utilize de-interleaved SIMD processing algorithm.\r\nWhile it gives no performance benefit if the \"float4\" SSE processing type is\r\nused, it offers some performance boost if the \"float8\" AVX processing type is\r\nused (given dithering is not performed, or otherwise performance is reduced at\r\nthe dithering stage since recursive dithering cannot be parallelized). The\r\ninternal type remains non-SIMD \"float\". De-interleaved algorithm can be used\r\nthis way:\r\n\r\n```c++\r\n#include \"avir_float8_avx.h\"\r\navir :: CImageResizer\u003c avir :: fpclass_float8_dil \u003e ImageResizer( 8 );\r\n```\r\n\r\nIt's important to note that on the latest Intel processors (i7-7700K and\r\nprobably later) the use of the aforementioned SIMD-specific resizing code may\r\nnot be justifiable, or may be even counter-productive due to many factors:\r\nmemory bandwidth bottleneck, increased efficiency of processor's circuitry\r\nutilization and out-of-order execution, automatic SIMD optimizations performed\r\nby the compiler. This is at least true when compiling 64-bit code with Intel\r\nC++ Compiler 18.2 with /QxSSE4.2, or especially with the /QxCORE-AVX2 option.\r\nSSE-specific resizing code may still be a little bit more efficient for\r\n4-channel image resizing.\r\n\r\n## Notes\r\n\r\nThis library was tested for compatibility with [GNU C++](http://gcc.gnu.org/),\r\n[Microsoft Visual C++](http://www.microsoft.com/visualstudio/eng/products/visual-studio-express-products),\r\n[LLVM](https://llvm.org/), and [Intel C++](http://software.intel.com/en-us/c-compilers)\r\ncompilers, on 32- and 64-bit Windows, macOS, and CentOS Linux. The code was\r\nalso tested with Dr.Memory/Win32 for the absence of uninitialized or\r\nunaddressable memory accesses.\r\n\r\nAll code is fully \"inline\", without the need to compile any source files. The\r\nmemory footprint of the library itself is very modest, except that the size of\r\nthe temporary image buffers depends on the input and output image sizes, and\r\nis proportionally large.\r\n\r\nThe \"heart\" of resizing algorithm's quality resides in the parameters defined\r\nvia the `avir::CImageResizerParams` structure. While the default set of\r\nparameters that offers a good quality was already provided, there is\r\n(probably) still a place for improvement exists, and the default parameters\r\nmay change in a future update. If you need to recall an exact set of\r\nparameters, simply save them locally for a later use.\r\n\r\nWhen the algorithm is run with no resizing applied (k=1), the result of\r\nresizing will not be an exact, but a very close copy of the source image. The\r\nreason for such inexactness is that the image is always low-pass filtered at\r\nfirst to reduce aliasing during subsequent resizing, and at last filtered by a\r\ncorrection filter. Such approach allows algorithm to maintain a stable level\r\nof quality regardless of the resizing \"k\" factor used.\r\n\r\nThis library includes a binary command line tool \"imageresize\" for some\r\ndesktop platforms. This tool was designed to be used as a demonstration of\r\nlibrary's performance, and as a reference, it is multi-threaded (the `-t`\r\nswitch can be used to control the number of threads utilized). This tool uses\r\nplain \"float\" processing (no explicit SIMD) and relies on automatic compiler\r\noptimizations. This tool uses the following libraries:\r\n\r\n* turbojpeg Copyright (c) 2009-2013 D. R. Commander\r\n* libpng Copyright (c) 1998-2013 Glenn Randers-Pehrson\r\n* zlib Copyright (c) 1995-2013 Jean-loup Gailly and Mark Adler\r\n\r\nNote that you can enable gamma-correction with the `-g` switch. However,\r\nsometimes gamma-correction produces \"greenish/reddish/bluish haze\" since\r\nlow-amplitude oscillations produced by resizing at object boundaries are\r\namplified by gamma correction. This can also have an effect of reduced\r\ncontrast.\r\n\r\n## Interpolation Discussion\r\n\r\nThe use of certain low-pass filters and 2X upsampling in this library is\r\nhardly debatable, because they are needed to attain a certain anti-aliasing\r\neffect and keep ringing artifacts low. But the use of sinc function-based\r\ninterpolation filter that is 18 taps-long (may be higher, up to 36 taps in\r\npractice) can be questioned, because such interpolation filter requires 18\r\nmultiply-add operations. Comparatively, an optimal Hermite or cubic\r\ninterpolation spline requires 8 multiply and 11 add operations.\r\n\r\nOne of the reasons 18-tap filter is preferred, is because due to memory\r\nbandwidth limitations using a lower-order filter does not provide any\r\nsignificant performance increase (e.g. 14-tap filter is less than 5% more\r\nefficient overall). At the same time, in comparison to cubic spline, 18-tap\r\nfilter embeds a low-pass filter that rejects signal above 0.5\\*pi (provides\r\nadditional anti-aliasing filtering), and this filter has a consistent shape at\r\nall fractional offsets. Splines have a varying low-pass filter shape at\r\ndifferent fractional offsets (e.g. no low-pass filtering at 0.0 offset,\r\nand maximal low-pass filtering at 0.5 offset). 18-tap filter also offers a\r\nsuperior stop-band attenuation which almost guarantees absence of artifacts if\r\nthe image is considerably sharpened afterwards.\r\n\r\n## Why 2X upsizing in AVIR?\r\n\r\nClassic approaches to image resizing do not perform an additional 2X upsizing.\r\nSo, why such upsizing is needed at all in AVIR? Indeed, image resizing can be\r\nimplemented using a single interpolation filter which is applied to the source\r\nimage directly. However, such approach has limitations:\r\n\r\nFirst of all, speaking about non-2X-upsized resizing, during upsizing the\r\ninterpolation filter has to be tuned to a frequency close to pi (Nyquist) in\r\norder to reduce high-frequency smoothing: this reduces the space left for\r\nfilter optimization. Beside that, during downsizing, a filter that performs\r\nwell and predictable when tuned to frequencies close to the Nyquist frequency,\r\nmay become distorted in its spectral shape when it is tuned to lower\r\nfrequencies. That is why it is usually a good idea to have filter's stop-band\r\nbegin below Nyquist so that the transition band's shape remains stable at any\r\nlower-frequency setting. At the same time, this requirement complicates a\r\nfurther corrective filtering, because correction filter may become too steep\r\nat the point where the stop-band begins.\r\n\r\nSecondly, speaking about non-2X-upsized resizing, filter has to be very short\r\n(with a base length of 5-7 taps, further multiplied by the resizing factor) or\r\notherwise the ringing artifacts will be very strong: it is a general rule that\r\nthe steeper the filter is around signal frequencies being removed the higher\r\nthe ringing artifacts are. That is why it is preferred to move steep\r\ntransitions into the spectral area with a quieter signal. A short filter also\r\nmeans it cannot provide a strong \"beyond-Nyquist\" stop-band attenuation, so an\r\ninterpolated image will look a bit edgy or not very clean due to stop-band\r\nartifacts.\r\n\r\nTo sum up, only additional controlled 2X upsizing provides enough spectral\r\nspace to design interpolation filter without visible ringing artifacts yet\r\nproviding a strong stop-band attenuation and stable spectral characteristics\r\n(good at any resizing \"k\" factor). Moreover, 2X upsizing becomes very\r\nimportant in maintaining a good resizing quality when downsizing and upsizing\r\nby small \"k\" factors, in the range 0.5 to 2: resizing approaches that do not\r\nperform 2X upsizing usually cannot design a good interpolation filter for such\r\nfactors just because there is not enough spectral space available.\r\n\r\n## Why Peaked Cosine in AVIR?\r\n\r\nFirst of all, AVIR is a general solution to image resizing problem. That is\r\nwhy it should not be directly compared to \"spline interpolation\" or \"Lanczos\r\nresampling\", because the latter two are only means to design interpolation\r\nfilters, and they can be implemented in a variety of ways, even in sub-optimal\r\nways. Secondly, with only a minimal effort AVIR can be changed to use any\r\nexisting interpolation formula and any window function, but this is just not\r\nneeded.\r\n\r\nAn effort was made to compare Peaked Cosine to Lanczos window function, and\r\nhere is the author's opinion. Peaked Cosine has two degrees of freedom whereas\r\nLanczos has one degree of freedom. While both functions can be used with\r\nacceptable results, Peaked Cosine window function used in automatic parameter\r\noptimization really pushes the limits of frequency response linearity,\r\nanti-aliasing strength (stop-band attenuation) and low-ringing performance\r\nwhich Lanczos cannot usually achieve. This is true at least when using a\r\ngeneral-purpose downhill simplex optimization method. Lanczos window has good\r\n(but not better) characteristics in several special cases (certain \"k\"\r\nfactors) which makes it of limited use in a general solution such as AVIR.\r\n\r\nAmong other window functions (Kaiser, Gaussian, Cauchy, Poisson, generalized\r\ncosine windows) there are no better candidates as well. It looks like Peaked\r\nCosine function's scalability (it retains stable, almost continously-variable\r\nspectral characteristics at any window parameter values), and its ability to\r\ncreate \"desirable\" pass-band ripple in the frequency response near the cutoff\r\npoint contribute to its better overall quality. Somehow Peaked Cosine window\r\nfunction optimization manages to converge to reasonable states in most cases\r\n(that is why AVIR library comes with a set of equally robust, but distinctive\r\nparameter sets) whereas all other window functions tend to produce\r\nunpredictable optimization results.\r\n\r\nThe only disadvantage of Peaked Cosine window function is that usable filters\r\nwindowed by this function tend to be longer than \"usual\" (with Kaiser window\r\nbeing the \"golden standard\" for filter length per decibel of stop-band\r\nattenuation). This is a price that should be paid for stable spectral\r\ncharacteristics.\r\n\r\nThis waterfall graph depicts the windowing function, at varying Alpha values.\r\n\r\n\u003cimg src=\"other/_peaked_cosine.png\" width=\"550\"\u003e\r\n\r\nNote that since mathematical formulas cannot be patented nor copyrighted, you\r\nare free to adopt this windowing function in your applications and research.\r\nJust consider giving it a proper credit.\r\n\r\n## LANCIR\r\n\r\nAs a part of AVIR library, the `CLancIR` class is also offered which is an\r\noptimal implementation of [Lanczos](https://en.wikipedia.org/wiki/Lanczos_resampling)\r\nimage resizing filter. This class has a similar programmatic interface to\r\nAVIR, but it is not thread-safe: each executing thread should have its own\r\n`CLancIR` object. This class was designed for cases of batch processing of\r\nsame-sized frames like in video encoding, or for just-in-time resizing of\r\nan application's assets. This Lanczos implementation is likely one of the\r\nfastest available for CPUs; it features radical AVX, SSE2, and NEON\r\noptimizations.\r\n\r\nLANCIR offers up to three times faster image resizing in comparison to AVIR.\r\nThe quality difference is, however, debatable. Note that while LANCIR can\r\ntake 8- and 16-bit and float image buffers, its precision is limited to\r\n8-bit resizing.\r\n\r\nLANCIR should be seen as a bonus and as an \"industrial standard\" reference\r\nfor comparison. By default, LANCIR uses Lanczos filter's `a` parameter equal\r\nto 3 which is similar to AVIR's default setting.\r\n\r\n## Comparison\r\n\r\nThis graph displays a comparison of AVIR 2.9 (default parameters) and\r\nLanczos-3 image resizing algorithm in the area of frequency response.\r\nThe methodology can be seen in the `other/frtest.cpp` file. This graph\r\ndisplays an average frequency response over a set of resizing factors.\r\nIt is similar but not equal to Fourier analysis as any errors and aliasing\r\nartifacts are integrated into the response. As you can see, AVIR offers a\r\nvisibly better frequency response linearity. The horizontal scale displays a\r\nnormalized frequency scale, where 0 is DC frequency and 1 is Nyquist\r\nfrequency. In common terms, 1 corresponds to 1-pixel image features, 0.5\r\ncorresponds to 2-pixel features while 0.25 corresponds to 4-pixel features,\r\netc. The vertical scale is in decibel.\r\n\r\n![FR plot](https://github.com/avaneev/avir/blob/master/other/_fr_up.png)\r\n\r\nThe following graph displays a comparison of an average dynamic range over a\r\nset of resizing factors. The dynamic range is estimated by performing\r\ntwo-way resizing, followed by deviation/error estimation relative to the\r\noriginal image. As you can see here, aliasing artifacts visibly reduce dynamic\r\nrange above 0.5\\*Nyquist. An interesting aspect of this measurement method is\r\nthat it reflects modes of visual ringing very well: they correspond to the\r\npoints on frequency response where differential approaches zero.\r\n\r\n![DR plot](https://github.com/avaneev/avir/blob/master/other/_dr_up.png)\r\n\r\nNote that on downsizing the response graphs look similar to these.\r\n\r\n## Users\r\n\r\nThis library is used by:\r\n\r\n  * [Contaware.com](http://www.contaware.com/)\r\n  * [Pretext contact maps](https://github.com/wtsi-hpag/PretextSnapshot)\r\n  * [LVC Audio](https://lvcaudio.com)\r\n  * [Trainz](https://www.trainzportal.com/files/TRS19/credits.html)\r\n  * [MLV App](https://mlv.app/)\r\n\r\n[This video](https://www.youtube.com/watch?v=oNF-c6YX7-8) was \"unsqueezed\"\r\nwith AVIR by a factor of 3 from ML RAW video, and at the final stage was\r\ndownsampled to 4K resolution.\r\n\r\nPlease drop me a note at aleksey.vaneev@gmail.com and I will include a link to\r\nyour software product to the list of users. This list is important at\r\nmaintaining confidence in this library among the interested parties.\r\n\r\n## Change Log\r\n\r\nVersion 3.0:\r\n\r\n* Improved speed by 10-25% on upsizing by utilizing a special resizing\r\nfunction together with filter-less 2X upsizing. Does not apply to the\r\nde-interleaved (AVX) resizing.\r\n* Minor LANCIR optimization.\r\n\r\nVersion 2.9:\r\n\r\n* Removed a rarely-used half-band resizing step completely since it offers no\r\npractical performance nor quality benefits.\r\n* Optimized filter generation function (removed divisions by a constant) as\r\nfilters are always post-normalized anyway. This may reduce overhead when\r\ncreating thumbnail-sized images.\r\n\r\nVersion 2.8:\r\n\r\n* Fixed regression with the copy-constructor of CImageResizeVars class\r\n(previously it caused uninitialized accesses).\r\n* Removed filter length optimization as it did not reduce overhead measurably.\r\n* Optimized \"peaked cosine\" window function generator (removed division).\r\n* Added \"unbiasing\" to resizer - an unconventional approach which reduces peak\r\nerror significantly, at the expense of 5% increased overhead.\r\n* Reoptimized filter parameters, now yielding an unprecedented quality.\r\n\r\nVersion 2.7:\r\n\r\n* Added normalization of individual fractional delay filters. This reduced\r\npeak error by 3 dB, which is substantial for image resizing.\r\n* Reoptimized all filter parameters resulting in better frequency response\r\nlinearity.\r\n* Added AVIR_NOCTOR macro to avoid copy-constructing and copying objects of\r\nsome classes via a default copy function.\r\n* Added copy-constructor and assignment operator to the CImageResizerVars\r\nclass, to avoid uninitialized memory copying.\r\n* Corrected automatic image offseting and \"k\" factor on image upsizing.\r\n\r\nVersion 2.6:\r\n\r\n* A minor fix to sRGB gamma approximation functions.\r\n* LANCIR: fixed a rare access violation crash.\r\n\r\nVersion 2.5:\r\n\r\n* Surrounded `memcpy` calls with length checks to conform to `memcpy`\r\nspecification which does not allow NULL pointers even with zero copy length.\r\n\r\nVersion 2.4:\r\n\r\n* Removed outdated `_mm_reset()` function calls from the SIMD code.\r\n* Changed `float4 round()` to use SSE2 rounding features, avoiding use of\r\n64-bit registers.\r\n\r\nVersion 2.3:\r\n\r\n* Implemented CLancIR image resizing algorithm.\r\n* Fixed a minor image offset on image upsizing.\r\n\r\nVersion 2.2:\r\n\r\n* Released AVIR under a permissive MIT license agreement.\r\n\r\nVersion 2.1:\r\n\r\n* Fixed error-diffusion dither problems introduced in the previous version.\r\n* Added the `-1` switch to the `imageresize` to enable 1-bit output for\r\ndither's quality evaluation (use together with the `-d` switch).\r\n* Added the `--algparams=` switch to the `imageresize` to control resizing\r\nquality (replaces the `--low-ring` switch).\r\n* Added `avir :: CImageResizerParamsULR` parameter set for lowest-ringing\r\nperformance possible (not considerably different to\r\n`avir :: CImageResizerParamsLR`, but a bit lower ringing).\r\n\r\nVersion 2.0:\r\n\r\n* Minor inner loop optimizations.\r\n* Lifted the supported image size constraint by switching buffer addressing to\r\n`size_t` from `int`, now image size is limited by the available system memory.\r\n* Added several useful switches to the `imageresize` utility.\r\n* Now `imageresize` does not apply gamma-correction by default.\r\n* Fixed scaling of bit depth-reduction operation.\r\n* Improved error-diffusion dither's signal-to-noise ratio.\r\n* Compiled binaries with AVX2 instruction set (SSE4 for macOS).\r\n","funding_links":[],"categories":["C++"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Favaneev%2Favir","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Favaneev%2Favir","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Favaneev%2Favir/lists"}