summaryrefslogtreecommitdiff
path: root/im/src/old_imresize.c
blob: 819103728c855b05efaa40f2830beb327d193418 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
/** \file
 * \brief Old resize/stretch functions
 *
 * See Copyright Notice in im_lib.h
 * $Id: old_imresize.c,v 1.1 2008/10/17 06:10:16 scuri Exp $
 */

#include "old_im.h"

#include <stdlib.h>
#include <math.h>
#include <memory.h>


/*
  BILINEAR INTERPOLATION:

  x' = floor(x)                                        f(x'   , y')    = fll
  y' = floor(y)                                        f(x'   , y'+ 1) = flh
                                                       f(x'+ 1, y')    = fhl
  t = x - x'                                           f(x'+ 1, y'+ 1) = fhh
  u = y - y'

  f(x,y) = (1-t) * (1-u) * f(x'   , y'),
           (1-t) *    u  * f(x'   , y'+ 1),
               t * (1-u) * f(x'+ 1, y'),
               t *    u  * f(x'+ 1, y'+ 1)

  f(x,y) =          fll +                              (re-arranging)
               t * (fhl - fll),
               u * (flh - fll),
           u * t * (fhh - flh - fhl + fll)
          
*/

void imResize(int src_width, int src_height, unsigned char *src_map, int dst_width, int dst_height, unsigned char *dst_map)
{
  /* Do bilinear interpolation */

	unsigned char *line_mapl, *line_maph;
  double t, u, src_x, src_y, factor;
  int fhh, fll, fhl, flh, xl, yl, xh, yh, x, y;

  int *XL = (int*)malloc(dst_width * sizeof(int));
  double *T = (double*)malloc(dst_width * sizeof(double));

	factor = (double)(src_width-1) / (double)(dst_width-1);
  for (x = 0; x < dst_width; x++)
  {
	  src_x = x * factor;
	  xl = (int)floor(src_x);
	  T[x] = src_x - xl;
	  XL[x] = xl;
  }

	factor = (double)(src_height-1) / (double)(dst_height-1);

  for (y = 0; y < dst_height; y++)
  {
	  src_y = y * factor;
	  yl = (int)floor(src_y);
    yh = (yl == src_height-1)? yl: yl + 1;
	  u = src_y - yl;

	  line_mapl = src_map + yl * src_width;
	  line_maph = src_map + yh * src_width;

	  for (x = 0; x < dst_width; x++)
	  {
		  xl = XL[x];
      xh = (xl == src_width-1)? xl: xl + 1;
		  t = T[x];

		  fll = line_mapl[xl];
		  fhl = line_mapl[xh];
		  flh = line_maph[xl];
		  fhh = line_maph[xh];

		  *(dst_map++) = (unsigned char)(u * t * (fhh - flh - fhl + fll) + t * (fhl - fll) + u * (flh - fll) + fll);
	  }
  }

  free(XL);
  free(T);
}

void imStretch(int src_width, int src_height, unsigned char *src_map, int dst_width, int dst_height, unsigned char *dst_map)
{
  int x, y, offset;
  double factor;
  unsigned char *line_map;
	int* XTab = (int*)malloc(dst_width*sizeof(int));

  /* initialize convertion tables to speed up the stretch process */
	factor = (double)(src_width-1) / (double)(dst_width-1);
	for(x = 0; x < dst_width; x++)
		XTab[x] = (int)(factor * x + 0.5);

	factor = (double)(src_height-1) / (double)(dst_height-1);

  line_map = src_map;

  for (y = 0; y < dst_height; y++)
  {
    for (x = 0; x < dst_width; x++)
    {
      offset = XTab[x];
      *(dst_map++) = line_map[offset];
    }

    offset = ((int)(factor * y + 0.5)) * src_width;
		line_map = src_map + offset;
  }

  free(XTab);
}