Canola
0.8.D001
|
00001 // 00002 // canola - canon canola 1614p emulator 00003 // Copyright (C) 2011 Peter Miller 00004 // 00005 // This program is free software; you can redistribute it and/or modify 00006 // it under the terms of the GNU General Public License, version 3, as 00007 // published by the Free Software Foundation. 00008 // 00009 // This program is distributed in the hope that it will be useful, 00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 // General Public License for more details. 00013 // 00014 // You should have received a copy of the GNU General Public License along 00015 // with this program. If not, see <http://www.gnu.org/licenses/>. 00016 // 00017 00018 #ifndef LIB_ICON_PIXEL_H 00019 #define LIB_ICON_PIXEL_H 00020 00021 #include <lib/ac/math.h> 00022 #include <string> 00023 00024 00032 class icon_pixel 00033 { 00034 public: 00039 ~icon_pixel(){} 00040 00041 static const icon_pixel black; 00042 static const icon_pixel white; 00043 static const icon_pixel transparent; 00044 00045 typedef double real_type; 00046 typedef unsigned short short_type; 00047 typedef unsigned char byte_type; 00048 00053 icon_pixel() : 00054 red_real(0), 00055 red_short(0), 00056 green_real(0), 00057 green_short(0), 00058 blue_real(0), 00059 blue_short(0), 00060 alpha_real(0), 00061 alpha_short(0), 00062 real_valid(true), 00063 short_valid(true) 00064 { 00065 } 00066 00079 icon_pixel(short_type rr, short_type gg, short_type bb) : 00080 red_real(0), 00081 red_short(rr), 00082 green_real(0), 00083 green_short(gg), 00084 blue_real(0), 00085 blue_short(bb), 00086 alpha_real(1.), 00087 alpha_short(65535), 00088 real_valid(false), 00089 short_valid(true) 00090 { 00091 } 00092 00105 icon_pixel(short_type rr, short_type gg, short_type bb, short_type aa) : 00106 red_real(0), 00107 red_short(aa ? rr : 0), 00108 green_real(0), 00109 green_short(aa ? gg : 0), 00110 blue_real(0), 00111 blue_short(aa ? bb : 0), 00112 alpha_real(0), 00113 alpha_short(aa), 00114 real_valid(false), 00115 short_valid(true) 00116 { 00117 } 00118 00131 icon_pixel(real_type rr, real_type gg, real_type bb) : 00132 red_real(rr), 00133 red_short(0), 00134 green_real(gg), 00135 green_short(0), 00136 blue_real(bb), 00137 blue_short(0), 00138 alpha_real(1.0), 00139 alpha_short(65535), 00140 real_valid(true), 00141 short_valid(false) 00142 { 00143 } 00144 00157 icon_pixel(real_type rr, real_type gg, real_type bb, real_type aa) : 00158 red_real(aa > 0 ? rr : 0), 00159 red_short(0), 00160 green_real(aa > 0 ? gg : 0), 00161 green_short(0), 00162 blue_real(aa > 0 ? bb : 0), 00163 blue_short(0), 00164 alpha_real(aa), 00165 alpha_short(0), 00166 real_valid(true), 00167 short_valid(false) 00168 { 00169 } 00170 00174 icon_pixel(const icon_pixel &arg) : 00175 red_real(arg.red_real), 00176 red_short(arg.red_short), 00177 green_real(arg.green_real), 00178 green_short(arg.green_short), 00179 blue_real(arg.blue_real), 00180 blue_short(arg.blue_short), 00181 alpha_real(arg.alpha_real), 00182 alpha_short(arg.alpha_short), 00183 real_valid(arg.real_valid), 00184 short_valid(arg.short_valid) 00185 { 00186 } 00187 00191 icon_pixel & 00192 operator=(const icon_pixel &arg) 00193 { 00194 if (this != &arg) 00195 { 00196 red_real = arg.red_real; 00197 red_short = arg.red_short; 00198 green_real = arg.green_real; 00199 green_short = arg.green_short; 00200 blue_real = arg.blue_real; 00201 blue_short = arg.blue_short; 00202 alpha_real = arg.alpha_real; 00203 alpha_short = arg.alpha_short; 00204 real_valid = arg.real_valid; 00205 short_valid = arg.short_valid; 00206 } 00207 return *this; 00208 } 00209 00215 bool 00216 is_transparent(void) 00217 const 00218 { 00219 return (short_valid ? (alpha_short == 0) : (alpha_real < 0.002)); 00220 } 00221 00227 bool 00228 is_opaque(void) 00229 const 00230 { 00231 return (short_valid ? (alpha_short >= 65408) : (alpha_real >= 1.0)); 00232 } 00233 00239 icon_pixel 00240 invert(void) 00241 const 00242 { 00243 return 00244 ( 00245 real_valid 00246 ? 00247 icon_pixel 00248 ( 00249 1. - red_real, 00250 1. - green_real, 00251 1. - blue_real, 00252 alpha_real 00253 ) 00254 : 00255 icon_pixel 00256 ( 00257 short_type(65535 - red_short), 00258 short_type(65535 - green_short), 00259 short_type(65535 - blue_short), 00260 alpha_short 00261 ) 00262 ); 00263 } 00264 00265 real_type 00266 get_red(void) 00267 const 00268 { 00269 if (!real_valid) 00270 convert_short_to_real(); 00271 return red_real; 00272 } 00273 00274 real_type 00275 get_green(void) 00276 const 00277 { 00278 if (!real_valid) 00279 convert_short_to_real(); 00280 return green_real; 00281 } 00282 00283 real_type 00284 get_blue(void) 00285 const 00286 { 00287 if (!real_valid) 00288 convert_short_to_real(); 00289 return blue_real; 00290 } 00291 00292 real_type 00293 get_alpha(void) 00294 const 00295 { 00296 if (!real_valid) 00297 convert_short_to_real(); 00298 return alpha_real; 00299 } 00300 00301 short_type 00302 get_red_short(void) 00303 const 00304 { 00305 if (!short_valid) 00306 convert_real_to_short(); 00307 return red_short; 00308 } 00309 00310 byte_type 00311 get_red_byte(void) 00312 const 00313 { 00314 if (!short_valid) 00315 convert_real_to_short(); 00316 return (red_short >> 8); 00317 } 00318 00319 short_type 00320 get_green_short(void) 00321 const 00322 { 00323 if (!short_valid) 00324 convert_real_to_short(); 00325 return green_short; 00326 } 00327 00328 byte_type 00329 get_green_byte(void) 00330 const 00331 { 00332 if (!short_valid) 00333 convert_real_to_short(); 00334 return (green_short >> 8); 00335 } 00336 00337 short_type 00338 get_blue_short(void) 00339 const 00340 { 00341 if (!short_valid) 00342 convert_real_to_short(); 00343 return blue_short; 00344 } 00345 00346 byte_type 00347 get_blue_byte(void) 00348 const 00349 { 00350 if (!short_valid) 00351 convert_real_to_short(); 00352 return (blue_short >> 8); 00353 } 00354 00355 short_type 00356 get_alpha_short(void) 00357 const 00358 { 00359 if (!short_valid) 00360 convert_real_to_short(); 00361 return alpha_short; 00362 } 00363 00364 byte_type 00365 get_alpha_byte(void) 00366 const 00367 { 00368 if (!short_valid) 00369 convert_real_to_short(); 00370 return (alpha_short >> 8); 00371 } 00372 00377 std::string representation(void) const; 00378 00386 bool operator==(const icon_pixel &rhs) const; 00387 00395 bool 00396 operator!=(const icon_pixel &rhs) 00397 const 00398 { 00399 return !operator==(rhs); 00400 } 00401 00405 void operator*=(const icon_pixel &rhs); 00406 00410 icon_pixel operator*(const icon_pixel &rhs) const; 00411 00415 void operator*=(double); 00416 00420 icon_pixel operator*(double) const; 00421 00426 icon_pixel monochrome(void) const; 00427 00432 real_type get_intensity(void) const; 00433 00438 static short_type 00439 short_from_byte(byte_type x) 00440 { 00441 return ((short_type(x) << 8) | short_type(x)); 00442 } 00443 00444 private: 00450 mutable real_type red_real; 00451 00456 mutable short_type red_short; 00457 00463 mutable real_type green_real; 00464 00469 mutable short_type green_short; 00470 00476 mutable real_type blue_real; 00477 00482 mutable short_type blue_short; 00483 00489 mutable real_type alpha_real; 00490 00495 mutable short_type alpha_short; 00496 00501 mutable bool real_valid; 00502 00507 mutable bool short_valid; 00508 00517 static short_type 00518 convert_channel_real_to_short(real_type x) 00519 { 00520 // multiply by 65535 is slow, so break it up 00521 unsigned n = x * 65536; 00522 n -= (n >> 16); 00523 return n; 00524 } 00525 00530 void 00531 convert_real_to_short(void) 00532 const 00533 { 00534 red_short = convert_channel_real_to_short(red_real); 00535 green_short = convert_channel_real_to_short(green_real); 00536 blue_short = convert_channel_real_to_short(blue_real); 00537 alpha_short = convert_channel_real_to_short(alpha_real); 00538 short_valid = true; 00539 } 00540 00548 static real_type 00549 convert_channel_short_to_real(short_type x) 00550 { 00551 if (x >= 65535) 00552 return 1; 00553 return ldexp(real_type(x), -16); 00554 } 00555 00556 void 00557 convert_short_to_real(void) 00558 const 00559 { 00560 red_real = convert_channel_short_to_real(red_short); 00561 green_real = convert_channel_short_to_real(green_short); 00562 blue_real = convert_channel_short_to_real(blue_short); 00563 alpha_real = convert_channel_short_to_real(alpha_short); 00564 real_valid = true; 00565 } 00566 }; 00567 00568 #endif // LIB_ICON_PIXEL_H