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

流媒体/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. vop.hpp
  24. Abstract:
  25. class for Video Object Plane 
  26. Revision History:
  27. *************************************************************************/
  28. #include <math.h>
  29. #include <string.h>
  30. #include <stdio.h>
  31. #include <stdlib.h>
  32. #include "basic.hpp"
  33. #include "transf.hpp"
  34. #include "warp.hpp"
  35. #include "vop.hpp"
  36. #include "typeapi.h"
  37. #ifdef __MFC_
  38. #ifdef _DEBUG
  39. #undef THIS_FILE
  40. static char BASED_CODE THIS_FILE[] = __FILE__;
  41. #endif
  42. #define new DEBUG_NEW    
  43. #endif // __MFC_
  44. Int numPln = 4;
  45. CVideoObjectPlane::~CVideoObjectPlane ()
  46. {
  47. delete [] m_ppxl;
  48. }
  49. Void CVideoObjectPlane::allocate (CRct r, CPixel pxl) 
  50. {
  51. m_rc = r;
  52. delete [] m_ppxl, m_ppxl = NULL;
  53. // allocate pixels and initialize
  54. if (m_rc.empty()) return;
  55. m_ppxl = new CPixel [m_rc.area ()];
  56. for (UInt i = 0; i < m_rc.area (); i++)
  57. m_ppxl [i] = pxl;
  58. // memset (m_ppxl, pxl, m_rc.area () * sizeof (CPixel));
  59. }
  60. Void CVideoObjectPlane::copyConstruct (const CVideoObjectPlane& vop, CRct r) 
  61. {
  62. if (!r.valid()) 
  63. r = vop.where ();
  64. if (!vop.valid () || (!vop.m_rc.empty () && vop.m_ppxl == NULL))
  65. assert (FALSE);
  66. allocate (r, transpPixel);
  67. if (!valid ()) return; 
  68. // Copy data
  69. if (r == vop.where ())
  70. memcpy (m_ppxl, vop.pixels (), m_rc.area () * sizeof (PixelF));
  71. else {
  72. r.clip (vop.where ()); // find the intersection
  73. CoordI x = r.left; // copy pixels
  74. Int cbLine = r.width * numPln;
  75. CPixel* ppxl = (CPixel*) pixels (x, r.top);
  76. const CPixel* ppxlVop = vop.pixels (x, r.top);
  77. Int widthCurr = where ().width;
  78. Int widthVop = vop.where ().width;
  79. for (CoordI y = r.top; y < r.bottom; y++) {
  80. memcpy (ppxl, ppxlVop, cbLine);
  81. ppxl += widthCurr;
  82. ppxlVop += widthVop;
  83. }
  84. }
  85. }
  86. Void CVideoObjectPlane::swap (CVideoObjectPlane& vop) 
  87. {
  88. assert (this && &vop);
  89. CRct rcT = vop.m_rc; 
  90. vop.m_rc = m_rc; 
  91. m_rc = rcT; 
  92. CPixel* ppxlT = vop.m_ppxl; 
  93. vop.m_ppxl = m_ppxl; 
  94. m_ppxl = ppxlT; 
  95. }
  96. CVideoObjectPlane::CVideoObjectPlane (const CVideoObjectPlane& vop, CRct r) : m_ppxl (NULL)
  97. {
  98. copyConstruct (vop, r);
  99. }
  100. CVideoObjectPlane::CVideoObjectPlane (CRct r, CPixel pxl) : m_ppxl (NULL)
  101. {
  102. allocate (r, pxl);
  103. }
  104. CVideoObjectPlane::CVideoObjectPlane (const Char* vdlFileName) : m_ppxl (NULL)
  105. {
  106. FILE* pf = fopen (vdlFileName, "rb");
  107. // write overhead
  108. Int c0 = getc (pf);
  109. Int c1 = getc (pf);
  110. assert (c0 == 'V' && (c1 == 'M' || c1 == 'B') );
  111. CRct rc;
  112. if (c1 == 'M'){
  113. fread (&rc.left, sizeof (CoordI), 1, pf);
  114. fread (&rc.top, sizeof (CoordI), 1, pf);
  115. fread (&rc.right, sizeof (CoordI), 1, pf);
  116. fread (&rc.bottom, sizeof (CoordI), 1, pf);
  117. rc.width = rc.right - rc.left;
  118. }
  119. else {
  120. U8 byte1, byte2;
  121. Int sign;
  122. byte1 = getc (pf);
  123. byte2 = getc (pf);
  124. sign = ((byte1 / 128) == 1) ? 1 : -1;
  125. rc.left = byte1 % 128;
  126. rc.left = (rc.left * 256) + byte2;
  127. rc.left *= sign; 
  128. byte1 = getc (pf);
  129. byte2 = getc (pf);
  130. sign = ((byte1 / 128) > 0) ? 1 : -1;
  131. rc.top = byte1 % 128;
  132. rc.top = (rc.top * 256) + byte2;
  133. rc.top *= sign; 
  134. byte1 = getc (pf);
  135. byte2 = getc (pf);
  136. sign = ((byte1 / 128) > 0) ? 1 : -1;
  137. rc.right = byte1 % 128;
  138. rc.right = (rc.right * 256) + byte2;
  139. rc.right *= sign; 
  140. byte1 = getc (pf);
  141. byte2 = getc (pf);
  142. sign = ((byte1 / 128) > 0) ? 1 : -1;
  143. rc.bottom = byte1 % 128;
  144. rc.bottom = (rc.bottom * 256) + byte2;
  145. rc.bottom *= sign;
  146. rc.width = rc.right - rc.left;
  147. }
  148. allocate (rc);
  149. // read the actual data
  150. fread (m_ppxl, sizeof (CPixel), where ().area (), pf);
  151. fclose (pf);
  152. }
  153. CVideoObjectPlane::CVideoObjectPlane (
  154. const Char* pchFileName, 
  155. UInt ifr, 
  156. const CRct& rct,
  157. ChromType chrType,
  158. Int nszHeader
  159. ) : m_ppxl (NULL)
  160. {
  161. assert (!rct.empty ());
  162. assert (ifr >= 0);
  163. assert (nszHeader >= 0);
  164. Int iWidth = rct.width, iHeight = rct.height ();
  165. UInt area = rct.area ();
  166. Int iUVWidth = iWidth, iUVHeight = iHeight;
  167. Int uiXSubsample = 1, uiYSubsample = 1;
  168. if (chrType == FOUR_TWO_TWO) {
  169. uiXSubsample = 2;
  170. iUVWidth = (iWidth + 1) / uiXSubsample;
  171. }
  172. else if (chrType == FOUR_TWO_ZERO) {
  173. uiXSubsample = 2;
  174. uiYSubsample = 2;
  175. iUVWidth = (iWidth + 1) / uiXSubsample;
  176. iUVHeight = (iHeight + 1) / uiYSubsample;
  177. }
  178. UInt iUVArea = iUVWidth * iUVHeight;
  179. // allocate mem for buffers
  180. U8* pchyBuffer = new U8 [area];
  181. U8* pchuBuffer = new U8 [iUVArea];
  182. U8* pchvBuffer = new U8 [iUVArea];
  183. U8* pchyBuffer0 = pchyBuffer;
  184. U8* pchuBuffer0 = pchuBuffer;
  185. U8* pchvBuffer0 = pchvBuffer;
  186. // read data from a file
  187. FILE* fpYuvSrc = fopen (pchFileName, "rb");
  188. assert (fpYuvSrc != NULL);
  189. UInt skipSize = (UInt) ((Float) (ifr * sizeof (U8) * (area + 2 * iUVArea)));
  190. fseek (fpYuvSrc, nszHeader + skipSize, SEEK_SET);
  191. Int size = (Int) fread (pchyBuffer, sizeof (U8), area, fpYuvSrc);
  192. assert (size != 0);
  193. size = (Int) fread (pchuBuffer, 1, iUVArea, fpYuvSrc);
  194. assert (size != 0);
  195. size = (Int) fread (pchvBuffer, 1, iUVArea, fpYuvSrc);
  196. assert (size != 0);
  197. fclose(fpYuvSrc);
  198. // assign buffers to a vframe
  199. allocate (rct, opaquePixel); 
  200. CPixel* p = (CPixel*) pixels ();
  201. for (CoordI y = 0; y < iHeight; y++) {
  202. if ((y % uiYSubsample) == 1) { 
  203. pchuBuffer -= iUVWidth; 
  204. pchvBuffer -= iUVWidth;
  205. }
  206. for (CoordI x = 0; x < iWidth; x++) {
  207. p -> pxlU.yuv.y = *pchyBuffer++;
  208. p -> pxlU.yuv.u = *pchuBuffer;
  209. p -> pxlU.yuv.v = *pchvBuffer;
  210. if (chrType == FOUR_FOUR_FOUR || (x % uiXSubsample) != 0) {
  211. pchuBuffer++;
  212. pchvBuffer++;
  213. }
  214. p++;
  215. }
  216. }
  217. delete [] pchyBuffer0;
  218. delete [] pchuBuffer0;
  219. delete [] pchvBuffer0;
  220. }
  221. Void CVideoObjectPlane::where (const CRct& r) 
  222. {
  223. if (!valid ()) return; 
  224. if (where () == r) return; 
  225. CVideoObjectPlane* pvop = new CVideoObjectPlane (*this, r);
  226. swap (*pvop);
  227. delete pvop;
  228. }
  229. CRct CVideoObjectPlane::whereVisible() const 
  230. {
  231. if (!valid () || !m_rc.valid ()) return CRct ();
  232. CoordI left = where ().right - 1;
  233. CoordI top = where ().bottom - 1;
  234. CoordI right = where ().left;
  235. CoordI bottom = where ().top;
  236. const CPixel* ppxlThis = pixels ();
  237. for (CoordI y = where ().top; y < where ().bottom; y++) {
  238. for (CoordI x = where ().left; x < where ().right; x++) {
  239. if (ppxlThis -> pxlU.rgb.a != transpValue) {
  240. left = min (left, x);
  241. top = min (top, y);
  242. right = max (right, x);
  243. bottom = max (bottom, y);
  244. }
  245. ppxlThis++;
  246. }
  247. }
  248. right++;
  249. bottom++;
  250. return CRct (left, top, right, bottom);
  251. if (!valid () || !m_rc.valid ()) return CRct ();}
  252. CPixel CVideoObjectPlane::pixel (CoordI x, CoordI y, UInt accuracy_ori) const
  253. {
  254. UInt accuracy1 = accuracy_ori + 1;
  255. CoordI left = (CoordI) floor ((Double) (x >> accuracy1)); // find the coordinates of the four corners
  256. CoordI wLeft = where ().left, wRight1 = where ().right - 1, wTop = where ().top, wBottom1 = where ().bottom - 1;
  257. left = checkrange (left, wLeft, wRight1);
  258. CoordI right = (CoordI) ceil ((Double) (x >> accuracy1));
  259. right = checkrange (right, wLeft, wRight1);
  260. CoordI top = (CoordI) floor ((Double) (y >> accuracy1));
  261. top = checkrange (top, wTop, wBottom1);
  262. CoordI bottom = (CoordI) ceil ((Double) (y >> accuracy1));
  263. bottom = checkrange (bottom, wTop, wBottom1);
  264. UInt accuracy2 = (accuracy_ori << 1) + 2;
  265. const CPixel lt = pixel (left, top);
  266. const CPixel rt = pixel (right, top);
  267. const CPixel lb = pixel (left, bottom);
  268. const CPixel rb = pixel (right, bottom);
  269. const Int distX = (x - left) << accuracy1;
  270. const Int distY = (y - top) << accuracy1;
  271. Int x01 = (distX * (rt.pxlU.rgb.r - lt.pxlU.rgb.r) + (Int) lt.pxlU.rgb.r) << accuracy1; // use p.59's notation (Wolberg, Digital Image Warping)
  272. Int x23 = (distX * (rb.pxlU.rgb.r - lb.pxlU.rgb.r) + (Int) lb.pxlU.rgb.r) << accuracy1; 
  273. Int r = checkrange (((x01 << accuracy1) + (x23 - x01) * distY) >> accuracy2, 0, 255);
  274. x01 = (distX * (rt.pxlU.rgb.g - lt.pxlU.rgb.g) + (Int) lt.pxlU.rgb.g) << accuracy1; // use p.59's notation
  275. x23 = (distX * (rb.pxlU.rgb.g - lb.pxlU.rgb.g) + (Int) lb.pxlU.rgb.g) << accuracy1;
  276. Int g = checkrange (((x01 << accuracy1) + (x23 - x01) * distY) >> accuracy2, 0, 255);
  277. x01 = (distX * (rt.pxlU.rgb.b - lt.pxlU.rgb.b) + (Int) lt.pxlU.rgb.b) << accuracy1; // use p.59's notation
  278. x23 = (distX * (rb.pxlU.rgb.b - lb.pxlU.rgb.b) + (Int) lb.pxlU.rgb.b) << accuracy1;
  279. Int b = checkrange (((x01 << accuracy1) + (x23 - x01) * distY) >> accuracy2, 0, 255);
  280. x01 = (distX * (rt.pxlU.rgb.a - lt.pxlU.rgb.a) + (Int) lt.pxlU.rgb.a) << accuracy1; // use p.59's notation
  281. x23 = (distX * (rb.pxlU.rgb.a - lb.pxlU.rgb.a) + (Int) lb.pxlU.rgb.a) << accuracy1;
  282. Int a = checkrange (((x01 << accuracy1) + (x23 - x01) * distY) >> accuracy2, 0, 255);
  283. return CPixel ((U8) r, (U8) g, (U8) b, (U8) a);
  284. }
  285. CPixel CVideoObjectPlane::pixel (CoordD x, CoordD y) const
  286. {
  287. CoordI left = (CoordI) floor (x); // find the coordinates of the four corners
  288. CoordI wLeft = where ().left, wRight1 = where ().right - 1, wTop = where ().top, wBottom1 = where ().bottom - 1;
  289. left = checkrange (left, wLeft, wRight1);
  290. CoordI right = (CoordI) ceil (x);
  291. right = checkrange (right, wLeft, wRight1);
  292. CoordI top = (CoordI) floor (y);
  293. top = checkrange (top, wTop, wBottom1);
  294. CoordI bottom = (CoordI) ceil (y);
  295. bottom = checkrange (bottom, wTop, wBottom1);
  296. const CPixel lt = pixel (left, top);
  297. const CPixel rt = pixel (right, top);
  298. const CPixel lb = pixel (left, bottom);
  299. const CPixel rb = pixel (right, bottom);
  300. const Double distX = x - left;
  301. const Double distY = y - top;
  302. Double x01 = distX * (rt.pxlU.rgb.r - lt.pxlU.rgb.r) + lt.pxlU.rgb.r; // use p.59's notation (Wolberg, Digital Image Warping)
  303. Double x23 = distX * (rb.pxlU.rgb.r - lb.pxlU.rgb.r) + lb.pxlU.rgb.r;
  304. Int r = checkrange ((Int) (x01 + (x23 - x01) * distY + .5), 0, 255);
  305. x01 = distX * (rt.pxlU.rgb.g - lt.pxlU.rgb.g) + lt.pxlU.rgb.g; // use p.59's notation
  306. x23 = distX * (rb.pxlU.rgb.g - lb.pxlU.rgb.g) + lb.pxlU.rgb.g;
  307. Int g = checkrange ((Int) (x01 + (x23 - x01) * distY + .5), 0, 255);
  308. x01 = distX * (rt.pxlU.rgb.b - lt.pxlU.rgb.b) + lt.pxlU.rgb.b; // use p.59's notation
  309. x23 = distX * (rb.pxlU.rgb.b - lb.pxlU.rgb.b) + lb.pxlU.rgb.b;
  310. Int b = checkrange ((Int) (x01 + (x23 - x01) * distY + .5), 0, 255);
  311. x01 = distX * (rt.pxlU.rgb.a - lt.pxlU.rgb.a) + lt.pxlU.rgb.a; // use p.59's notation
  312. x23 = distX * (rb.pxlU.rgb.a - lb.pxlU.rgb.a) + lb.pxlU.rgb.a;
  313. Int a = checkrange ((Int) (x01 + (x23 - x01) * distY + .5), 0, 255);
  314. return CPixel ((U8) r, (U8) g, (U8) b, (U8) a);
  315. }
  316. own CVideoObjectPlane* CVideoObjectPlane::warp (const CAffine2D& aff) const // affine warp
  317. {
  318. CSiteD stdLeftTopWarp = aff * CSiteD (where ().left, where ().top);
  319. CSiteD stdRightTopWarp = aff * CSiteD (where ().right, where ().top);
  320. CSiteD stdLeftBottomWarp = aff * CSiteD (where ().left, where ().bottom);
  321. CSiteD stdRightBottomWarp = aff * CSiteD (where ().right, where ().bottom);
  322. CRct rctWarp (stdLeftTopWarp, stdRightTopWarp, stdLeftBottomWarp, stdRightBottomWarp);
  323. CVideoObjectPlane* pvopRet = new CVideoObjectPlane (rctWarp);
  324. CPixel* ppxlRet = (CPixel*) pvopRet -> pixels ();
  325. CAffine2D affInv = aff.inverse ();
  326. for (CoordI y = rctWarp.top; y < rctWarp.bottom; y++) {
  327. for (CoordI x = rctWarp.left; x < rctWarp.right; x++) {
  328. CSiteD src = affInv * CSiteD (x, y); 
  329. CoordI fx = (CoordI) floor (src.x); //.5 is for better truncation
  330. CoordI fy = (CoordI) floor (src.y); //.5 is for better truncation
  331. CoordI cx = (CoordI) ceil (src.x); //.5 is for better truncation
  332. CoordI cy = (CoordI) ceil (src.y); //.5 is for better truncation
  333. if (
  334. where ().includes (fx, fy) && 
  335. where ().includes (fx, cy) && 
  336. where ().includes (cx, fy) && 
  337. where ().includes (cx, cy)
  338. )
  339. *ppxlRet = pixel (src);
  340. ppxlRet++;
  341. }
  342. }
  343. return pvopRet;
  344. }
  345. own CVideoObjectPlane* CVideoObjectPlane::warp (const CAffine2D& aff, const CRct& rctWarp) const // affine warp
  346. {
  347. CVideoObjectPlane* pvopRet = new CVideoObjectPlane (rctWarp);
  348. CPixel* ppxlRet = (CPixel*) pvopRet -> pixels ();
  349. //CAffine2D affInv = aff.inverse ();
  350. for (CoordI y = rctWarp.top; y < rctWarp.bottom; y++) {
  351. for (CoordI x = rctWarp.left; x < rctWarp.right; x++) {
  352. CSiteD src = aff * CSiteD (x, y); 
  353. CoordI fx = (CoordI) floor (src.x); //.5 is for better truncation
  354. CoordI fy = (CoordI) floor (src.y); //.5 is for better truncation
  355. CoordI cx = (CoordI) ceil (src.x); //.5 is for better truncation
  356. CoordI cy = (CoordI) ceil (src.y); //.5 is for better truncation
  357. if (
  358. where ().includes (fx, fy) && 
  359. where ().includes (fx, cy) && 
  360. where ().includes (cx, fy) && 
  361. where ().includes (cx, cy)
  362. )
  363. *ppxlRet = pixel (src);
  364. ppxlRet++;
  365. }
  366. }
  367. return pvopRet;
  368. }
  369. own CVideoObjectPlane* CVideoObjectPlane::warp (const CPerspective2D& persp) const // perspective warp
  370. {
  371. CSiteD stdLeftTopWarp = (persp * CSiteD (where ().left, where ().top)).s;
  372. CSiteD stdRightTopWarp = (persp * CSiteD (where ().right, where ().top)).s;
  373. CSiteD stdLeftBottomWarp = (persp * CSiteD (where ().left, where ().bottom)).s;
  374. CSiteD stdRightBottomWarp = (persp * CSiteD (where ().right, where ().bottom)).s;
  375. CRct rctWarp (stdLeftTopWarp, stdRightTopWarp, stdLeftBottomWarp, stdRightBottomWarp);
  376. CVideoObjectPlane* pvopRet = new CVideoObjectPlane (rctWarp);
  377. CPixel* ppxlRet = (CPixel*) pvopRet -> pixels ();
  378. CPerspective2D perspInv = persp.inverse ();
  379. for (CoordI y = rctWarp.top; y != rctWarp.bottom; y++) {
  380. for (CoordI x = rctWarp.left; x != rctWarp.right; x++) {
  381. CSiteD src = (perspInv * CSiteD (x, y)).s; 
  382. CoordI fx = (CoordI) floor (src.x); //.5 is for better truncation
  383. CoordI fy = (CoordI) floor (src.y); //.5 is for better truncation
  384. CoordI cx = (CoordI) ceil (src.x); //.5 is for better truncation
  385. CoordI cy = (CoordI) ceil (src.y); //.5 is for better truncation
  386. if (
  387. where ().includes (fx, fy) && 
  388. where ().includes (fx, cy) && 
  389. where ().includes (cx, fy) && 
  390. where ().includes (cx, cy)
  391. )
  392. *ppxlRet = pixel (src);
  393. ppxlRet++;
  394. }
  395. }
  396. return pvopRet;
  397. }  
  398. own CVideoObjectPlane* CVideoObjectPlane::warp (const CPerspective2D& persp, const CRct& rctWarp) const // perspective warp
  399. {
  400. CVideoObjectPlane* pvopRet = new CVideoObjectPlane (rctWarp);
  401. CPixel* ppxlRet = (CPixel*) pvopRet -> pixels ();
  402. //CPerspective2D perspInv = persp.inverse ();
  403. for (CoordI y = rctWarp.top; y < rctWarp.bottom; y++) {
  404. for (CoordI x = rctWarp.left; x < rctWarp.right; x++) {
  405. CSiteD src = (persp * CSiteD (x, y)).s; 
  406. CoordI fx = (CoordI) floor (src.x); //.5 is for better truncation
  407. CoordI fy = (CoordI) floor (src.y); //.5 is for better truncation
  408. CoordI cx = (CoordI) ceil (src.x); //.5 is for better truncation
  409. CoordI cy = (CoordI) ceil (src.y); //.5 is for better truncation
  410. if (
  411. where ().includes (fx, fy) && 
  412. where ().includes (fx, cy) && 
  413. where ().includes (cx, fy) && 
  414. where ().includes (cx, cy)
  415. )
  416. *ppxlRet = pixel (src);
  417. ppxlRet++;
  418. }
  419. }
  420. return pvopRet;
  421. }  
  422. own CVideoObjectPlane* CVideoObjectPlane::warp (const CPerspective2D& persp, const CRct& rctWarp, UInt accuracy) const // perspective warp
  423. {
  424. UInt accuracy1 = accuracy + 1;
  425. CVideoObjectPlane* pvopRet = new CVideoObjectPlane (rctWarp);
  426. CPixel* ppxlRet = (CPixel*) pvopRet -> pixels ();
  427. for (CoordI y = rctWarp.top; y < rctWarp.bottom; y++) {
  428. for (CoordI x = rctWarp.left; x < rctWarp.right; x++) {
  429. CSite src = (persp * (CSite (x, y))).s; 
  430. CoordI fx = (CoordI) floor ((Double) (src.x >> accuracy1)); 
  431. CoordI fy = (CoordI) floor ((Double) (src.y >> accuracy1)); 
  432. CoordI cx = (CoordI) ceil ((Double) (src.x >> accuracy1));
  433. CoordI cy = (CoordI) ceil ((Double) (src.y >> accuracy1));
  434. if (
  435. where ().includes (fx, fy) && 
  436. where ().includes (fx, cy) && 
  437. where ().includes (cx, fy) && 
  438. where ().includes (cx, cy)
  439. )
  440. *ppxlRet = pixel (src, accuracy);
  441. ppxlRet++;
  442. }
  443. }
  444. return pvopRet;
  445. }  
  446. Void CVideoObjectPlane::multiplyAlpha ()
  447. {
  448. if (!valid ()) return;
  449. CPixel* ppxlThis = (CPixel*) pixels ();
  450. Float inv255 = (Float) 1. / (Float) 255.;
  451. UInt area = where ().area ();
  452. for (UInt i = 0; i < area; i++) {
  453. Float alpha = inv255 * ppxlThis -> pxlU.rgb.a;
  454. ppxlThis -> pxlU.rgb.r = (U8) (alpha * ppxlThis -> pxlU.rgb.r + .5);
  455. ppxlThis -> pxlU.rgb.g = (U8) (alpha * ppxlThis -> pxlU.rgb.g + .5);
  456. ppxlThis -> pxlU.rgb.b = (U8) (alpha * ppxlThis -> pxlU.rgb.b + .5);
  457. ppxlThis++;
  458. }
  459. Void CVideoObjectPlane::multiplyBiAlpha ()
  460. {
  461. if (!valid ()) return;
  462. CPixel* ppxlThis = (CPixel*) pixels ();
  463. UInt area = where ().area ();
  464. for (UInt i = 0; i < area; i++) {
  465. if (ppxlThis -> pxlU.rgb.a == 0) {
  466. ppxlThis -> pxlU.rgb.r = 0;
  467. ppxlThis -> pxlU.rgb.g = 0;
  468. ppxlThis -> pxlU.rgb.b = 0;
  469. }
  470. ppxlThis++;
  471. }
  472. Void CVideoObjectPlane::unmultiplyAlpha ()
  473. {
  474. if (!valid ()) return;
  475. CPixel* ppxlThis = (CPixel*) pixels ();
  476. UInt area = where ().area ();
  477. for (UInt i = 0; i < area; i++) {
  478. if (ppxlThis->pxlU.rgb.a != 0) {
  479. Float invAlpha = (Float) (255 / ppxlThis -> pxlU.rgb.a);
  480. ppxlThis -> pxlU.rgb.r = (U8) checkrange (invAlpha * ppxlThis -> pxlU.rgb.r + 0.5f, 0.0F, 255.0F);
  481. ppxlThis -> pxlU.rgb.g = (U8) checkrange (invAlpha * ppxlThis -> pxlU.rgb.g + 0.5f, 0.0F, 255.0F);
  482. ppxlThis -> pxlU.rgb.b = (U8) checkrange (invAlpha * ppxlThis -> pxlU.rgb.b + 0.5f, 0.0F, 255.0F);
  483. }
  484. ppxlThis++;
  485. }
  486. Void CVideoObjectPlane::thresholdAlpha (U8 uThresh)
  487. {
  488. CPixel* ppxlThis = (CPixel*) pixels ();
  489. UInt area = where ().area ();
  490. for (UInt i = 0; i < area; i++) {
  491. ppxlThis -> pxlU.rgb.a = (ppxlThis -> pxlU.rgb.a > uThresh) ? opaqueValue : transpValue;
  492. ppxlThis++;
  493. }
  494. Void CVideoObjectPlane::thresholdRGB (U8 uThresh)
  495. {
  496. CPixel* ppxlThis = (CPixel*) pixels ();
  497. UInt area = where ().area ();
  498. for (UInt i = 0; i < area; i++) {
  499. if (ppxlThis -> pxlU.rgb.r < uThresh && ppxlThis -> pxlU.rgb.g < uThresh && ppxlThis -> pxlU.rgb.b < uThresh) {
  500. ppxlThis -> pxlU.rgb.r = 0;
  501. ppxlThis -> pxlU.rgb.g = 0;
  502. ppxlThis -> pxlU.rgb.b = 0;
  503. }
  504. ppxlThis++;
  505. }
  506. Void CVideoObjectPlane::cropOnAlpha ()
  507. {
  508. CoordI left = where ().right - 1;
  509. CoordI top = where ().bottom - 1;
  510. CoordI right = where ().left;
  511. CoordI bottom = where ().top;
  512. const CPixel* ppxlThis = pixels ();
  513. for (CoordI y = where ().top; y < where ().bottom; y++) {
  514. for (CoordI x = where ().left; x < where ().right; x++) {
  515. if (ppxlThis -> pxlU.rgb.a != transpValue) {
  516. left = min (left, x);
  517. top = min (top, y);
  518. right = max (right, x);
  519. bottom = max (bottom, y);
  520. }
  521. ppxlThis++;
  522. }
  523. }
  524. right++;
  525. bottom++;
  526. where (CRct (left, top, right, bottom));
  527. own CVideoObjectPlane* CVideoObjectPlane::decimate (UInt rateX, UInt rateY) const
  528. {
  529. const CoordI left = where ().left / (CoordI) rateX;
  530. const CoordI top = where ().top / (CoordI)  rateY;
  531. const CoordI right = 
  532. (where ().right >= 0) ? (where ().right + (CoordI) rateX - 1) / (CoordI) rateX :
  533. (where ().right - (CoordI) rateX + 1) / (CoordI) rateX;
  534. const CoordI bottom = 
  535. (where ().bottom >= 0) ? (where ().bottom + (CoordI) rateX - 1) / (CoordI) rateY :
  536. (where ().bottom - (CoordI) rateX + 1) / (CoordI) rateY;
  537. CVideoObjectPlane* pvopRet = new CVideoObjectPlane (CRct (left, top, right, bottom), opaquePixel);
  538. CPixel* pret = (CPixel*) pvopRet -> pixels ();
  539. const CPixel* pori = pixels ();
  540. Int skipY = rateY * where ().width;
  541. for (CoordI y = top; y != bottom; y++)
  542. {
  543. const CPixel* pvf = pori;
  544. for (CoordI x = left; x != right; x++)
  545. {
  546. *pret++ = *pvf;
  547. pvf += rateX;
  548. pori += skipY;
  549. }
  550. return pvopRet;
  551. }
  552. Void CVideoObjectPlane::falseColor (CPixel pxl)
  553. {
  554. CPixel* ppxl = m_ppxl;
  555. UInt area = where ().area ();
  556. for (UInt i = 0; i < area; i++) {
  557. if (ppxl -> pxlU.rgb.a == transpValue) {
  558. ppxl -> pxlU.rgb.r = pxl.pxlU.rgb.r;
  559. ppxl -> pxlU.rgb.g = pxl.pxlU.rgb.g;
  560. ppxl -> pxlU.rgb.b = pxl.pxlU.rgb.b;
  561. }
  562. ppxl++;
  563. }
  564. }
  565. Void CVideoObjectPlane::falseColor (U8 r, U8 g, U8 b)
  566. {
  567. CPixel* ppxl = m_ppxl;
  568. UInt area = where ().area ();
  569. for (UInt i = 0; i < area; i++) {
  570. if (ppxl -> pxlU.rgb.a == transpValue) {
  571. ppxl -> pxlU.rgb.r = r;
  572. ppxl -> pxlU.rgb.g = g;
  573. ppxl -> pxlU.rgb.b = b;
  574. }
  575. ppxl++;
  576. }
  577. }
  578. own CVideoObjectPlane* CVideoObjectPlane::zoomup (UInt rateX, UInt rateY) const
  579. {
  580. const CoordI left = where ().left * rateX;
  581. const CoordI top = where ().top * rateY;
  582. const CoordI right = where ().right * rateX;
  583. const CoordI bottom = where ().bottom * rateY;
  584. CVideoObjectPlane* retVf = new CVideoObjectPlane (CRct (left, top, right, bottom), opaquePixel);
  585. CPixel* pret = (CPixel*) retVf -> pixels ();
  586. for (CoordI y = top; y != bottom; y++)
  587. {
  588. for (CoordI x = left; x != right; x++)
  589. {
  590. *pret++ = pixel ((CoordI) (x / rateX), (CoordI)  (y / rateY));
  591. }
  592. }
  593. return retVf;
  594. }
  595. own CVideoObjectPlane* CVideoObjectPlane::expand (UInt rateX, UInt rateY) const
  596. {
  597. const CoordI left = where ().left; // left-top coordinate remain the same
  598. const CoordI top = where ().top;
  599. const CoordI right = left + where ().width * rateX;
  600. const CoordI bottom = top + where ().height () * rateY;
  601. CVideoObjectPlane* pvopRet = new CVideoObjectPlane (CRct (left, top, right, bottom), transpPixel);
  602. CPixel* ppxlRet = (CPixel*) pvopRet -> pixels ();
  603. const CPixel* ppxlThis = pixels ();
  604. for (CoordI y = top; y != bottom; y++) {
  605. for (CoordI x = left; x != right; x++) {
  606. if (x % rateX == 0 && y % rateY == 0) 
  607. *ppxlRet++ = *ppxlThis++;
  608. else
  609. *ppxlRet++ = CPixel (0, 0, 0, opaqueValue);
  610. }
  611. }
  612. return pvopRet;
  613. }
  614. inline CPixel averageP (const CPixel& p1, const CPixel& p2)
  615. {
  616. return CPixel (
  617. (p1.pxlU.rgb.r + p2.pxlU.rgb.r + 1) >> 1,
  618. (p1.pxlU.rgb.g + p2.pxlU.rgb.g + 1) >> 1,
  619. (p1.pxlU.rgb.b + p2.pxlU.rgb.b + 1) >> 1,
  620. p1.pxlU.rgb.a
  621. );
  622. }
  623. own CVideoObjectPlane* CVideoObjectPlane::biInterpolate () const
  624. {
  625. const CoordI left = where ().left; // left-top coordinate remain the same
  626. const CoordI top = where ().top;
  627. const CoordI right = left + where ().width * 2;
  628. const CoordI bottom = top + where ().height () * 2;
  629. const CoordI width = right - left;
  630. CoordI x, y;
  631. CVideoObjectPlane* pvopRet = new CVideoObjectPlane (CRct (left, top, right, bottom), opaquePixel);
  632. CPixel* ppxlRet = (CPixel*) pvopRet -> pixels ();
  633. const CPixel* ppxl = pixels ();
  634. const CoordI right1 = right - 2;
  635. for (y = top; y < bottom; y += 2) { // x-direction interpolation
  636. for (x = left; x < right1; x += 2) {
  637. *ppxlRet++ = *ppxl++;
  638. *ppxlRet++ = averageP (*ppxl, *(ppxl - 1));
  639. }
  640. *ppxlRet++ = *ppxl;
  641. *ppxlRet++ = *ppxl++; // the last pixel of every row do not need average
  642. ppxlRet += width;
  643. }
  644. ppxlRet = (CPixel*) pvopRet -> pixels ();
  645. ppxlRet += width; // start from the second row
  646. const CoordI width2 = width << 1;
  647. const CoordI bottom1 = bottom - 1;
  648. for (x = left; x < right; x++) { // y-direction interpolation
  649. CPixel* ppxlRett = ppxlRet++;
  650. for (y = top + 1; y < bottom1; y += 2) {
  651. *ppxlRett = averageP (*(ppxlRett - width), *(ppxlRett + width));
  652. ppxlRett += width2;
  653. }
  654. *ppxlRett = *(ppxlRett - width); // the last pixel of every column do not need average
  655. }
  656. return pvopRet;
  657. }
  658. own CVideoObjectPlane* CVideoObjectPlane::biInterpolate (UInt accuracy) const
  659. {
  660. const CoordI left = where ().left * accuracy;
  661. const CoordI top = where ().top * accuracy;
  662. const CoordI right = where ().right * accuracy;
  663. const CoordI bottom = where ().bottom * accuracy;
  664. CVideoObjectPlane* pvopRet = new CVideoObjectPlane (CRct (left, top, right, bottom));
  665. CPixel* ppxlRet = (CPixel*) pvopRet -> pixels ();
  666. for (CoordI y = top; y < bottom; y++) { // x-direction interpolation
  667. for (CoordI x = left; x < right; x++) {
  668. *ppxlRet = pixel (x, y, accuracy);
  669. ppxlRet++;
  670. }
  671. }
  672. return pvopRet;
  673. }
  674. own CVideoObjectPlane* CVideoObjectPlane::biInterpolate (const CRct& r) const
  675. {
  676. CVideoObjectPlane* pvopRet = new CVideoObjectPlane (r, opaquePixel);
  677. for (CoordI x = r.left; x < r.right; x++)
  678. for (CoordI y = r.top; y < r.bottom; y++) {
  679. CoordD dx = (Double) ((where ().right - 1 - where ().left) / (Double) (r.right  - 1 - r.left)) * (x - r.left) + where ().left;
  680. CoordD dy = (Double) ((where ().bottom - 1 - where ().top) / (Double) (r.bottom - 1 - r.top)) * (y - r.top) + where ().top;
  681. CPixel result = pixel (dx, dy);
  682. pvopRet -> pixel (x, y, result); 
  683. }
  684. return pvopRet;
  685. }
  686. own CFloatImage* CVideoObjectPlane::plane (RGBA pxlCom) const
  687. {
  688. if (!valid ()) return NULL;
  689. CFloatImage* pfiRet = new CFloatImage (where ());
  690. const CPixel* ppxlVop = pixels ();
  691. PixelF* ppxlRet = (PixelF*) pfiRet -> pixels ();
  692. UInt area = where ().area ();
  693. for (UInt ip = 0; ip < area; ip++) {
  694. *ppxlRet = (PixelF) ppxlVop -> pxlU.color [pxlCom];
  695. ppxlRet++;
  696. ppxlVop++;
  697. }
  698. return pfiRet;
  699. }
  700. Void CVideoObjectPlane::lightChange (Int rShift, Int gShift, Int bShift)
  701. {
  702. CPixel* ppix = (CPixel*) pixels ();
  703. UInt area = where ().area ();
  704. for (UInt i = 0; i < area; i++) {
  705. ppix -> pxlU.rgb.r = (U8) checkrange (rShift + ppix -> pxlU.rgb.r, 0, 255);
  706. ppix -> pxlU.rgb.g = (U8) checkrange (gShift + ppix -> pxlU.rgb.g, 0, 255);
  707. ppix -> pxlU.rgb.b = (U8) checkrange (bShift + ppix -> pxlU.rgb.b, 0, 255);
  708. ppix++;
  709. }
  710. }
  711. Void CVideoObjectPlane::overlay (const CVideoObjectPlane& vop)
  712. {
  713. if (!valid () || !vop.valid () || vop.where ().empty ()) return;
  714. CRct r = m_rc; 
  715. r.include (vop.m_rc); // overlay is defined on union of rects
  716. where (r); 
  717. if (!valid ()) return; 
  718. assert (vop.m_ppxl != NULL); 
  719. CRct rctVop = vop.m_rc;
  720. Float inv255 = 1.0f / 255.0f;
  721. const CPixel* ppxlVop = vop.pixels (); 
  722. CPixel* ppxlThisY = (CPixel*) pixels (rctVop.left, rctVop.top);
  723. Int widthCurr = where ().width;
  724. for (CoordI y = rctVop.top; y < rctVop.bottom; y++) { // loop through VOP CRct
  725. CPixel* ppxlThisX = ppxlThisY;
  726. for (CoordI x = rctVop.left; x < rctVop.right; x++) {
  727. Float beta = inv255 * (Float) ppxlVop -> pxlU.rgb.a;
  728. Float alpha = inv255 * (Float) ppxlThisX -> pxlU.rgb.a;
  729. for (UInt ip = 0; ip < 3; ip++) {
  730. Int value = (Int) (
  731. beta * (Float) ppxlVop -> pxlU.color [ip] + 
  732. alpha * (Float) ppxlThisX -> pxlU.color [ip] - 
  733. alpha * beta * (Float) ppxlThisX -> pxlU.color [ip] + .5f
  734. );
  735. ppxlThisX -> pxlU.color [ip] = (U8) checkrange (value, 0, 255);
  736. }
  737. Int val = (Int) ((beta + alpha - alpha * beta) * 255. + .5f);
  738. ppxlThisX -> pxlU.rgb.a = (U8) checkrange (val, 0, 255);
  739. ppxlThisX++;
  740. ppxlVop++;
  741. }
  742. ppxlThisY += widthCurr;
  743. }
  744. }
  745. Void CVideoObjectPlane::setPlane (const CFloatImage& fi, RGBA pxlCom)
  746. {
  747. if (!valid ()) return;
  748. assert (where () == fi.where ());
  749. CPixel* ppxlVop = (CPixel*) pixels ();
  750. const PixelF* ppxlFi = fi.pixels ();
  751. UInt area = where ().area ();
  752. for (UInt ip = 0; ip < area; ip++) {
  753. Int value = checkrange ((Int) (*ppxlFi + .5), 0, 255);
  754. ppxlVop -> pxlU.color [pxlCom] = (U8) value;
  755. ppxlVop++;
  756. ppxlFi++;
  757. }
  758. }
  759. Void CVideoObjectPlane::setPlane (const CIntImage& ii, RGBA pxlCom)
  760. {
  761. if (!valid ()) return;
  762. assert (where () == ii.where ());
  763. CPixel* ppxlVop = (CPixel*) pixels ();
  764. const PixelI* ppxli = ii.pixels ();
  765. UInt area = where ().area ();
  766. for (UInt ip = 0; ip < area; ip++) {
  767. Int value = checkrange (*ppxli, 0, 255);
  768. ppxlVop -> pxlU.color [pxlCom] = (U8) value;
  769. ppxlVop++;
  770. ppxli++;
  771. }
  772. }
  773. Void CVideoObjectPlane::setPlane (const CU8Image& ci, RGBA pxlCom)
  774. {
  775. if (!valid ()) return;
  776. assert (where () == ci.where ());
  777. CPixel* ppxlVop = (CPixel*) pixels ();
  778. const PixelC* ppxlc = ci.pixels ();
  779. UInt area = where ().area ();
  780. for (UInt ip = 0; ip < area; ip++) {
  781. Int value = checkrange (*ppxlc, 0U, 255U);
  782. ppxlVop -> pxlU.color [pxlCom] = (U8) value;
  783. ppxlVop++;
  784. ppxlc++;
  785. }
  786. }
  787. Void CVideoObjectPlane::getDownSampledPlane(CFloatImage &fiDst,Int iPlane,Int iSx,Int iSy)
  788. {
  789. Int iDstWidth = fiDst.where().width;
  790. Int iDstHeight = fiDst.where().height();
  791. Int iSrcWidth = where().width;
  792. Int iSrcHeight = where().height();
  793. PixelF *ppxlfDst = (PixelF *)fiDst.pixels();
  794. const CPixel *ppxlSrc = pixels();
  795. assert(iDstWidth == iSrcWidth/iSx && iDstHeight == iSrcHeight/iSy);
  796. Int iSrcStep = iSrcWidth*iSy;
  797. Int iX,iY,iXX;
  798. for(iY=0;iY<iDstHeight;iY++,ppxlSrc+=iSrcStep)
  799. for(iX=0,iXX=0;iX<iDstWidth;iX++,iXX+=iSx)
  800. *ppxlfDst++ = ppxlSrc[iXX].pxlU.color[iPlane];
  801. }
  802. Void CVideoObjectPlane::setUpSampledPlane(const CFloatImage &fiSrc,Int iPlane,Int iSx,Int iSy)
  803. {
  804. Int iSrcWidth = fiSrc.where().width;
  805. Int iSrcHeight = fiSrc.where().height();
  806. Int iDstWidth = where().width;
  807. Int iDstHeight = where().height();
  808. const PixelF *ppxlfSrc = fiSrc.pixels();
  809. CPixel *ppxlDst = (CPixel *)pixels();
  810. assert(iSrcWidth == iDstWidth/iSx && iSrcHeight == iDstHeight/iSy);
  811. Int iCx,iCy,iXX,iX,iY;
  812. for(iCy=0,iY=0;iY<iDstHeight;iY++)
  813. {
  814. for(iCx=0,iXX=iX=0;iX<iDstWidth;iX++,ppxlDst++)
  815. {
  816. ppxlDst->pxlU.color[iPlane] =
  817. checkrange ((Int) (ppxlfSrc[iXX] + .5), 0, 255);
  818. iCx++;
  819. if(iCx==iSx)
  820. {
  821. iXX++;
  822. iCx=0;
  823. }
  824. }
  825. iCy++;
  826. if(iCy==iSy)
  827. {
  828. ppxlfSrc+=iSrcWidth;
  829. iCy=0;
  830. }
  831. }
  832. }
  833. Void CVideoObjectPlane::getDownSampledPlane(CIntImage &iiDst,Int iPlane,Int iSx,Int iSy)
  834. {
  835. Int iDstWidth = iiDst.where().width;
  836. Int iDstHeight = iiDst.where().height();
  837. Int iSrcWidth = where().width;
  838. Int iSrcHeight = where().height();
  839. PixelI *ppxliDst = (PixelI *)iiDst.pixels();
  840. const CPixel *ppxlSrc = pixels();
  841. assert(iDstWidth == iSrcWidth/iSx && iDstHeight == iSrcHeight/iSy);
  842. Int iSrcStep = iSrcWidth*iSy;
  843. Int iX,iY,iXX;
  844. for(iY=0;iY<iDstHeight;iY++,ppxlSrc+=iSrcStep)
  845. for(iX=0,iXX=0;iX<iDstWidth;iX++,iXX+=iSx)
  846. *ppxliDst++ = ppxlSrc[iXX].pxlU.color[iPlane];
  847. }
  848. Void CVideoObjectPlane::setUpSampledPlane(const CIntImage &iiSrc,Int iPlane,Int iSx,Int iSy)
  849. {
  850. Int iSrcWidth = iiSrc.where().width;
  851. Int iSrcHeight = iiSrc.where().height();
  852. Int iDstWidth = where().width;
  853. Int iDstHeight = where().height();
  854. const PixelI *ppxliSrc = iiSrc.pixels();
  855. CPixel *ppxlDst = (CPixel *)pixels();
  856. assert(iSrcWidth == iDstWidth/iSx && iSrcHeight == iDstHeight/iSy);
  857. Int iCx,iCy,iXX,iX,iY,iVal;
  858. for(iCy=0,iY=0;iY<iDstHeight;iY++)
  859. {
  860. for(iCx=0,iXX=iX=0;iX<iDstWidth;iX++,ppxlDst++)
  861. {
  862. iVal=ppxliSrc[iXX];
  863. ppxlDst->pxlU.color[iPlane] = ( (iVal>255) ? 255 : ((iVal<0)?0:iVal) );
  864. iCx++;
  865. if(iCx==iSx)
  866. {
  867. iXX++;
  868. iCx=0;
  869. }
  870. }
  871. iCy++;
  872. if(iCy==iSy)
  873. {
  874. ppxliSrc+=iSrcWidth;
  875. iCy=0;
  876. }
  877. }
  878. }
  879. Void CVideoObjectPlane::rgbToYUV () // transform from rgb to yuv
  880. {
  881. if (!valid ()) return;
  882. CPixel* ppxl = (CPixel*) pixels ();
  883. UInt area = where ().area ();
  884. for (UInt ip = 0; ip < area; ip++) {
  885. Int y = (Int) ((Double) (0.257 * ppxl -> pxlU.rgb.r + 0.504 * ppxl -> pxlU.rgb.g + 0.098 * ppxl -> pxlU.rgb.b + 16) + .5);
  886. Int cb = (Int) ((Double) (0.439 * ppxl -> pxlU.rgb.r - 0.368 * ppxl -> pxlU.rgb.g - 0.071 * ppxl -> pxlU.rgb.b + 128) + .5);
  887. Int cr = (Int) ((Double) (-0.148 * ppxl -> pxlU.rgb.r - 0.291 * ppxl -> pxlU.rgb.g + 0.439 * ppxl -> pxlU.rgb.b + 128) + .5);
  888. ppxl -> pxlU.yuv.y = (U8) y;
  889. ppxl -> pxlU.yuv.u = (U8) cr;
  890. ppxl -> pxlU.yuv.v = (U8) cb;
  891. ppxl++;
  892. }
  893. }
  894. Void CVideoObjectPlane::yuvToRGB () // transform from yuv to rgb
  895. {
  896. if (!valid ()) return;
  897. CPixel* ppxl = (CPixel*) pixels ();
  898. UInt area = where ().area ();
  899. for (UInt ip = 0; ip < area; ip++) {
  900. Double var = 1.164 * (ppxl -> pxlU.yuv.y - 16);
  901. Int r = (Int) ((Double) (var + 1.596 * (ppxl -> pxlU.yuv.v - 128)) + .5);
  902. Int g = (Int) ((Double) (var - 0.813 * (ppxl -> pxlU.yuv.v - 128) - 0.391 * (ppxl -> pxlU.yuv.u - 128)) + .5);
  903. Int b = (Int) ((Double) (var + 2.018 * (ppxl -> pxlU.yuv.u - 128)) + .5);
  904. ppxl -> pxlU.rgb.r = (U8) checkrange (r, 0, 255);
  905. ppxl -> pxlU.rgb.g = (U8) checkrange (g, 0, 255);
  906. ppxl -> pxlU.rgb.b = (U8) checkrange (b, 0, 255);
  907. ppxl++;
  908. }
  909. }
  910. own CVideoObjectPlane* CVideoObjectPlane::operator * (const CTransform& tf) const
  911. {
  912. CVideoObjectPlane* pvopRet = tf.apply (*this);
  913. return pvopRet; 
  914. }
  915. own CVideoObjectPlane* CVideoObjectPlane::operator - (const CVideoObjectPlane& vop) const
  916. {
  917. // make the difference in the intersection area
  918. if (!valid () || !vop.valid ()) return NULL;
  919. CRct rctSrc = vop.where ();
  920. CRct rctDes = where ();
  921. CRct rctInt = rctSrc;
  922. rctInt.clip (rctDes);
  923. CVideoObjectPlane* pvopDiff = new CVideoObjectPlane (rctInt);
  924. UInt offsetSrc = rctSrc.width - rctInt.width;
  925. UInt offsetDes = rctDes.width - rctInt.width;
  926. CPixel* ppxlRet = (CPixel*) pvopDiff -> pixels ();
  927. CPixel* ppxlDes = (CPixel*) pixels (rctInt.left, rctInt.top);
  928. CPixel* ppxlSrc = (CPixel*) vop.pixels (rctInt.left, rctInt.top);
  929. for (CoordI j = rctInt.top; j < rctInt.bottom; j++) { 
  930. for (CoordI i = rctInt.left; i < rctInt.right; i++) {
  931. ppxlRet -> pxlU.rgb.r = (U8) checkrange (ppxlDes -> pxlU.rgb.r - ppxlSrc -> pxlU.rgb.r + 128, 0, 255);
  932. ppxlRet -> pxlU.rgb.g = (U8) checkrange (ppxlDes -> pxlU.rgb.g - ppxlSrc -> pxlU.rgb.g + 128, 0, 255);
  933. ppxlRet -> pxlU.rgb.b = (U8) checkrange (ppxlDes -> pxlU.rgb.b - ppxlSrc -> pxlU.rgb.b + 128, 0, 255);
  934. ppxlRet -> pxlU.rgb.a = (ppxlDes -> pxlU.rgb.a == ppxlSrc -> pxlU.rgb.a) ? opaqueValue : transpValue;
  935. ppxlRet++;
  936. ppxlDes++;
  937. ppxlSrc++;
  938. }
  939. ppxlDes += offsetDes;
  940. ppxlSrc += offsetSrc;
  941. }
  942. return pvopDiff;
  943. }
  944. Void CVideoObjectPlane::vdlDump (const Char* fileName, CPixel ppxlFalse) const
  945. {
  946. if (!valid ()) return;
  947. FILE* pf = fopen (fileName, "wb");
  948. // write overhead
  949. putc ('V', pf);
  950. putc ('M', pf);
  951. CoordI cord = (CoordI) where ().left;
  952. fwrite (&cord, sizeof (CoordI), 1, pf);
  953. cord = (CoordI) where ().top;
  954. fwrite (&cord, sizeof (CoordI), 1, pf);
  955. cord = (CoordI) where ().right;
  956. fwrite (&cord, sizeof (CoordI), 1, pf);
  957. cord = (CoordI) where ().bottom;
  958. fwrite (&cord, sizeof (CoordI), 1, pf);
  959. // dump the actual data
  960. UInt area = where ().area ();
  961. const CPixel* ppxl = pixels ();
  962. for (UInt ip = 0; ip < area; ip++, ppxl++) {
  963. CPixel pp = *ppxl;
  964. if (ppxl -> pxlU.rgb.a == transpValue) {
  965. pp.pxlU.rgb.r = ppxlFalse.pxlU.rgb.r;
  966. pp.pxlU.rgb.g = ppxlFalse.pxlU.rgb.g;
  967. pp.pxlU.rgb.b = ppxlFalse.pxlU.rgb.b;
  968. }
  969. fwrite (&pp, sizeof (CPixel), 1, pf);
  970. }
  971. fclose (pf);
  972. }
  973. Void CVideoObjectPlane::vdlByteDump (const Char* fileName, CPixel ppxlFalse) const
  974. {
  975. if (!valid ()) return;
  976. FILE* pf = fopen (fileName, "wb");
  977. // write overhead
  978. putc ('V', pf);
  979. putc ('B', pf);
  980. int left, top, right, bottom;
  981. left = where ().left;
  982. top = where ().top;
  983. right = where ().right;
  984. bottom = where ().bottom;
  985. U8 byte1, byte2;
  986. byte1 = (left>0)? 128:0;
  987. left = abs (left);
  988. byte1 += left / 256;
  989. byte2 =  left % 256;
  990. putc (byte1,pf);
  991. putc (byte2,pf);
  992. byte1 = (top>0)? 128:0;
  993. top = abs (top);
  994. byte1 += top / 256;
  995. byte2 = top % 256;
  996. putc (byte1, pf);
  997. putc (byte2, pf);
  998. byte1 = (right>0)? 128:0;
  999. right = abs (right);
  1000. byte1 += right / 256;
  1001. byte2 =  right % 256;
  1002. putc(byte1,pf);
  1003. putc(byte2,pf);
  1004. byte1 = (bottom>0)? 128:0;
  1005. bottom = abs (bottom);
  1006. byte1 += bottom / 256;
  1007. byte2 =  bottom % 256;
  1008. putc(byte1,pf);
  1009. putc(byte2,pf);
  1010. // dump the actual data
  1011. UInt area = where ().area ();
  1012. const CPixel* ppxl = pixels ();
  1013. for (UInt ip = 0; ip < area; ip++, ppxl++) {
  1014. CPixel pp = *ppxl;
  1015. if (ppxl -> pxlU.rgb.a == transpValue) {
  1016. pp.pxlU.rgb.r = ppxlFalse.pxlU.rgb.r;
  1017. pp.pxlU.rgb.g = ppxlFalse.pxlU.rgb.g;
  1018. pp.pxlU.rgb.b = ppxlFalse.pxlU.rgb.b;
  1019. }
  1020. fwrite (&pp, sizeof (CPixel), 1, pf);
  1021. }
  1022. fclose (pf);
  1023. }
  1024. Void CVideoObjectPlane::dump (FILE* pfFile, ChromType chrType) const
  1025. {
  1026. if (!valid ()) return;
  1027. Int iWidth = where ().width, iHeight = where ().height ();
  1028. Int iUVWidth = iWidth, iUVHeight = iHeight;
  1029. UInt uiXSubsample = 1, uiYSubsample = 1;
  1030. if (chrType == FOUR_TWO_TWO) {
  1031. uiXSubsample = 2;
  1032. iUVWidth = (iWidth + 1) / uiXSubsample;
  1033. }
  1034. else if (chrType == FOUR_TWO_ZERO) {
  1035. uiXSubsample = 2;
  1036. uiYSubsample = 2;
  1037. iUVWidth = (iWidth + 1) / uiXSubsample;
  1038. iUVHeight = (iHeight + 1) / uiYSubsample;
  1039. }
  1040. UInt iUVArea = iUVWidth * iUVHeight;
  1041. UInt area = where ().area ();
  1042. // allocate mem for buffers
  1043. U8* pchyBuffer = new U8 [area];
  1044. U8* pchuBuffer = new U8 [iUVArea];
  1045. U8* pchvBuffer = new U8 [iUVArea];
  1046. U8* pchyBuffer0 = pchyBuffer;
  1047. U8* pchuBuffer0 = pchuBuffer;
  1048. U8* pchvBuffer0 = pchvBuffer;
  1049. // assign buffers to a vframe
  1050. const CPixel* p = pixels ();
  1051. for (CoordI y = 0; y < iHeight; y++) {
  1052. if ((y % uiYSubsample) == 1) { 
  1053. pchuBuffer -= iUVWidth; 
  1054. pchvBuffer -= iUVWidth;
  1055. }
  1056. for (CoordI x = 0; x < iWidth; x++) {
  1057. if ((x % uiXSubsample) == 0) {
  1058. *pchuBuffer = p -> pxlU.yuv.u;
  1059. *pchvBuffer = p -> pxlU.yuv.v;
  1060. pchuBuffer++;
  1061. pchvBuffer++;
  1062. }
  1063. *pchyBuffer++ = p -> pxlU.yuv.y;
  1064. p++;
  1065. }
  1066. }
  1067. // write data from a file
  1068. Int size = fwrite (pchyBuffer0, sizeof (U8), area, pfFile);
  1069. assert (size != 0);
  1070. size = (Int) fwrite (pchuBuffer0, sizeof (U8), iUVArea, pfFile);
  1071. assert (size != 0);
  1072. size = (Int) fwrite (pchvBuffer0, sizeof (U8), iUVArea, pfFile);
  1073. assert (size != 0);
  1074. delete [] pchyBuffer0;
  1075. delete [] pchuBuffer0;
  1076. delete [] pchvBuffer0;
  1077. }
  1078. Void CVideoObjectPlane::dumpAlpha (FILE* pfFile) const
  1079. {   
  1080. if (!valid ()) return;
  1081. UInt area = where ().area ();
  1082. const CPixel* ppxl = pixels ();
  1083. for (UInt ip = 0; ip < area; ip++, ppxl++)
  1084. putc (ppxl -> pxlU.rgb.a, pfFile);
  1085. }
  1086. Void CVideoObjectPlane::dumpAbekas (FILE* pfFile) const
  1087. {
  1088. //dump in YCbCr but interlaced as per Abekas machine
  1089. assert (valid ());
  1090. Int iWidth = where ().width, iHeight = where ().height ();
  1091. assert (iWidth == 720);
  1092. assert (iHeight == 486); //ccir 601
  1093. UInt uiXSubsample = 2; //always has to be FOUR_TWO_TWO)
  1094. const CPixel* p = pixels ();
  1095. for (CoordI y = 0; y < iHeight; y++) {
  1096. for (CoordI x = 0; x < iWidth; x++) {
  1097. if (x % uiXSubsample == 0) {
  1098. putc(p -> pxlU.yuv.u, pfFile);
  1099. putc(p -> pxlU.yuv.y, pfFile);
  1100. }
  1101. else {
  1102. putc(p -> pxlU.yuv.v, pfFile);
  1103. putc(p -> pxlU.yuv.y, pfFile);
  1104. }
  1105. p++;
  1106. }
  1107. }
  1108. }