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