grayf.cpp
上传用户:sun1608
上传日期:2007-02-02
资源大小:6116k
文件大小:50k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. /*************************************************************************
  2. This software module was originally developed by 
  3. Ming-Chieh Lee (mingcl@microsoft.com), Microsoft Corporation
  4. Wei-ge Chen (wchen@microsoft.com), Microsoft Corporation
  5. Bruce Lin (blin@microsoft.com), Microsoft Corporation
  6. Chuang Gu (chuanggu@microsoft.com), Microsoft Corporation
  7. (date: March, 1996)
  8. in the course of development of the MPEG-4 Video (ISO/IEC 14496-2). 
  9. This software module is an implementation of a part of one or more MPEG-4 Video tools 
  10. as specified by the MPEG-4 Video. 
  11. ISO/IEC gives users of the MPEG-4 Video free license to this software module or modifications 
  12. thereof for use in hardware or software products claiming conformance to the MPEG-4 Video. 
  13. Those intending to use this software module in hardware or software products are advised that its use may infringe existing patents. 
  14. The original developer of this software module and his/her company, 
  15. the subsequent editors and their companies, 
  16. and ISO/IEC have no liability for use of this software module or modifications thereof in an implementation. 
  17. Copyright is not released for non MPEG-4 Video conforming products. 
  18. Microsoft retains full right to use the code for his/her own purpose, 
  19. assign or donate the code to a third party and to inhibit third parties from using the code for non <MPEG standard> conforming products. 
  20. This copyright notice must be included in all copies or derivative works. 
  21. Copyright (c) 1996, 1997.
  22. Module Name:
  23. grayf.hpp
  24. Abstract:
  25. Float image class for gray (one-plane) pictures 
  26. Revision History:
  27. *************************************************************************/
  28. #include <stdlib.h>
  29. #include <math.h>
  30. #include <stdio.h>
  31. #include <string.h>
  32. #include "typeapi.h"
  33. #ifdef __MFC_
  34. #ifdef _DEBUG
  35. #undef THIS_FILE
  36. static char BASED_CODE THIS_FILE[] = __FILE__;
  37. #endif
  38. #define new DEBUG_NEW    
  39. #endif // __MFC_
  40. CFloatImage::~CFloatImage ()
  41. {
  42. delete [] m_ppxlf;
  43. m_ppxlf = NULL;
  44. }
  45. Void CFloatImage::allocate (const CRct& r, PixelF pxlf) 
  46. {
  47. m_rc = r;
  48. delete [] m_ppxlf, m_ppxlf = NULL;
  49. // allocate pixels and initialize
  50. if (m_rc.empty ()) return;
  51. m_ppxlf = new PixelF [m_rc.area ()];
  52. PixelF* ppxlf = m_ppxlf;
  53. UInt area = where ().area ();
  54. for (UInt i = 0; i < area; i++)
  55. *ppxlf++ = pxlf;
  56. }
  57. Void CFloatImage::copyConstruct (const CFloatImage& fi, const CRct& rct) 
  58. {
  59. CRct r = rct;
  60. if (!r.valid()) 
  61. r = fi.where ();
  62. if (!fi.valid () || (!fi.m_rc.empty () && fi.m_ppxlf == NULL))
  63. assert (FALSE);
  64. allocate (r, (PixelF) 0);
  65. if (!valid ()) return; 
  66. // Copy data
  67. if (r == fi.where ())
  68. memcpy (m_ppxlf, fi.pixels (), m_rc.area () * sizeof (PixelF));
  69. else {
  70. r.clip (fi.where ()); // find the intersection
  71. CoordI x = r.left; // copy pixels
  72. Int cbLine = r.width * sizeof (PixelF);
  73. PixelF* ppxl = (PixelF*) pixels (x, r.top);
  74. const PixelF* ppxlFi = fi.pixels (x, r.top);
  75. Int widthCurr = where ().width;
  76. Int widthFi = fi.where ().width;
  77. for (CoordI y = r.top; y < r.bottom; y++) {
  78. memcpy (ppxl, ppxlFi, cbLine);
  79. ppxl += widthCurr;
  80. ppxlFi += widthFi;
  81. }
  82. }
  83. }
  84. Void CFloatImage::swap (CFloatImage& fi) 
  85. {
  86. assert (this && &fi);
  87. CRct rcT = fi.m_rc; 
  88. fi.m_rc = m_rc; 
  89. m_rc = rcT; 
  90. PixelF* ppxlfT = fi.m_ppxlf; 
  91. fi.m_ppxlf = m_ppxlf; 
  92. m_ppxlf = ppxlfT; 
  93. }
  94. CFloatImage::CFloatImage (const CFloatImage& fi, const CRct& r) : m_ppxlf (NULL)
  95. {
  96. copyConstruct (fi, r);
  97. }
  98. CFloatImage::CFloatImage (const CIntImage& ii, const CRct& rct) : m_ppxlf (NULL)
  99. {
  100. CRct r = rct;
  101. if (!r.valid()) 
  102. r = ii.where ();
  103. if (!ii.valid ())
  104. assert (FALSE);
  105. allocate (r, (PixelF) 0);
  106. if (!valid ()) return; 
  107. // Copy data
  108. if (r == ii.where ())
  109. {
  110. Int i;
  111. PixelF *ppxlf = m_ppxlf;
  112. const PixelI *ppxli = ii.pixels();
  113. for(i=m_rc.area();i;i--)
  114. *ppxlf++ = (PixelF)*ppxli++;
  115. }
  116. else {
  117. r.clip (ii.where ()); // find the intersection
  118. CoordI x = r.left; // copy pixels
  119. Int cbLine = r.width;
  120. PixelF* ppxlf = (PixelF*) pixels (x, r.top);
  121. const PixelI* ppxli = ii.pixels (x, r.top);
  122. Int widthCurr = where ().width;
  123. Int widthii = ii.where ().width;
  124. for (CoordI y = r.top; y < r.bottom; y++) {
  125. for(x = 0;x<cbLine;x++)
  126. ppxlf[x]=(PixelF)ppxli[x];
  127. ppxlf += widthCurr;
  128. ppxli += widthii;
  129. }
  130. }
  131. }
  132. CFloatImage::CFloatImage (const CRct& r, PixelF px) : m_ppxlf (NULL)
  133. {
  134. allocate (r, px);
  135. }
  136. CFloatImage::CFloatImage (const CVideoObjectPlane& vop, RGBA comp, const CRct& r) : m_ppxlf (NULL)
  137. {
  138. if (!vop.valid ()) return;
  139. CFloatImage* pfi = new CFloatImage (vop.where ());
  140. PixelF* ppxlf = (PixelF*) pfi -> pixels ();
  141. const CPixel* ppxl = vop.pixels ();
  142. UInt area = pfi -> where ().area ();
  143. for (UInt ip = 0; ip < area; ip++, ppxl++)
  144. *ppxlf++ = (PixelF) ppxl -> pxlU.color [comp];
  145. copyConstruct (*pfi, r);
  146. delete pfi;
  147. }
  148. CFloatImage::CFloatImage (
  149. const Char* pchFileName, 
  150. UInt ifr,
  151. const CRct& rct,
  152. UInt nszHeader ) : m_ppxlf (NULL)
  153. {
  154. assert (!rct.empty ());
  155. assert (ifr >= 0);
  156. assert (nszHeader >= 0);
  157. UInt area = rct.area ();
  158. // allocate mem for buffers
  159. U8* pchBuffer = new U8 [area];
  160. U8* pchBuffer0 = pchBuffer;
  161. // read data from a file
  162. FILE* fpSrc = fopen (pchFileName, "rb");
  163. assert (fpSrc != NULL);
  164. fseek (fpSrc, nszHeader + ifr * sizeof (U8) * area, SEEK_SET);
  165. Int size = (Int) fread (pchBuffer, sizeof (U8), area, fpSrc);
  166. assert (size != 0);
  167. fclose (fpSrc);
  168. // assign buffers to a vframe
  169. allocate (rct, .0f); 
  170. PixelF* p = (PixelF*) pixels ();
  171. UInt areaThis = where ().area ();
  172. for (UInt ip = 0; ip < areaThis; ip++)
  173. *p++ = (PixelF) *pchBuffer0++;
  174. delete [] pchBuffer;
  175. }
  176. CFloatImage::CFloatImage (const Char* vdlFileName) : m_ppxlf (NULL)// read from a VM file.
  177. {
  178. CVideoObjectPlane vop (vdlFileName);
  179. allocate (vop.where (), 0.0f);
  180. const CPixel* ppxlVop = vop.pixels ();
  181. PixelF* ppxlfRet = (PixelF*) pixels ();
  182. UInt area = where ().area ();
  183. for (UInt ip = 0; ip < area; ip++, ppxlfRet++, ppxlVop++)
  184. *ppxlfRet = (PixelF) ppxlVop -> pxlU.rgb.r;
  185. }
  186. Void CFloatImage::where (const CRct& r) 
  187. {
  188. if (!valid ()) return; 
  189. if (where () == r) return; 
  190. CFloatImage* pfi = new CFloatImage (*this, r);
  191. swap (*pfi);
  192. delete pfi;
  193. }
  194. CRct CFloatImage::boundingBox (const PixelF pxlfOutsideColor) const
  195. {
  196. if (allValue ((PixelF) pxlfOutsideColor))
  197. return CRct ();
  198. CoordI left = where ().right - 1;
  199. CoordI top = where ().bottom - 1;
  200. CoordI right = where ().left;
  201. CoordI bottom = where ().top;
  202. const PixelF* ppxlfThis = pixels ();
  203. for (CoordI y = where ().top; y < where ().bottom; y++) {
  204. for (CoordI x = where ().left; x < where ().right; x++) {
  205. if (*ppxlfThis != (PixelF) pxlfOutsideColor) {
  206. left = min (left, x);
  207. top = min (top, y);
  208. right = max (right, x);
  209. bottom = max (bottom, y);
  210. }
  211. ppxlfThis++;
  212. }
  213. }
  214. right++;
  215. bottom++;
  216. return (CRct (left, top, right, bottom));
  217. }
  218. Double CFloatImage::mean () const
  219. {
  220. if (where ().empty ()) return 0;
  221. Double meanRet = 0;
  222. PixelF* ppxlf = (PixelF*) pixels ();
  223. UInt area = where ().area ();
  224. for (UInt ip = 0; ip < area; ip++)
  225. meanRet += *ppxlf++;
  226. meanRet /= area;
  227. return meanRet;
  228. }
  229. Double CFloatImage::mean (const CFloatImage* pfiMsk) const
  230. {
  231. assert (where () == pfiMsk -> where ()); // no compute if rects are different
  232. if (where ().empty ()) return 0;
  233. Double meanRet = 0;
  234. PixelF* ppxlf = (PixelF*) pixels ();
  235. const PixelF* ppxlfMsk = pfiMsk -> pixels ();
  236. UInt area = where ().area ();
  237. UInt uiNumNonTransp = 0;
  238. for (UInt ip = 0; ip < area; ip++, ppxlf++, ppxlfMsk++) {
  239. if (*ppxlfMsk != transpValueF) {
  240. uiNumNonTransp++;
  241. meanRet += *ppxlf;
  242. }
  243. }
  244. meanRet /= uiNumNonTransp;
  245. return meanRet;
  246. }
  247. Double CFloatImage::sumAbs (const CRct& rct) const 
  248. {
  249. CRct rctToDo = (!rct.valid ()) ? where () : rct;
  250. Double dblRet = 0;
  251. if (rctToDo == where ()) {
  252. const PixelF* ppxlf = pixels ();
  253. UInt area = where ().area ();
  254. for (UInt ip = 0; ip < area; ip++, ppxlf++) {
  255. if (*ppxlf > 0)
  256. dblRet += *ppxlf;
  257. else
  258. dblRet -= *ppxlf;
  259. }
  260. }
  261. else {
  262. Int width = where ().width;
  263. const PixelF* ppxlfRow = pixels (rct.left, rct.top);
  264. for (CoordI y = rctToDo.top; y < rctToDo.bottom; y++) {
  265. const PixelF* ppxlf = ppxlfRow;
  266. for (CoordI x = rctToDo.left; x < rctToDo.right; x++, ppxlf++) {
  267. if (*ppxlf > 0)
  268. dblRet += *ppxlf;
  269. else
  270. dblRet -= *ppxlf;
  271. }
  272. ppxlfRow += width;
  273. }
  274. }
  275. return dblRet;
  276. }
  277. Double CFloatImage::sumDeviation (const CFloatImage* pfiMsk) const // sum of first-order deviation
  278. {
  279. Double meanPxl = mean (pfiMsk);
  280. Double devRet = 0;
  281. PixelF* ppxlf = (PixelF*) pixels ();
  282. const PixelF* ppxlfMsk = pfiMsk -> pixels ();
  283. UInt area = where ().area ();
  284. for (UInt ip = 0; ip < area; ip++, ppxlf++, ppxlfMsk++) {
  285. if (*ppxlfMsk != transpValueF) {
  286. Float fDiff = *ppxlf - (Float) meanPxl;
  287. if (fDiff > 0)
  288. devRet += fDiff;
  289. else 
  290. devRet -= fDiff;
  291. }
  292. }
  293. return devRet;
  294. }
  295. Double CFloatImage::sumDeviation () const // sum of first-order deviation
  296. {
  297. Double meanPxl = mean ();
  298. Double devRet = 0;
  299. PixelF* ppxlf = (PixelF*) pixels ();
  300. UInt area = where ().area ();
  301. for (UInt ip = 0; ip < area; ip++, ppxlf++) {
  302. Float fDiff = *ppxlf - (Float) meanPxl;
  303. if (fDiff > 0)
  304. devRet += fDiff;
  305. else 
  306. devRet -= fDiff;
  307. }
  308. return devRet;
  309. }
  310. Bool CFloatImage::allValue (Float vl, const CRct& rct) const
  311. {
  312. Int ivl = (Int) vl;
  313. Bool bRet = TRUE;
  314. CRct rctToDo = (!rct.valid ()) ? where () : rct;
  315. if (rctToDo == where ()) {
  316. const PixelF* ppxlf = pixels ();
  317. UInt area = where ().area ();
  318. for (UInt ip = 0; ip < area; ip++, ppxlf++) {
  319. Int ipxl = (Int) *ppxlf; //truncation
  320. // if (*ppxlf != vl) {
  321. if (ipxl != ivl) {
  322. bRet = FALSE;
  323. return bRet;
  324. }
  325. }
  326. }
  327. else {
  328. Int width = where ().width;
  329. const PixelF* ppxlf = pixels (rct.left, rct.top);
  330. for (CoordI y = rctToDo.top; y < rctToDo.bottom; y++) {
  331. const PixelF* ppxlfRow = ppxlf;
  332. for (CoordI x = rctToDo.left; x < rctToDo.right; x++, ppxlfRow++) {
  333. Int ipxl = (Int) *ppxlfRow; //truncation
  334. // if (*ppxlfRow != vl) {
  335. if (ipxl != ivl) {
  336. bRet = FALSE;
  337. return bRet;
  338. }
  339. }
  340. ppxlf += width;
  341. }
  342. }
  343. return bRet;
  344. }
  345. Bool CFloatImage::biLevel (const CRct& rct) const
  346. {
  347. Bool bRet = TRUE;
  348. CRct rctToDo = (!rct.valid ()) ? where () : rct;
  349. if (rctToDo == where ()) {
  350. const PixelF* ppxlf = pixels ();
  351. UInt area = where ().area ();
  352. for (UInt ip = 0; ip < area; ip++, ppxlf++) {
  353. Int ipxl = (Int) *ppxlf; //truncation
  354. if (ipxl != opaqueValue && ipxl != transpValue ) {
  355. bRet = FALSE;
  356. return bRet;
  357. }
  358. }
  359. }
  360. else {
  361. Int width = where ().width;
  362. const PixelF* ppxlf = pixels (rct.left, rct.top);
  363. for (CoordI y = rctToDo.top; y < rctToDo.bottom; y++) {
  364. const PixelF* ppxlfRow = ppxlf;
  365. for (CoordI x = rctToDo.left; x < rctToDo.right; x++, ppxlfRow++) {
  366. Int ipxl = (Int) *ppxlfRow; //truncation
  367. if (ipxl != opaqueValue && ipxl != transpValue ) {
  368. bRet = FALSE;
  369. return bRet;
  370. }
  371. }
  372. ppxlf += width;
  373. }
  374. }
  375. return bRet;
  376. }
  377. CRct CFloatImage::whereVisible () const
  378. {
  379. CoordI left = where ().right - 1;
  380. CoordI top = where ().bottom - 1;
  381. CoordI right = where ().left;
  382. CoordI bottom = where ().top;
  383. const PixelF* ppxlfThis = pixels ();
  384. for (CoordI y = where ().top; y < where ().bottom; y++) {
  385. for (CoordI x = where ().left; x < where ().right; x++) {
  386. if (*ppxlfThis != (PixelF) transpValue) {
  387. left = min (left, x);
  388. top = min (top, y);
  389. right = max (right, x);
  390. bottom = max (bottom, y);
  391. }
  392. ppxlfThis++;
  393. }
  394. }
  395. right++;
  396. bottom++;
  397. return CRct (left, top, right, bottom);
  398. }
  399. Bool CFloatImage::atLeastOneValue (Float vl, const CRct& rct) const
  400. {
  401. CRct rctRegionOfInterest = (!rct.valid ()) ? where () : rct;
  402. assert (rctRegionOfInterest <= where ());
  403. if (rctRegionOfInterest == where ()) {
  404. const PixelF* ppxlf = pixels ();
  405. UInt area = where ().area ();
  406. for (UInt ip = 0; ip < area; ip++, ppxlf++) {
  407. if (*ppxlf == vl) {
  408. return (TRUE);
  409. }
  410. }
  411. }
  412. else {
  413. Int width = where ().width;
  414. const PixelF* ppxlf = pixels (rctRegionOfInterest.left, rctRegionOfInterest.top);
  415. for (CoordI y = rctRegionOfInterest.top; y < rctRegionOfInterest.bottom; y++) {
  416. const PixelF* ppxlfRow = ppxlf;
  417. for (CoordI x = rctRegionOfInterest.left; x < rctRegionOfInterest.right; x++, ppxlfRow++) {
  418. if (*ppxlfRow == vl) {
  419. return (TRUE);
  420. break;
  421. }
  422. }
  423. ppxlf += width;
  424. }
  425. }
  426. return (FALSE);
  427. }
  428. UInt CFloatImage::numPixelsNotValued (Float vl, const CRct& rct) const // number of pixels not valued vl in region rct
  429. {
  430. CRct rctInterest = (!rct.valid ()) ? where () : rct;
  431. assert (rctInterest <= where ());
  432. UInt nRet = 0;
  433. if (rctInterest == where ()) {
  434. const PixelF* ppxlf = pixels ();
  435. UInt area = where ().area ();
  436. for (UInt ip = 0; ip < area; ip++, ppxlf++) {
  437. if (*ppxlf != vl)
  438. nRet++;
  439. }
  440. }
  441. else {
  442. Int width = where ().width;
  443. const PixelF* ppxlf = pixels (rctInterest.left, rctInterest.top);
  444. for (CoordI y = rctInterest.top; y < rctInterest.bottom; y++) {
  445. const PixelF* ppxlfRow = ppxlf;
  446. for (CoordI x = rctInterest.left; x < rctInterest.right; x++, ppxlfRow++) {
  447. if (*ppxlfRow != vl)
  448. nRet++;
  449. }
  450. ppxlf += width;
  451. }
  452. }
  453. return nRet;
  454. }
  455. Void CFloatImage::setRect (const CRct& rct)
  456. {
  457. assert (rct.area () == m_rc.area ());
  458. m_rc = rct;
  459. }
  460. Void CFloatImage::threshold (Float thresh)
  461. {
  462. PixelF* ppxlThis = (PixelF*) pixels ();
  463. UInt area = where ().area ();
  464. for (UInt id = 0; id < area; id++)
  465. {
  466. if (fabs (*ppxlThis) < thresh)
  467. *ppxlThis = (PixelF) 0;
  468. ppxlThis++;
  469. }
  470. }
  471. Void CFloatImage::binarize (Float fltThresh)
  472. {
  473. PixelF* ppxlThis = (PixelF*) pixels ();
  474. UInt area = where ().area ();
  475. for (UInt id = 0; id < area; id++)
  476. {
  477. if (fabs (*ppxlThis) < fltThresh)
  478. *ppxlThis = (PixelF) transpValue;
  479. else
  480. *ppxlThis = (PixelF) opaqueValue;
  481. ppxlThis++;
  482. }
  483. }
  484. Void CFloatImage::checkRange (Float fltMin, Float fltMax)
  485. {
  486. PixelF* ppxlThis = (PixelF*) pixels ();
  487. UInt area = where ().area ();
  488. for (UInt id = 0; id < area; id++, ppxlThis++)
  489. *ppxlThis = checkrange (*ppxlThis, fltMin, fltMax);
  490. }
  491. own CFloatImage* CFloatImage::decimate (UInt rateX, UInt rateY) const
  492. {
  493. const CoordI left = where ().left / (CoordI) rateX;
  494. const CoordI top = where ().top / (CoordI)  rateY;
  495. const CoordI right = (where ().right >= 0) ? (where ().right + (CoordI) rateX - 1) / (CoordI) rateX 
  496. : (where ().right - (CoordI) rateX + 1) / (CoordI) rateX;
  497. const CoordI bottom = (where ().bottom >= 0) ? (where ().bottom + (CoordI) rateX - 1) / (CoordI) rateY
  498. : (where ().bottom - (CoordI) rateX + 1) / (CoordI) rateY;
  499. CFloatImage* pfiRet = new CFloatImage (CRct (left, top, right, bottom));
  500. PixelF* ppxlfRet = (PixelF*) pfiRet -> pixels ();
  501. const PixelF* ppxlfOrgY = pixels ();
  502. Int skipY = rateY * where ().width;
  503. for (CoordI y = top; y < bottom; y++) {
  504. const PixelF* ppxlfOrgX = ppxlfOrgY;
  505. for (CoordI x = left; x < right; x++) {
  506. *ppxlfRet++ = *ppxlfOrgX;
  507. ppxlfOrgX += rateX;
  508. }
  509. ppxlfOrgY += skipY;
  510. }
  511. return pfiRet;
  512. }
  513. own CFloatImage* CFloatImage::decimateBinaryShape (UInt rateX, UInt rateY) const
  514. {
  515. const CoordI left = where ().left / (CoordI) rateX;
  516. const CoordI top = where ().top / (CoordI) rateY;
  517. Int roundR = (where ().right >= 0) ? rateX - 1 : 1 - rateX;
  518. Int roundB = (where ().bottom >= 0) ? rateY - 1 : 1 - rateY;
  519. const CoordI right = (where ().right + roundR) / (CoordI) rateX;
  520. const CoordI bottom = (where ().bottom + roundB) / (CoordI) rateY;
  521. CFloatImage* pfiRet = new CFloatImage (CRct (left, top, right, bottom));
  522. PixelF* ppxlfRet = (PixelF*) pfiRet -> pixels ();
  523. const PixelF* ppxlfOrgY = pixels ();
  524. Int skipY = rateY * where ().width;
  525. CoordI x, y;
  526. CoordI iXOrigLeft, iYOrigTop; //left top of a sampling square
  527. for (y = top, iYOrigTop = where().top; y < bottom; y++, iYOrigTop += rateY) {
  528. const PixelF* ppxlfOrgX = ppxlfOrgY;
  529. for (x = left, iXOrigLeft = where().left; x < right; x++, iXOrigLeft += rateX) {
  530. CoordI iXOrig, iYOrig; //for scanning of the sampling square
  531. const PixelF* ppxlfOrigScanY = ppxlfOrgX; //same
  532. *ppxlfRet = transpValueF;
  533. for (iYOrig = iYOrigTop; iYOrig < (iYOrigTop + (Int) rateY); iYOrig++) {
  534. if (iYOrig >= where().bottom || *ppxlfRet == opaqueValueF)
  535. break;
  536. const PixelF* ppxlfOrigScanX = ppxlfOrigScanY; //for scan also
  537. for (iXOrig = iXOrigLeft; iXOrig < (iXOrigLeft + (Int) rateX); iXOrig++) {
  538. if (iXOrig >= where().right)
  539. break;
  540. assert (*ppxlfOrigScanX == transpValueF || *ppxlfOrigScanX == opaqueValueF);
  541. if (*ppxlfOrigScanX == opaqueValueF) {
  542. *ppxlfRet = opaqueValueF;
  543. break;
  544. }
  545. ppxlfOrigScanX++;
  546. }
  547. ppxlfOrigScanY += where().width;
  548. }
  549. assert (*ppxlfRet == transpValueF || *ppxlfRet == opaqueValueF);
  550. ppxlfRet++;
  551. // *ppxlfRet++ = *ppxlfOrgX;
  552. ppxlfOrgX += rateX;
  553. }
  554. ppxlfOrgY += skipY;
  555. }
  556. return pfiRet;
  557. }
  558. own CFloatImage* CFloatImage::zoomup (UInt rateX, UInt rateY) const
  559. {
  560. const CoordI left = where ().left * rateX; // left-top coordinate remain the same
  561. const CoordI top = where ().top * rateY;
  562. const CoordI right = where ().right * rateX;
  563. const CoordI bottom = where ().bottom * rateY;
  564. CFloatImage* pfiRet = new CFloatImage (CRct (left, top, right, bottom));
  565. PixelF* ppxlRet = (PixelF*) pfiRet -> pixels ();
  566. for (CoordI y = top; y < bottom; y++)
  567. {
  568. for (CoordI x = left; x < right; x++)
  569. *ppxlRet++ = pixel ((CoordI) (x / rateX), (CoordI) (y / rateY));
  570. }
  571. return pfiRet;
  572. }
  573. own CFloatImage* CFloatImage::expand (UInt rateX, UInt rateY) const // expand by putting zeros in between
  574. {
  575. const CoordI left = where ().left * rateX; // left-top coordinate remain the same
  576. const CoordI top = where ().top * rateY;
  577. const CoordI right = where ().right * rateX;
  578. const CoordI bottom = where ().bottom * rateY;
  579. CFloatImage* pfiRet = new CFloatImage (CRct (left, top, right, bottom));
  580. PixelF* ppxlRet = (PixelF*) pfiRet -> pixels ();
  581. const PixelF* ppxlThis = pixels ();
  582. for (CoordI y = top; y < bottom; y++) {
  583. for (CoordI x = left; x < right; x++) {
  584. if (x % rateX == 0 && y % rateY == 0) 
  585. *ppxlRet++ = *ppxlThis++;
  586. else
  587. *ppxlRet++ = (PixelF) 0;
  588. }
  589. }
  590. return pfiRet;
  591. }
  592. own CFloatImage* CFloatImage::biInterpolate () const // bilinearly interpolate the vframe
  593. {
  594. const CoordI left = where ().left << 1; // left-top coordinate remain the same
  595. const CoordI top = where ().top << 1;
  596. const CoordI right = where ().right << 1;
  597. const CoordI bottom = where ().bottom << 1;
  598. const CoordI width = right - left;
  599. CoordI x, y;
  600. CFloatImage* pfiRet = new CFloatImage (CRct (left, top, right, bottom));
  601. PixelF* ppxlfRet = (PixelF*) pfiRet -> pixels ();
  602. const PixelF* ppxlf = pixels ();
  603. const CoordI right1 = right - 2;
  604. for (y = top; y < bottom; y += 2) { // x-direction interpolation
  605. for (x = left; x < right1; x += 2) {
  606. *ppxlfRet++ = *ppxlf++;
  607. *ppxlfRet++ = (*ppxlf + *(ppxlf - 1)) * .5f;
  608. }
  609. *ppxlfRet++ = *ppxlf;
  610. *ppxlfRet++ = *ppxlf++; // the last pixel of every row do not need average
  611. ppxlfRet += width;
  612. }
  613. ppxlfRet = (PixelF*) pfiRet -> pixels ();
  614. ppxlfRet += width; // start from the second row
  615. const CoordI width2 = width << 1;
  616. const CoordI bottom1 = bottom - 1;
  617. for (x = left; x < right; x++) { // y-direction interpolation
  618. PixelF* ppxlfRett = ppxlfRet++;
  619. for (y = top + 1; y < bottom1; y += 2) {
  620. *ppxlfRett = (*(ppxlfRett - width) + *(ppxlfRett + width)) * .5f;
  621. ppxlfRett += width2;
  622. }
  623. *ppxlfRett = *(ppxlfRett - width); // the last pixel of every column do not need average
  624. }
  625. return pfiRet;
  626. }
  627. own CFloatImage* CFloatImage::downsampleForSpatialScalability () const
  628. {
  629. static Int rgiFilterVertical[13] = {2, 0, -4, -3, 5, 19, 26, 19, 5, -3, -4, 0, 2};
  630. static Int rgiFilterHorizontal[4] = {5, 11, 11, 5};
  631. Int iWidthSrc = where (). width;
  632. Int iHeightSrc = where (). height ();
  633. assert (iWidthSrc % 2 == 0 && iHeightSrc % 2 == 0);
  634. Int iWidthDst = iWidthSrc / 2;
  635. Int iHeightDst = iHeightSrc / 2;
  636. CFloatImage* pfiBuffer = new CFloatImage (CRct (0, 0, iWidthSrc, iHeightDst));
  637. CFloatImage* pfiRet = new CFloatImage (CRct (0, 0, iWidthDst, iHeightDst));
  638. assert (pfiBuffer != NULL);
  639. assert (pfiRet != NULL);
  640. //filter and downsample vertically
  641. const PixelF* ppxlfSrc;
  642. const PixelF* ppxlfColumnHeadSrc = pixels ();
  643. PixelF* ppxlfDst = (PixelF*) pfiBuffer->pixels ();
  644. PixelF* ppxlfColumnHeadDst = (PixelF*) pfiBuffer->pixels ();
  645. Int i, j, k;
  646. for (i = 0; i < iWidthSrc; i++) {
  647. ppxlfSrc = ppxlfColumnHeadSrc;
  648. ppxlfDst = ppxlfColumnHeadDst;
  649. for (j = 0; j < iHeightDst; j++) {
  650. k = j * 2;         
  651. const PixelF* ppxlfMinusOne = ( k < 1 ) ? ppxlfSrc : ppxlfSrc - iWidthSrc;
  652. const PixelF* ppxlfMinusTwo = ( k < 2 ) ? ppxlfSrc : ppxlfMinusOne - iWidthSrc;
  653. const PixelF* ppxlfMinusThree = ( k < 3 ) ? ppxlfSrc : ppxlfMinusTwo - iWidthSrc;
  654. const PixelF* ppxlfMinusFour = ( k < 4 ) ? ppxlfSrc : ppxlfMinusThree - iWidthSrc;
  655. const PixelF* ppxlfMinusFive = ( k < 5 ) ? ppxlfSrc : ppxlfMinusFour - iWidthSrc;
  656. const PixelF* ppxlfMinusSix = ( k < 6 ) ? ppxlfSrc : ppxlfMinusFive - iWidthSrc;
  657. const PixelF* ppxlfPlusOne = ( k >= iHeightSrc - 1) ? ppxlfSrc : ppxlfSrc + iWidthSrc;
  658. const PixelF* ppxlfPlusTwo = ( k >= iHeightSrc - 2) ? ppxlfPlusOne : ppxlfPlusOne + iWidthSrc;
  659. const PixelF* ppxlfPlusThree = ( k >= iHeightSrc - 3) ? ppxlfPlusTwo : ppxlfPlusTwo + iWidthSrc;
  660. const PixelF* ppxlfPlusFour = ( k >= iHeightSrc - 4) ? ppxlfPlusThree : ppxlfPlusThree + iWidthSrc;
  661. const PixelF* ppxlfPlusFive = ( k >= iHeightSrc - 5) ? ppxlfPlusFour : ppxlfPlusFour + iWidthSrc;
  662. const PixelF* ppxlfPlusSix = ( k >= iHeightSrc - 6) ? ppxlfPlusFive : ppxlfPlusFive + iWidthSrc;
  663. *ppxlfDst = checkrange ((*ppxlfMinusSix  * rgiFilterVertical [0] +
  664. *ppxlfMinusFive * rgiFilterVertical [1] +
  665. *ppxlfMinusFour * rgiFilterVertical [2] +
  666. *ppxlfMinusThree* rgiFilterVertical [3] +
  667. *ppxlfMinusTwo  * rgiFilterVertical [4] +
  668. *ppxlfMinusOne  * rgiFilterVertical [5] +
  669. *ppxlfSrc    * rgiFilterVertical [6] +
  670. *ppxlfPlusOne   * rgiFilterVertical [7] +
  671. *ppxlfPlusTwo   * rgiFilterVertical [8] +
  672. *ppxlfPlusThree * rgiFilterVertical [9] +
  673. *ppxlfPlusFour  * rgiFilterVertical [10] +
  674. *ppxlfPlusFive  * rgiFilterVertical [11] +
  675. *ppxlfPlusSix   * rgiFilterVertical [12]) / 64,
  676. 0.0F, 255.0F);
  677. ppxlfSrc += 2 * iWidthSrc;
  678. ppxlfDst += iWidthSrc;
  679. }
  680. ppxlfColumnHeadSrc++;
  681. ppxlfColumnHeadDst++;
  682. //filter and downsample horizontally
  683. ppxlfSrc = pfiBuffer->pixels ();
  684. ppxlfDst = (PixelF*) pfiRet->pixels ();
  685. for (j = 0; j < iHeightDst; j++) {
  686. for (i = 0; i < iWidthDst; i++) {
  687. k = i * 2;         
  688. const PixelF* ppxlfMinusOne = ( k < 1 ) ? ppxlfSrc : ppxlfSrc - 1;
  689. const PixelF* ppxlfPlusOne = ( k >= iWidthSrc - 1) ? ppxlfSrc : ppxlfSrc + 1;
  690. const PixelF* ppxlfPlusTwo = ( k >= iWidthSrc - 2) ? ppxlfSrc : ppxlfSrc + 2;
  691. *ppxlfDst = checkrange ((*ppxlfMinusOne  * rgiFilterHorizontal [0] +
  692. *ppxlfSrc    * rgiFilterHorizontal [1] +
  693. *ppxlfPlusOne   * rgiFilterHorizontal [2] +
  694. *ppxlfPlusTwo   * rgiFilterHorizontal [3]) / 32,
  695. 0.0F, 255.0F);
  696. ppxlfSrc += 2;
  697. ppxlfDst++;
  698. }
  699. delete pfiBuffer;
  700. return pfiRet;
  701. }
  702. own CFloatImage* CFloatImage::upsampleForSpatialScalability () const
  703. {
  704. CRct rctDst = where () * 2;
  705. Int iWidthSrc = where (). width;
  706. Int iHeightSrc = where (). height ();
  707. Int iHeightDst = iHeightSrc * 2;
  708. CFloatImage* pfiBuffer = new CFloatImage (CRct (where().left, rctDst.top, 
  709.  where().right, rctDst.bottom));
  710. CFloatImage* pfiRet = new CFloatImage (CRct (rctDst.left, rctDst.top, 
  711.   rctDst.right, rctDst.bottom));
  712. //upsample vertically
  713. const PixelF* ppxlfSrc;
  714. const PixelF* ppxlfSrcPlusOne;
  715. const PixelF* ppxlfColumnHeadSrc = pixels ();
  716. PixelF* ppxlfDst;
  717. PixelF* ppxlfColumnHeadDst = (PixelF*) pfiBuffer->pixels ();
  718. Int i, j;
  719. for (i = 0; i < iWidthSrc; i++) {
  720. ppxlfSrc = ppxlfColumnHeadSrc;
  721. ppxlfSrcPlusOne = ppxlfSrc + iWidthSrc;
  722. ppxlfDst = ppxlfColumnHeadDst;
  723. for (j = 0; j < iHeightSrc; j++) {
  724. *ppxlfDst = checkrange ( (*ppxlfSrc * 3 + *ppxlfSrcPlusOne) / 4,
  725. 0.0F, 255.0F);
  726. ppxlfDst += iWidthSrc;
  727. *ppxlfDst = checkrange ( (*ppxlfSrc + *ppxlfSrcPlusOne * 3) / 4,
  728. 0.0F, 255.0F);
  729. ppxlfDst += iWidthSrc;
  730. ppxlfSrc += iWidthSrc;
  731. ppxlfSrcPlusOne = (j >= iHeightSrc - 2) ? ppxlfSrc : ppxlfSrc + iWidthSrc;
  732. }
  733. ppxlfColumnHeadSrc++;
  734. ppxlfColumnHeadDst++;
  735. //upsample horizontally
  736. ppxlfSrc = pfiBuffer->pixels ();
  737. ppxlfDst = (PixelF*) pfiRet->pixels ();
  738. for (j = 0; j < iHeightDst; j++) {
  739. ppxlfSrcPlusOne = ppxlfSrc + 1;
  740. for (i = 0; i < iWidthSrc; i++) {
  741. *ppxlfDst = checkrange ( (*ppxlfSrc * 3 + *ppxlfSrcPlusOne) / 4,
  742. 0.0F, 255.0F);
  743. ppxlfDst++;
  744. *ppxlfDst = checkrange ( (*ppxlfSrc + *ppxlfSrcPlusOne * 3) / 4,
  745. 0.0F, 255.0F);
  746. ppxlfDst++;
  747. ppxlfSrc++;
  748. ppxlfSrcPlusOne = (i >= iWidthSrc - 2) ? ppxlfSrc : ppxlfSrc + 1;
  749. }
  750. delete pfiBuffer;
  751. return pfiRet;
  752. }
  753. own CFloatImage* CFloatImage::biInterpolate (UInt accuracy) const // bilinearly interpolate the vframe
  754. {
  755. const CoordI left = where ().left * accuracy;
  756. const CoordI top = where ().top * accuracy;
  757. const CoordI right = where ().right * accuracy;
  758. const CoordI bottom = where ().bottom * accuracy;
  759. CFloatImage* pfiRet = new CFloatImage (CRct (left, top, right, bottom));
  760. PixelF* ppxlfRet = (PixelF*) pfiRet -> pixels ();
  761. for (CoordI y = top; y < bottom; y++) { // x-direction interpolation
  762. for (CoordI x = left; x < right; x++) {
  763. *ppxlfRet = pixel (x, y, accuracy);
  764. ppxlfRet++;
  765. }
  766. }
  767. return pfiRet;
  768. }
  769. own CFloatImage* CFloatImage::transpose () const
  770. {
  771. CRct rctDst = where ();
  772. rctDst.transpose ();
  773. CFloatImage* pfiDst = new CFloatImage (rctDst);
  774. const PixelF* ppxlSrc = pixels ();
  775. PixelF* ppxlDstRow = (PixelF*) pfiDst->pixels ();
  776. PixelF* ppxlDst;
  777. UInt height = where ().height ();
  778. for (CoordI iy = where ().top; iy < where ().bottom; iy++) {
  779. ppxlDst = ppxlDstRow;
  780. for (CoordI ix = where ().left; ix < where ().right; ix++) {
  781. *ppxlDst = *ppxlSrc++;
  782. ppxlDst += height;
  783. }
  784. ppxlDstRow++;
  785. }
  786. return pfiDst;
  787. }
  788. own CFloatImage* CFloatImage::warp (const CAffine2D& aff) const // affine warp
  789. {
  790. CSiteD stdLeftTopWarp = aff * CSiteD (where ().left, where ().top);
  791. CSiteD stdRightTopWarp = aff * CSiteD (where ().right, where ().top);
  792. CSiteD stdLeftBottomWarp = aff * CSiteD (where ().left, where ().bottom);
  793. CSiteD stdRightBottomWarp = aff * CSiteD (where ().right, where ().bottom);
  794. CRct rctWarp (stdLeftTopWarp, stdRightTopWarp, stdLeftBottomWarp, stdRightBottomWarp);
  795. CFloatImage* pfiRet = new CFloatImage (rctWarp);
  796. PixelF* ppxlfRet = (PixelF*) pfiRet -> pixels ();
  797. CAffine2D affInv = aff.inverse ();
  798. for (CoordI y = rctWarp.top; y != rctWarp.bottom; y++) {
  799. for (CoordI x = rctWarp.left; x != rctWarp.right; x++) {
  800. CSiteD src = affInv * CSiteD (x, y); 
  801. CoordI fx = (CoordI) floor (src.x); //.5 is for better truncation
  802. CoordI fy = (CoordI) floor (src.y); //.5 is for better truncation
  803. CoordI cx = (CoordI) ceil (src.x); //.5 is for better truncation
  804. CoordI cy = (CoordI) ceil (src.y); //.5 is for better truncation
  805. if (
  806. where ().includes (fx, fy) && 
  807. where ().includes (fx, cy) && 
  808. where ().includes (cx, fy) && 
  809. where ().includes (cx, cy)
  810. )
  811. *ppxlfRet = pixel (src);
  812. ppxlfRet++;
  813. }
  814. }
  815. return pfiRet;
  816. }
  817. own CFloatImage* CFloatImage::warp (const CPerspective2D& persp) const // perspective warp
  818. {
  819. CSiteD src [4], dest [4];
  820. src [0] = CSiteD (where ().left, where ().top);
  821. src [1] = CSiteD (where ().right, where ().top);
  822. src [2] = CSiteD (where ().left, where ().bottom);
  823. src [3] = CSiteD (where ().right, where ().bottom);
  824. for (UInt i = 0; i < 4; i++) {
  825. dest [i] = (persp * src [i]).s;
  826. }
  827. CRct rctWarp (dest [0], dest [1], dest [2], dest [3]);
  828. CFloatImage* pfiRet = new CFloatImage (rctWarp);
  829. PixelF* ppxlfRet = (PixelF*) pfiRet -> pixels ();
  830. CPerspective2D perspInv = CPerspective2D (dest, src);
  831. for (CoordI y = rctWarp.top; y != rctWarp.bottom; y++) {
  832. for (CoordI x = rctWarp.left; x != rctWarp.right; x++) {
  833. CSiteD src = (perspInv * CSiteD (x, y)).s; 
  834. CoordI fx = (CoordI) floor (src.x); //.5 is for better truncation
  835. CoordI fy = (CoordI) floor (src.y); //.5 is for better truncation
  836. CoordI cx = (CoordI) ceil (src.x); //.5 is for better truncation
  837. CoordI cy = (CoordI) ceil (src.y); //.5 is for better truncation
  838. if (
  839. where ().includes (fx, fy) && 
  840. where ().includes (fx, cy) && 
  841. where ().includes (cx, fy) && 
  842. where ().includes (cx, cy)
  843. )
  844. *ppxlfRet = pixel (src);
  845. ppxlfRet++;
  846. }
  847. }
  848. return pfiRet;
  849. }
  850. own CFloatImage* CFloatImage::warp (const CPerspective2D& persp, const CRct& rctWarp) const // perspective warp
  851. {
  852. CFloatImage* pfiRet = new CFloatImage (rctWarp);
  853. PixelF* ppxlfRet = (PixelF*) pfiRet -> pixels ();
  854. CPerspective2D perspInv = persp.inverse ();
  855. for (CoordI y = rctWarp.top; y != rctWarp.bottom; y++) {
  856. for (CoordI x = rctWarp.left; x != rctWarp.right; x++) {
  857. CSiteD src = (perspInv * CSiteD (x, y)).s; 
  858. CoordI fx = (CoordI) floor (src.x); //.5 is for better truncation
  859. CoordI fy = (CoordI) floor (src.y); //.5 is for better truncation
  860. CoordI cx = (CoordI) ceil (src.x); //.5 is for better truncation
  861. CoordI cy = (CoordI) ceil (src.y); //.5 is for better truncation
  862. if (
  863. where ().includes (fx, fy) && 
  864. where ().includes (fx, cy) && 
  865. where ().includes (cx, fy) && 
  866. where ().includes (cx, cy)
  867. )
  868. *ppxlfRet = pixel (src);
  869. ppxlfRet++;
  870. }
  871. }
  872. return pfiRet;
  873. }
  874. own CFloatImage* CFloatImage::warp (const CPerspective2D& persp, const CRct& rctWarp, const UInt accuracy) const // perspective warp
  875. {
  876. CFloatImage* pfiRet = new CFloatImage (rctWarp);
  877. PixelF* ppxlfRet = (PixelF*) pfiRet -> pixels ();
  878. for (CoordI y = rctWarp.top; y != rctWarp.bottom; y++) {
  879. for (CoordI x = rctWarp.left; x != rctWarp.right; x++) {
  880. CSite src = (persp * CSite (x, y)).s; 
  881. CoordI fx = (CoordI) floor ((CoordD) src.x / (CoordD) accuracy); //.5 is for better truncation
  882. CoordI fy = (CoordI) floor ((CoordD) src.y / (CoordD) accuracy); //.5 is for better truncation
  883. CoordI cx = (CoordI) ceil ((CoordD) src.x / (CoordD) accuracy); //.5 is for better truncation
  884. CoordI cy = (CoordI) ceil ((CoordD) src.y / (CoordD) accuracy); //.5 is for better truncation
  885. if (
  886. where ().includes (fx, fy) && 
  887. where ().includes (fx, cy) && 
  888. where ().includes (cx, fy) && 
  889. where ().includes (cx, cy)
  890. )
  891. *ppxlfRet = pixel (src, accuracy);
  892. ppxlfRet++;
  893. }
  894. }
  895. return pfiRet;
  896. }
  897. PixelF CFloatImage::pixel (CoordD x, CoordD y) const
  898. {
  899. CoordI left = (CoordI) floor (x); // find the coordinates of the four corners
  900. CoordI wLeft = where ().left, wRight1 = where ().right - 1, wTop = where ().top, wBottom1 = where ().bottom - 1;
  901. left = checkrange (left, wLeft, wRight1);
  902. CoordI right = (CoordI) ceil (x);
  903. right = checkrange (right, wLeft, wRight1);
  904. CoordI top = (CoordI) floor (y);
  905. top = checkrange (top, wTop, wBottom1);
  906. CoordI bottom = (CoordI) ceil (y);
  907. bottom = checkrange (bottom, wTop, wBottom1);
  908. const PixelF lt = pixel (left, top);
  909. const PixelF rt = pixel (right, top);
  910. const PixelF lb = pixel (left, bottom);
  911. const PixelF rb = pixel (right, bottom);
  912. const Double distX = x - left;
  913. const Double distY = y - top;
  914. Double x01 = distX * (rt - lt) + lt; // use p.59's notation (Wolberg, Digital Image Warping)
  915. Double x23 = distX * (rb - lb) + lb;
  916. PixelF pxlRet = checkrange ((Float) (x01 + (x23 - x01) * distY), 0.0f, 255.0f);
  917. return pxlRet;
  918. }
  919. PixelF CFloatImage::pixel (CoordI x, CoordI y, UInt accuracy) const // accuracy indicates the 2/4/8/16 quantization
  920. {
  921. CoordI left = (CoordI) floor ((CoordD)x / (CoordD)accuracy); // find the coordinates of the four corners
  922. CoordI wLeft = where ().left, wRight1 = where ().right - 1, wTop = where ().top, wBottom1 = where ().bottom - 1;
  923. left = checkrange (left, wLeft, wRight1);
  924. CoordI right = (CoordI) ceil ((CoordD)x / (CoordD)accuracy);
  925. right = checkrange (right, wLeft, wRight1);
  926. CoordI top = (CoordI) floor ((CoordD)y / (CoordD)accuracy);
  927. top = checkrange (top, wTop, wBottom1);
  928. CoordI bottom = (CoordI) ceil ((CoordD)y / (CoordD)accuracy);
  929. bottom = checkrange (bottom, wTop, wBottom1);
  930. const PixelF lt = pixel (left, top);
  931. const PixelF rt = pixel (right, top);
  932. const PixelF lb = pixel (left, bottom);
  933. const PixelF rb = pixel (right, bottom);
  934. const CoordI distX = x - left * accuracy;
  935. const CoordI distY = y - top * accuracy;
  936. Double x01 = distX * (rt - lt) + accuracy * lt; // use p.59's notation (Wolberg, Digital Image Warping)
  937. Double x23 = distX * (rb - lb) + accuracy * lb;
  938. PixelF pxlRet = checkrange ((Float) ((accuracy * x01 + (x23 - x01) * distY)) / (accuracy * accuracy), 0.0f, 255.0f);
  939. return pxlRet;
  940. }
  941. own CFloatImage* CFloatImage::complement () const
  942. {
  943. CFloatImage* pfiDst = new CFloatImage (where(), (PixelF) transpValue);
  944. const PixelF* ppxlfSrc = pixels ();
  945. PixelF* ppxlfDst = (PixelF*) pfiDst->pixels ();
  946. for (UInt iPxl = 0; iPxl < where ().area (); iPxl++) {
  947. if (*ppxlfSrc == (PixelF) opaqueValue)
  948. *ppxlfDst = (PixelF) transpValue;
  949. else if (*ppxlfSrc == (PixelF) transpValue)
  950. *ppxlfDst = (PixelF) opaqueValue;
  951. else
  952. assert (FALSE); //complemetn only work on pseudo-binary data
  953. ppxlfSrc++;
  954. ppxlfDst++;
  955. }
  956. return pfiDst;
  957. }
  958. Void CFloatImage::overlay (const CFloatImage& fi)
  959. {
  960. if (!valid () || !fi.valid () || fi.where ().empty ()) return;
  961. CRct r = m_rc; 
  962. r.include (fi.m_rc); // overlay is defined on union of rects
  963. where (r); 
  964. if (!valid ()) return; 
  965. assert (fi.m_ppxlf != NULL); 
  966. CRct rctFi = fi.m_rc;
  967. Int widthFi = rctFi.width;
  968. Int widthCurr = where ().width;
  969. PixelF* ppxlfThis = (PixelF*) pixels (rctFi.left, rctFi.top);
  970. const PixelF* ppxlfFi = fi.pixels ();
  971. for (CoordI y = rctFi.top; y < rctFi.bottom; y++) { // loop through VOP CRct
  972. memcpy (ppxlfThis, ppxlfFi, rctFi.width * sizeof (PixelF));
  973. ppxlfThis += widthCurr; 
  974. ppxlfFi += widthFi;
  975. }
  976. }
  977. own CFloatImage* CFloatImage::smooth_ (UInt window) const
  978. {
  979. const UInt offset = window >> 1;
  980. const UInt offset2 = offset << 1;
  981. const UInt size = window * window; // array size to be sorted
  982. const UInt med = size >> 1;
  983. CFloatImage* pfmgRet = new CFloatImage (*this);
  984. // bound of the image to be filtered.
  985. const CoordI left = where ().left + offset;
  986. const CoordI top = where ().top + offset;
  987. const CoordI right = where ().right - offset;
  988. const CoordI bottom = where ().bottom - offset;
  989. const Int width = where ().width;
  990. const Int dist = offset + offset * width;
  991. const Int wwidth = width - window;
  992. PixelF* rgValues = new PixelF [size];
  993. PixelF* pRet = (PixelF*) pfmgRet -> pixels (left, top);
  994. const PixelF* p = pixels (left, top);
  995. for (CoordI y = top; y != bottom; y++) {
  996. for (CoordI x = left; x != right; x++) {
  997. const PixelF* pp = p - dist; // get correct index
  998. UInt numTransp = 0;
  999. for (UInt sy = 0; sy != window; sy++) {
  1000. for (UInt sx = 0; sx != window; sx++) {
  1001. if (*pp == (PixelF) transpValue)
  1002. numTransp++;
  1003. pp++;
  1004. }
  1005. pp += wwidth;
  1006. }
  1007. *pRet++ = (PixelF) ((numTransp <= med) ? opaqueValue : transpValue);
  1008. p++;
  1009. }
  1010. pRet += offset2;
  1011. p += offset2;
  1012. }
  1013. delete [] rgValues;
  1014. return pfmgRet;
  1015. }
  1016. own CFloatImage* CFloatImage::smooth (UInt window) const
  1017. {
  1018. UInt offset = window >> 1;
  1019. CRct rctExp (where ());
  1020. rctExp.expand (offset);
  1021. CFloatImage* pfiExp = new CFloatImage (*this, rctExp);
  1022. CFloatImage* pfiSmooth = pfiExp -> smooth_ (window);
  1023. pfiSmooth -> where (where ());
  1024. delete pfiExp;
  1025. return pfiSmooth;
  1026. }
  1027. Void CFloatImage::xorFi (const CFloatImage& fi)
  1028. {
  1029. CRct rctIntersect = m_rc;
  1030. rctIntersect.clip (fi.where());
  1031. if (!rctIntersect.valid () || rctIntersect.empty ()) return;
  1032. PixelF* ppxlfRowStart1 = (PixelF*) pixels (rctIntersect.left, rctIntersect.top);
  1033. const PixelF* ppxlfRowStart2 = fi.pixels (rctIntersect.left, rctIntersect.top);
  1034. for (CoordI iy = rctIntersect.top; iy < rctIntersect.bottom; iy++)   {
  1035. PixelF* ppxlf1 = ppxlfRowStart1;
  1036. const PixelF* ppxlf2 = ppxlfRowStart2;
  1037. for (CoordI ix = rctIntersect.left; ix < rctIntersect.right; ix++) {
  1038. assert (*ppxlf1 == (PixelF) transpValue || *ppxlf1 == (PixelF) opaqueValue);
  1039. assert (*ppxlf2 == (PixelF) transpValue || *ppxlf2 == (PixelF) opaqueValue);
  1040. if (*ppxlf1 == *ppxlf2)
  1041. *ppxlf1 = (PixelF) transpValue;
  1042. else 
  1043. *ppxlf1 = (PixelF) opaqueValue;
  1044. ppxlf1++;
  1045. ppxlf2++;
  1046. }
  1047. ppxlfRowStart1 += where().width;
  1048. ppxlfRowStart2 += fi.where().width;
  1049. }
  1050. }
  1051. Void CFloatImage::orFi (const CFloatImage& fi)
  1052. {
  1053. CRct rctIntersect = m_rc;
  1054. rctIntersect.clip (fi.where());
  1055. if (!rctIntersect.valid () || rctIntersect.empty ()) return;
  1056. PixelF* ppxlfRowStart1 = (PixelF*) pixels (rctIntersect.left, rctIntersect.top);
  1057. const PixelF* ppxlfRowStart2 = fi.pixels (rctIntersect.left, rctIntersect.top);
  1058. for (CoordI iy = rctIntersect.top; iy < rctIntersect.bottom; iy++)   {
  1059. PixelF* ppxlf1 = ppxlfRowStart1;
  1060. const PixelF* ppxlf2 = ppxlfRowStart2;
  1061. for (CoordI ix = rctIntersect.left; ix < rctIntersect.right; ix++) {
  1062. assert (*ppxlf1 == (PixelF) transpValue || *ppxlf1 == (PixelF) opaqueValue);
  1063. assert (*ppxlf2 == (PixelF) transpValue || *ppxlf2 == (PixelF) opaqueValue);
  1064. if (*ppxlf2 == opaqueValue)
  1065. *ppxlf1 = (PixelF) opaqueValue;
  1066. ppxlf1++;
  1067. ppxlf2++;
  1068. }
  1069. ppxlfRowStart1 += where().width;
  1070. ppxlfRowStart2 += fi.where().width;
  1071. }
  1072. }
  1073. Void CFloatImage::andFi (const CFloatImage& fi)
  1074. {
  1075. CRct rctIntersect = m_rc;
  1076. rctIntersect.clip (fi.where());
  1077. if (!rctIntersect.valid () || rctIntersect.empty ()) return;
  1078. PixelF* ppxlfRowStart1 = (PixelF*) pixels (rctIntersect.left, rctIntersect.top);
  1079. const PixelF* ppxlfRowStart2 = fi.pixels (rctIntersect.left, rctIntersect.top);
  1080. for (CoordI iy = rctIntersect.top; iy < rctIntersect.bottom; iy++)   {
  1081. PixelF* ppxlf1 = ppxlfRowStart1;
  1082. const PixelF* ppxlf2 = ppxlfRowStart2;
  1083. for (CoordI ix = rctIntersect.left; ix < rctIntersect.right; ix++) {
  1084. assert (*ppxlf1 == (PixelF) transpValue || *ppxlf1 == (PixelF) opaqueValue);
  1085. assert (*ppxlf2 == (PixelF) transpValue || *ppxlf2 == (PixelF) opaqueValue);
  1086. if (*ppxlf2 == transpValue)
  1087. *ppxlf1 = (PixelF) transpValue;
  1088. ppxlf1++;
  1089. ppxlf2++;
  1090. }
  1091. ppxlfRowStart1 += where().width;
  1092. ppxlfRowStart2 += fi.where().width;
  1093. }
  1094. }
  1095. Void CFloatImage::maskOut (const CFloatImage& fi)
  1096. {
  1097. CRct rctIntersect = m_rc;
  1098. rctIntersect.clip (fi.where());
  1099. if (!rctIntersect.valid () || rctIntersect.empty ()) return;
  1100. PixelF* ppxlfRowStart = (PixelF*) pixels (rctIntersect.left, rctIntersect.top);
  1101. const PixelF* ppxlfRowStartMask = fi.pixels (rctIntersect.left, rctIntersect.top);
  1102. for (CoordI iy = rctIntersect.top; iy < rctIntersect.bottom; iy++)   {
  1103. PixelF* ppxlf = ppxlfRowStart;
  1104. const PixelF* ppxlfMask = ppxlfRowStartMask;
  1105. for (CoordI ix = rctIntersect.left; ix < rctIntersect.right; ix++) {
  1106. assert (*ppxlfMask == (PixelF) transpValue || *ppxlfMask == (PixelF) opaqueValue);
  1107. assert (*ppxlf == (PixelF) transpValue || *ppxlf == (PixelF) opaqueValue);
  1108. if (*ppxlfMask == (PixelF) transpValue) {
  1109. }
  1110. else
  1111. *ppxlf = (PixelF) transpValue;
  1112. ppxlf++;
  1113. ppxlfMask++;
  1114. }
  1115. ppxlfRowStart += where().width;
  1116. ppxlfRowStartMask += fi.where().width;
  1117. }
  1118. }
  1119. Void CFloatImage::mutiplyAlpha (const CFloatImage& fi)
  1120. {
  1121. CRct rctIntersect = m_rc;
  1122. rctIntersect.clip (fi.where());
  1123. if (!rctIntersect.valid () || rctIntersect.empty ()) return;
  1124. PixelF* ppxlfRowStart = (PixelF*) pixels (rctIntersect.left, rctIntersect.top);
  1125. const PixelF* ppxlfRowStartMask = fi.pixels (rctIntersect.left, rctIntersect.top);
  1126. for (CoordI iy = rctIntersect.top; iy < rctIntersect.bottom; iy++)   {
  1127. PixelF* ppxlf = ppxlfRowStart;
  1128. const PixelF* ppxlfMask = ppxlfRowStartMask;
  1129. for (CoordI ix = rctIntersect.left; ix < rctIntersect.right; ix++) {
  1130. assert (*ppxlfMask == transpValueF || *ppxlfMask == opaqueValueF);
  1131. if (*ppxlfMask == transpValueF) {
  1132. *ppxlf = transpValueF;
  1133. }
  1134. else
  1135. *ppxlf = *ppxlf * *ppxlfMask / opaqueValueF; //normalize
  1136. ppxlf++;
  1137. ppxlfMask++;
  1138. }
  1139. ppxlfRowStart += where().width;
  1140. ppxlfRowStartMask += fi.where().width;
  1141. }
  1142. }
  1143. Void CFloatImage::cropOnAlpha ()
  1144. {
  1145. CRct rctVisible = whereVisible ();
  1146. where (rctVisible);
  1147. }
  1148. own CFloatImage& CFloatImage::operator += (const CFloatImage& fiSrc)
  1149. {
  1150. assert (valid() && fiSrc.valid());
  1151. assert (where() == fiSrc.where());
  1152. PixelF *ppxlfDst = (PixelF *) pixels();
  1153. const PixelF *ppxlfSrc = fiSrc.pixels();
  1154. Int i,area = where().area();
  1155. for(i=0;i<area;i++)
  1156. *ppxlfDst++ += *ppxlfSrc++;
  1157. return *this;
  1158. }
  1159. own CFloatImage* CFloatImage::operator + (const CFloatImage& fi) const
  1160. {
  1161. if (!valid () || !fi.valid ()) return NULL;
  1162. assert (where () == fi.where ());
  1163. CFloatImage* pfiSumRet = new CFloatImage (where ());
  1164. PixelF* ppxlfRet = (PixelF*) pfiSumRet -> pixels ();
  1165. const PixelF* ppxlfThis = pixels ();
  1166. const PixelF* ppxlfFi = fi.pixels ();
  1167. UInt area = where ().area ();
  1168. for (UInt ip = 0; ip < area; ip++, ppxlfRet++, ppxlfThis++, ppxlfFi++)
  1169. *ppxlfRet = *ppxlfThis + *ppxlfFi;
  1170. return pfiSumRet;
  1171. }
  1172. own CFloatImage* CFloatImage::operator - (const CFloatImage& fi) const
  1173. {
  1174. if (!valid () || !fi.valid ()) return NULL;
  1175. assert (where () == fi.where ());
  1176. CFloatImage* pfiSumRet = new CFloatImage (where ());
  1177. PixelF* ppxlfRet = (PixelF*) pfiSumRet -> pixels ();
  1178. const PixelF* ppxlfThis = pixels ();
  1179. const PixelF* ppxlfFi = fi.pixels ();
  1180. UInt area = where ().area ();
  1181. for (UInt ip = 0; ip < area; ip++, ppxlfRet++, ppxlfThis++, ppxlfFi++)
  1182. *ppxlfRet = *ppxlfThis - *ppxlfFi;
  1183. return pfiSumRet;
  1184. }
  1185. own CFloatImage* CFloatImage::operator * (Float scale) const
  1186. {
  1187. if (!valid ()) return NULL;
  1188. CFloatImage* pfiSumRet = new CFloatImage (where ());
  1189. PixelF* ppxlfRet = (PixelF*) pfiSumRet -> pixels ();
  1190. const PixelF* ppxlfThis = pixels ();
  1191. UInt area = where ().area ();
  1192. for (UInt ip = 0; ip < area; ip++, ppxlfRet++, ppxlfThis++)
  1193. *ppxlfRet = *ppxlfThis * scale;
  1194. return pfiSumRet;
  1195. }
  1196. own CFloatImage* CFloatImage::operator * (const CTransform& tf) const
  1197. {
  1198. CFloatImage* pfiRet = tf.apply (*this);
  1199. return pfiRet; 
  1200. }
  1201. own CFloatImage* CFloatImage::operator / (Float scale) const
  1202. {
  1203. if (!valid ()) return NULL;
  1204. assert (scale != .0f);
  1205. CFloatImage* pfiSumRet = new CFloatImage (where ());
  1206. PixelF* ppxlfRet = (PixelF*) pfiSumRet -> pixels ();
  1207. const PixelF* ppxlfThis = pixels ();
  1208. UInt area = where ().area ();
  1209. for (UInt ip = 0; ip < area; ip++, ppxlfRet++, ppxlfThis++)
  1210. *ppxlfRet = *ppxlfThis / scale;
  1211. return pfiSumRet;
  1212. }
  1213. Void CFloatImage::operator = (const CFloatImage& fi)
  1214. {
  1215. delete [] m_ppxlf;
  1216. copyConstruct (fi, fi.where ());
  1217. }
  1218. Bool CFloatImage::operator == (const CFloatImage& fi) const
  1219. {
  1220. if (fi.where () != where ())
  1221. return FALSE;
  1222. UInt area = where ().area ();
  1223. const PixelF* ppxlf = fi.pixels ();
  1224. const PixelF* ppxlfThis = pixels ();
  1225. for (UInt ip = 0; ip < area; ip++, ppxlf++, ppxlfThis++)
  1226. if (*ppxlf != *ppxlfThis)
  1227. return FALSE;
  1228. return TRUE;
  1229. }
  1230. Double CFloatImage::mse (const CFloatImage& fiCompare) const
  1231. {
  1232. assert (fiCompare.where () == where ());
  1233. Double sqr = 0;
  1234. const PixelF* ppxlfThis = pixels ();
  1235. const PixelF* ppxlfCompare = fiCompare.pixels ();
  1236. UInt area = where ().area ();
  1237. UInt uiNonTransp = 0;
  1238. for (UInt i = 0; i < area; i++) {
  1239. Double diffR = (Double) (*ppxlfThis - *ppxlfCompare);
  1240. sqr += diffR * diffR;
  1241. uiNonTransp++;
  1242. ppxlfThis++;
  1243. ppxlfCompare++;
  1244. }
  1245. sqr /= (Double) uiNonTransp;
  1246. return sqr;
  1247. }
  1248. Double CFloatImage::mse (const CFloatImage& fiCompare, const CFloatImage& fiMsk) const
  1249. {
  1250. assert (fiCompare.where () == where () && fiMsk.where () == where ());
  1251. Double sqr = 0;
  1252. const PixelF* ppxlfThis = pixels ();
  1253. const PixelF* ppxlfCompare = fiCompare.pixels ();
  1254. const PixelF* ppxlfMsk = fiMsk.pixels ();
  1255. UInt area = where ().area ();
  1256. UInt uiNonTransp = 0;
  1257. for (UInt i = 0; i < area; i++) {
  1258. if (*ppxlfMsk != transpValue) {
  1259. Double diffR = (Double) (*ppxlfThis - ((Int) *ppxlfCompare));
  1260. sqr += diffR * diffR;
  1261. uiNonTransp++;
  1262. }
  1263. ppxlfThis++;
  1264. ppxlfCompare++;
  1265. ppxlfMsk++;
  1266. }
  1267. if (uiNonTransp == 0) 
  1268. return 0;
  1269. sqr /= (Double) uiNonTransp;
  1270. return sqr;
  1271. }
  1272. Double CFloatImage::snr (const CFloatImage& fiCompare) const
  1273. {
  1274. Double msError = 0;
  1275. msError = mse (fiCompare);
  1276. if (msError == 0.0)
  1277. return 1000000.0;
  1278. else 
  1279. return (log10 (255 * 255 / msError) * 10.0);
  1280. }
  1281. Double CFloatImage::snr (const CFloatImage& fiCompare, const CFloatImage& fiMsk) const
  1282. {
  1283. CFloatImage* pfiMskOp = NULL;
  1284. Double msError = 0;
  1285. if (&fiMsk == NULL) {
  1286. pfiMskOp = new CFloatImage (where (), (PixelF) opaqueValue);
  1287. msError = mse (fiCompare, *pfiMskOp);
  1288. delete pfiMskOp;
  1289. }
  1290. else
  1291. msError = mse (fiCompare, fiMsk);
  1292. if (msError == 0.0)
  1293. return 1000000.0;
  1294. else 
  1295. return (log10 (255 * 255 / msError) * 10.0);
  1296. }
  1297. Void CFloatImage::vdlDump (const Char* fileName) const
  1298. {
  1299. CVideoObjectPlane vop (where (), opaquePixel);
  1300. CPixel* ppxl = (CPixel*) vop.pixels ();
  1301. const PixelF* ppxlf = pixels ();
  1302. UInt area = where ().area ();
  1303. for (UInt ip = 0; ip < area; ip++, ppxl++, ppxlf++) {
  1304. U8 vl = (U8) (checkrange (*ppxlf, 0.0f, 255.0f) + 0.5f);
  1305. *ppxl = CPixel (vl, vl, vl, opaqueValue);
  1306. }
  1307. vop.vdlDump (fileName);
  1308. }
  1309. Void CFloatImage::dump (FILE* pf) const
  1310. {
  1311. assert (pf != NULL);
  1312. UInt area = where ().area ();
  1313. U8* rguchPixelData = new U8 [where().area()];
  1314. U8* puch = rguchPixelData;
  1315. const PixelF* ppxlf = pixels ();
  1316. for (UInt ip = 0; ip < area; ip++, puch++, ppxlf++) {
  1317. U8 vl = (U8) checkrange (*ppxlf, 0.0f, 255.0f);
  1318. *puch = vl;
  1319. }
  1320. fwrite (rguchPixelData, sizeof (U8), area, pf);
  1321. delete [] rguchPixelData;
  1322. }
  1323. Void CFloatImage::txtDump (const Char* fileName) const
  1324. {
  1325. FILE* pfTxt;
  1326. const PixelF* ppxlf = pixels ();
  1327. if (fileName != NULL)
  1328. pfTxt = fopen (fileName, "w");
  1329. else
  1330. pfTxt = NULL;
  1331. for (CoordI y = 0; y < where ().height (); y++) {
  1332. for (CoordI x = 0; x < where ().width; x++) {
  1333. if (pfTxt != NULL)
  1334. fprintf (pfTxt, "%6.2f  ", *ppxlf);
  1335. else
  1336. printf ("%d  ", (Int) *ppxlf);
  1337. ppxlf++;
  1338. }
  1339. if (pfTxt != NULL)
  1340. fprintf (pfTxt, "n");
  1341. else
  1342. printf ("n");
  1343. }
  1344. if (pfTxt != NULL)
  1345. fclose (pfTxt);
  1346. }
  1347. Void CFloatImage::txtDump(FILE *pf) const
  1348. {
  1349. const PixelF *ppxlf = pixels();
  1350. for (CoordI y = 0; y < where ().height (); y++) {
  1351. for (CoordI x = 0; x < where ().width; x++) {
  1352. fprintf (pf, "%6.2f ", *ppxlf);
  1353. ppxlf++;
  1354. }
  1355. fprintf (pf,"n");
  1356. }
  1357. fprintf (pf,"n");
  1358. }
  1359. Void CFloatImage::txtDumpMask(FILE *pf) const
  1360. {
  1361. const PixelF *ppxlf = pixels();
  1362. for (CoordI y = 0; y < where ().height (); y++) {
  1363. for (CoordI x = 0; x < where ().width; x++) {
  1364. if(*ppxlf==transpValue)
  1365. fprintf (pf, "..");
  1366. else
  1367. fprintf (pf, "[]");
  1368. ppxlf++;
  1369. }
  1370. fprintf (pf,"n");
  1371. }
  1372. fprintf (pf,"n");
  1373. }
  1374. Void CFloatImage::quantize (Int stepsize, Bool dpcm)
  1375. {
  1376. CoordI x, y;
  1377. const Int owidth = where ().width;
  1378. const CoordI left = where ().left;
  1379. const CoordI top = where ().top;
  1380. const CoordI right = where ().right;
  1381. const CoordI bottom = where ().bottom;
  1382. PixelF* px = (PixelF*) pixels ();
  1383. if (TRUE){
  1384. //Float halfStepsize = (Float) stepsize / 2;
  1385. for (y = top; y != bottom; y++) {
  1386. for (x = left; x != right; x++) {
  1387. //Float round = (*px >= 0) ? halfStepsize : -halfStepsize;
  1388. //*px++ = (Float) ((Int) ((*px + round) / stepsize));
  1389. *px++ = (Float) ((Int) (*px / stepsize));
  1390. }
  1391. }
  1392. }
  1393. else {
  1394. Float halfStepsize = (Float) stepsize / 4;
  1395. //Float halfStepsize = (Float) stepsize / 2;
  1396. for (y = top; y != bottom; y++) {
  1397. for (x = left; x != right; x++) {
  1398. Float round = (*px >= 0) ? halfStepsize : -halfStepsize;
  1399. *px++ = (Float) ((Int) ((*px - round) / stepsize));
  1400. //*px++ = (Float) ((Int) ((*px + round) / stepsize));
  1401. //*px++ = (Float) ((Int) ((*px ) / stepsize));
  1402. }
  1403. }
  1404. }
  1405. if (dpcm) { // zig-zag dpcm
  1406. CFloatImage* buf1 = new CFloatImage (*this);
  1407. for (y = top; y != bottom; y++) {
  1408. if (((y - top) & 1) == 0) { // even
  1409. const Float* pbuf = buf1 -> pixels (left, y);
  1410. PixelF* psig = (PixelF*) pixels (left, y);
  1411. *psig++ = (y != top) ? *pbuf - *(pbuf - owidth) : *pbuf;
  1412. pbuf++;
  1413. for (x = left + 1; x != right; x++) {
  1414. *psig = *pbuf - *(pbuf - 1);
  1415. psig++;
  1416. pbuf++;
  1417. }
  1418. }
  1419. else {
  1420. const PixelF* pbuf = buf1 -> pixels (right - 1, y);
  1421. PixelF* psig = (PixelF*) pixels (right - 1, y);
  1422. *psig-- = *pbuf - *(pbuf - owidth);
  1423. pbuf--;
  1424. for (x = right - 2; x >= left; x--) {
  1425. *psig = *pbuf - *(pbuf + 1);
  1426. psig--;
  1427. pbuf--;
  1428. }
  1429. }
  1430. }
  1431. delete buf1;
  1432. }
  1433. }
  1434. Void CFloatImage::deQuantize (Int stepsize, Bool dpcm)
  1435. {
  1436. CoordI x, y;
  1437. const Int owidth = where ().width;
  1438. const CoordI left = where ().left;
  1439. const CoordI top = where ().top;
  1440. const CoordI right = where ().right;
  1441. const CoordI bottom = where ().bottom;
  1442. if (dpcm) {
  1443. for (y = top; y != bottom; y++) {
  1444. if (((y - top) & 1) == 0) {
  1445. PixelF* psig = (PixelF*) pixels (left, y);
  1446. if (y != top)
  1447. *psig += *(psig - owidth);
  1448. psig++;
  1449. for (x = left + 1; x != right; x++) {
  1450. *psig += *(psig - 1);
  1451. psig++;
  1452. }
  1453. }
  1454. else {
  1455. PixelF* psig = (PixelF*) pixels (right - 1, y);
  1456. *psig += *(psig - owidth);
  1457. psig--;
  1458. for (x = right - 2; x >= left; x--) {
  1459. *psig += *(psig + 1);
  1460. psig--;
  1461. }
  1462. }
  1463. }
  1464. }
  1465. Float halfStepsize ;
  1466. if ( stepsize % 4 == 0)
  1467. halfStepsize = (Float) stepsize / 2 - 1;
  1468. else
  1469. halfStepsize = (Float) stepsize / 2;
  1470. PixelF* px = (PixelF*) pixels ();
  1471. for (y = top; y != bottom; y++) {
  1472. for (x = left; x != right; x++){
  1473. //Int round = (*px >= 0) ? (stepsize >> 1) : -(stepsize >> 1);
  1474. Float round = (*px >= 0) ? (halfStepsize) : -(halfStepsize);
  1475. *px = (*px == 0)? *px: (*px * (Float) stepsize + round);
  1476. px++;
  1477. //*px++ *= (Float) stepsize;
  1478. }
  1479. }
  1480. }
  1481. Void CFloatImage::roundNearestInt()
  1482. {
  1483. Int i;
  1484. PixelF fVal,*ppxlf = (PixelF *)pixels();
  1485. for(i=where().area();i;i--,ppxlf++)
  1486. {
  1487. fVal = *ppxlf;
  1488. if(fVal>=0)
  1489. *ppxlf = (PixelF)floor(fVal+0.5);
  1490. else
  1491. *ppxlf = (PixelF)ceil(fVal-0.5);
  1492. }
  1493. }