1 /*
2 * image.c
3 * Yet Another Osuwari Multi for X11
4 * (Create Image Module)
5 */
6
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
10
11 #include <X11/Xlib.h>
12 #include <X11/Xutil.h>
13 #include <X11/Xmd.h> /* �ޥ����ͭ���������CARDPtr�ʤ� */
14
15 /* ����Ū���֤���(̤����ʤ��Ȥ�����) */
16 #ifndef EXIT_SUCCESS
17 #define EXIT_SUCCESS 0
18 #endif
19 #ifndef EXIT_FAILURE
20 #define EXIT_FAILURE 1
21 #endif
22
23 /******** External Value ********/
24
25 extern Display *Disp;
26 extern Colormap MyColorMap;
27
28 /******** Functions Prototype ********/
29
30 unsigned int GetXDepth( );
31 XImage *CreateMyImage( );
32 static void CopyImageFromData32( );
33 static void CopyImageFromData16( );
34 static void CopyImageFromData8( );
35 static void PalettePix32( );
36 static void PalettePix16( );
37 static void PalettePix8( );
38 static int PickNearColor( );
39 Cursor CreateMyCursor( );
40
41 /******** GetXDepth ********
42 * Xü���Υ��顼�⡼�ɤ�����
43 */
GetXDepth(disp)44 unsigned int GetXDepth( disp )
45 Display *disp;
46 {
47
48 return DefaultDepth(disp, 0);
49 XVisualInfo xvi_template;
50 XVisualInfo *p_xvi;
51 int n_item, i;
52 int depth = 0;
53
54 /**** Visual Class ���� ****
55 * #define StaticGray 0
56 * #define GrayScale 1
57 * #define StaticColor 2
58 * #define PseudoColor 3
59 * #define TrueColor 4
60 * #define DirectColor 5
61 ****/
62
63 memset( &xvi_template, 0, sizeof(XVisualInfo) );
64 /* xvi_template.depth = 8; /**/
65 /* xvi_template.depth = PseudoColor; /**/
66
67 p_xvi = XGetVisualInfo( disp, VisualNoMask,
68 &xvi_template, &n_item );
69
70 for( i=0; i<n_item; i++ )
71 {
72 /* printf( "INFO: %d: depth=%d, class=%d\n",
73 i, p_xvi[i].depth, p_xvi[i].class ); /* DEBUG */
74
75 if( depth < p_xvi[i].depth ) /* ���������� */
76 { depth = p_xvi[i].depth;
77 }
78 }
79
80 XFree( p_xvi );
81 return depth;
82 }
83
84 /******** CreateMyImage ********
85 * �ӥåȥǡ������� XImage����������
86 */
87
CreateMyImage(width,height,palette,ncolor,depth,data)88 XImage *CreateMyImage( width, height, palette, ncolor, depth, data )
89 int width;
90 int height;
91 unsigned char *palette;
92 int ncolor;
93 unsigned int depth;
94 unsigned char *data;
95 {
96 XImage *image;
97 XColor *color_tbl;
98 int index;
99 int pixel_size, padding;
100
101 /* XImage���������� */
102 { int bitmap_pad, line_bytes;
103
104 if( depth <= 8 )
105 { bitmap_pad = 8;
106 line_bytes = width;
107 }else
108 { bitmap_pad = 32;
109 line_bytes = 0;
110 }
111
112 image = XCreateImage( Disp,
113 DefaultVisual( Disp, DefaultScreen(Disp) ),
114 depth, ZPixmap, 0,
115 None, /* <- �ޤ����Υǡ������������� */
116 width, height,
117 bitmap_pad, line_bytes
118 );
119 if( image == NULL )
120 { fprintf( stderr, "ERROR: Can't allocate memory for XImage.\n" );
121 return NULL;
122 }
123
124 image->data = (char*)malloc( image->bytes_per_line * height );
125 if( image->data == NULL )
126 { fprintf( stderr, "ERROR: Can't allocate memory for image data.\n" );
127 return NULL;
128 }
129 }
130
131 pixel_size = image->bytes_per_line / width;
132 padding = image->bytes_per_line - (width * pixel_size);
133
134 /* data -> image->data �˥��ԡ� */
135 if( pixel_size >= 4 )
136 { CopyImageFromData32( image->data, data, width, height, padding );
137 }
138 else if( pixel_size >= 2 )
139 { CopyImageFromData16( image->data, data, width, height, padding );
140 }
141 else
142 { CopyImageFromData8( image->data, data, width, height, padding );
143 }
144
145 /* ��(���顼����)�γ��� */
146 color_tbl = (XColor*)malloc( sizeof(XColor) * ncolor );
147 if( color_tbl == NULL )
148 { fprintf( stderr, "ERROR: Can't allocate memory for XColor.\n" );
149 return NULL;
150 }
151
152 for( index = 0; index < ncolor; index++ )
153 {
154 color_tbl[ index ].red = palette[ index * 3 ] << 8;
155 color_tbl[ index ].green = palette[ index * 3 + 1 ] << 8;
156 color_tbl[ index ].blue = palette[ index * 3 + 2 ] << 8;
157
158 if( XAllocColor( Disp, MyColorMap, &color_tbl[index] ) == 0 )
159 {
160 /* ��(���顼����)�γ��ݤ˼��Ԥ����� */
161 /* printf( "INFO: Not enough ColorCell, using Near Color.\n" ); /* DEBUG */
162
163 if( PickNearColor( &palette[index], &color_tbl[index] ) != EXIT_SUCCESS )
164 { fprintf( stderr, "ERROR: Internal Color Allocate Error!\n" );
165 }
166 }
167 }
168
169 /* �ԥ�����ǡ����� XAllocColor �����ԥ������ֹ�˽����� */
170 if( pixel_size >= 4 )
171 { PalettePix32( image->data, color_tbl, width, height, padding );
172 }
173 else if( pixel_size >= 2 )
174 { PalettePix16( image->data, color_tbl, width, height, padding );
175 }
176 else
177 { PalettePix8( image->data, color_tbl, width, height, padding );
178 }
179
180 /* ���Ȥ��ޤ� */
181 free( (char*)color_tbl );
182
183 return( image );
184 }
185
186 /******** CopyImageFromData ********
187 * data -> image->data �˥��ԡ�
188 * 8, 16, 32bit ������
189 * ��Ȥˤʤ�����ǡ����ϣ����� (4bit)
190 */
CopyImageFromData32(dst_data,src_data,width,height,pad)191 static void CopyImageFromData32( dst_data, src_data, width, height, pad )
192 CARD32 *dst_data;
193 unsigned char *src_data;
194 int width;
195 int height;
196 int pad;
197 {
198 int x, y;
199 Bool lower = 0;
200
201 for( y=0 ; y<height ; y++ )
202 { for( x=0; x<width; x++ )
203 {
204 #if 0
205 *dst_data++ = *src_data++; /* DEBUG * 256���ǡ����� */
206 #else
207 if( lower == 0 )
208 { *dst_data++ = (*src_data >> 4);
209 }else
210 { *dst_data++ = *src_data & 0x0F;
211 src_data++;
212 }
213 lower ^= 0x01;
214 #endif
215 }
216 dst_data = (CARD32*)( (char*)dst_data + pad );
217 }
218 }
219
CopyImageFromData16(dst_data,src_data,width,height,pad)220 static void CopyImageFromData16( dst_data, src_data, width, height, pad )
221 CARD16 *dst_data;
222 unsigned char *src_data;
223 int width;
224 int height;
225 int pad;
226 {
227 int x, y;
228 Bool lower = 0;
229
230 for( y=0 ; y<height ; y++ )
231 { for( x=0; x<width; x++ )
232 {
233 #if 0
234 *dst_data++ = *src_data++; /* DEBUG * 256�ǡ������� */
235 #else
236 if( lower == 0 )
237 { *dst_data++ = (*src_data >> 4);
238 }else
239 { *dst_data++ = *src_data & 0x0F;
240 src_data++;
241 }
242 lower ^= 0x01;
243 #endif
244 }
245 dst_data = (CARD16*)( (char*)dst_data + pad );
246 }
247 }
248
CopyImageFromData8(dst_data,src_data,width,height,pad)249 static void CopyImageFromData8( dst_data, src_data, width, height, pad )
250 CARD8 *dst_data;
251 unsigned char *src_data;
252 int width;
253 int height;
254 int pad;
255 {
256 int x, y;
257 Bool lower = 0;
258
259 for( y=0 ; y<height ; y++ )
260 { for( x=0; x<width; x++ )
261 {
262 #if 0
263 *dst_data++ = *src_data++; /* DEBUG * 256�ǡ������� */
264 #else
265 if( lower == 0 )
266 { *dst_data++ = (*src_data >> 4);
267 }else
268 { *dst_data++ = *src_data & 0x0F;
269 src_data++;
270 }
271 lower ^= 0x01;
272 #endif
273 }
274 dst_data = (char*)dst_data + pad ;
275 }
276 }
277
278 /******** PalettePix ********
279 * �ԥ�����ǡ����� XAllocColor �����ԥ������ֹ�˽�����
280 * 8, 16, 32bit ������
281 */
PalettePix32(dst_data,color_tbl,width,height,pad)282 static void PalettePix32( dst_data, color_tbl, width, height, pad )
283 CARD32 *dst_data;
284 XColor *color_tbl;
285 int width;
286 int height;
287 int pad;
288 {
289 int x, y;
290
291 for (y = 0; y < height; y++)
292 { for (x = 0; x < width; x++)
293 { *dst_data = color_tbl[ (CARD8)*dst_data ].pixel;
294 dst_data++;
295 }
296 dst_data = (CARD32*)( (char*)dst_data + pad );
297 }
298 }
299
PalettePix16(dst_data,color_tbl,width,height,pad)300 static void PalettePix16( dst_data, color_tbl, width, height, pad )
301 CARD16 *dst_data;
302 XColor *color_tbl;
303 int width;
304 int height;
305 int pad;
306 {
307 int x, y;
308
309 for (y = 0; y < height; y++)
310 { for (x = 0; x < width; x++)
311 { *dst_data = color_tbl[ (CARD8)*dst_data ].pixel;
312 dst_data++;
313 }
314 dst_data = (CARD16*)( (char*)dst_data + pad );
315 }
316 }
317
PalettePix8(dst_data,color_tbl,width,height,pad)318 static void PalettePix8( dst_data, color_tbl, width, height, pad )
319 CARD8 *dst_data;
320 XColor *color_tbl;
321 int width;
322 int height;
323 int pad;
324 {
325 int x, y;
326
327 for (y = 0; y < height; y++)
328 { for (x = 0; x < width; x++)
329 { *dst_data = color_tbl[ (CARD8)*dst_data ].pixel;
330 dst_data++;
331 }
332 dst_data = (char*)dst_data + pad ;
333 }
334 }
335
336 /******** PickNearColor ********
337 * ���顼�ޥåפˤ���Ǥ�ᤤ��������
338 * ��(���顼����)�γ��ݤ˼��Ԥ������ν���
339 */
PickNearColor(palette,color_return)340 static int PickNearColor( palette, color_return )
341 unsigned char *palette;
342 XColor *color_return;
343 {
344 XColor color_tbl[ 256 ];
345 int n_cmap_color;
346 long dist, nearest;
347 int nearest_index;
348 int red_dist, green_dist, blue_dist;
349 int i;
350
351 /* ���ԤΥ��顼�ޥå�ο�����Ф� */
352 { int dCells = DisplayCells( Disp, DefaultScreen(Disp) );
353 n_cmap_color = (dCells < 256) ? dCells : 256 ;
354 }
355 for( i = 0; i < n_cmap_color; i++ )
356 { color_tbl[i].pixel = (unsigned long) i;
357 }
358
359 XQueryColors( Disp, MyColorMap, color_tbl, n_cmap_color );
360
361 /* ��ΥŪ�˺Ǥ�ᤤ���Υԥ������ͤ� */
362 nearest = 0xFF * 0xFF * 3 + 1;
363 nearest_index = -1;
364
365 for( i=0; i< n_cmap_color; i++ )
366 {
367 red_dist = palette[ 0 ] - (color_tbl[i].red >> 8);
368 green_dist = palette[ 1 ] - (color_tbl[i].green >> 8);
369 blue_dist = palette[ 2 ] - (color_tbl[i].blue >> 8);
370
371 dist = (red_dist * red_dist) +
372 (green_dist * green_dist) +
373 (blue_dist * blue_dist);
374
375 if( dist < nearest )
376 { nearest = dist;
377 nearest_index = i;
378 }
379 }
380
381 if( nearest_index < 0 )
382 { return EXIT_FAILURE ;
383 }
384
385 color_return->pixel = color_tbl[ nearest_index ].pixel;
386 color_return->red = color_tbl[ nearest_index ].red;
387 color_return->green = color_tbl[ nearest_index ].green;
388 color_return->blue = color_tbl[ nearest_index ].blue;
389
390 return EXIT_SUCCESS ;
391 }
392
393 /******** CreateMyCursor *******
394 * �ӥåȥޥåץǡ������饫���������������
395 * (�������ϣ�������������)
396 */
CreateMyCursor(win,f_bits,b_bits)397 Cursor CreateMyCursor( win, f_bits, b_bits )
398 Window win;
399 unsigned char *f_bits;
400 unsigned char *b_bits;
401 {
402 Cursor cur;
403 Pixmap front;
404 Pixmap mask;
405 XColor c1, c2, cc;
406 #define CURSOR_SIZE 32
407
408 XAllocNamedColor( Disp, MyColorMap, "black", &c1, &cc );
409 XAllocNamedColor( Disp, MyColorMap, "white", &c2, &cc );
410
411 front = XCreateBitmapFromData( Disp, win,
412 f_bits, CURSOR_SIZE, CURSOR_SIZE );
413 mask = XCreateBitmapFromData( Disp, win,
414 b_bits, CURSOR_SIZE, CURSOR_SIZE );
415
416 cur = XCreatePixmapCursor( Disp, front, mask, &c1, &c2, 0, 0 );
417
418 XFreePixmap( Disp, front );
419 XFreePixmap( Disp, mask );
420
421 return cur;
422 }
423
424 /******** End of File ********/
425