File: asscale.c

package info (click to toggle)
afterstep 2.2.12-19
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 33,168 kB
  • sloc: ansic: 201,695; sh: 5,894; xml: 3,721; makefile: 2,095; perl: 1,558; cpp: 811
file content (233 lines) | stat: -rw-r--r-- 8,100 bytes parent folder | download | duplicates (7)
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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
#include "config.h"

#include <string.h>
#include <stdlib.h>

/****h* libAfterImage/tutorials/ASScale
 * NAME 
 * ASScale
 * SYNOPSIS
 * Simple program based on libAfterImage to scale an image.
 * DESCRIPTION
 * We will load image and scale it up to new size, specified as command
 * line arguments
 * We then display the result in simple window.
 * After that we would want to wait, until user closes our window.
 *
 * In this tutorial we will only explain new steps, not described in
 * previous tutorial. New steps described in this tutorial are :
 * ASScale.1. Parsing geometry spec.
 * ASScale.2. Scaling ASImage.
 * SEE ALSO
 * Tutorial 1: ASView - explanation of basic steps needed to use
 *                      libAfterImage and some other simple things.
 * SOURCE
 */

#include "../afterbase.h"
#include "../afterimage.h"
#include "common.h"

void usage()
{
	printf( "Usage: asscale [-h]|[image [WIDTH[xHEIGHT]]]\n");
	printf( "Where: image - is image filename.\n");
	printf( "       WIDTH - width to scale image to.( Naturally :)\n");
	printf( "       HEIGHT- height to scale image to.\n");
}

int main(int argc, char* argv[])
{
	char *image_file = "rose512.jpg" ;
	int dummy, geom_flags = 0;
	unsigned int to_width, to_height ;
	ASImage *im ;
	int clip_x = 0, clip_y = 0, clip_width = 0, clip_height = 0 ;
	int slice_x_start = 0, slice_x_end = 0, slice_y_start = 0, slice_y_end = 0 ;
	Bool slice_scale = False ;
	Display *dpy = NULL;

	/* see ASView.1 : */
	set_application_name( argv[0] );

	if( argc > 1 )
	{
		int i = 2;
		if( strncmp( argv[1], "-h", 2 ) == 0 )
		{
			usage();
			return 0;
		}
		image_file = argv[1] ;
		if( argc > 2 )   /* see ASScale.1 : */
			geom_flags = XParseGeometry( argv[2], &dummy, &dummy,
			                             &to_width, &to_height );
	
		while( ++i < argc )
		{	
			if( strncmp( argv[i], "-sx1", 4 ) == 0 && i+1 < argc )
				slice_x_start = atoi(argv[++i]) ;
			else if( strncmp( argv[i], "-sx2", 4 ) == 0 && i+1 < argc )
				slice_x_end = atoi(argv[++i]) ;
			else if( strncmp( argv[i], "-sy1", 4 ) == 0 && i+1 < argc )
				slice_y_start = atoi(argv[++i]) ;
			else if( strncmp( argv[i], "-sy2", 4 ) == 0 && i+1 < argc )
				slice_y_end = atoi(argv[++i]) ;
			else if( strncmp( argv[i], "-cx", 4 ) == 0 && i+1 < argc )
				clip_x = atoi(argv[++i]) ;
			else if( strncmp( argv[i], "-cy", 4 ) == 0 && i+1 < argc )
				clip_y = atoi(argv[++i]) ;
			else if( strncmp( argv[i], "-cwidth", 7 ) == 0 && i+1 < argc )
				clip_width = atoi(argv[++i]) ;
			else if( strncmp( argv[i], "-cheight", 8 ) == 0 && i+1 < argc )
				clip_height = atoi(argv[++i]) ;
			else if( strncmp( argv[i], "-ss", 3 ) == 0 )
				slice_scale = True ;
		}
			   
	
	}else
	{
		show_warning( "no image file or scale geometry - defaults used:"
					  " \"%s\" ",
		              image_file );
		usage();
	}
	/* see ASView.2 : */
	im = file2ASImage( image_file, 0xFFFFFFFF, SCREEN_GAMMA, 0, getenv("IMAGE_PATH"), NULL );

	if( im != NULL )
	{
		ASVisual *asv ;
		ASImage *scaled_im ;
		/* Making sure tiling geometry is sane : */
		if( !get_flags(geom_flags, WidthValue ) )
			to_width = im->width*2 ;
		if( !get_flags(geom_flags, HeightValue ) )
			to_height = im->height*2;
		printf( "%s: scaling image \"%s\" to %dx%d by factor of %fx%f\n",
			    get_application_name(), image_file, to_width, to_height,
				(double)to_width/(double)(im->width),
				(double)to_height/(double)(im->height) );

#ifndef X_DISPLAY_MISSING
		{
			Window w ;
			int screen, depth ;

		    dpy = XOpenDisplay(NULL);
			_XA_WM_DELETE_WINDOW = XInternAtom( dpy, 
												"WM_DELETE_WINDOW", 
												False);
			screen = DefaultScreen(dpy);
			depth = DefaultDepth( dpy, screen );
			/* see ASView.3 : */
			asv = create_asvisual( dpy, screen, depth, NULL );
			/* see ASView.4 : */
			w = create_top_level_window( asv, DefaultRootWindow(dpy), 
										 32, 32,
				                         to_width, to_height, 1, 0, NULL,
										 "ASScale", image_file );
			if( w != None )
			{
				Pixmap p ;

		  		XMapRaised   (dpy, w);
				/* see ASScale.2 : */
				if( slice_x_start == 0 && slice_x_end == 0 && 
					slice_y_start == 0 && slice_y_end == 0 )
				{
					scaled_im = scale_asimage2( asv, im,
												clip_x, clip_y, clip_width, clip_height, 
												to_width, to_height,
					                       	ASA_XImage, 0, 
										   	ASIMAGE_QUALITY_DEFAULT );
				}else
				{
					scaled_im = slice_asimage2( asv, im, slice_x_start, slice_x_end, 
											   slice_y_start, slice_y_end,
											to_width, to_height, slice_scale,
					                       	ASA_XImage, 0, 
										   	ASIMAGE_QUALITY_DEFAULT );
				}					   
				destroy_asimage( &im );
				/* see ASView.5 : */
				p = asimage2pixmap(asv, DefaultRootWindow(dpy), scaled_im,
					                NULL, True );
				/* print_storage(NULL); */
				destroy_asimage( &scaled_im );
				/* see common.c: set_window_background_and_free() : */
				p = set_window_background_and_free( w, p );
			}
			/* see common.c: wait_closedown() : */
			wait_closedown(w);
			dpy = NULL;			
		}
#else
		asv = create_asvisual( NULL, 0, 0, NULL );
		scaled_im = scale_asimage(asv, im, to_width, to_height,
			                      ASA_ASImage, 0, 
								  ASIMAGE_QUALITY_DEFAULT );
		/* writing result into the file */
		ASImage2file( scaled_im, NULL, "asscale.jpg", ASIT_Jpeg, NULL );
		destroy_asimage( &scaled_im );
		destroy_asimage( &im );
#endif
	}
    return 0 ;
}
/**************/

