Panda3D
 All Classes Functions Variables Enumerations
image_util.cxx
1 #include "zgl.h"
2 
3 /*
4  * image conversion
5  */
6 
7 void gl_convertRGB_to_5R6G5B(unsigned short *pixmap,unsigned char *rgb,
8  int xsize,int ysize)
9 {
10  int i,n;
11  unsigned char *p;
12 
13  p=rgb;
14  n=xsize*ysize;
15  for(i=0;i<n;i++) {
16  pixmap[i]=((p[0]&0xF8)<<8) | ((p[1]&0xFC)<<3) | ((p[2]&0xF8)>>3);
17  p+=3;
18  }
19 }
20 
21 void gl_convertRGB_to_8A8R8G8B(unsigned int *pixmap, unsigned char *rgb,
22  int xsize, int ysize)
23 {
24  int i,n;
25  unsigned char *p;
26 
27  p=rgb;
28  n=xsize*ysize;
29  for(i=0;i<n;i++) {
30  pixmap[i]=(((unsigned int)p[0])<<16) |
31  (((unsigned int)p[1])<<8) |
32  ((unsigned int)p[2]) |
33  0xff000000;
34  p+=3;
35  }
36 }
37 
38 void gl_convertRGBA_to_8A8R8G8B(unsigned int *pixmap, unsigned char *rgb,
39  int xsize, int ysize)
40 {
41  int i,n;
42  unsigned char *p;
43 
44  p=rgb;
45  n=xsize*ysize;
46  for(i=0;i<n;i++) {
47  pixmap[i]=(((unsigned int)p[0])<<16) |
48  (((unsigned int)p[1])<<8) |
49  ((unsigned int)p[2]) |
50  (((unsigned int)p[3])<<24);
51  p+=4;
52  }
53 }
54 
55 /*
56  * linear interpolation with xf,yf normalized to 2^16
57  */
58 
59 #define INTERP_NORM_BITS 16
60 #define INTERP_NORM (1 << INTERP_NORM_BITS)
61 
62 static inline int interpolate(int v00,int v01,int v10,int xf,int yf)
63 {
64  return v00+(((v01-v00)*xf + (v10-v00)*yf) >> INTERP_NORM_BITS);
65 }
66 
67 
68 /*
69  * TODO: more accurate resampling
70  */
71 
72 void gl_resizeImage(unsigned char *dest,int xsize_dest,int ysize_dest,
73  unsigned char *src,int xsize_src,int ysize_src)
74 {
75  unsigned char *pix,*pix_src;
76  PN_stdfloat x1,y1,x1inc,y1inc;
77  int xi,yi,j,xf,yf,x,y;
78 
79  pix=dest;
80  pix_src=src;
81 
82  x1inc=(PN_stdfloat) (xsize_src - 1) / (PN_stdfloat) (xsize_dest - 1);
83  y1inc=(PN_stdfloat) (ysize_src - 1) / (PN_stdfloat) (ysize_dest - 1);
84 
85  y1=0;
86  for(y=0;y<ysize_dest;y++) {
87  x1=0;
88  for(x=0;x<xsize_dest;x++) {
89  xi=(int) x1;
90  yi=(int) y1;
91  xf=(int) ((x1 - floor(x1)) * INTERP_NORM);
92  yf=(int) ((y1 - floor(y1)) * INTERP_NORM);
93 
94  if ((xf+yf) <= INTERP_NORM) {
95  for(j=0;j<4;j++) {
96  pix[j]=interpolate(pix_src[(yi*xsize_src+xi)*4+j],
97  pix_src[(yi*xsize_src+xi+1)*4+j],
98  pix_src[((yi+1)*xsize_src+xi)*4+j],
99  xf,yf);
100  }
101  } else {
102  xf=INTERP_NORM - xf;
103  yf=INTERP_NORM - yf;
104  for(j=0;j<4;j++) {
105  pix[j]=interpolate(pix_src[((yi+1)*xsize_src+xi+1)*4+j],
106  pix_src[((yi+1)*xsize_src+xi)*4+j],
107  pix_src[(yi*xsize_src+xi+1)*4+j],
108  xf,yf);
109  }
110  }
111 
112  pix+=4;
113  x1+=x1inc;
114  }
115  y1+=y1inc;
116  }
117 }
118 
119 #define FRAC_BITS 16
120 
121 /* resizing with no interlating nor nearest pixel */
122 
123 void gl_resizeImageNoInterpolate(unsigned char *dest,int xsize_dest,int ysize_dest,
124  unsigned char *src,int xsize_src,int ysize_src)
125 {
126  unsigned char *pix,*pix_src,*pix1;
127  int x1,y1,x1inc,y1inc;
128  int xi,yi,x,y;
129 
130  pix=dest;
131  pix_src=src;
132 
133  x1inc=(int)((PN_stdfloat) ((xsize_src)<<FRAC_BITS) / (PN_stdfloat) (xsize_dest));
134  y1inc=(int)((PN_stdfloat) ((ysize_src)<<FRAC_BITS) / (PN_stdfloat) (ysize_dest));
135 
136  y1=0;
137  for(y=0;y<ysize_dest;y++) {
138  x1=0;
139  for(x=0;x<xsize_dest;x++) {
140  xi=x1 >> FRAC_BITS;
141  yi=y1 >> FRAC_BITS;
142  pix1=pix_src+(yi*xsize_src+xi)*4;
143 
144  pix[0]=pix1[0];
145  pix[1]=pix1[1];
146  pix[2]=pix1[2];
147  pix[3]=pix1[3];
148 
149  pix+=4;
150  x1+=x1inc;
151  }
152  y1+=y1inc;
153  }
154 }
155