synfig-core  1.0.3
pixelformat.h
Go to the documentation of this file.
1 /* === S Y N F I G ========================================================= */
24 /* ========================================================================= */
25 
26 #ifndef __SYNFIG_COLOR_PIXELFORMAT_H
27 #define __SYNFIG_COLOR_PIXELFORMAT_H
28 
29 #include <synfig/color/color.h>
30 
31 namespace synfig {
32 
33 
35 {
36 /* Bit Descriptions (ON/OFF)
37 ** ----+-------------
38 ** 0 Color Channels (Gray/RGB)
39 ** 1 Alpha Channel (WITH/WITHOUT)
40 ** 2 ZDepth (WITH/WITHOUT)
41 ** 3 Endian (BGR/RGB)
42 ** 4 Alpha Location (Start/End)
43 ** 5 ZDepth Location (Start/End)
44 ** 6 Alpha/ZDepth Arrangement (ZA,AZ)
45 ** 7 Alpha Range (Inverted,Normal)
46 ** 8 Z Range (Inverted,Normal)
47 */
48  PF_RGB = 0,
49  PF_GRAY = (1<<0),
50  PF_A = (1<<1),
51  PF_Z = (1<<2),
52  PF_BGR = (1<<3),
53  PF_A_START = (1<<4),
54  PF_Z_START = (1<<5),
55  PF_ZA = (1<<6),
56  PF_A_INV = (1<<7),
57  PF_Z_INV = (1<<8),
58  PF_RAW_COLOR = (1<<9)+(1<<1)
59 };
60 
62  { return static_cast<PixelFormat>((int)lhs|(int)rhs); }
63 
65  { return static_cast<PixelFormat>((int)lhs&(int)rhs); }
66 #define FLAGS(x,y) (((x)&(y))==(y))
67 
69 inline int channels(const PixelFormat x)
70 {
71  int chan = 0;
72  if(FLAGS(x, PF_GRAY))
73  {
74  ++chan;
75  }
76  else
77  {
78  chan += 3;
79  }
80 
81  if(FLAGS(x, PF_A))
82  {
83  ++chan;
84  }
85  if(FLAGS(x, PF_Z))
86  {
87  ++chan;
88  }
89  if(FLAGS(x, PF_RAW_COLOR))
90  {
91  chan = sizeof(Color);
92  }
93 
94  return chan;
95 }
96 
97 inline unsigned char * Color2PixelFormat(const Color &color, const PixelFormat &pf,
98  unsigned char *out, const Gamma &gamma)
99 {
100  if(FLAGS(pf, PF_RAW_COLOR))
101  {
102  Color *outcol = reinterpret_cast<Color *>(out);
103  *outcol = color;
104  out += sizeof(color);
105  return out;
106  }
107 
108  int alpha = 0;
109  if (FLAGS(pf, PF_A_INV))
110  {
111  alpha = (-(float)color.get_a()+1) * 255;
112  }
113  else
114  {
115  alpha = (float)color.get_a() * 255;
116  }
117 
118  if(alpha < 0)
119  {
120  alpha=0;
121  }
122  if(alpha > 255)
123  {
124  alpha=255;
125  }
126 
128  {
129  if(FLAGS(pf, PF_Z_START))
130  {
131  out++;
132  }
133  if(FLAGS(pf, PF_A_START))
134  {
135  *out++ = static_cast<unsigned char>(alpha);
136  }
137  }
138  else
139  {
140  if(FLAGS(pf, PF_A_START))
141  {
142  *out++ = static_cast<unsigned char>(alpha);
143  }
144  if(FLAGS(pf, PF_Z_START))
145  {
146  out++;
147  }
148  }
149 
150  if(FLAGS(pf,PF_GRAY))
151  {
152  *out++ = static_cast<unsigned char>(gamma.g_F32_to_U8(color.get_y()));
153  }
154  else
155  {
156  if(FLAGS(pf,PF_BGR))
157  {
158  *out++ = static_cast<unsigned char>(gamma.r_F32_to_U8(color.get_b()));
159  *out++ = static_cast<unsigned char>(gamma.g_F32_to_U8(color.get_g()));
160  *out++ = static_cast<unsigned char>(gamma.b_F32_to_U8(color.get_r()));
161  }
162  else
163  {
164  *out++ = static_cast<unsigned char>(gamma.r_F32_to_U8(color.get_r()));
165  *out++ = static_cast<unsigned char>(gamma.g_F32_to_U8(color.get_g()));
166  *out++ = static_cast<unsigned char>(gamma.b_F32_to_U8(color.get_b()));
167  }
168  }
169 
170  if(FLAGS(pf, PF_ZA))
171  {
172  if(!FLAGS(pf, PF_Z_START) && FLAGS(pf, PF_Z))
173  {
174  out++;
175  }
176  if(!FLAGS(pf, PF_A_START) && FLAGS(pf, PF_A))
177  {
178  *out++ = static_cast<unsigned char>(alpha);
179  }
180  }
181  else
182  {
183  if(!FLAGS(pf, PF_Z_START) && FLAGS(pf, PF_Z))
184  {
185  out++;
186  }
187  if(!FLAGS(pf, PF_A_START) && FLAGS(pf, PF_A))
188  {
189  *out++ = static_cast<unsigned char>(alpha);
190  }
191  }
192 
193  return out;
194 }
195 
196 inline void convert_color_format(unsigned char *dest, const Color *src,
197  int w, PixelFormat pf,const Gamma &gamma)
198 {
199  assert(w >= 0);
200  while(w--)
201  {
202  dest = Color2PixelFormat((*(src++)).clamped(),
203  pf, dest, gamma);
204  }
205 }
206 
207 inline const unsigned char * PixelFormat2Color(Color &color,
208  const PixelFormat &pf,
209  const unsigned char *out)
210 {
212  {
213  if(FLAGS(pf, PF_Z_START))
214  {
215  out++;
216  }
217  if(FLAGS(pf,PF_A_START))
218  {
219  color.set_a((float)*out++ / 255);
220  }
221  }
222  else
223  {
224  if(FLAGS(pf, PF_A_START))
225  {
226  color.set_a((float)*out++ / 255);
227  }
228  if(FLAGS(pf, PF_Z_START))
229  {
230  out++;
231  }
232  }
233 
234  if(FLAGS(pf, PF_GRAY))
235  {
236  color.set_yuv((float)*out++ / 255, 0, 0);
237  }
238  else
239  {
240  if(FLAGS(pf, PF_BGR))
241  {
242  color.set_b((float)*out++ / 255);
243  color.set_g((float)*out++ / 255);
244  color.set_r((float)*out++ / 255);
245  }
246  else
247  {
248  color.set_r((float)*out++ / 255);
249  color.set_g((float)*out++ / 255);
250  color.set_b((float)*out++ / 255);
251  }
252  }
253 
254  if(FLAGS(pf, PF_ZA))
255  {
256  if(!FLAGS(pf, PF_Z_START) && FLAGS(pf, PF_Z))
257  {
258  out++;
259  }
260  if(!FLAGS(pf, PF_A_START) && FLAGS(pf, PF_A))
261  {
262  color.set_a((float)*out++ / 255);
263  }
264  }
265  else
266  {
267  if(!FLAGS(pf, PF_A_START) && FLAGS(pf, PF_A))
268  {
269  color.set_a((float)*out++ / 255);
270  }
271  if(!FLAGS(pf, PF_Z_START) && FLAGS(pf, PF_Z))
272  {
273  out++;
274  }
275  }
276 
277  return out;
278 }
279 
280 } // synfig namespace
281 
282 #endif // __SYNFIG_COLOR_PIXELFORMAT_H
283