1 #include "config.h"
2 
3 #include <string.h>
4 #include <stdlib.h>
5 
6 #if TIME_WITH_SYS_TIME
7 # include <sys/time.h>
8 # include <time.h>
9 #else
10 # if HAVE_SYS_TIME_H
11 #  include <sys/time.h>
12 # else
13 #  include <time.h>
14 # endif
15 #endif
16 
17 /****h* libAfterImage/tutorials/ASTile
18  * NAME
19  * ASTile
20  * SYNOPSIS
21  * Simple program based on libAfterImage to tile and tint image.
22  * DESCRIPTION
23  * All we want to do here is to get image filename, tint color and
24  * desired geometry from the command line. We then load this image, and
25  * proceed on to tiling it based on parameters. Tiling geometry
26  * specifies rectangular shape on limitless plane on which original
27  * image is tiled. While we are at tiling the image we also tint it to
28  * specified color, or to some random value derived from the current
29  * time in seconds elapsed since 1971.
30  * We then display the result in simple window.
31  * After that we would want to wait, until user closes our window.
32  *
33  * In this tutorial we will only explain new steps, not described in
34  * previous tutorial. New steps described in this tutorial are :
35  * ASTile.1. Parsing ARGB32 tinting color.
36  * ASTile.2. Parsing geometry spec.
37  * ASTile.3. Tiling and tinting ASImage.
38  * SEE ALSO
39  * ASView - explanation of basic steps needed to use libAfterImage and
40  *          some other simple things.
41  * SOURCE
42  */
43 
44 #include "../afterbase.h"
45 #include "../afterimage.h"
46 #include "common.h"
47 
usage()48 void usage()
49 {
50 	printf( "Usage: astile [-h]|[[-g geometry][-t tint_color] image]\n");
51 	printf( "Where: image    - source image filename.\n");
52 	printf( "       geometry - width and height of the resulting image,\n");
53 	printf( "                  and x, y of the origin of the tiling on "
54 			"source image.\n");
55 	printf( "       tint_color - color to tint image with.( defaults to "
56 			"current time :)\n");
57 }
58 
main(int argc,char * argv[])59 int main(int argc, char* argv[])
60 {
61 	Window w ;
62 	Display *dpy = NULL;
63 	ASVisual *asv ;
64 	int screen = 0, depth = 0;
65 	char *image_file = "rose512.jpg" ;
66 	ARGB32 tint_color = time(NULL);
67 	int tile_x, tile_y, geom_flags = 0;
68 	unsigned int tile_width, tile_height ;
69 	ASImage *im ;
70 
71 	/* see ASView.1 : */
72 	set_application_name( argv[0] );
73 
74 #ifndef X_DISPLAY_MISSING
75 	/* parse_argb_color can only be used after display is open,
76 	   otherwise we are limited to colors defined as ARGB values : */
77   	dpy = XOpenDisplay(NULL);
78 	_XA_WM_DELETE_WINDOW = XInternAtom( dpy, "WM_DELETE_WINDOW", False);
79 	screen = DefaultScreen(dpy);
80 	depth = DefaultDepth( dpy, screen );
81 #endif
82 
83 	if( argc > 1 )
84 	{
85 		int i ;
86 
87 		if( strncmp( argv[1], "-h", 2 ) == 0 )
88 		{
89 			usage();
90 			return 0;
91 		}
92 
93 		for( i = 1 ; i < argc ; i++ )
94 		{
95 			if( argv[i][0] == '-' && i < argc-1 )
96 			{
97 				switch(argv[i][1])
98 				{
99 					case 't' :			/* see ASTile.1 : */
100 						if( parse_argb_color( argv[i+1], &tint_color ) ==
101 							argv[i+1] )
102 							show_warning( "unable to parse tint color - "
103 										  "default used: #%8.8lX",
104 				            			  (unsigned long)tint_color );
105 					    break ;
106 					case 'g' :   		/* see ASTile.2 : */
107 	    				geom_flags = XParseGeometry( argv[i+1],
108 							                         &tile_x, &tile_y,
109 		        				        			 &tile_width,
110 													 &tile_height );
111 					    break ;
112 				}
113 				++i ;
114 			}else
115 				image_file = argv[i] ;
116 		}
117 	}else
118 	{
119 		show_warning( "no image file or tint color specified - "
120 					  "defaults used: \"%s\" #%8.8lX",
121 		              image_file, (unsigned long)tint_color );
122 		usage();
123 	}
124 
125 	/* see ASView.2 : */
126 	im = file2ASImage( image_file, 0xFFFFFFFF, SCREEN_GAMMA, 0, getenv("IMAGE_PATH"), NULL );
127 
128 	/* Making sure tiling geometry is sane : */
129 	if( !get_flags(geom_flags, XValue ) )
130 		tile_x = im->width/2 ;
131 	if( !get_flags(geom_flags, YValue ) )
132 		tile_y = im->height/2 ;
133 	if( !get_flags(geom_flags, WidthValue ) )
134 		tile_width = im->width*2 ;
135 	if( !get_flags(geom_flags, HeightValue ) )
136 		tile_height = im->height*2;
137 	printf( "%s: tiling image \"%s\" to "
138 			"%dx%d%+d%+d tinting with #%8.8lX\n",
139 		    get_application_name(), image_file, tile_width, tile_height,
140 			tile_x, tile_y, (unsigned long)tint_color );
141 
142 	if( im != NULL )
143 	{
144 		/* see ASView.3 : */
145 		asv = create_asvisual( dpy, screen, depth, NULL );
146 		w = None ;
147 #ifndef X_DISPLAY_MISSING
148 		/* see ASView.4 : */
149 		w = create_top_level_window( asv, DefaultRootWindow(dpy), 32, 32,
150 			                         tile_width, tile_height, 1, 0, NULL,
151 									 "ASTile", image_file );
152 		if( w != None )
153 		{
154 			Pixmap p ;
155 			ASImage *tinted_im ;
156 
157 	  		XMapRaised   (dpy, w);
158 			/* see ASTile.3 : */
159 			tinted_im = tile_asimage( asv, im, tile_x, tile_y,
160 				                      tile_width, tile_height,
161 				                      tint_color, ASA_XImage, 0,
162 									  ASIMAGE_QUALITY_TOP );
163 			destroy_asimage( &im );
164 			/* see ASView.5 : */
165 			p = asimage2pixmap( asv, DefaultRootWindow(dpy), tinted_im,
166 				                NULL, True );
167 			destroy_asimage( &tinted_im );
168 			/* see common.c: set_window_background_and_free() : */
169 			p = set_window_background_and_free( w, p );
170 		}
171 		/* see common.c: wait_closedown() : */
172 		wait_closedown(w);
173 		dpy = NULL;
174 #else
175 		{
176 			ASImage *tinted_im ;
177 			/* see ASTile.3 : */
178 			tinted_im = tile_asimage( asv, im, tile_x, tile_y,
179 				                      tile_width, tile_height,
180 				                      tint_color, ASA_ASImage, 0,
181 									  ASIMAGE_QUALITY_TOP );
182 			destroy_asimage( &im );
183 			/* writing result into the file */
184 			ASImage2file( tinted_im, NULL, "astile.jpg", ASIT_Jpeg, NULL );
185 			destroy_asimage( &tinted_im );
186 		}
187 #endif
188 	}
189     return 0 ;
190 }
191 /**************/
192 
193 /****f* libAfterImage/tutorials/ASTile.1 [3.1]
194  * SYNOPSIS
195  * Step 1. Color parsing.
196  * DESCRIPTION
197  * libAfterImage utilizes function provided by libAfterBase for color
198  * parsing. In case libAfterBase is unavailable - libAfterImage
199  * includes its own copy of that function. This function differs from
200  * standard XParseColor in a way that it allows for parsing of alpha
201  * channel in addition to red, green and blue. It autodetects if value
202  * include alpha channel or not, using the following logic:
203  * If number of hex digits in color spec is divisible by 4 and is not
204  * equal to 12 then first digits are treated as alpha channel.
205  * In case named color is specified or now apha channel is specified
206  * alpha value of 0xFF will be used, marking this color as solid.
207  * EXAMPLE
208  *     if( parse_argb_color( argv[i+1], &tint_color ) == argv[i+1] )
209  * 	       show_warning( "unable to parse tint color - default used: #%8.8X",
210  *                        tint_color );
211  * NOTES
212  * On success parse_argb_color returns pointer to the character
213  * immidiately following color specification in original string.
214  * Therefore test for returned value to be equal to original string will
215  * can be used to detect error.
216  * SEE ALSO
217  * libAfterBase, parse_argb_color(), ARGB32
218  *******/
219 /****f* libAfterImage/tutorials/ASTile.2 [3.2]
220  * SYNOPSIS
221  * Step 2. Parsing the geometry.
222  * DESCRIPTION
223  * Geometry can be specified in WIDTHxHEIGHT+X+Y format. Accordingly we
224  * use standard X function to parse it: XParseGeometry. Returned flags
225  * tell us what values has been specified. We only have to fill the rest
226  * with some sensible defaults. Default x is width/2, y is height/2, and
227  * default size is same as image's width.
228  * EXAMPLE
229  *     geom_flags = XParseGeometry ( argv[i+1], &tile_x, &tile_y,
230  *                                   &tile_width, &tile_height );
231  * SEE ALSO
232  * ASScale.1
233  ********/
234 /****f* libAfterImage/tutorials/ASTile.3 [3.3]
235  * SYNOPSIS
236  * Step 3. Actuall tiling of the image.
237  * DESCRIPTION
238  * Actuall tiling is quite simple - just call tile_asimage and it will
239  * generate new ASImage containing tiled and tinted image. For the sake
240  * of example we set quality to TOP, but normally GOOD quality is quite
241  * sufficient, and is a default. Again, compression is set to 0 since we
242  * do not intend to store image for long time. Even better we don't need
243  * to store it at all - all we need is XImage, so we can transfer it to
244  * the server easily. That is why to_xim argument is set to ASA_XImage.
245  * As the result obtained ASImage will not have any data in its buffers,
246  * but it will have ximage member set to point to valid XImage.
247  * Subsequently we enjoy that convinience, by setting use_cached to True
248  * in call to asimage2pixmap(). That ought to save us a lot of processing.
249  *
250  * Tinting works in both directions - it can increase intensity of the
251  * color or decrease it. If any particular channel of the tint_color is
252  * greater then 127 then intensity is increased, otherwise its decreased.
253  * EXAMPLE
254  * tinted_im = tile_asimage( asv, im, tile_x, tile_y,
255  *                         tile_width, tile_height,
256  *                         tint_color,
257  *                         ASA_XImage, 0, ASIMAGE_QUALITY_TOP );
258  * destroy_asimage( &im );
259  * NOTES
260  * SEE ALSO
261  * tile_asimage().
262  ********/
263