File: color_shifts.c

package info (click to toggle)
garlic 1.6-3
  • links: PTS, VCS
  • area: main
  • in suites: bullseye, buster, sid
  • size: 4,516 kB
  • sloc: ansic: 52,465; makefile: 2,254
file content (211 lines) | stat: -rw-r--r-- 5,766 bytes parent folder | download | duplicates (6)
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
/* Copyright (C) 2000 Damir Zucic */

/*=============================================================================

				color_shifts.c

Purpose:
	Prepare left and right color shift for RGB color components. Each
	color component (red, green and blue) must be shifted properly to
	prepare the pixel value for a given RGB triplet.  Every component
	should be shifted first to the right, to remove unused bits, then
	to the left,  to put the remaining bits into the proper position.
	This function prepares  the shifts for all three  RGB components.
	Shifts are used later to prepare colors  for drawing.  Masks from
	XVisualInfo structure (part of GUIS structure) are used as input.

Input:
	(1) Pointer to GUIS structure.  Input data are there; output data
	    will be stored to the same structure.

Output:
	(1) Data added to GUIS structure.
	(2) Return value.

Return value:
	(1) Positive on success.
	(2) Negative on failure.

=============================================================================*/

#include <stdio.h>

#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xos.h>
#include <X11/Xatom.h>

#include "defines.h"
#include "typedefs.h"

/*======function prototypes:=================================================*/

void		ErrorMessage_ (char *, char *, char *,
			       char *, char *, char *, char *);

/*======prepare color shifts:================================================*/

int PrepareColorShifts_ (GUIS *guiSP)
{
XColor		colorS;
int		color_component_size, pixel_value_size;
unsigned long	mask, lowest_bit_mask = 1;
int		lowest_bit_position, highest_bit_position, bitsN;
int		i;

/* Prepare the color component size int bits (16 expected): */
color_component_size = 8 * sizeof (colorS.red);

/* Prepare the pixel value size in bits (32 expected): */
pixel_value_size = 8 * sizeof (colorS.pixel);

/*---------------------------------------------------------------------------*/

/* Find the shifts for red color component: */

/** Check the red mask: **/
if (guiSP->visual_infoS.red_mask == 0)
	{
	ErrorMessage_ ("garlic", "PrepareColorShifts_", "",
		       "Red mask equal to zero!\n", "", "", "");
	return -1;
	}

/** The least significant bit position: **/
mask = guiSP->visual_infoS.red_mask;
lowest_bit_position = -1;
for (i = 0; i < pixel_value_size; i++)
	{
	if ((mask >> i) & lowest_bit_mask)
		{
		lowest_bit_position = i;
		break;
		}
	}

/** Check was it found at all: **/
if (lowest_bit_position < 0)
	{
	ErrorMessage_ ("garlic", "PrepareColorShifts_", "",
		       "Unable to find the lowest bit position",
		       " in the red mask!\n", "", "");
	return -2;
	}

/** The most significant bit position: **/
mask = guiSP->visual_infoS.red_mask;
highest_bit_position = lowest_bit_position;
for (i = lowest_bit_position; i < pixel_value_size; i++)
	{
	if (!((mask >> i) & lowest_bit_mask)) break;
	highest_bit_position = i;
	}

/** Prepare the shifts: **/
bitsN = highest_bit_position - lowest_bit_position + 1;
guiSP->red_right_shift  = color_component_size - bitsN;
guiSP->red_left_shift = lowest_bit_position;

/*---------------------------------------------------------------------------*/

/* Find the shifts for green color component: */

/** Check the green mask: **/
if (guiSP->visual_infoS.green_mask == 0)
	{
	ErrorMessage_ ("garlic", "PrepareColorShifts_", "",
		       "Green mask equal to zero!\n", "", "", "");
	return -3;
	}

/** The least significant bit position: **/
mask = guiSP->visual_infoS.green_mask;
lowest_bit_position = -1;
for (i = 0; i < pixel_value_size; i++)
	{
	if ((mask >> i) & lowest_bit_mask)
		{
		lowest_bit_position = i;
		break;
		}
	}

/** Check was it found at all: **/
if (lowest_bit_position < 0)
	{
	ErrorMessage_ ("garlic", "PrepareColorShifts_", "",
		       "Unable to find the lowest bit position",
		       " in the green mask!\n", "", "");
	return -4;
	}

/** The most significant bit position: **/
mask = guiSP->visual_infoS.green_mask;
highest_bit_position = lowest_bit_position;
for (i = lowest_bit_position; i < pixel_value_size; i++)
	{
	if (!((mask >> i) & lowest_bit_mask)) break;
	highest_bit_position = i;
	}

/** Prepare the shifts: **/
bitsN = highest_bit_position - lowest_bit_position + 1;
guiSP->green_right_shift  = color_component_size - bitsN;
guiSP->green_left_shift = lowest_bit_position;

/*---------------------------------------------------------------------------*/

/* Find the shifts for blue color component: */

/** Check the blue mask: **/
if (guiSP->visual_infoS.blue_mask == 0)
	{
	ErrorMessage_ ("garlic", "PrepareColorShifts_", "",
		       "Blue mask equal to zero!\n", "", "", "");
	return -5;
	}

/** The least significant bit position: **/
mask = guiSP->visual_infoS.blue_mask;
lowest_bit_position = -1;
for (i = 0; i < pixel_value_size; i++)
	{
	if ((mask >> i) & lowest_bit_mask)
		{
		lowest_bit_position = i;
		break;
		}
	}

/** Check was it found at all: **/
if (lowest_bit_position < 0)
	{
	ErrorMessage_ ("garlic", "PrepareColorShifts_", "",
		       "Unable to find the lowest bit position",
		       " in the blue mask!\n", "", "");
	return -6;
	}

/** The most significant bit position: **/
mask = guiSP->visual_infoS.blue_mask;
highest_bit_position = lowest_bit_position;
for (i = lowest_bit_position; i < pixel_value_size; i++)
	{
	if (!((mask >> i) & lowest_bit_mask)) break;
	highest_bit_position = i;
	}

/** Prepare the shifts: **/
bitsN = highest_bit_position - lowest_bit_position + 1;
guiSP->blue_right_shift  = color_component_size - bitsN;
guiSP->blue_left_shift = lowest_bit_position;

/*---------------------------------------------------------------------------*/

/* Return positive value on success: */
return 1;
}

/*===========================================================================*/