BRL-CAD
color_space.c
Go to the documentation of this file.
1 /* C O L O R _ S P A C E . C
2  * BRL-CAD
3  *
4  * Copyright (c) 2013-2014 United States Government as represented by
5  * the U.S. Army Research Laboratory.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public License
9  * version 2.1 as published by the Free Software Foundation.
10  *
11  * This library is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this file; see the file named COPYING for more
18  * information.
19  */
20 /** @file libicv/color_space.c
21  *
22  * This file contains color_space conversion routines.
23  *
24  */
25 #include "common.h"
26 
27 #include <stdlib.h>
28 #include <string.h>
29 
30 #include "vmath.h"
31 #include "bio.h"
32 #include "bu/malloc.h"
33 #include "bu/log.h"
34 #include "icv.h"
35 
36 int
38 {
39  double *out_data, *op;
40  double *in_data;
41  long int size;
42  long int i = 0;
43 
44  ICV_IMAGE_VAL_INT(img);
45 
46  /* This is a true condition i.e the image is already RGB*/
47  if (img->color_space == ICV_COLOR_SPACE_RGB) {
48  return 0;
49  }
50  else if (img->color_space != ICV_COLOR_SPACE_GRAY) {
51  bu_log("ERROR : color_space error");
52  return -1;
53  }
54 
55  size = img->height*img->width;
56  op = out_data = (double *)bu_malloc(size*3*sizeof(double), "Out Image Data");
57  in_data = img->data;
58  for (i =0 ; i < size; i++) {
59  *(out_data) = *in_data;
60  *(out_data+1) = *in_data;
61  *(out_data+2) = *in_data;
62  out_data+=3;
63  in_data++;
64  }
65 
66  bu_free(img->data, "icv_gray2rgb : gray image data");
67  img->data = op;
69  img->channels = 3;
70 
71  return 0;
72 }
73 
74 int
75 icv_rgb2gray(icv_image_t *img, ICV_COLOR color, double rweight, double gweight, double bweight)
76 {
77  double *out_data, *in_data;
78  size_t in, out, size;
79  int multiple_colors = 0;
80  int num_color_planes = 3;
81 
82  double value;
83  int red, green, blue;
84  red = green = blue = 0;
85 
86  ICV_IMAGE_VAL_INT(img);
87 
88  /* This is a true condition i.e the image is already GRAY*/
90  return 0;
91  else if (img->color_space != ICV_COLOR_SPACE_RGB) {
92  bu_log("ERROR : color_space error");
93  return -1;
94  }
95 
96  switch (color) {
97  case ICV_COLOR_R :
98  red = 1;
99  bweight = 0;
100  gweight = 0;
101  multiple_colors = 0;
102  break;
103  case ICV_COLOR_G :
104  green = 1;
105  rweight = 0;
106  bweight = 0;
107  multiple_colors = 0;
108  break;
109  case ICV_COLOR_B :
110  blue = 1;
111  rweight = 0;
112  gweight = 0;
113  multiple_colors = 0;
114  break;
115  case ICV_COLOR_RG :
116  red = 1;
117  green = 1;
118  bweight = 0;
119  multiple_colors = 1;
120  break;
121  case ICV_COLOR_RB :
122  blue = 1;
123  red = 1;
124  gweight = 0;
125  multiple_colors = 1;
126  break;
127  case ICV_COLOR_BG :
128  blue = 1;
129  green = 1;
130  rweight = 0;
131  multiple_colors = 1;
132  break;
133  case ICV_COLOR_RGB :
134  red = 1;
135  green = 1;
136  blue = 1;
137  multiple_colors = 1;
138  break;
139  default :
140  bu_log("ERROR: Wrong Arguments for Color");
141  return -1;
142  }
143 
144  /* Gets number of planes according to the status of arguments
145  check */
146  num_color_planes = red + green + blue;
147  in_data = img->data;
148 
149 
150  /* If function is called with zero for weight of respective plane
151  then divide the weight equally among all the planes */
152  if (red != 0 && ZERO(rweight))
153  rweight = 1.0 / (double)num_color_planes;
154  if (green != 0 && ZERO(gweight))
155  gweight = 1.0 / (double)num_color_planes;
156  if (blue != 0 && ZERO(bweight))
157  bweight = 1.0 / (double)num_color_planes;
158 
159  size = img->height*img->width;
160  out_data = (double*) bu_malloc(size*sizeof(double), "Out Image Data");
161  if (multiple_colors) {
162  for (in = out = 0; out < size; out++, in += 3) {
163  value = rweight*in_data[in] + gweight*in_data[in+1] + bweight*in_data[in+2];
164  if (value > 1.0) {
165  out_data[out] = 1.0;
166  } else if (value < 0.0) {
167  out_data[out] = 0.0;
168  } else
169  out_data[out] = value;
170  }
171  } else if (red) {
172  for (in = out = 0; out < size; out++, in += 3)
173  out_data[out] = in_data[in];
174  } else if (green) {
175  for (in = out = 0; out < size; out++, in += 3)
176  out_data[out] = in_data[in+1];
177  } else if (blue) {
178  for (in = out = 0; out < size; out++, in += 3)
179  out_data[out] = in_data[in+2];
180  } else {
181  /* uniform weight */
182  for (in = out = 0; out < size; out++, in += 3)
183  out_data[out] = (in_data[in] + in_data[in+1] + in_data[in+2]) / 3.0;
184  }
185  bu_free(img->data, "icv_image_rgb2gray : rgb image data");
186  img->data = out_data;
188  img->channels = 1;
189 
190  return 0;
191 }
192 
193 
194 /*
195  * Local Variables:
196  * tab-width: 8
197  * mode: C
198  * indent-tabs-mode: t
199  * c-file-style: "stroustrup"
200  * End:
201  * ex: shiftwidth=4 tabstop=8
202  */
double * data
Definition: icv.h:89
void bu_log(const char *,...) _BU_ATTR_PRINTF12
Definition: log.c:176
int width
Definition: icv.h:91
Header file for the BRL-CAD common definitions.
int channels
Definition: icv.h:91
Definition: icv.h:86
int height
Definition: icv.h:91
void * bu_malloc(size_t siz, const char *str)
Definition: malloc.c:314
int icv_gray2rgb(icv_image_t *img)
Definition: color_space.c:37
goto out
Definition: nmg_mod.c:3846
ICV_COLOR_SPACE color_space
Definition: icv.h:88
int icv_rgb2gray(icv_image_t *img, ICV_COLOR color, double rweight, double gweight, double bweight)
Definition: color_space.c:75
#define ZERO(val)
Definition: units.c:38
ICV_COLOR
Definition: icv.h:259
void bu_free(void *ptr, const char *str)
Definition: malloc.c:328
#define ICV_IMAGE_VAL_INT(_i)
Definition: icv.h:123