Path: blob/master/thirdparty/basis_universal/encoder/basisu_resampler.h
9903 views
// basisu_resampler.h1// Copyright (C) 2019-2024 Binomial LLC. All Rights Reserved.2//3// Licensed under the Apache License, Version 2.0 (the "License");4// you may not use this file except in compliance with the License.5// You may obtain a copy of the License at6//7// http://www.apache.org/licenses/LICENSE-2.08//9// Unless required by applicable law or agreed to in writing, software10// distributed under the License is distributed on an "AS IS" BASIS,11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.12// See the License for the specific language governing permissions and13// limitations under the License.14#pragma once15#include "../transcoder/basisu.h"1617#define BASISU_RESAMPLER_DEBUG_OPS (0)18#define BASISU_RESAMPLER_DEFAULT_FILTER "lanczos4"19#define BASISU_RESAMPLER_MAX_DIMENSION (16384)2021namespace basisu22{23// float or double24typedef float Resample_Real;2526class Resampler27{28public:29typedef Resample_Real Sample;3031struct Contrib32{33Resample_Real weight;34uint16_t pixel;35};3637struct Contrib_List38{39uint16_t n;40Contrib *p;41};4243enum Boundary_Op44{45BOUNDARY_WRAP = 0,46BOUNDARY_REFLECT = 1,47BOUNDARY_CLAMP = 248};4950enum Status51{52STATUS_OKAY = 0,53STATUS_OUT_OF_MEMORY = 1,54STATUS_BAD_FILTER_NAME = 2,55STATUS_SCAN_BUFFER_FULL = 356};5758// src_x/src_y - Input dimensions59// dst_x/dst_y - Output dimensions60// boundary_op - How to sample pixels near the image boundaries61// sample_low/sample_high - Clamp output samples to specified range, or disable clamping if sample_low >= sample_high62// Pclist_x/Pclist_y - Optional pointers to contributor lists from another instance of a Resampler63// src_x_ofs/src_y_ofs - Offset input image by specified amount (fractional values okay)64Resampler(65int src_x, int src_y,66int dst_x, int dst_y,67Boundary_Op boundary_op = BOUNDARY_CLAMP,68Resample_Real sample_low = 0.0f, Resample_Real sample_high = 0.0f,69const char *Pfilter_name = BASISU_RESAMPLER_DEFAULT_FILTER,70Contrib_List *Pclist_x = NULL,71Contrib_List *Pclist_y = NULL,72Resample_Real filter_x_scale = 1.0f,73Resample_Real filter_y_scale = 1.0f,74Resample_Real src_x_ofs = 0.0f,75Resample_Real src_y_ofs = 0.0f);7677~Resampler();7879// Reinits resampler so it can handle another frame.80void restart();8182// false on out of memory.83bool put_line(const Sample *Psrc);8485// NULL if no scanlines are currently available (give the resampler more scanlines!)86const Sample *get_line();8788Status status() const89{90return m_status;91}9293// Returned contributor lists can be shared with another Resampler.94void get_clists(Contrib_List **ptr_clist_x, Contrib_List **ptr_clist_y);95Contrib_List *get_clist_x() const96{97return m_Pclist_x;98}99Contrib_List *get_clist_y() const100{101return m_Pclist_y;102}103104// Filter accessors.105static int get_filter_num();106static const char *get_filter_name(int filter_num);107108static Contrib_List *make_clist(109int src_x, int dst_x, Boundary_Op boundary_op,110Resample_Real(*Pfilter)(Resample_Real),111Resample_Real filter_support,112Resample_Real filter_scale,113Resample_Real src_ofs);114115static void free_clist(Contrib_List* p) { if (p) { free(p->p); free(p); } }116117private:118Resampler();119Resampler(const Resampler &o);120Resampler &operator=(const Resampler &o);121122#ifdef BASISU_RESAMPLER_DEBUG_OPS123int total_ops;124#endif125126int m_intermediate_x;127128int m_resample_src_x;129int m_resample_src_y;130int m_resample_dst_x;131int m_resample_dst_y;132133Boundary_Op m_boundary_op;134135Sample *m_Pdst_buf;136Sample *m_Ptmp_buf;137138Contrib_List *m_Pclist_x;139Contrib_List *m_Pclist_y;140141bool m_clist_x_forced;142bool m_clist_y_forced;143144bool m_delay_x_resample;145146int *m_Psrc_y_count;147uint8_t *m_Psrc_y_flag;148149// The maximum number of scanlines that can be buffered at one time.150enum151{152MAX_SCAN_BUF_SIZE = BASISU_RESAMPLER_MAX_DIMENSION153};154155struct Scan_Buf156{157int scan_buf_y[MAX_SCAN_BUF_SIZE];158Sample *scan_buf_l[MAX_SCAN_BUF_SIZE];159};160161Scan_Buf *m_Pscan_buf;162163int m_cur_src_y;164int m_cur_dst_y;165166Status m_status;167168void resample_x(Sample *Pdst, const Sample *Psrc);169void scale_y_mov(Sample *Ptmp, const Sample *Psrc, Resample_Real weight, int dst_x);170void scale_y_add(Sample *Ptmp, const Sample *Psrc, Resample_Real weight, int dst_x);171void clamp(Sample *Pdst, int n);172void resample_y(Sample *Pdst);173174static int reflect(const int j, const int src_x, const Boundary_Op boundary_op);175176inline int count_ops(Contrib_List *Pclist, int k)177{178int i, t = 0;179for (i = 0; i < k; i++)180t += Pclist[i].n;181return (t);182}183184Resample_Real m_lo;185Resample_Real m_hi;186187inline Resample_Real clamp_sample(Resample_Real f) const188{189if (f < m_lo)190f = m_lo;191else if (f > m_hi)192f = m_hi;193return f;194}195};196197} // namespace basisu198199200