Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Copyright (C) 2003 Maxim Stepin ( maxst@hiend3d.com )
  3.  *
  4.  * Copyright (C) 2010 Cameron Zemek ( grom@zeminvaders.net)
  5.  * Copyright (C) 2011 Francois Gannaz <mytskine@gmail.com>
  6.  *
  7.  * This program is free software; you can redistribute it and/or
  8.  * modify it under the terms of the GNU Lesser General Public
  9.  * License as published by the Free Software Foundation; either
  10.  * version 2.1 of the License, or (at your option) any later version.
  11.  *
  12.  * This program is distributed in the hope that it will be useful,
  13.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15.  * Lesser General Public License for more details.
  16.  *
  17.  * You should have received a copy of the GNU Lesser General Public
  18.  * License along with this program; if not, write to the Free Software
  19.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  20.  */
  21.  
  22. #ifndef __HQX_COMMON_H_
  23. #define __HQX_COMMON_H_
  24.  
  25. #include <stdlib.h>
  26. #include <stdint.h>
  27. #include <string.h>
  28.  
  29. #define MASK_2     0x0000FF00
  30. #define MASK_13    0x00FF00FF
  31. #define MASK_RGB   0x00FFFFFF
  32. #define MASK_ALPHA 0xFF000000
  33.  
  34. #define MASK16_2     0x07E0
  35. #define MASK16_13    0xF81F
  36. #define MASK16_RGB   0xFFFF
  37.  
  38. #define Ymask 0x00FF0000
  39. #define Umask 0x0000FF00
  40. #define Vmask 0x000000FF
  41. #define trY   0x00300000
  42. #define trU   0x00000700
  43. #define trV   0x00000006
  44.  
  45. /* RGB to YUV lookup table */
  46. extern uint32_t RGBtoYUV[16777216];
  47.  
  48. static inline uint32_t rgb32_to_yuv(uint32_t c)
  49. {
  50.     // Mask against MASK_RGB to discard the alpha channel
  51.     return RGBtoYUV[MASK_RGB & c];
  52. }
  53.  
  54. static inline uint32_t rgb16_to_yuv(uint16_t c)
  55. {
  56.     return RGBtoYUV[(((c & 0xF800) << 8) |
  57.                      ((c & 0x07E0) << 5) |
  58.                      ((c & 0x001F) << 3))];
  59. }
  60.  
  61. static inline uint24_t *u24cpy(uint24_t *dst, const uint24_t src)
  62. {
  63.         /* memcpy() is sometimes faster. */
  64. #ifdef HQX_U24CPY_MEMCPY
  65.         memcpy(*dst, src, sizeof(*dst));
  66. #else
  67.         (*dst)[0] = src[0];
  68.         (*dst)[1] = src[1];
  69.         (*dst)[2] = src[2];
  70. #endif
  71.         return dst;
  72. }
  73.  
  74. static inline uint32_t rgb24_to_yuv(uint24_t c)
  75. {
  76.     return RGBtoYUV[((c[0] << 16) | (c[1] << 8) | c[2])];
  77. }
  78.  
  79. /* Test if there is difference in color */
  80. static inline int yuv_diff(uint32_t yuv1, uint32_t yuv2) {
  81.     return (( abs((yuv1 & Ymask) - (yuv2 & Ymask)) > trY ) ||
  82.             ( abs((yuv1 & Umask) - (yuv2 & Umask)) > trU ) ||
  83.             ( abs((yuv1 & Vmask) - (yuv2 & Vmask)) > trV ) );
  84. }
  85.  
  86. static inline int Diff32(uint32_t c1, uint32_t c2)
  87. {
  88.     return yuv_diff(rgb32_to_yuv(c1), rgb32_to_yuv(c2));
  89. }
  90.  
  91. static inline int Diff16(uint16_t c1, uint16_t c2)
  92. {
  93.     return yuv_diff(rgb16_to_yuv(c1), rgb16_to_yuv(c2));
  94. }
  95.  
  96. static inline int Diff24(uint24_t c1, uint24_t c2)
  97. {
  98.     return yuv_diff(rgb24_to_yuv(c1), rgb24_to_yuv(c2));
  99. }
  100.  
  101. /* Interpolate functions */
  102. static inline uint32_t Interpolate_2_32(uint32_t c1, int w1, uint32_t c2, int w2, int s)
  103. {
  104.     if (c1 == c2) {
  105.         return c1;
  106.     }
  107.     return
  108.         (((((c1 & MASK_ALPHA) >> 24) * w1 + ((c2 & MASK_ALPHA) >> 24) * w2) << (24-s)) & MASK_ALPHA) +
  109.         ((((c1 & MASK_2) * w1 + (c2 & MASK_2) * w2) >> s) & MASK_2)     +
  110.         ((((c1 & MASK_13) * w1 + (c2 & MASK_13) * w2) >> s) & MASK_13);
  111. }
  112.  
  113. static inline uint32_t Interpolate_3_32(uint32_t c1, int w1, uint32_t c2, int w2, uint32_t c3, int w3, int s)
  114. {
  115.     return
  116.         (((((c1 & MASK_ALPHA) >> 24) * w1 + ((c2 & MASK_ALPHA) >> 24) * w2 + ((c3 & MASK_ALPHA) >> 24) * w3) << (24-s)) & MASK_ALPHA) +
  117.         ((((c1 & MASK_2) * w1 + (c2 & MASK_2) * w2 + (c3 & MASK_2) * w3) >> s) & MASK_2) +
  118.         ((((c1 & MASK_13) * w1 + (c2 & MASK_13) * w2 + (c3 & MASK_13) * w3) >> s) & MASK_13);
  119. }
  120.  
  121. static inline uint32_t Interp1_32(uint32_t c1, uint32_t c2)
  122. {
  123.     //(c1*3+c2) >> 2;
  124.     return Interpolate_2_32(c1, 3, c2, 1, 2);
  125. }
  126.  
  127. static inline uint32_t Interp2_32(uint32_t c1, uint32_t c2, uint32_t c3)
  128. {
  129.     //(c1*2+c2+c3) >> 2;
  130.     return Interpolate_3_32(c1, 2, c2, 1, c3, 1, 2);
  131. }
  132.  
  133. static inline uint32_t Interp3_32(uint32_t c1, uint32_t c2)
  134. {
  135.     //(c1*7+c2)/8;
  136.     return Interpolate_2_32(c1, 7, c2, 1, 3);
  137. }
  138.  
  139. static inline uint32_t Interp4_32(uint32_t c1, uint32_t c2, uint32_t c3)
  140. {
  141.     //(c1*2+(c2+c3)*7)/16;
  142.     return Interpolate_3_32(c1, 2, c2, 7, c3, 7, 4);
  143. }
  144.  
  145. static inline uint32_t Interp5_32(uint32_t c1, uint32_t c2)
  146. {
  147.     //(c1+c2) >> 1;
  148.     return Interpolate_2_32(c1, 1, c2, 1, 1);
  149. }
  150.  
  151. static inline uint32_t Interp6_32(uint32_t c1, uint32_t c2, uint32_t c3)
  152. {
  153.     //(c1*5+c2*2+c3)/8;
  154.     return Interpolate_3_32(c1, 5, c2, 2, c3, 1, 3);
  155. }
  156.  
  157. static inline uint32_t Interp7_32(uint32_t c1, uint32_t c2, uint32_t c3)
  158. {
  159.     //(c1*6+c2+c3)/8;
  160.     return Interpolate_3_32(c1, 6, c2, 1, c3, 1, 3);
  161. }
  162.  
  163. static inline uint32_t Interp8_32(uint32_t c1, uint32_t c2)
  164. {
  165.     //(c1*5+c2*3)/8;
  166.     return Interpolate_2_32(c1, 5, c2, 3, 3);
  167. }
  168.  
  169. static inline uint32_t Interp9_32(uint32_t c1, uint32_t c2, uint32_t c3)
  170. {
  171.     //(c1*2+(c2+c3)*3)/8;
  172.     return Interpolate_3_32(c1, 2, c2, 3, c3, 3, 3);
  173. }
  174.  
  175. static inline uint32_t Interp10_32(uint32_t c1, uint32_t c2, uint32_t c3)
  176. {
  177.     //(c1*14+c2+c3)/16;
  178.     return Interpolate_3_32(c1, 14, c2, 1, c3, 1, 4);
  179. }
  180.  
  181. /* Interpolate functions (16 bit, 565) */
  182. static inline uint16_t Interpolate_2_16(uint16_t c1, int w1, uint16_t c2, int w2, int s)
  183. {
  184.     if (c1 == c2) {
  185.         return c1;
  186.     }
  187.     return
  188.         ((((c1 & MASK16_2) * w1 + (c2 & MASK16_2) * w2) >> s) & MASK16_2) +
  189.         ((((c1 & MASK16_13) * w1 + (c2 & MASK16_13) * w2) >> s) & MASK16_13);
  190. }
  191.  
  192. static inline uint16_t Interpolate_3_16(uint16_t c1, int w1, uint16_t c2, int w2, uint16_t c3, int w3, int s)
  193. {
  194.     return
  195.         ((((c1 & MASK16_2) * w1 + (c2 & MASK16_2) * w2 + (c3 & MASK16_2) * w3) >> s) & MASK16_2) +
  196.         ((((c1 & MASK16_13) * w1 + (c2 & MASK16_13) * w2 + (c3 & MASK16_13) * w3) >> s) & MASK16_13);
  197. }
  198.  
  199. static inline uint16_t Interp1_16(uint16_t c1, uint16_t c2)
  200. {
  201.     //(c1*3+c2) >> 2;
  202.     return Interpolate_2_16(c1, 3, c2, 1, 2);
  203. }
  204.  
  205. static inline uint16_t Interp2_16(uint16_t c1, uint16_t c2, uint16_t c3)
  206. {
  207.     //(c1*2+c2+c3) >> 2;
  208.     return Interpolate_3_16(c1, 2, c2, 1, c3, 1, 2);
  209. }
  210.  
  211. static inline uint16_t Interp3_16(uint16_t c1, uint16_t c2)
  212. {
  213.     //(c1*7+c2)/8;
  214.     return Interpolate_2_16(c1, 7, c2, 1, 3);
  215. }
  216.  
  217. static inline uint16_t Interp4_16(uint16_t c1, uint16_t c2, uint16_t c3)
  218. {
  219.     //(c1*2+(c2+c3)*7)/16;
  220.     return Interpolate_3_16(c1, 2, c2, 7, c3, 7, 4);
  221. }
  222.  
  223. static inline uint16_t Interp5_16(uint16_t c1, uint16_t c2)
  224. {
  225.     //(c1+c2) >> 1;
  226.     return Interpolate_2_16(c1, 1, c2, 1, 1);
  227. }
  228.  
  229. static inline uint16_t Interp6_16(uint16_t c1, uint16_t c2, uint16_t c3)
  230. {
  231.     //(c1*5+c2*2+c3)/8;
  232.     return Interpolate_3_16(c1, 5, c2, 2, c3, 1, 3);
  233. }
  234.  
  235. static inline uint16_t Interp7_16(uint16_t c1, uint16_t c2, uint16_t c3)
  236. {
  237.     //(c1*6+c2+c3)/8;
  238.     return Interpolate_3_16(c1, 6, c2, 1, c3, 1, 3);
  239. }
  240.  
  241. static inline uint16_t Interp8_16(uint16_t c1, uint16_t c2)
  242. {
  243.     //(c1*5+c2*3)/8;
  244.     return Interpolate_2_16(c1, 5, c2, 3, 3);
  245. }
  246.  
  247. static inline uint16_t Interp9_16(uint16_t c1, uint16_t c2, uint16_t c3)
  248. {
  249.     //(c1*2+(c2+c3)*3)/8;
  250.     return Interpolate_3_16(c1, 2, c2, 3, c3, 3, 3);
  251. }
  252.  
  253. static inline uint16_t Interp10_16(uint16_t c1, uint16_t c2, uint16_t c3)
  254. {
  255.     //(c1*14+c2+c3)/16;
  256.     return Interpolate_3_16(c1, 14, c2, 1, c3, 1, 4);
  257. }
  258.  
  259. /* Interpolate functions (24 bit, 888) */
  260. static inline void Interpolate_2_24(uint24_t *ret, uint24_t c1, int w1, uint24_t c2, int w2, int s)
  261. {
  262.     if (!memcmp(c1, c2, 3)) {
  263.         u24cpy(ret, c1);
  264.         return;
  265.     }
  266.     (*ret)[0] = (((c1[0] * w1) + (c2[0] * w2)) >> s);
  267.     (*ret)[1] = (((c1[1] * w1) + (c2[1] * w2)) >> s);
  268.     (*ret)[2] = (((c1[2] * w1) + (c2[2] * w2)) >> s);
  269. }
  270.  
  271. static inline void Interpolate_3_24(uint24_t *ret, uint24_t c1, int w1, uint24_t c2, int w2, uint24_t c3, int w3, int s)
  272. {
  273.     (*ret)[0] = (((c1[0] * w1) + (c2[0] * w2) + (c3[0] * w3)) >> s);
  274.     (*ret)[1] = (((c1[1] * w1) + (c2[1] * w2) + (c3[1] * w3)) >> s);
  275.     (*ret)[2] = (((c1[2] * w1) + (c2[2] * w2) + (c3[2] * w3)) >> s);
  276. }
  277.  
  278. static inline void Interp1_24(uint24_t *ret, uint24_t c1, uint24_t c2)
  279. {
  280.     //(c1*3+c2) >> 2;
  281.     Interpolate_2_24(ret, c1, 3, c2, 1, 2);
  282. }
  283.  
  284. static inline void Interp2_24(uint24_t *ret, uint24_t c1, uint24_t c2, uint24_t c3)
  285. {
  286.     //(c1*2+c2+c3) >> 2;
  287.     Interpolate_3_24(ret, c1, 2, c2, 1, c3, 1, 2);
  288. }
  289.  
  290. static inline void Interp3_24(uint24_t *ret, uint24_t c1, uint24_t c2)
  291. {
  292.     //(c1*7+c2)/8;
  293.     Interpolate_2_24(ret, c1, 7, c2, 1, 3);
  294. }
  295.  
  296. static inline void Interp4_24(uint24_t *ret, uint24_t c1, uint24_t c2, uint24_t c3)
  297. {
  298.     //(c1*2+(c2+c3)*7)/16;
  299.     Interpolate_3_24(ret, c1, 2, c2, 7, c3, 7, 4);
  300. }
  301.  
  302. static inline void Interp5_24(uint24_t *ret, uint24_t c1, uint24_t c2)
  303. {
  304.     //(c1+c2) >> 1;
  305.     Interpolate_2_24(ret, c1, 1, c2, 1, 1);
  306. }
  307.  
  308. static inline void Interp6_24(uint24_t *ret, uint24_t c1, uint24_t c2, uint24_t c3)
  309. {
  310.     //(c1*5+c2*2+c3)/8;
  311.     Interpolate_3_24(ret, c1, 5, c2, 2, c3, 1, 3);
  312. }
  313.  
  314. static inline void Interp7_24(uint24_t *ret, uint24_t c1, uint24_t c2, uint24_t c3)
  315. {
  316.     //(c1*6+c2+c3)/8;
  317.     Interpolate_3_24(ret, c1, 6, c2, 1, c3, 1, 3);
  318. }
  319.  
  320. static inline void Interp8_24(uint24_t *ret, uint24_t c1, uint24_t c2)
  321. {
  322.     //(c1*5+c2*3)/8;
  323.     Interpolate_2_24(ret, c1, 5, c2, 3, 3);
  324. }
  325.  
  326. static inline void Interp9_24(uint24_t *ret, uint24_t c1, uint24_t c2, uint24_t c3)
  327. {
  328.     //(c1*2+(c2+c3)*3)/8;
  329.     Interpolate_3_24(ret, c1, 2, c2, 3, c3, 3, 3);
  330. }
  331.  
  332. static inline void Interp10_24(uint24_t *ret, uint24_t c1, uint24_t c2, uint24_t c3)
  333. {
  334.     //(c1*14+c2+c3)/16;
  335.     Interpolate_3_24(ret, c1, 14, c2, 1, c3, 1, 4);
  336. }
  337.  
  338. #endif
  339.