1 /**************************************************************************
3 * Copyright 2013-2014 RAD Game Tools and Valve Software
4 * Copyright 2010-2014 Rich Geldreich and Tenacious Software LLC
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 **************************************************************************/
27 // File: vogl_resampler.h
28 // RG: This is public domain code, originally derived from Graphics Gems 3, see: http://code.google.com/p/imageresampler/
31 #include "vogl_core.h"
35 #define VOGL_RESAMPLER_DEBUG_OPS 0
36 #define VOGL_RESAMPLER_DEFAULT_FILTER "lanczos4"
38 #define VOGL_RESAMPLER_MAX_DIMENSION 16384
41 typedef float Resample_Real;
46 typedef Resample_Real Sample;
70 STATUS_OUT_OF_MEMORY = 1,
71 STATUS_BAD_FILTER_NAME = 2,
72 STATUS_SCAN_BUFFER_FULL = 3
75 // src_x/src_y - Input dimensions
76 // dst_x/dst_y - Output dimensions
77 // boundary_op - How to sample pixels near the image boundaries
78 // sample_low/sample_high - Clamp output samples to specified range, or disable clamping if sample_low >= sample_high
79 // Pclist_x/Pclist_y - Optional pointers to contributor lists from another instance of a Resampler
80 // src_x_ofs/src_y_ofs - Offset input image by specified amount (fractional values okay)
84 Boundary_Op boundary_op = BOUNDARY_CLAMP,
85 Resample_Real sample_low = 0.0f, Resample_Real sample_high = 0.0f,
86 const char *Pfilter_name = VOGL_RESAMPLER_DEFAULT_FILTER,
87 Contrib_List *Pclist_x = NULL,
88 Contrib_List *Pclist_y = NULL,
89 Resample_Real filter_x_scale = 1.0f,
90 Resample_Real filter_y_scale = 1.0f,
91 Resample_Real src_x_ofs = 0.0f,
92 Resample_Real src_y_ofs = 0.0f);
96 // Reinits resampler so it can handle another frame.
99 // false on out of memory.
100 bool put_line(const Sample *Psrc);
102 // NULL if no scanlines are currently available (give the resampler more scanlines!)
103 const Sample *get_line();
105 Status status() const
110 // Returned contributor lists can be shared with another Resampler.
111 void get_clists(Contrib_List **ptr_clist_x, Contrib_List **ptr_clist_y);
112 Contrib_List *get_clist_x() const
116 Contrib_List *get_clist_y() const
122 static int get_filter_num();
123 static const char *get_filter_name(int filter_num);
125 static Contrib_List *make_clist(
126 int src_x, int dst_x, Boundary_Op boundary_op,
127 Resample_Real (*Pfilter)(Resample_Real),
128 Resample_Real filter_support,
129 Resample_Real filter_scale,
130 Resample_Real src_ofs);
134 Resampler(const Resampler &o);
135 Resampler &operator=(const Resampler &o);
137 #ifdef VOGL_RESAMPLER_DEBUG_OPS
141 int m_intermediate_x;
143 int m_resample_src_x;
144 int m_resample_src_y;
145 int m_resample_dst_x;
146 int m_resample_dst_y;
148 Boundary_Op m_boundary_op;
153 Contrib_List *m_Pclist_x;
154 Contrib_List *m_Pclist_y;
156 bool m_clist_x_forced;
157 bool m_clist_y_forced;
159 bool m_delay_x_resample;
162 unsigned char *m_Psrc_y_flag;
164 // The maximum number of scanlines that can be buffered at one time.
167 MAX_SCAN_BUF_SIZE = VOGL_RESAMPLER_MAX_DIMENSION
172 int scan_buf_y[MAX_SCAN_BUF_SIZE];
173 Sample *scan_buf_l[MAX_SCAN_BUF_SIZE];
176 Scan_Buf *m_Pscan_buf;
183 void resample_x(Sample *Pdst, const Sample *Psrc);
184 void scale_y_mov(Sample *Ptmp, const Sample *Psrc, Resample_Real weight, int dst_x);
185 void scale_y_add(Sample *Ptmp, const Sample *Psrc, Resample_Real weight, int dst_x);
186 void clamp(Sample *Pdst, int n);
187 void resample_y(Sample *Pdst);
189 static int reflect(const int j, const int src_x, const Boundary_Op boundary_op);
191 inline int count_ops(Contrib_List *Pclist, int k)
194 for (i = 0; i < k; i++)
202 inline Resample_Real clamp_sample(Resample_Real f) const