/extlibs/libmng/libmng_filter.c

https://bitbucket.org/khurley/devil · C · 890 lines · 640 code · 191 blank · 59 comment · 48 complexity · a3c3536036029b406e87f795ca0a5bb7 MD5 · raw file

  1. /* ************************************************************************** */
  2. /* * For conditions of distribution and use, * */
  3. /* * see copyright notice in libmng.h * */
  4. /* ************************************************************************** */
  5. /* * * */
  6. /* * project : libmng * */
  7. /* * file : libmng_filter.c copyright (c) 2000 G.Juyn * */
  8. /* * version : 1.0.0 * */
  9. /* * * */
  10. /* * purpose : Filtering routines (implementation) * */
  11. /* * * */
  12. /* * author : G.Juyn * */
  13. /* * web : http://www.3-t.com * */
  14. /* * email : mailto:info@3-t.com * */
  15. /* * * */
  16. /* * comment : implementation of the filtering routines * */
  17. /* * * */
  18. /* * changes : 0.5.1 - 05/08/2000 - G.Juyn * */
  19. /* * - changed strict-ANSI stuff * */
  20. /* * 0.5.1 - 05/12/2000 - G.Juyn * */
  21. /* * - changed trace to macro for callback error-reporting * */
  22. /* * * */
  23. /* * 0.9.2 - 08/05/2000 - G.Juyn * */
  24. /* * - changed file-prefixes * */
  25. /* * * */
  26. /* * 0.9.3 - 09/07/2000 - G.Juyn * */
  27. /* * - added support for new filter_types * */
  28. /* * * */
  29. /* ************************************************************************** */
  30. #include "libmng.h"
  31. #include "libmng_data.h"
  32. #include "libmng_error.h"
  33. #include "libmng_trace.h"
  34. #ifdef __BORLANDC__
  35. #pragma hdrstop
  36. #endif
  37. #include "libmng_filter.h"
  38. #if defined(__BORLANDC__) && defined(MNG_STRICT_ANSI)
  39. #pragma option -A /* force ANSI-C */
  40. #endif
  41. /* ************************************************************************** */
  42. #ifdef MNG_INCLUDE_FILTERS
  43. /* ************************************************************************** */
  44. mng_retcode filter_a_row (mng_datap pData)
  45. {
  46. mng_retcode iRetcode;
  47. #ifdef MNG_SUPPORT_TRACE
  48. MNG_TRACE (pData, MNG_FN_FILTER_A_ROW, MNG_LC_START)
  49. #endif
  50. switch (*(pData->pWorkrow + pData->iFilterofs))
  51. {
  52. case 1 : {
  53. iRetcode = filter_sub (pData);
  54. break;
  55. }
  56. case 2 : {
  57. iRetcode = filter_up (pData);
  58. break;
  59. }
  60. case 3 : {
  61. iRetcode = filter_average (pData);
  62. break;
  63. }
  64. case 4 : {
  65. iRetcode = filter_paeth (pData);
  66. break;
  67. }
  68. default : iRetcode = MNG_INVALIDFILTER;
  69. }
  70. #ifdef MNG_SUPPORT_TRACE
  71. MNG_TRACE (pData, MNG_FN_FILTER_A_ROW, MNG_LC_END)
  72. #endif
  73. return iRetcode;
  74. }
  75. /* ************************************************************************** */
  76. mng_retcode filter_sub (mng_datap pData)
  77. {
  78. mng_uint32 iBpp;
  79. mng_uint8p pRawx;
  80. mng_uint8p pRawx_prev;
  81. mng_int32 iX;
  82. #ifdef MNG_SUPPORT_TRACE
  83. MNG_TRACE (pData, MNG_FN_FILTER_SUB, MNG_LC_START)
  84. #endif
  85. iBpp = pData->iFilterbpp;
  86. pRawx = pData->pWorkrow + pData->iPixelofs + iBpp;
  87. pRawx_prev = pData->pWorkrow + pData->iPixelofs;
  88. for (iX = iBpp; iX < pData->iRowsize; iX++)
  89. {
  90. *pRawx = (mng_uint8)(*pRawx + *pRawx_prev);
  91. pRawx++;
  92. pRawx_prev++;
  93. }
  94. #ifdef MNG_SUPPORT_TRACE
  95. MNG_TRACE (pData, MNG_FN_FILTER_SUB, MNG_LC_END)
  96. #endif
  97. return MNG_NOERROR;
  98. }
  99. /* ************************************************************************** */
  100. mng_retcode filter_up (mng_datap pData)
  101. {
  102. mng_uint8p pRawx;
  103. mng_uint8p pPriorx;
  104. mng_int32 iX;
  105. #ifdef MNG_SUPPORT_TRACE
  106. MNG_TRACE (pData, MNG_FN_FILTER_UP, MNG_LC_START)
  107. #endif
  108. pRawx = pData->pWorkrow + pData->iPixelofs;
  109. pPriorx = pData->pPrevrow + pData->iPixelofs;
  110. for (iX = 0; iX < pData->iRowsize; iX++)
  111. {
  112. *pRawx = (mng_uint8)(*pRawx + *pPriorx);
  113. pRawx++;
  114. pPriorx++;
  115. }
  116. #ifdef MNG_SUPPORT_TRACE
  117. MNG_TRACE (pData, MNG_FN_FILTER_UP, MNG_LC_END)
  118. #endif
  119. return MNG_NOERROR;
  120. }
  121. /* ************************************************************************** */
  122. mng_retcode filter_average (mng_datap pData)
  123. {
  124. mng_int32 iBpp;
  125. mng_uint8p pRawx;
  126. mng_uint8p pRawx_prev;
  127. mng_uint8p pPriorx;
  128. mng_int32 iX;
  129. #ifdef MNG_SUPPORT_TRACE
  130. MNG_TRACE (pData, MNG_FN_FILTER_AVERAGE, MNG_LC_START)
  131. #endif
  132. iBpp = pData->iFilterbpp;
  133. pRawx = pData->pWorkrow + pData->iPixelofs;
  134. pPriorx = pData->pPrevrow + pData->iPixelofs;
  135. pRawx_prev = pData->pWorkrow + pData->iPixelofs;
  136. for (iX = 0; iX < iBpp; iX++)
  137. {
  138. *pRawx = (mng_uint8)(*pRawx + ((*pPriorx) >> 1));
  139. pRawx++;
  140. pPriorx++;
  141. }
  142. for (iX = iBpp; iX < pData->iRowsize; iX++)
  143. {
  144. *pRawx = (mng_uint8)(*pRawx + ((*pRawx_prev + *pPriorx) >> 1));
  145. pRawx++;
  146. pPriorx++;
  147. pRawx_prev++;
  148. }
  149. #ifdef MNG_SUPPORT_TRACE
  150. MNG_TRACE (pData, MNG_FN_FILTER_AVERAGE, MNG_LC_END)
  151. #endif
  152. return MNG_NOERROR;
  153. }
  154. /* ************************************************************************** */
  155. mng_retcode filter_paeth (mng_datap pData)
  156. {
  157. mng_int32 iBpp;
  158. mng_uint8p pRawx;
  159. mng_uint8p pRawx_prev;
  160. mng_uint8p pPriorx;
  161. mng_uint8p pPriorx_prev;
  162. mng_int32 iX;
  163. mng_uint32 iA, iB, iC;
  164. mng_uint32 iP;
  165. mng_uint32 iPa, iPb, iPc;
  166. #ifdef MNG_SUPPORT_TRACE
  167. MNG_TRACE (pData, MNG_FN_FILTER_PAETH, MNG_LC_START)
  168. #endif
  169. iBpp = pData->iFilterbpp;
  170. pRawx = pData->pWorkrow + pData->iPixelofs;
  171. pPriorx = pData->pPrevrow + pData->iPixelofs;
  172. pRawx_prev = pData->pWorkrow + pData->iPixelofs;
  173. pPriorx_prev = pData->pPrevrow + pData->iPixelofs;
  174. for (iX = 0; iX < iBpp; iX++)
  175. {
  176. *pRawx = (mng_uint8)(*pRawx + *pPriorx);
  177. pRawx++;
  178. pPriorx++;
  179. }
  180. for (iX = iBpp; iX < pData->iRowsize; iX++)
  181. {
  182. iA = (mng_uint32)*pRawx_prev;
  183. iB = (mng_uint32)*pPriorx;
  184. iC = (mng_uint32)*pPriorx_prev;
  185. iP = iA + iB - iC;
  186. iPa = abs (iP - iA);
  187. iPb = abs (iP - iB);
  188. iPc = abs (iP - iC);
  189. if ((iPa <= iPb) && (iPa <= iPc))
  190. *pRawx = (mng_uint8)(*pRawx + iA);
  191. else
  192. if (iPb <= iPc)
  193. *pRawx = (mng_uint8)(*pRawx + iB);
  194. else
  195. *pRawx = (mng_uint8)(*pRawx + iC);
  196. pRawx++;
  197. pPriorx++;
  198. pRawx_prev++;
  199. pPriorx_prev++;
  200. }
  201. #ifdef MNG_SUPPORT_TRACE
  202. MNG_TRACE (pData, MNG_FN_FILTER_PAETH, MNG_LC_END)
  203. #endif
  204. return MNG_NOERROR;
  205. }
  206. /* ************************************************************************** */
  207. /* ************************************************************************** */
  208. mng_retcode init_rowdiffering (mng_datap pData)
  209. {
  210. mng_uint8p pRawi, pRawo;
  211. mng_int32 iX;
  212. #ifdef MNG_SUPPORT_TRACE
  213. MNG_TRACE (pData, MNG_FN_INIT_ROWDIFFERING, MNG_LC_START)
  214. #endif
  215. if (pData->iFilter & 0x40) /* has leveling parameters ? */
  216. {
  217. switch (pData->iColortype) /* salvage leveling parameters */
  218. {
  219. case 0 : { /* gray */
  220. if (pData->iBitdepth <= 8)
  221. pData->iLevel0 = (mng_uint16)*pData->pWorkrow;
  222. else
  223. pData->iLevel0 = mng_get_uint16 (pData->pWorkrow);
  224. break;
  225. }
  226. case 2 : { /* rgb */
  227. if (pData->iBitdepth <= 8)
  228. {
  229. pData->iLevel0 = (mng_uint16)*pData->pWorkrow;
  230. pData->iLevel1 = (mng_uint16)*(pData->pWorkrow+1);
  231. pData->iLevel2 = (mng_uint16)*(pData->pWorkrow+2);
  232. }
  233. else
  234. {
  235. pData->iLevel0 = mng_get_uint16 (pData->pWorkrow);
  236. pData->iLevel1 = mng_get_uint16 (pData->pWorkrow+2);
  237. pData->iLevel2 = mng_get_uint16 (pData->pWorkrow+4);
  238. }
  239. break;
  240. }
  241. case 3 : { /* indexed */
  242. pData->iLevel0 = (mng_uint16)*pData->pWorkrow;
  243. break;
  244. }
  245. case 4 : { /* gray+alpha */
  246. if (pData->iBitdepth <= 8)
  247. {
  248. pData->iLevel0 = (mng_uint16)*pData->pWorkrow;
  249. pData->iLevel1 = (mng_uint16)*(pData->pWorkrow+1);
  250. }
  251. else
  252. {
  253. pData->iLevel0 = mng_get_uint16 (pData->pWorkrow);
  254. pData->iLevel1 = mng_get_uint16 (pData->pWorkrow+2);
  255. }
  256. break;
  257. }
  258. case 6 : { /* rgb+alpha */
  259. if (pData->iBitdepth <= 8)
  260. {
  261. pData->iLevel0 = (mng_uint16)*pData->pWorkrow;
  262. pData->iLevel1 = (mng_uint16)*(pData->pWorkrow+1);
  263. pData->iLevel2 = (mng_uint16)*(pData->pWorkrow+2);
  264. pData->iLevel3 = (mng_uint16)*(pData->pWorkrow+3);
  265. }
  266. else
  267. {
  268. pData->iLevel0 = mng_get_uint16 (pData->pWorkrow);
  269. pData->iLevel1 = mng_get_uint16 (pData->pWorkrow+2);
  270. pData->iLevel2 = mng_get_uint16 (pData->pWorkrow+4);
  271. pData->iLevel3 = mng_get_uint16 (pData->pWorkrow+6);
  272. }
  273. break;
  274. }
  275. }
  276. }
  277. /* shift the entire row back in place */
  278. pRawi = pData->pWorkrow + pData->iFilterofs;
  279. pRawo = pData->pWorkrow;
  280. for (iX = 0; iX < pData->iRowsize + pData->iPixelofs - pData->iFilterofs; iX++)
  281. *pRawo++ = *pRawi++;
  282. pData->iFilterofs = 0; /* indicate so ! */
  283. if (pData->iFilter & 0x01) /* no adaptive filtering ? */
  284. pData->iPixelofs = pData->iFilterofs;
  285. else
  286. pData->iPixelofs = pData->iFilterofs + 1;
  287. #ifdef MNG_SUPPORT_TRACE
  288. MNG_TRACE (pData, MNG_FN_INIT_ROWDIFFERING, MNG_LC_END)
  289. #endif
  290. return MNG_NOERROR;
  291. }
  292. /* ************************************************************************** */
  293. mng_retcode differ_g1 (mng_datap pData)
  294. {
  295. mng_uint8p pRawi, pRawo;
  296. mng_int32 iX;
  297. #ifdef MNG_SUPPORT_TRACE
  298. MNG_TRACE (pData, MNG_FN_DIFFER_G1, MNG_LC_START)
  299. #endif
  300. if (pData->iLevel0 & 0x01) /* is it uneven level ? */
  301. {
  302. pRawi = pData->pWorkrow + pData->iPixelofs;
  303. pRawo = pData->pPrevrow + pData->iPixelofs;
  304. /* just invert every bit */
  305. for (iX = 0; iX < pData->iRowsize; iX++)
  306. *pRawo++ = (mng_uint8)(~(*pRawi++));
  307. }
  308. #ifdef MNG_SUPPORT_TRACE
  309. MNG_TRACE (pData, MNG_FN_DIFFER_G1, MNG_LC_END)
  310. #endif
  311. return MNG_NOERROR;
  312. }
  313. /* ************************************************************************** */
  314. mng_retcode differ_g2 (mng_datap pData)
  315. {
  316. mng_uint8p pRawi, pRawo;
  317. mng_int32 iX;
  318. mng_int32 iC, iS;
  319. mng_uint8 iB, iN, iQ;
  320. #ifdef MNG_SUPPORT_TRACE
  321. MNG_TRACE (pData, MNG_FN_DIFFER_G2, MNG_LC_START)
  322. #endif
  323. pRawi = pData->pWorkrow + pData->iPixelofs;
  324. pRawo = pData->pPrevrow + pData->iPixelofs;
  325. iC = 0;
  326. iB = 0;
  327. iN = 0;
  328. iS = 0;
  329. for (iX = 0; iX < pData->iRowsamples; iX++)
  330. {
  331. if (!iC)
  332. {
  333. iC = 4;
  334. iB = *pRawi++;
  335. iN = 0;
  336. iS = 8;
  337. }
  338. iS -= 2;
  339. iQ = (mng_uint8)(((iB >> iS) + pData->iLevel0) & 0x03);
  340. iN = (mng_uint8)((iN << 2) + iQ);
  341. iC--;
  342. if (!iC)
  343. *pRawo++ = iN;
  344. }
  345. if (iC)
  346. *pRawo = (mng_uint8)(iN << iS);
  347. #ifdef MNG_SUPPORT_TRACE
  348. MNG_TRACE (pData, MNG_FN_DIFFER_G2, MNG_LC_END)
  349. #endif
  350. return MNG_NOERROR;
  351. }
  352. /* ************************************************************************** */
  353. mng_retcode differ_g4 (mng_datap pData)
  354. {
  355. mng_uint8p pRawi, pRawo;
  356. mng_int32 iX;
  357. mng_int32 iC, iS;
  358. mng_uint8 iB, iN, iQ;
  359. #ifdef MNG_SUPPORT_TRACE
  360. MNG_TRACE (pData, MNG_FN_DIFFER_G4, MNG_LC_START)
  361. #endif
  362. pRawi = pData->pWorkrow + pData->iPixelofs;
  363. pRawo = pData->pPrevrow + pData->iPixelofs;
  364. iC = 0;
  365. iB = 0;
  366. iN = 0;
  367. iS = 0;
  368. for (iX = 0; iX < pData->iRowsamples; iX++)
  369. {
  370. if (!iC)
  371. {
  372. iC = 2;
  373. iB = *pRawi++;
  374. iN = 0;
  375. iS = 8;
  376. }
  377. iS -= 4;
  378. iQ = (mng_uint8)(((iB >> iS) + pData->iLevel0) & 0x0F);
  379. iN = (mng_uint8)((iN << 4) + iQ);
  380. iC--;
  381. if (!iC)
  382. *pRawo++ = iN;
  383. }
  384. if (iC)
  385. *pRawo = (mng_uint8)(iN << iS);
  386. #ifdef MNG_SUPPORT_TRACE
  387. MNG_TRACE (pData, MNG_FN_DIFFER_G4, MNG_LC_END)
  388. #endif
  389. return MNG_NOERROR;
  390. }
  391. /* ************************************************************************** */
  392. mng_retcode differ_g8 (mng_datap pData)
  393. {
  394. mng_uint8p pRawi, pRawo;
  395. mng_int32 iX;
  396. #ifdef MNG_SUPPORT_TRACE
  397. MNG_TRACE (pData, MNG_FN_DIFFER_G8, MNG_LC_START)
  398. #endif
  399. pRawi = pData->pWorkrow + pData->iPixelofs;
  400. pRawo = pData->pPrevrow + pData->iPixelofs;
  401. for (iX = 0; iX < pData->iRowsamples; iX++)
  402. {
  403. *pRawo++ = (mng_uint8)(((mng_uint16)*pRawi + pData->iLevel0) & 0xFF);
  404. pRawi++;
  405. }
  406. #ifdef MNG_SUPPORT_TRACE
  407. MNG_TRACE (pData, MNG_FN_DIFFER_G8, MNG_LC_END)
  408. #endif
  409. return MNG_NOERROR;
  410. }
  411. /* ************************************************************************** */
  412. mng_retcode differ_g16 (mng_datap pData)
  413. {
  414. mng_uint16p pRawi, pRawo;
  415. mng_int32 iX;
  416. #ifdef MNG_SUPPORT_TRACE
  417. MNG_TRACE (pData, MNG_FN_DIFFER_G16, MNG_LC_START)
  418. #endif
  419. pRawi = (mng_uint16p)(pData->pWorkrow + pData->iPixelofs);
  420. pRawo = (mng_uint16p)(pData->pPrevrow + pData->iPixelofs);
  421. for (iX = 0; iX < pData->iRowsamples; iX++)
  422. {
  423. *pRawo++ = (mng_uint16)(((mng_uint32)*pRawi + (mng_uint32)pData->iLevel0) & 0xFFFF);
  424. pRawi++;
  425. }
  426. #ifdef MNG_SUPPORT_TRACE
  427. MNG_TRACE (pData, MNG_FN_DIFFER_G16, MNG_LC_END)
  428. #endif
  429. return MNG_NOERROR;
  430. }
  431. /* ************************************************************************** */
  432. mng_retcode differ_rgb8 (mng_datap pData)
  433. {
  434. mng_uint8p pRawi, pRawo;
  435. mng_int32 iX;
  436. #ifdef MNG_SUPPORT_TRACE
  437. MNG_TRACE (pData, MNG_FN_DIFFER_RGB8, MNG_LC_START)
  438. #endif
  439. pRawi = pData->pWorkrow + pData->iPixelofs;
  440. pRawo = pData->pPrevrow + pData->iPixelofs;
  441. for (iX = 0; iX < pData->iRowsamples; iX++)
  442. {
  443. *(pRawo+1) = (mng_uint8)(((mng_uint16)*(pRawi+1) + pData->iLevel1) & 0xFF);
  444. *pRawo = (mng_uint8)(((mng_uint16)*pRawi + pData->iLevel0 +
  445. (mng_uint16)*(pRawo+1)) & 0xFF);
  446. *(pRawo+2) = (mng_uint8)(((mng_uint16)*(pRawi+2) + pData->iLevel2 +
  447. (mng_uint16)*(pRawo+1)) & 0xFF);
  448. pRawi += 3;
  449. pRawo += 3;
  450. }
  451. #ifdef MNG_SUPPORT_TRACE
  452. MNG_TRACE (pData, MNG_FN_DIFFER_RGB8, MNG_LC_END)
  453. #endif
  454. return MNG_NOERROR;
  455. }
  456. /* ************************************************************************** */
  457. mng_retcode differ_rgb16 (mng_datap pData)
  458. {
  459. mng_uint16p pRawi, pRawo;
  460. mng_int32 iX;
  461. #ifdef MNG_SUPPORT_TRACE
  462. MNG_TRACE (pData, MNG_FN_DIFFER_RGB16, MNG_LC_START)
  463. #endif
  464. pRawi = (mng_uint16p)(pData->pWorkrow + pData->iPixelofs);
  465. pRawo = (mng_uint16p)(pData->pPrevrow + pData->iPixelofs);
  466. for (iX = 0; iX < pData->iRowsamples; iX++)
  467. {
  468. *(pRawo+1) = (mng_uint16)(((mng_uint32)*(pRawi+1) + (mng_uint32)pData->iLevel1) & 0xFFFF);
  469. *pRawo = (mng_uint16)(((mng_uint32)*pRawi + (mng_uint32)pData->iLevel0 +
  470. (mng_uint32)*(pRawo+1)) & 0xFFFF);
  471. *(pRawo+2) = (mng_uint16)(((mng_uint32)*(pRawi+2) + (mng_uint32)pData->iLevel2 +
  472. (mng_uint32)*(pRawo+1)) & 0xFFFF);
  473. pRawi += 3;
  474. pRawo += 3;
  475. }
  476. #ifdef MNG_SUPPORT_TRACE
  477. MNG_TRACE (pData, MNG_FN_DIFFER_RGB16, MNG_LC_END)
  478. #endif
  479. return MNG_NOERROR;
  480. }
  481. /* ************************************************************************** */
  482. mng_retcode differ_idx1 (mng_datap pData)
  483. {
  484. mng_uint8p pRawi, pRawo;
  485. mng_int32 iX;
  486. #ifdef MNG_SUPPORT_TRACE
  487. MNG_TRACE (pData, MNG_FN_DIFFER_IDX1, MNG_LC_START)
  488. #endif
  489. if (pData->iLevel0 & 0x01) /* is it uneven level ? */
  490. {
  491. pRawi = pData->pWorkrow + pData->iPixelofs;
  492. pRawo = pData->pPrevrow + pData->iPixelofs;
  493. /* just invert every bit */
  494. for (iX = 0; iX < pData->iRowsize; iX++)
  495. *pRawo++ = (mng_uint8)(~(*pRawi++));
  496. }
  497. #ifdef MNG_SUPPORT_TRACE
  498. MNG_TRACE (pData, MNG_FN_DIFFER_IDX1, MNG_LC_END)
  499. #endif
  500. return MNG_NOERROR;
  501. }
  502. /* ************************************************************************** */
  503. mng_retcode differ_idx2 (mng_datap pData)
  504. {
  505. mng_uint8p pRawi, pRawo;
  506. mng_int32 iX;
  507. mng_int32 iC, iS;
  508. mng_uint8 iB, iN, iQ;
  509. #ifdef MNG_SUPPORT_TRACE
  510. MNG_TRACE (pData, MNG_FN_DIFFER_IDX2, MNG_LC_START)
  511. #endif
  512. pRawi = pData->pWorkrow + pData->iPixelofs;
  513. pRawo = pData->pPrevrow + pData->iPixelofs;
  514. iC = 0;
  515. iB = 0;
  516. iN = 0;
  517. iS = 0;
  518. for (iX = 0; iX < pData->iRowsamples; iX++)
  519. {
  520. if (!iC)
  521. {
  522. iC = 4;
  523. iB = *pRawi++;
  524. iN = 0;
  525. iS = 8;
  526. }
  527. iS -= 2;
  528. iQ = (mng_uint8)(((iB >> iS) + pData->iLevel0) & 0x03);
  529. iN = (mng_uint8)((iN << 2) + iQ);
  530. iC--;
  531. if (!iC)
  532. *pRawo++ = iN;
  533. }
  534. if (iC)
  535. *pRawo = (mng_uint8)(iN << iS);
  536. #ifdef MNG_SUPPORT_TRACE
  537. MNG_TRACE (pData, MNG_FN_DIFFER_IDX2, MNG_LC_END)
  538. #endif
  539. return MNG_NOERROR;
  540. }
  541. /* ************************************************************************** */
  542. mng_retcode differ_idx4 (mng_datap pData)
  543. {
  544. mng_uint8p pRawi, pRawo;
  545. mng_int32 iX;
  546. mng_int32 iC, iS;
  547. mng_uint8 iB, iN, iQ;
  548. #ifdef MNG_SUPPORT_TRACE
  549. MNG_TRACE (pData, MNG_FN_DIFFER_IDX4, MNG_LC_START)
  550. #endif
  551. pRawi = pData->pWorkrow + pData->iPixelofs;
  552. pRawo = pData->pPrevrow + pData->iPixelofs;
  553. iC = 0;
  554. iB = 0;
  555. iN = 0;
  556. iS = 0;
  557. for (iX = 0; iX < pData->iRowsamples; iX++)
  558. {
  559. if (!iC)
  560. {
  561. iC = 2;
  562. iB = *pRawi++;
  563. iN = 0;
  564. iS = 8;
  565. }
  566. iS -= 4;
  567. iQ = (mng_uint8)(((iB >> iS) + pData->iLevel0) & 0x0F);
  568. iN = (mng_uint8)((iN << 4) + iQ);
  569. iC--;
  570. if (!iC)
  571. *pRawo++ = iN;
  572. }
  573. if (iC)
  574. *pRawo = (mng_uint8)(iN << iS);
  575. #ifdef MNG_SUPPORT_TRACE
  576. MNG_TRACE (pData, MNG_FN_DIFFER_IDX4, MNG_LC_END)
  577. #endif
  578. return MNG_NOERROR;
  579. }
  580. /* ************************************************************************** */
  581. mng_retcode differ_idx8 (mng_datap pData)
  582. {
  583. mng_uint8p pRawi, pRawo;
  584. mng_int32 iX;
  585. #ifdef MNG_SUPPORT_TRACE
  586. MNG_TRACE (pData, MNG_FN_DIFFER_IDX8, MNG_LC_START)
  587. #endif
  588. pRawi = pData->pWorkrow + pData->iPixelofs;
  589. pRawo = pData->pPrevrow + pData->iPixelofs;
  590. for (iX = 0; iX < pData->iRowsamples; iX++)
  591. {
  592. *pRawo++ = (mng_uint8)(((mng_uint16)*pRawi + pData->iLevel0) & 0xFF);
  593. pRawi++;
  594. }
  595. #ifdef MNG_SUPPORT_TRACE
  596. MNG_TRACE (pData, MNG_FN_DIFFER_IDX8, MNG_LC_END)
  597. #endif
  598. return MNG_NOERROR;
  599. }
  600. /* ************************************************************************** */
  601. mng_retcode differ_ga8 (mng_datap pData)
  602. {
  603. mng_uint8p pRawi, pRawo;
  604. mng_int32 iX;
  605. #ifdef MNG_SUPPORT_TRACE
  606. MNG_TRACE (pData, MNG_FN_DIFFER_GA8, MNG_LC_START)
  607. #endif
  608. pRawi = pData->pWorkrow + pData->iPixelofs;
  609. pRawo = pData->pPrevrow + pData->iPixelofs;
  610. for (iX = 0; iX < pData->iRowsamples; iX++)
  611. {
  612. *pRawo = (mng_uint8)(((mng_uint16)*pRawi + pData->iLevel0) & 0xFF);
  613. *(pRawo+1) = (mng_uint8)(((mng_uint16)*(pRawi+1) + pData->iLevel1) & 0xFF);
  614. pRawi += 2;
  615. pRawo += 2;
  616. }
  617. #ifdef MNG_SUPPORT_TRACE
  618. MNG_TRACE (pData, MNG_FN_DIFFER_GA8, MNG_LC_END)
  619. #endif
  620. return MNG_NOERROR;
  621. }
  622. /* ************************************************************************** */
  623. mng_retcode differ_ga16 (mng_datap pData)
  624. {
  625. mng_uint16p pRawi, pRawo;
  626. mng_int32 iX;
  627. #ifdef MNG_SUPPORT_TRACE
  628. MNG_TRACE (pData, MNG_FN_DIFFER_GA16, MNG_LC_START)
  629. #endif
  630. pRawi = (mng_uint16p)(pData->pWorkrow + pData->iPixelofs);
  631. pRawo = (mng_uint16p)(pData->pPrevrow + pData->iPixelofs);
  632. for (iX = 0; iX < pData->iRowsamples; iX++)
  633. {
  634. *pRawo = (mng_uint16)(((mng_uint32)*pRawi + (mng_uint32)pData->iLevel0) & 0xFFFF);
  635. *(pRawo+1) = (mng_uint16)(((mng_uint32)*(pRawi+1) + (mng_uint32)pData->iLevel1) & 0xFFFF);
  636. pRawi += 2;
  637. }
  638. #ifdef MNG_SUPPORT_TRACE
  639. MNG_TRACE (pData, MNG_FN_DIFFER_GA16, MNG_LC_END)
  640. #endif
  641. return MNG_NOERROR;
  642. }
  643. /* ************************************************************************** */
  644. mng_retcode differ_rgba8 (mng_datap pData)
  645. {
  646. mng_uint8p pRawi, pRawo;
  647. mng_int32 iX;
  648. #ifdef MNG_SUPPORT_TRACE
  649. MNG_TRACE (pData, MNG_FN_DIFFER_RGBA8, MNG_LC_START)
  650. #endif
  651. pRawi = pData->pWorkrow + pData->iPixelofs;
  652. pRawo = pData->pPrevrow + pData->iPixelofs;
  653. for (iX = 0; iX < pData->iRowsamples; iX++)
  654. {
  655. *(pRawo+1) = (mng_uint8)(((mng_uint16)*(pRawi+1) + pData->iLevel1) & 0xFF);
  656. *pRawo = (mng_uint8)(((mng_uint16)*pRawi + pData->iLevel0 +
  657. (mng_uint16)*(pRawo+1)) & 0xFF);
  658. *(pRawo+2) = (mng_uint8)(((mng_uint16)*(pRawi+2) + pData->iLevel2 +
  659. (mng_uint16)*(pRawo+1)) & 0xFF);
  660. *(pRawo+3) = (mng_uint8)(((mng_uint16)*(pRawi+3) + pData->iLevel3) & 0xFF);
  661. pRawi += 4;
  662. pRawo += 4;
  663. }
  664. #ifdef MNG_SUPPORT_TRACE
  665. MNG_TRACE (pData, MNG_FN_DIFFER_RGBA8, MNG_LC_END)
  666. #endif
  667. return MNG_NOERROR;
  668. }
  669. /* ************************************************************************** */
  670. mng_retcode differ_rgba16 (mng_datap pData)
  671. {
  672. mng_uint16p pRawi, pRawo;
  673. mng_int32 iX;
  674. #ifdef MNG_SUPPORT_TRACE
  675. MNG_TRACE (pData, MNG_FN_DIFFER_RGBA16, MNG_LC_START)
  676. #endif
  677. pRawi = (mng_uint16p)(pData->pWorkrow + pData->iPixelofs);
  678. pRawo = (mng_uint16p)(pData->pPrevrow + pData->iPixelofs);
  679. for (iX = 0; iX < pData->iRowsamples; iX++)
  680. {
  681. *(pRawo+1) = (mng_uint16)(((mng_uint32)*(pRawi+1) + (mng_uint32)pData->iLevel1) & 0xFFFF);
  682. *pRawo = (mng_uint16)(((mng_uint32)*pRawi + (mng_uint32)pData->iLevel0 +
  683. (mng_uint32)*(pRawo+1)) & 0xFFFF);
  684. *(pRawo+2) = (mng_uint16)(((mng_uint32)*(pRawi+2) + (mng_uint32)pData->iLevel2 +
  685. (mng_uint32)*(pRawo+1)) & 0xFFFF);
  686. *(pRawo+3) = (mng_uint16)(((mng_uint32)*(pRawi+3) + (mng_uint32)pData->iLevel3) & 0xFFFF);
  687. pRawi += 4;
  688. pRawo += 4;
  689. }
  690. #ifdef MNG_SUPPORT_TRACE
  691. MNG_TRACE (pData, MNG_FN_DIFFER_RGBA16, MNG_LC_END)
  692. #endif
  693. return MNG_NOERROR;
  694. }
  695. /* ************************************************************************** */
  696. #endif /* MNG_INCLUDE_FILTERS */
  697. /* ************************************************************************** */
  698. /* * end of file * */
  699. /* ************************************************************************** */