1asscale(1) AfterStep X11 window manager asscale(1)
2
3
4
6 asscale - demonstrates image loading and scaling libAfterImage/tutoriā
7 als/ASScale
8
11 Simple program based on libAfterImage to scale an image.
12
14 We will load image and scale it up to new size, specified as command
15 line arguments
16 We then display the result in simple window.
17 After that we would want to wait, until user closes our window.
18
19 In this tutorial we will only explain new steps, not described in
20 previous tutorial. New steps described in this tutorial are :
21 ASScale.1. Parsing geometry spec.
22 ASScale.2. Scaling ASImage.
23
25 Tutorial 1: ASView - explanation of basic steps needed to use
26 libAfterImage and some other simple things.
27
29 Source :
30 #include "../afterbase.h"
31 #include "../afterimage.h"
32 #include "common.h"
33
34 void usage()
35 {
36 printf( "Usage: asscale [-h]|[image [WIDTH[xHEIGHT]]]0);
37 printf( "Where: image - is image filename.0);
38 printf( " WIDTH - width to scale image to.( Naturally :)0);
39 printf( " HEIGHT- height to scale image to.0);
40 }
41
42 int main(int argc, char* argv[])
43 {
44 char *image_file = "rose512.jpg" ;
45 int dummy, geom_flags = 0;
46 unsigned int to_width, to_height ;
47 ASImage *im ;
48 int clip_x = 0, clip_y = 0, clip_width = 0, clip_height = 0 ;
49 int slice_x_start = 0, slice_x_end = 0, slice_y_start = 0, slice_y_end = 0 ;
50 Bool slice_scale = False ;
51
52 /* see ASView.1 : */
53 set_application_name( argv[0] );
54
55 if( argc > 1 )
56 {
57 int i = 2;
58 if( strncmp( argv[1], "-h", 2 ) == 0 )
59 {
60 usage();
61 return 0;
62 }
63 image_file = argv[1] ;
64 if( argc > 2 ) /* see ASScale.1 : */
65 geom_flags = XParseGeometry( argv[2], &dummy, &dummy,
66 &to_width, &to_height );
67
68 while( ++i < argc )
69 {
70 if( strncmp( argv[i], "-sx1", 4 ) == 0 && i+1 < argc )
71 slice_x_start = atoi(argv[++i]) ;
72 else if( strncmp( argv[i], "-sx2", 4 ) == 0 && i+1 < argc )
73 slice_x_end = atoi(argv[++i]) ;
74 else if( strncmp( argv[i], "-sy1", 4 ) == 0 && i+1 < argc )
75 slice_y_start = atoi(argv[++i]) ;
76 else if( strncmp( argv[i], "-sy2", 4 ) == 0 && i+1 < argc )
77 slice_y_end = atoi(argv[++i]) ;
78 else if( strncmp( argv[i], "-cx", 4 ) == 0 && i+1 < argc )
79 clip_x = atoi(argv[++i]) ;
80 else if( strncmp( argv[i], "-cy", 4 ) == 0 && i+1 < argc )
81 clip_y = atoi(argv[++i]) ;
82 else if( strncmp( argv[i], "-cwidth", 7 ) == 0 && i+1 < argc )
83 clip_width = atoi(argv[++i]) ;
84 else if( strncmp( argv[i], "-cheight", 8 ) == 0 && i+1 < argc )
85 clip_height = atoi(argv[++i]) ;
86 else if( strncmp( argv[i], "-ss", 3 ) == 0 )
87 slice_scale = True ;
88 }
89
90
91 }else
92 {
93 show_warning( "no image file or scale geometry - defaults used:"
94 "
95 image_file );
96 usage();
97 }
98 /* see ASView.2 : */
99 im = file2ASImage( image_file, 0xFFFFFFFF, SCREEN_GAMMA, 0, getenv("IMAGE_PATH"), NULL );
100
101 if( im != NULL )
102 {
103 ASVisual *asv ;
104 ASImage *scaled_im ;
105 /* Making sure tiling geometry is sane : */
106 if( !get_flags(geom_flags, WidthValue ) )
107 to_width = im->width*2 ;
108 if( !get_flags(geom_flags, HeightValue ) )
109 to_height = im->height*2;
110 printf( "%s: scaling image
111 get_application_name(), image_file, to_width, to_height,
112 (double)to_width/(double)(im->width),
113 (double)to_height/(double)(im->height) );
114
115 #ifndef X_DISPLAY_MISSING
116 {
117 Window w ;
118 int screen, depth ;
119
120 dpy = XOpenDisplay(NULL);
121 _XA_WM_DELETE_WINDOW = XInternAtom( dpy,
122 "WM_DELETE_WINDOW",
123 False);
124 screen = DefaultScreen(dpy);
125 depth = DefaultDepth( dpy, screen );
126 /* see ASView.3 : */
127 asv = create_asvisual( dpy, screen, depth, NULL );
128 /* see ASView.4 : */
129 w = create_top_level_window( asv, DefaultRootWindow(dpy),
130 32, 32,
131 to_width, to_height, 1, 0, NULL,
132 "ASScale", image_file );
133 if( w != None )
134 {
135 Pixmap p ;
136
137 XMapRaised (dpy, w);
138 /* see ASScale.2 : */
139 if( slice_x_start == 0 && slice_x_end == 0 &&
140 slice_y_start == 0 && slice_y_end == 0 )
141 {
142 scaled_im = scale_asimage2( asv, im,
143 clip_x, clip_y, clip_width, clip_height,
144 to_width, to_height,
145 ASA_XImage, 0,
146 ASIMAGE_QUALITY_DEFAULT );
147 }else
148 {
149 scaled_im = slice_asimage2( asv, im, slice_x_start, slice_x_end,
150 slice_y_start, slice_y_end,
151 to_width, to_height, slice_scale,
152 ASA_ASImage, 0,
153 ASIMAGE_QUALITY_DEFAULT );
154 }
155 destroy_asimage( &im );
156 /* see ASView.5 : */
157 p = asimage2pixmap(asv, DefaultRootWindow(dpy), scaled_im,
158 NULL, True );
159 /* print_storage(NULL); */
160 destroy_asimage( &scaled_im );
161 /* see common.c: set_window_background_and_free() : */
162 p = set_window_background_and_free( w, p );
163 }
164 /* see common.c: wait_closedown() : */
165 wait_closedown(w);
166 }
167 #else
168 asv = create_asvisual( NULL, 0, 0, NULL );
169 scaled_im = scale_asimage(asv, im, to_width, to_height,
170 ASA_ASImage, 0,
171 ASIMAGE_QUALITY_DEFAULT );
172 /* writing result into the file */
173 ASImage2file( scaled_im, NULL, "asscale.jpg", ASIT_Jpeg, NULL );
174 destroy_asimage( &scaled_im );
175 destroy_asimage( &im );
176 #endif
177 }
178 return 0 ;
179 }
180
182 Step 1. Parsing the geometry.
183
185 Geometry can be specified in WIDTHxHEIGHT+X+Y format. Accordingly we
186 use standard X function to parse it: XParseGeometry. Returned flags
187 tell us what values has been specified. Since we only need size -
188 we check if it is specified and if not - simply default it to twice
189 as big as original image. Accordingly we use dummy variable to pass
190 to XParseGeometry.
191
193 geom_flags = XParseGeometry( argv[3], &dummy, &dummy,
194 &to_width, &to_height );
195
197 Step 2. Actual scaling the image.
198
200 scale_asimage() scales image both up and down, and is very easy to
201 use - just pass it new size. In this example we use default quality.
202 Default is equivalent to GOOD which should be sufficient in
203 most cases. Compression is set to 0 since we do not intend to store
204 image for long time. Even better - we don't need to store it at all -
205 all we need is XImage, so we can transfer it to the server easily.
206 That is why to_xim argument is set to ASA_XImage. As the result obtained
207 ASImage will not have any data in its buffers, but it will have
208 ximage member set to point to valid XImage. Subsequently we enjoy
209 that convenience, by setting use_cached to True in call to
210 asimage2pixmap. That ought to save us alot of processing.
211
212 Scaling algorithm is rather sophisticated and is implementing 4 point
213 interpolation. Which basically means that we try to approximate each
214 missing point as an extension of the trend of 4 neighboring points -
215 two on each side. Closest neighbor's have more weight then outside
216 ones. 2D scaling is performed by scaling each scanline first, and
217 then interpolating missing scanlines.
218 Scaling down is somewhat skimpier, as it amounts to simple averaging
219 of the multiple pixels. All calculations are done in integer math on
220 per channel basis, and with precision 24.8 bits per channel per pixel.
221
223 scaled_im = scale_asimage( asv, im, to_width, to_height,
224 ASA_XImage, 0, ASIMAGE_QUALITY_DEFAULT );
225 destroy_asimage( &im );
226
228 Scaling image up to very large height is much slower then to same
229 width due to algorithm specifics. Yet even on inferior hardware it
230 yields decent speeds.
231 When we successfully scaled image - we no longer need the original -
232 getting rid of it so it does not clog memory.
233
235 scale_asimage().
236
237
238
2393rd Berkeley Distribution AfterStep v.2.2.6 asscale(1)