diff --git a/libcore/imagescaler.c b/libcore/imagescaler.c deleted file mode 100644 index 64fe3dc..0000000 --- a/libcore/imagescaler.c +++ /dev/null @@ -1,149 +0,0 @@ - -#include "imagescaler.h" - -#include -#include - -ImageScaler::ImageScaler() : - m_memory(NULL), - m_hor_filters(NULL), - m_ver_filters(NULL), - m_buffer(NULL), - m_dst_image(NULL), - m_dst_stride(0), - m_dst_width(0), - m_dst_height(0), - m_src_width(0), - m_src_height(0), - m_src_x(0), - m_src_y(0), - m_dst_x(0), - m_dst_y(0) { -} - -ImageScaler::~ImageScaler() { - if ( m_memory ) free( m_memory ); -} - -// sin(x)/(x) -static float sincf( float x ) { - if ( fabsf(x) < 0.05f ) return 1.0f - (1.0f/6.0f)*x*x; // taylor series approximation to avoid 0/0 - return sin(x)/x; -} - -static void CalculateFilters( ImageScaler::Filter *filters, int dst_size, int src_size ) { - const float fc = dst_size >= src_size ? 1.0f : ((float) dst_size)/((float) src_size); - - for (int i = 0; i < dst_size; i++) { - const int d = 2*dst_size; // sample position denominator - const int e = (2*i+1) * src_size - dst_size; // sample position enumerator - int offset = e / d; // truncated sample position - const float sub_offset = ((float) (e - offset*d)) / ((float) d); // exact sample position is (float) e/d = offset + sub_offset - - // calculate filter coefficients - float h[4]; - for (int j=0; j<4; j++) { - const float t = 3.14159265359f * (sub_offset+(1-j)); - h[j] = sincf( fc * t ) * cosf( 0.25f * t ); // sinc-lowpass and cos-window - } - - // ensure that filter does not reach out off image bounds: - while ( offset < 1 ) { - h[0] += h[1]; - h[1] = h[2]; - h[2] = h[3]; - h[3] = 0.0f; - offset++; - } - - while ( offset+3 > src_size ) { - h[3] += h[2]; - h[2] = h[1]; - h[1] = h[0]; - h[0] = 0.0f; - offset--; - } - - // coefficients are normalized to sum up to 2048 - const float norm = 2048.0f / ( h[0] + h[1] + h[2] + h[3] ); - - offset--; // offset of fist used pixel - - filters[i].m_offset = offset + 4; // store offset of first unused pixel - - for (int j=0; j<4; j++) { - const float t = norm * h[j]; - filters[i].m_coeff[(offset+j) & 3] = (int) ((t > 0.0f) ? (t+0.5f) : (t-0.5f)); // consider ring buffer index permutations - } - } - - // set end marker - filters[dst_size].m_offset = (unsigned) -1; - -} - -void ImageScaler::SetImageParameters( unsigned *dst_image, unsigned dst_stride, unsigned dst_width, unsigned dst_height, unsigned src_width, unsigned src_height ) { - m_src_x = 0; - m_src_y = 0; - m_dst_x = 0; - m_dst_y = 0; - - m_dst_image = dst_image; - m_dst_stride = dst_stride; - - // if image dimensions do not change we can keep the old filter coefficients - if ( (src_width == m_src_width) && (src_height == m_src_height) && (dst_width == m_dst_width) && (dst_height == m_dst_height) ) return; - - m_dst_width = dst_width; - m_dst_height = dst_height; - m_src_width = src_width; - m_src_height = src_height; - - if ( m_memory ) free( m_memory ); - - const unsigned hor_filters_size = (m_dst_width + 1) * sizeof(Filter); // reserve one extra position for end marker - const unsigned ver_filters_size = (m_dst_height + 1) * sizeof(Filter); - const unsigned buffer_size = 4 * m_dst_width * sizeof(TmpPixel); - - char *p = (char *) malloc( hor_filters_size + ver_filters_size + buffer_size ); - - m_memory = p; - - m_hor_filters = (Filter *) p; p += hor_filters_size; - m_ver_filters = (Filter *) p; p += ver_filters_size; - m_buffer = (TmpPixel *) p; - - CalculateFilters( m_hor_filters, m_dst_width , m_src_width ); - CalculateFilters( m_ver_filters, m_dst_height, m_src_height ); -} - -// shift range to 0..255 and clamp overflows -static unsigned shift_clamp( int x ) { - x = ( x + (1<<21) ) >> 22; - if ( x < 0 ) return 0; - if ( x > 255 ) return 255; - return x; -} - -void ImageScaler::NextSourceLine() { - m_dst_x = 0; - m_src_x = 0; - m_src_y++; - - while ( m_ver_filters[m_dst_y].m_offset == m_src_y ) { - const int h0 = m_ver_filters[m_dst_y].m_coeff[0]; - const int h1 = m_ver_filters[m_dst_y].m_coeff[1]; - const int h2 = m_ver_filters[m_dst_y].m_coeff[2]; - const int h3 = m_ver_filters[m_dst_y].m_coeff[3]; - const TmpPixel *src = m_buffer; - unsigned *dst = m_dst_image + m_dst_stride * m_dst_y; - - for (unsigned i=0; im_offset == m_src_x ) { - *bp = m_hbuf[0]*fh->m_coeff[0] + m_hbuf[1]*fh->m_coeff[1] + m_hbuf[2]*fh->m_coeff[2] + m_hbuf[3]*fh->m_coeff[3]; - m_dst_x++; - bp += 4; - } - - if ( m_src_x == m_src_width ) NextSourceLine(); - } - -private: - - //! temporary image pixel class - a 4-element integer vector - class TmpPixel { - public: - TmpPixel() { - } - - TmpPixel( int c0, int c1, int c2, int c3 ) { - Set(c0,c1,c2,c3); - } - - void Set( int c0, int c1, int c2, int c3 ) { - m_comp[0] = c0; - m_comp[1] = c1; - m_comp[2] = c2; - m_comp[3] = c3; - } - - TmpPixel operator*( int s ) const { - return TmpPixel( m_comp[0]*s, m_comp[1]*s, m_comp[2]*s, m_comp[3]*s ); - } - - TmpPixel operator+( const TmpPixel &x ) const { - return TmpPixel( m_comp[0] + x[0], m_comp[1] + x[1], m_comp[2] + x[2], m_comp[3] + x[3] ); - } - - // return component i=[0..3] - No range check! - int operator[](unsigned i) const { - return m_comp[i]; - } - - private: - int m_comp[4]; - }; - - //! this is called whenever one input line is processed completely - void NextSourceLine(); - - TmpPixel m_hbuf[4]; //! ring buffer for 4 input pixels - char *m_memory; //! buffer container - Filter *m_hor_filters; //! buffer for horizontal filters (one for each output image column) - Filter *m_ver_filters; //! buffer for vertical filters (one for each output image row) - TmpPixel *m_buffer; //! buffer contains 4 horizontally filtered input lines, multiplexed - unsigned *m_dst_image; //! pointer to destination image - unsigned m_dst_stride; //! destination image stride - unsigned m_dst_width; //! destination image width - unsigned m_dst_height; //! destination image height - unsigned m_src_width; //! source image width - unsigned m_src_height; //! source image height - unsigned m_src_x; //! x position of next source image pixel - unsigned m_src_y; //! y position of source image line currently beeing processed - unsigned m_dst_x; //! x position of next destination image pixel - unsigned m_dst_y; //! x position of next destination image line -}; - -#endif // _ImageScaler_h -