home *** CD-ROM | disk | FTP | other *** search
/ Chip 2004 July / CMCD0704.ISO / Software / Freeware / Utilitare / VisualBoyAdvance-1.7.2 / src / hq2x.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2004-01-20  |  13.5 KB  |  605 lines

  1. /*
  2.  * This file is part of the Advance project.
  3.  *
  4.  * Copyright (C) 2003 Andrea Mazzoleni
  5.  *
  6.  * This program is free software; you can redistribute it and/or modify
  7.  * it under the terms of the GNU General Public License as published by
  8.  * the Free Software Foundation; either version 2 of the License, or
  9.  * (at your option) any later version.
  10.  *
  11.  * This program is distributed in the hope that it will be useful,
  12.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  * GNU General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU General Public License
  17.  * along with this program; if not, write to the Free Software
  18.  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  *
  20.  * In addition, as a special exception, Andrea Mazzoleni
  21.  * gives permission to link the code of this program with
  22.  * the MAME library (or with modified versions of MAME that use the
  23.  * same license as MAME), and distribute linked combinations including
  24.  * the two.  You must obey the GNU General Public License in all
  25.  * respects for all of the code used other than MAME.  If you modify
  26.  * this file, you may extend this exception to your version of the
  27.  * file, but you are not obligated to do so.  If you do not wish to
  28.  * do so, delete this exception statement from your version.
  29.  */
  30. #include "System.h"
  31. #include "interp.h"
  32.  
  33. /***************************************************************************/
  34. /* HQ2x C implementation */
  35.  
  36. /*
  37.  * This effect is a rewritten implementation of the hq2x effect made by Maxim Stepin
  38.  */
  39.  
  40. static void hq2x_16_def(u16* dst0, u16* dst1, const u16* src0, const u16* src1, const u16* src2, unsigned count)
  41. {
  42.   unsigned i;
  43.  
  44.   for(i=0;i<count;++i) {
  45.     unsigned char mask;
  46.  
  47.     u16 c[9];
  48.  
  49.     c[1] = src0[0];
  50.     c[4] = src1[0];
  51.     c[7] = src2[0];
  52.  
  53.     if (i>0) {
  54.       c[0] = src0[-1];
  55.       c[3] = src1[-1];
  56.       c[6] = src2[-1];
  57.     } else {
  58.       c[0] = c[1];
  59.       c[3] = c[4];
  60.       c[6] = c[7];
  61.     }
  62.  
  63.     if (i<count-1) {
  64.       c[2] = src0[1];
  65.       c[5] = src1[1];
  66.       c[8] = src2[1];
  67.     } else {
  68.       c[2] = c[1];
  69.       c[5] = c[4];
  70.       c[8] = c[7];
  71.     }
  72.  
  73.     mask = 0;
  74.  
  75.     if (interp_16_diff(c[0], c[4]))
  76.       mask |= 1 << 0;
  77.     if (interp_16_diff(c[1], c[4]))
  78.       mask |= 1 << 1;
  79.     if (interp_16_diff(c[2], c[4]))
  80.       mask |= 1 << 2;
  81.     if (interp_16_diff(c[3], c[4]))
  82.       mask |= 1 << 3;
  83.     if (interp_16_diff(c[5], c[4]))
  84.       mask |= 1 << 4;
  85.     if (interp_16_diff(c[6], c[4]))
  86.       mask |= 1 << 5;
  87.     if (interp_16_diff(c[7], c[4]))
  88.       mask |= 1 << 6;
  89.     if (interp_16_diff(c[8], c[4]))
  90.       mask |= 1 << 7;
  91.  
  92. #define P0 dst0[0]
  93. #define P1 dst0[1]
  94. #define P2 dst1[0]
  95. #define P3 dst1[1]
  96. #define MUR interp_16_diff(c[1], c[5])
  97. #define MDR interp_16_diff(c[5], c[7])
  98. #define MDL interp_16_diff(c[7], c[3])
  99. #define MUL interp_16_diff(c[3], c[1])
  100. #define IC(p0) c[p0]
  101. #define I11(p0,p1) interp_16_11(c[p0], c[p1])
  102. #define I211(p0,p1,p2) interp_16_211(c[p0], c[p1], c[p2])
  103. #define I31(p0,p1) interp_16_31(c[p0], c[p1])
  104. #define I332(p0,p1,p2) interp_16_332(c[p0], c[p1], c[p2])
  105. #define I431(p0,p1,p2) interp_16_431(c[p0], c[p1], c[p2])
  106. #define I521(p0,p1,p2) interp_16_521(c[p0], c[p1], c[p2])
  107. #define I53(p0,p1) interp_16_53(c[p0], c[p1])
  108. #define I611(p0,p1,p2) interp_16_611(c[p0], c[p1], c[p2])
  109. #define I71(p0,p1) interp_16_71(c[p0], c[p1])
  110. #define I772(p0,p1,p2) interp_16_772(c[p0], c[p1], c[p2])
  111. #define I97(p0,p1) interp_16_97(c[p0], c[p1])
  112. #define I1411(p0,p1,p2) interp_16_1411(c[p0], c[p1], c[p2])
  113. #define I151(p0,p1) interp_16_151(c[p0], c[p1])
  114.  
  115.     switch (mask) {
  116. #include "hq2x.h"
  117.     }
  118.  
  119. #undef P0
  120. #undef P1
  121. #undef P2
  122. #undef P3
  123. #undef MUR
  124. #undef MDR
  125. #undef MDL
  126. #undef MUL
  127. #undef IC
  128. #undef I11
  129. #undef I211
  130. #undef I31
  131. #undef I332
  132. #undef I431
  133. #undef I521
  134. #undef I53
  135. #undef I611
  136. #undef I71
  137. #undef I772
  138. #undef I97
  139. #undef I1411
  140. #undef I151
  141.  
  142.     src0 += 1;
  143.     src1 += 1;
  144.     src2 += 1;
  145.     dst0 += 2;
  146.     dst1 += 2;
  147.   }
  148. }
  149.  
  150. static void hq2x_32_def(u32* dst0, u32* dst1, const u32* src0, const u32* src1, const u32* src2, unsigned count)
  151. {
  152.   unsigned i;
  153.  
  154.   for(i=0;i<count;++i) {
  155.     unsigned char mask;
  156.  
  157.     u32 c[9];
  158.  
  159.     c[1] = src0[0];
  160.     c[4] = src1[0];
  161.     c[7] = src2[0];
  162.  
  163.     if (i>0) {
  164.       c[0] = src0[-1];
  165.       c[3] = src1[-1];
  166.       c[6] = src2[-1];
  167.     } else {
  168.       c[0] = c[1];
  169.       c[3] = c[4];
  170.       c[6] = c[7];
  171.     }
  172.  
  173.     if (i<count-1) {
  174.       c[2] = src0[1];
  175.       c[5] = src1[1];
  176.       c[8] = src2[1];
  177.     } else {
  178.       c[2] = c[1];
  179.       c[5] = c[4];
  180.       c[8] = c[7];
  181.     }
  182.  
  183.     mask = 0;
  184.  
  185.     if (interp_32_diff(c[0], c[4]))
  186.       mask |= 1 << 0;
  187.     if (interp_32_diff(c[1], c[4]))
  188.       mask |= 1 << 1;
  189.     if (interp_32_diff(c[2], c[4]))
  190.       mask |= 1 << 2;
  191.     if (interp_32_diff(c[3], c[4]))
  192.       mask |= 1 << 3;
  193.     if (interp_32_diff(c[5], c[4]))
  194.       mask |= 1 << 4;
  195.     if (interp_32_diff(c[6], c[4]))
  196.       mask |= 1 << 5;
  197.     if (interp_32_diff(c[7], c[4]))
  198.       mask |= 1 << 6;
  199.     if (interp_32_diff(c[8], c[4]))
  200.       mask |= 1 << 7;
  201.  
  202. #define P0 dst0[0]
  203. #define P1 dst0[1]
  204. #define P2 dst1[0]
  205. #define P3 dst1[1]
  206. #define MUR interp_32_diff(c[1], c[5])
  207. #define MDR interp_32_diff(c[5], c[7])
  208. #define MDL interp_32_diff(c[7], c[3])
  209. #define MUL interp_32_diff(c[3], c[1])
  210. #define IC(p0) c[p0]
  211. #define I11(p0,p1) interp_32_11(c[p0], c[p1])
  212. #define I211(p0,p1,p2) interp_32_211(c[p0], c[p1], c[p2])
  213. #define I31(p0,p1) interp_32_31(c[p0], c[p1])
  214. #define I332(p0,p1,p2) interp_32_332(c[p0], c[p1], c[p2])
  215. #define I431(p0,p1,p2) interp_32_431(c[p0], c[p1], c[p2])
  216. #define I521(p0,p1,p2) interp_32_521(c[p0], c[p1], c[p2])
  217. #define I53(p0,p1) interp_32_53(c[p0], c[p1])
  218. #define I611(p0,p1,p2) interp_32_611(c[p0], c[p1], c[p2])
  219. #define I71(p0,p1) interp_32_71(c[p0], c[p1])
  220. #define I772(p0,p1,p2) interp_32_772(c[p0], c[p1], c[p2])
  221. #define I97(p0,p1) interp_32_97(c[p0], c[p1])
  222. #define I1411(p0,p1,p2) interp_32_1411(c[p0], c[p1], c[p2])
  223. #define I151(p0,p1) interp_32_151(c[p0], c[p1])
  224.  
  225.     switch (mask) {
  226. #include "hq2x.h"
  227.     }
  228.  
  229. #undef P0
  230. #undef P1
  231. #undef P2
  232. #undef P3
  233. #undef MUR
  234. #undef MDR
  235. #undef MDL
  236. #undef MUL
  237. #undef IC
  238. #undef I11
  239. #undef I211
  240. #undef I31
  241. #undef I332
  242. #undef I431
  243. #undef I521
  244. #undef I53
  245. #undef I611
  246. #undef I71
  247. #undef I772
  248. #undef I97
  249. #undef I1411
  250. #undef I151
  251.  
  252.     src0 += 1;
  253.     src1 += 1;
  254.     src2 += 1;
  255.     dst0 += 2;
  256.     dst1 += 2;
  257.   }
  258. }
  259.  
  260. /***************************************************************************/
  261. /* LQ2x C implementation */
  262.  
  263. /*
  264.  * This effect is derived from the hq2x effect made by Maxim Stepin
  265.  */
  266.  
  267. static void lq2x_16_def(u16* dst0, u16* dst1, const u16* src0, const u16* src1, const u16* src2, unsigned count)
  268. {
  269.   unsigned i;
  270.  
  271.   for(i=0;i<count;++i) {
  272.     unsigned char mask;
  273.  
  274.     u16 c[9];
  275.  
  276.     c[1] = src0[0];
  277.     c[4] = src1[0];
  278.     c[7] = src2[0];
  279.  
  280.     if (i>0) {
  281.       c[0] = src0[-1];
  282.       c[3] = src1[-1];
  283.       c[6] = src2[-1];
  284.     } else {
  285.       c[0] = c[1];
  286.       c[3] = c[4];
  287.       c[6] = c[7];
  288.     }
  289.  
  290.     if (i<count-1) {
  291.       c[2] = src0[1];
  292.       c[5] = src1[1];
  293.       c[8] = src2[1];
  294.     } else {
  295.       c[2] = c[1];
  296.       c[5] = c[4];
  297.       c[8] = c[7];
  298.     }
  299.  
  300.     mask = 0;
  301.  
  302.     if (c[0] != c[4])
  303.       mask |= 1 << 0;
  304.     if (c[1] != c[4])
  305.       mask |= 1 << 1;
  306.     if (c[2] != c[4])
  307.       mask |= 1 << 2;
  308.     if (c[3] != c[4])
  309.       mask |= 1 << 3;
  310.     if (c[5] != c[4])
  311.       mask |= 1 << 4;
  312.     if (c[6] != c[4])
  313.       mask |= 1 << 5;
  314.     if (c[7] != c[4])
  315.       mask |= 1 << 6;
  316.     if (c[8] != c[4])
  317.       mask |= 1 << 7;
  318.  
  319. #define P0 dst0[0]
  320. #define P1 dst0[1]
  321. #define P2 dst1[0]
  322. #define P3 dst1[1]
  323. #define MUR (c[1] != c[5])
  324. #define MDR (c[5] != c[7])
  325. #define MDL (c[7] != c[3])
  326. #define MUL (c[3] != c[1])
  327. #define IC(p0) c[p0]
  328. #define I11(p0,p1) interp_16_11(c[p0], c[p1])
  329. #define I211(p0,p1,p2) interp_16_211(c[p0], c[p1], c[p2])
  330. #define I31(p0,p1) interp_16_31(c[p0], c[p1])
  331. #define I332(p0,p1,p2) interp_16_332(c[p0], c[p1], c[p2])
  332. #define I431(p0,p1,p2) interp_16_431(c[p0], c[p1], c[p2])
  333. #define I521(p0,p1,p2) interp_16_521(c[p0], c[p1], c[p2])
  334. #define I53(p0,p1) interp_16_53(c[p0], c[p1])
  335. #define I611(p0,p1,p2) interp_16_611(c[p0], c[p1], c[p2])
  336. #define I71(p0,p1) interp_16_71(c[p0], c[p1])
  337. #define I772(p0,p1,p2) interp_16_772(c[p0], c[p1], c[p2])
  338. #define I97(p0,p1) interp_16_97(c[p0], c[p1])
  339. #define I1411(p0,p1,p2) interp_16_1411(c[p0], c[p1], c[p2])
  340. #define I151(p0,p1) interp_16_151(c[p0], c[p1])
  341.  
  342.     switch (mask) {
  343. #include "lq2x.h"
  344.     }
  345.  
  346. #undef P0
  347. #undef P1
  348. #undef P2
  349. #undef P3
  350. #undef MUR
  351. #undef MDR
  352. #undef MDL
  353. #undef MUL
  354. #undef IC
  355. #undef I11
  356. #undef I211
  357. #undef I31
  358. #undef I332
  359. #undef I431
  360. #undef I521
  361. #undef I53
  362. #undef I611
  363. #undef I71
  364. #undef I772
  365. #undef I97
  366. #undef I1411
  367. #undef I151
  368.  
  369.     src0 += 1;
  370.     src1 += 1;
  371.     src2 += 1;
  372.     dst0 += 2;
  373.     dst1 += 2;
  374.   }
  375. }
  376.  
  377. static void lq2x_32_def(u32* dst0, u32* dst1, const u32* src0, const u32* src1, const u32* src2, unsigned count)
  378. {
  379.   unsigned i;
  380.  
  381.   for(i=0;i<count;++i) {
  382.     unsigned char mask;
  383.  
  384.     u32 c[9];
  385.  
  386.     c[1] = src0[0];
  387.     c[4] = src1[0];
  388.     c[7] = src2[0];
  389.  
  390.     if (i>0) {
  391.       c[0] = src0[-1];
  392.       c[3] = src1[-1];
  393.       c[6] = src2[-1];
  394.     } else {
  395.       c[0] = c[1];
  396.       c[3] = c[4];
  397.       c[6] = c[7];
  398.     }
  399.  
  400.     if (i<count-1) {
  401.       c[2] = src0[1];
  402.       c[5] = src1[1];
  403.       c[8] = src2[1];
  404.     } else {
  405.       c[2] = c[1];
  406.       c[5] = c[4];
  407.       c[8] = c[7];
  408.     }
  409.  
  410.     mask = 0;
  411.  
  412.     if (c[0] != c[4])
  413.       mask |= 1 << 0;
  414.     if (c[1] != c[4])
  415.       mask |= 1 << 1;
  416.     if (c[2] != c[4])
  417.       mask |= 1 << 2;
  418.     if (c[3] != c[4])
  419.       mask |= 1 << 3;
  420.     if (c[5] != c[4])
  421.       mask |= 1 << 4;
  422.     if (c[6] != c[4])
  423.       mask |= 1 << 5;
  424.     if (c[7] != c[4])
  425.       mask |= 1 << 6;
  426.     if (c[8] != c[4])
  427.       mask |= 1 << 7;
  428.  
  429. #define P0 dst0[0]
  430. #define P1 dst0[1]
  431. #define P2 dst1[0]
  432. #define P3 dst1[1]
  433. #define MUR (c[1] != c[5])
  434. #define MDR (c[5] != c[7])
  435. #define MDL (c[7] != c[3])
  436. #define MUL (c[3] != c[1])
  437. #define IC(p0) c[p0]
  438. #define I11(p0,p1) interp_32_11(c[p0], c[p1])
  439. #define I211(p0,p1,p2) interp_32_211(c[p0], c[p1], c[p2])
  440. #define I31(p0,p1) interp_32_31(c[p0], c[p1])
  441. #define I332(p0,p1,p2) interp_32_332(c[p0], c[p1], c[p2])
  442. #define I431(p0,p1,p2) interp_32_431(c[p0], c[p1], c[p2])
  443. #define I521(p0,p1,p2) interp_32_521(c[p0], c[p1], c[p2])
  444. #define I53(p0,p1) interp_32_53(c[p0], c[p1])
  445. #define I611(p0,p1,p2) interp_32_611(c[p0], c[p1], c[p2])
  446. #define I71(p0,p1) interp_32_71(c[p0], c[p1])
  447. #define I772(p0,p1,p2) interp_32_772(c[p0], c[p1], c[p2])
  448. #define I97(p0,p1) interp_32_97(c[p0], c[p1])
  449. #define I1411(p0,p1,p2) interp_32_1411(c[p0], c[p1], c[p2])
  450. #define I151(p0,p1) interp_32_151(c[p0], c[p1])
  451.  
  452.     switch (mask) {
  453. #include "lq2x.h"
  454.     }
  455.  
  456. #undef P0
  457. #undef P1
  458. #undef P2
  459. #undef P3
  460. #undef MUR
  461. #undef MDR
  462. #undef MDL
  463. #undef MUL
  464. #undef IC
  465. #undef I11
  466. #undef I211
  467. #undef I31
  468. #undef I332
  469. #undef I431
  470. #undef I521
  471. #undef I53
  472. #undef I611
  473. #undef I71
  474. #undef I772
  475. #undef I97
  476. #undef I1411
  477. #undef I151
  478.  
  479.     src0 += 1;
  480.     src1 += 1;
  481.     src2 += 1;
  482.     dst0 += 2;
  483.     dst1 += 2;
  484.   }
  485. }
  486.  
  487. void hq2x(u8 *srcPtr, u32 srcPitch, u8 * /* deltaPtr */,
  488.           u8 *dstPtr, u32 dstPitch, int width, int height)
  489. {
  490.   u16 *dst0 = (u16 *)dstPtr;
  491.   u16 *dst1 = dst0 + (dstPitch >> 1);
  492.   
  493.   u16 *src0 = (u16 *)srcPtr;
  494.   u16 *src1 = src0 + (srcPitch >> 1);
  495.   u16 *src2 = src1 + (srcPitch >> 1);
  496.   
  497.   hq2x_16_def(dst0, dst1, src0, src0, src1, width);
  498.   
  499.   int count = height;
  500.   
  501.   count -= 2;
  502.   while(count) {
  503.     dst0 += dstPitch;
  504.     dst1 += dstPitch;
  505.     hq2x_16_def(dst0, dst1, src0, src1, src2, width);
  506.     src0 = src1;
  507.     src1 = src2;
  508.     src2 += srcPitch >> 1;
  509.     --count;
  510.   }
  511.   dst0 += dstPitch;
  512.   dst1 += dstPitch;
  513.   hq2x_16_def(dst0, dst1, src0, src1, src1, width);
  514. }
  515.  
  516. void hq2x32(u8 *srcPtr, u32 srcPitch, u8 * /* deltaPtr */,
  517.             u8 *dstPtr, u32 dstPitch, int width, int height)
  518. {
  519.   u32 *dst0 = (u32 *)dstPtr;
  520.   u32 *dst1 = dst0 + (dstPitch >> 2);
  521.   
  522.   u32 *src0 = (u32 *)srcPtr;
  523.   u32 *src1 = src0 + (srcPitch >> 2);
  524.   u32 *src2 = src1 + (srcPitch >> 2);
  525.   hq2x_32_def(dst0, dst1, src0, src0, src1, width);
  526.   
  527.   int count = height;
  528.   
  529.   count -= 2;
  530.   while(count) {
  531.     dst0 += dstPitch >> 1;
  532.     dst1 += dstPitch >> 1;
  533.     hq2x_32_def(dst0, dst1, src0, src1, src2, width);
  534.     src0 = src1;
  535.     src1 = src2;
  536.     src2 += srcPitch >> 2;
  537.     --count;
  538.   }
  539.   dst0 += dstPitch >> 1;
  540.   dst1 += dstPitch >> 1;
  541.   hq2x_32_def(dst0, dst1, src0, src1, src1, width);
  542. }
  543.  
  544. void lq2x(u8 *srcPtr, u32 srcPitch, u8 * /* deltaPtr */,
  545.           u8 *dstPtr, u32 dstPitch, int width, int height)
  546. {
  547.   u16 *dst0 = (u16 *)dstPtr;
  548.   u16 *dst1 = dst0 + (dstPitch >> 1);
  549.   
  550.   u16 *src0 = (u16 *)srcPtr;
  551.   u16 *src1 = src0 + (srcPitch >> 1);
  552.   u16 *src2 = src1 + (srcPitch >> 1);
  553.   
  554.   lq2x_16_def(dst0, dst1, src0, src0, src1, width);
  555.   
  556.   int count = height;
  557.   
  558.   count -= 2;
  559.   while(count) {
  560.     dst0 += dstPitch;
  561.     dst1 += dstPitch;
  562.     hq2x_16_def(dst0, dst1, src0, src1, src2, width);
  563.     src0 = src1;
  564.     src1 = src2;
  565.     src2 += srcPitch >> 1;
  566.     --count;
  567.   }
  568.   dst0 += dstPitch;
  569.   dst1 += dstPitch;
  570.   lq2x_16_def(dst0, dst1, src0, src1, src1, width);
  571. }
  572.  
  573. void lq2x32(u8 *srcPtr, u32 srcPitch, u8 * /* deltaPtr */,
  574.             u8 *dstPtr, u32 dstPitch, int width, int height)
  575. {
  576.   u32 *dst0 = (u32 *)dstPtr;
  577.   u32 *dst1 = dst0 + (dstPitch >> 2);
  578.   
  579.   u32 *src0 = (u32 *)srcPtr;
  580.   u32 *src1 = src0 + (srcPitch >> 2);
  581.   u32 *src2 = src1 + (srcPitch >> 2);
  582.   lq2x_32_def(dst0, dst1, src0, src0, src1, width);
  583.   
  584.   int count = height;
  585.   
  586.   count -= 2;
  587.   while(count) {
  588.     dst0 += dstPitch >> 1;
  589.     dst1 += dstPitch >> 1;
  590.     hq2x_32_def(dst0, dst1, src0, src1, src2, width);
  591.     src0 = src1;
  592.     src1 = src2;
  593.     src2 += srcPitch >> 2;
  594.     --count;
  595.   }
  596.   dst0 += dstPitch >> 1;
  597.   dst1 += dstPitch >> 1;
  598.   lq2x_32_def(dst0, dst1, src0, src1, src1, width);
  599. }
  600.  
  601. void hq2x_init(unsigned bits_per_pixel)
  602. {
  603.   interp_set(bits_per_pixel);
  604. }
  605.