/****f* libAfterImage/tutorials/ASScale.1 [2.1]
 * SYNOPSIS
 * Step 1. Parsing the geometry.
 * DESCRIPTION
 * Geometry can be specified in WIDTHxHEIGHT+X+Y format. Accordingly we
 * use standard X function to parse it: XParseGeometry. Returned flags
 * tell us what values has been specified. Since we only need size -
 * we check if it is specified and if not - simply default it to twice
 * as big as original image. Accordingly we use dummy variable to pass
 * to XParseGeometry.
 * EXAMPLE
 *     geom_flags = XParseGeometry( argv[3], &dummy, &dummy,
 *                                  &to_width, &to_height );
 ********/
/****f* libAfterImage/tutorials/ASScale.2 [2.2]
 * SYNOPSIS
 * Step 2. Actual scaling the image.
 * DESCRIPTION
 * scale_asimage() scales image both up and down, and is very easy to
 * use - just pass it new size. In this example we use default quality.
 * Default is equivalent to GOOD which should be sufficient in
 * most cases. Compression is set to 0 since we do not intend to store
 * image for long time. Even better - we don't need to store it at all -
 * all we need is XImage, so we can transfer it to the server easily.
 * That is why to_xim argument is set to ASA_XImage. As the result obtained
 * ASImage will not have any data in its buffers, but it will have
 * ximage member set to point to valid XImage. Subsequently we enjoy
 * that convenience, by setting use_cached to True in call to
 * asimage2pixmap. That ought to save us a lot of processing.
 *
 * Scaling algorithm is rather sophisticated and is implementing 4 point
 * interpolation. Which basically means that we try to approximate each
 * missing point as an extension of the trend of 4 neighboring points -
 * two on each side. Closest neighbor's have more weight then outside
 * ones. 2D scaling is performed by scaling each scanline first, and
 * then interpolating missing scanlines.
 * Scaling down is somewhat skimpier, as it amounts to simple averaging
 * of the multiple pixels. All calculations are done in integer math on
 * per channel basis, and with precision 24.8 bits per channel per pixel.
 *
 * EXAMPLE
 *     scaled_im = scale_asimage( asv, im, to_width, to_height,
 * 	                           ASA_XImage, 0, ASIMAGE_QUALITY_DEFAULT );
 *     destroy_asimage( &im );
 * NOTES
 * Scaling image up to very large height is much slower then to same
 * width due to algorithm specifics. Yet even on inferior hardware it
 * yields decent speeds.
 * When we successfully scaled image - we no longer need the original -
 * getting rid of it so it does not clog memory.
 * SEE ALSO
 * scale_asimage().
 ********/