"Fossies" - the Fresh Open Source Software Archive 
Member "xzgv-0.9.2/src/resizepic.c" (3 Sep 2017, 4524 Bytes) of package /linux/misc/old/xzgv-0.9.2.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "resizepic.c" see the
Fossies "Dox" file reference documentation.
1 /* xzgv v0.2 - picture viewer for X, with file selector.
2 * Copyright (C) 1999 Russell Marks. See main.c for license details.
3 *
4 * resizepic.c - resize pic with smoothing (for thumbnails).
5 */
6
7 #include <stdio.h>
8 #include <string.h>
9 #include <stdlib.h>
10 #include <string.h>
11
12 #include "resizepic.h"
13
14
15 #define TN_CRUNCH_WIDTH 320
16 #define TN_CRUNCH_HEIGHT 240
17
18
19
20 /* used to resize (without smoothing) a picture loaded for
21 * thumbnail generation into a (hopefully) smaller image,
22 * which should then be reduced more nicely for the thumbnail.
23 */
24 unsigned char *nasty_resizepic(unsigned char *theimage,
25 int width,int height,int *sw_ask,int *sh_ask)
26 {
27 int x,y,yp,yw,sw,sh,lastyp,scrnwide,scrnhigh;
28 unsigned char *rline,*outimage;
29
30 scrnwide=*sw_ask;
31 scrnhigh=*sh_ask;
32
33 /* try landscapey */
34 sw=scrnwide; sh=(scrnwide*height)/width;
35 if(sh>scrnhigh)
36 /* no, oh well portraity then */
37 sh=scrnhigh,sw=(scrnhigh*width)/height;
38
39 /* fix things for very thin images */
40 if(sh==0) sh++;
41 if(sw==0) sw++;
42
43 *sw_ask=sw; *sh_ask=sh;
44
45 /* so now our zoomed image will be sw x sh */
46
47 if(width<=sw) return(NULL); /* abort if it's not smaller */
48
49 /* extra line added to avoid segfaults from obiwan errors in dest
50 * of memcpy() below. (I don't such errors are actually possible,
51 * but it can't hurt anyway.)
52 */
53 if((outimage=malloc(sw*(sh+1)*3))==NULL)
54 return(NULL);
55
56 lastyp=-1;
57 for(y=0;y<height;y++)
58 {
59 yp=(y*sh)/height;
60 rline=outimage+yp*sw*3;
61 if(yp!=lastyp)
62 {
63 yw=y*width;
64 for(x=0;x<width;x++,yw++)
65 memcpy(rline+(x*sw)/width*3,theimage+yw*3,3);
66 lastyp=yp;
67 }
68 }
69
70 return(outimage);
71 }
72
73
74
75 /* resamples from 'theimage' to a new malloc'ed area, a pointer to which is
76 * the return value.
77 * width x height - size of source image
78 * sw_ask x sh_ask - requested size of dest. image
79 * input and output image both 24-bit.
80 * new width x height in put back in sw_ask and sh_ask
81 */
82 unsigned char *resizepic(unsigned char *theimage,
83 int width,int height,int *sw_ask,int *sh_ask,
84 int allow_crunch)
85 {
86 int a,b,x,y,yp,yw,sw,sh,lastyp;
87 int c,pixwide,pixhigh;
88 int scrnwide,scrnhigh;
89 unsigned char *rline;
90 unsigned char *crunched=NULL;
91 int tmp2,tr,tg,tb,tn;
92 int xypos;
93
94 /* first, see if it would benefit from being reduced without
95 * smoothing (which is faster) before the `nice' resizing.
96 */
97 if(allow_crunch && (width>TN_CRUNCH_WIDTH || height>TN_CRUNCH_HEIGHT))
98 {
99 int our_sw_ask=TN_CRUNCH_WIDTH,our_sh_ask=TN_CRUNCH_HEIGHT;
100
101 crunched=nasty_resizepic(theimage,width,height,&our_sw_ask,&our_sh_ask);
102
103 /* if it worked, replace orig w/h with crunched pic's one, and
104 * set theimage to point to it.
105 */
106 if(crunched)
107 {
108 width=our_sw_ask;
109 height=our_sh_ask;
110 theimage=crunched;
111 }
112 }
113
114 scrnwide=*sw_ask;
115 scrnhigh=*sh_ask;
116
117 if((rline=calloc(scrnwide*scrnhigh*3,1))==NULL) return(0);
118
119 /* try landscapey */
120 sw=scrnwide; sh=(int)((scrnwide*((long)height))/((long)width));
121 if(sh>scrnhigh)
122 /* no, oh well portraity then */
123 { sh=scrnhigh; sw=(int)((scrnhigh*((long)width))/((long)height)); }
124
125 /* fix things for very thin images */
126 if(sh==0) sh++;
127 if(sw==0) sw++;
128
129 *sw_ask=sw; *sh_ask=sh;
130
131 /* so now our zoomed image will be sw x sh */
132 if(width>sw || height>sh)
133 /* it's been reduced - easy, just make 'em fit in less space */
134 {
135 lastyp=-1;
136 pixhigh=(int)(((float)height)/((float)sh)+0.5);
137 pixwide=(int)(((float)width)/((float)sw)+0.5);
138 pixhigh++;
139 pixwide++;
140 for(y=0;y<height;y++)
141 {
142 yp=(y*sh)/height;
143 if(yp!=lastyp)
144 {
145 yw=y*width;
146 /* we try to resample it a bit */
147 for(x=0;x<width;x++,yw++)
148 {
149 tr=tg=tb=tn=0;
150 for(b=0;(b<pixhigh)&&(y+b<height);b++)
151 for(a=0;(a<pixwide)&&(x+a<width);a++)
152 {
153 tmp2=(yw+a+b*width)*3;
154 tr+=theimage[tmp2 ];
155 tg+=theimage[tmp2+1];
156 tb+=theimage[tmp2+2];
157 tn++;
158 }
159 tr/=tn; tg/=tn; tb/=tn;
160 xypos=3*(((x*sw)/width)+yp*scrnwide);
161 rline[xypos]=tr;
162 rline[xypos+1]=tg;
163 rline[xypos+2]=tb;
164 }
165 lastyp=yp;
166 }
167 }
168 }
169 else
170 /* we just leave it the same size */
171 {
172 *sw_ask=width; *sh_ask=height;
173 for(y=0;y<height;y++)
174 for(x=0;x<width;x++)
175 {
176 c=(y*width+x)*3;
177 rline[3*(y*scrnwide+x) ]=theimage[c ];
178 rline[3*(y*scrnwide+x)+1]=theimage[c+1];
179 rline[3*(y*scrnwide+x)+2]=theimage[c+2];
180 }
181 }
182
183 if(crunched) free(crunched);
184
185 return(rline);
186 }