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

流媒体/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. yuva.hpp
  24. Abstract:
  25. YUVA (4:2:0) VOP 
  26. Revision History:
  27. *************************************************************************/
  28. #include "typeapi.h"
  29. #ifdef __MFC_
  30. #ifdef _DEBUG
  31. #undef THIS_FILE
  32. static char BASED_CODE THIS_FILE[] = __FILE__;
  33. #endif
  34. #define new DEBUG_NEW    
  35. #endif // __MFC_
  36. CVOPU8YUVBA::~CVOPU8YUVBA ()
  37. {
  38. delete m_puciY;
  39. delete m_puciU;
  40. delete m_puciV;
  41. delete m_puciBY;
  42. delete m_puciBUV;
  43. delete m_puciA;
  44. }
  45. Void CVOPU8YUVBA::constructFromVOPU8 (const CVOPU8YUVBA& vopf, const CRct& rc)
  46. {
  47. if (rc.valid ()) {
  48. m_rctY = rc;
  49. m_rctUV = m_rctY.downSampleBy2 ();
  50. m_puciY = new CU8Image (*vopf.getPlane (Y_PLANE), m_rctY);
  51. m_puciU = new CU8Image (*vopf.getPlane (U_PLANE), m_rctUV);
  52. m_puciV = new CU8Image (*vopf.getPlane (V_PLANE), m_rctUV);
  53. m_ppxlcY = (PixelC*) m_puciY->pixels ();
  54. m_ppxlcU = (PixelC*) m_puciU->pixels ();
  55. m_ppxlcV = (PixelC*) m_puciV->pixels ();
  56. if (m_fAUsage != RECTANGLE) {
  57. m_puciBY = new CU8Image (*vopf.getPlane (BY_PLANE), m_rctY);
  58. m_ppxlcBY = (PixelC*) m_puciBY->pixels ();
  59. m_puciBUV = new CU8Image (*vopf.getPlane (BUV_PLANE), m_rctUV);
  60. m_ppxlcBUV = (PixelC*) m_puciBUV->pixels ();
  61. assert (m_puciBY != NULL);
  62. assert (m_puciBUV != NULL);
  63. if (m_fAUsage == EIGHT_BIT) {
  64. m_puciA = new CU8Image (*vopf.getPlane (A_PLANE), m_rctY);
  65. assert (m_puciA != NULL);
  66. m_ppxlcA = (PixelC*) m_puciA->pixels ();
  67. }
  68. }
  69. }
  70. else {
  71. m_rctY = vopf.whereY ();
  72. m_rctUV = vopf.whereUV ();
  73. m_puciY = new CU8Image (*vopf.getPlane (Y_PLANE));
  74. m_puciU = new CU8Image (*vopf.getPlane (U_PLANE));
  75. m_puciV = new CU8Image (*vopf.getPlane (V_PLANE));
  76. m_ppxlcY = (PixelC*) m_puciY->pixels ();
  77. m_ppxlcU = (PixelC*) m_puciU->pixels ();
  78. m_ppxlcV = (PixelC*) m_puciV->pixels ();
  79. if (m_fAUsage != RECTANGLE) {
  80. m_puciBY = new CU8Image (*vopf.getPlane (BY_PLANE));
  81. m_ppxlcBY = (PixelC*) m_puciBY->pixels ();
  82. m_puciBUV = new CU8Image (*vopf.getPlane (BUV_PLANE));
  83. m_ppxlcBUV = (PixelC*) m_puciBUV->pixels ();
  84. assert (m_puciBY != NULL);
  85. assert (m_puciBUV != NULL);
  86. if (m_fAUsage == EIGHT_BIT) {
  87. m_puciA = new CU8Image (*vopf.getPlane (A_PLANE));
  88. assert (m_puciA != NULL);
  89. m_ppxlcA = (PixelC*) m_puciA->pixels ();
  90. }
  91. }
  92. }
  93. assert (m_puciY != NULL);
  94. assert (m_puciU != NULL);
  95. assert (m_puciV != NULL);
  96. }
  97. CVOPU8YUVBA::CVOPU8YUVBA (const CVOPU8YUVBA& vopf, AlphaUsage fAUsage, const CRct& rc)
  98. {
  99.   m_fAUsage = fAUsage;
  100.   m_puciY = NULL;
  101.   m_puciU = NULL; 
  102.   m_puciV  = NULL; 
  103.   m_puciBY  = NULL; 
  104.   m_puciBUV = NULL; 
  105.   m_puciA = NULL;
  106.   constructFromVOPU8 (vopf, rc);
  107. }
  108. CVOPU8YUVBA::CVOPU8YUVBA (const CVOPU8YUVBA& vopf, const CRct& rc) : 
  109. m_puciY (NULL), m_puciU (NULL), m_puciV (NULL), m_puciBY (NULL), m_puciBUV (NULL), m_puciA (NULL)
  110. {
  111. m_fAUsage = vopf.fAUsage ();
  112. constructFromVOPU8 (vopf, rc);
  113. }
  114. CVOPU8YUVBA::CVOPU8YUVBA (const Char* sptFilename) :
  115. m_puciY (NULL), m_puciU (NULL), m_puciV (NULL), m_puciBY (NULL), m_puciBUV (NULL), m_puciA (NULL)
  116. {
  117. FILE* pf = fopen (sptFilename, "rb");
  118. // read overhead
  119. Int c0 = getc (pf);
  120. Int c1 = getc (pf);
  121. Int c2 = getc (pf);
  122. assert (c0 == 'S' && (c1 == 'P' || c2 == 'T') );
  123. fread (&m_rctY.left, sizeof (CoordI), 1, pf);
  124. fread (&m_rctY.top, sizeof (CoordI), 1, pf);
  125. fread (&m_rctY.right, sizeof (CoordI), 1, pf);
  126. fread (&m_rctY.bottom, sizeof (CoordI), 1, pf);
  127. fread (&m_fAUsage, sizeof (Int), 1, pf);
  128. m_rctY.width = m_rctY.right - m_rctY.left;
  129. m_rctUV = m_rctY.downSampleBy2 ();
  130. m_puciY = new CU8Image (m_rctY);
  131. assert (m_puciY != NULL);
  132. m_puciU = new CU8Image (m_rctUV);
  133. assert (m_puciU != NULL);
  134. m_puciV = new CU8Image (m_rctUV);
  135. assert (m_puciV != NULL);
  136. m_ppxlcY = (PixelC*) m_puciY->pixels ();
  137. m_ppxlcU = (PixelC*) m_puciU->pixels ();
  138. m_ppxlcV = (PixelC*) m_puciV->pixels ();
  139. if (m_fAUsage != RECTANGLE) {
  140. m_puciBY = new CU8Image (m_rctY, MPEG4_TRANSPARENT); //initialize so that outside VOP is transp
  141. assert (m_puciBY != NULL);
  142. m_puciBUV = new CU8Image (m_rctUV, MPEG4_TRANSPARENT); //initialize so that outside VOP is transp
  143. assert (m_puciBUV != NULL);
  144. m_ppxlcBY = (PixelC*) m_puciBY->pixels ();
  145. m_ppxlcBUV = (PixelC*) m_puciBUV->pixels ();
  146. if (m_fAUsage == EIGHT_BIT) {
  147. m_puciA = new CU8Image (m_rctY, MPEG4_TRANSPARENT); //initialize so that outside VOP is transp
  148. assert (m_puciA != NULL);
  149. m_ppxlcA = (PixelC*) m_puciA->pixels ();
  150. }
  151. }
  152. // read the actual data
  153. fread (m_ppxlcY, sizeof (U8), m_rctY.area (), pf);
  154. fread (m_ppxlcU, sizeof (U8), m_rctUV.area (), pf);
  155. fread (m_ppxlcV, sizeof (U8), m_rctUV.area (), pf);
  156. if (m_fAUsage != RECTANGLE) {
  157. if (m_fAUsage == EIGHT_BIT)
  158. fread ((PixelC*) m_ppxlcA, sizeof (U8), m_rctY.area (), pf);
  159. else
  160. fread ((PixelC*) m_ppxlcBY, sizeof (U8), m_rctY.area (), pf);
  161. }
  162. fclose (pf);
  163. }
  164. CVOPU8YUVBA::CVOPU8YUVBA (AlphaUsage fAUsage, const CRct& rc)
  165. {
  166. m_puciY = NULL;
  167. m_puciU = NULL;
  168. m_puciV = NULL;
  169. m_puciBY = NULL;
  170. m_puciBUV = NULL;
  171. m_puciA = NULL;
  172. m_fAUsage = fAUsage;
  173. m_rctY = rc;
  174. m_rctUV = m_rctY.downSampleBy2 ();
  175. m_puciY = new CU8Image (m_rctY);
  176. assert (m_puciY != NULL);
  177. m_puciU = new CU8Image (m_rctUV);
  178. assert (m_puciU != NULL);
  179. m_puciV = new CU8Image (m_rctUV);
  180. assert (m_puciV != NULL);
  181. m_ppxlcY = (PixelC*) m_puciY->pixels ();
  182. m_ppxlcU = (PixelC*) m_puciU->pixels ();
  183. m_ppxlcV = (PixelC*) m_puciV->pixels ();
  184. if (m_fAUsage != RECTANGLE) {
  185. m_puciBY = new CU8Image (m_rctY, MPEG4_TRANSPARENT); //initialize so that outside VOP is transp
  186. assert (m_puciBY != NULL);
  187. m_puciBUV = new CU8Image (m_rctUV, MPEG4_TRANSPARENT); //initialize so that outside VOP is transp
  188. assert (m_puciBUV != NULL);
  189. m_ppxlcBY = (PixelC*) m_puciBY->pixels ();
  190. m_ppxlcBUV = (PixelC*) m_puciBUV->pixels ();
  191. if (m_fAUsage == EIGHT_BIT) {
  192. m_puciA = new CU8Image (m_rctY, MPEG4_TRANSPARENT); //initialize so that outside VOP is transp
  193. assert (m_puciA != NULL);
  194. m_ppxlcA = (PixelC*) m_puciA->pixels ();
  195. }
  196. }
  197. }
  198. CVOPU8YUVBA::CVOPU8YUVBA (AlphaUsage fAUsage)
  199. {
  200. m_puciY = NULL;
  201. m_puciU = NULL;
  202. m_puciV = NULL;
  203. m_puciBY = NULL;
  204. m_puciBUV = NULL;
  205. m_puciA = NULL;
  206. m_fAUsage = fAUsage;
  207. }
  208. Void CVOPU8YUVBA::shift (CoordI left, CoordI top)
  209. {
  210. m_rctY.shift (left, top);
  211. m_rctUV.shift (left / 2, top / 2);
  212. m_puciY -> shift (left, top);
  213. m_puciU -> shift (left / 2, top / 2);
  214. m_puciV -> shift (left / 2, top / 2);
  215. if (m_fAUsage == EIGHT_BIT) 
  216. m_puciA -> shift (left, top);
  217. else if (m_fAUsage == ONE_BIT) {
  218. m_puciBY -> shift (left, top);
  219. m_puciBUV -> shift (left / 2, top / 2);
  220. }
  221. }
  222. Void CVOPU8YUVBA::setBoundRct (const CRct& rctBoundY)
  223. {
  224. assert (rctBoundY <= m_rctY);
  225. m_rctBoundY = rctBoundY;
  226. m_rctBoundUV = m_rctBoundY.downSampleBy2 ();
  227. Int iOffsetY = m_rctY.offset (m_rctBoundY.left, m_rctBoundY.top);
  228. Int iOffsetUV = m_rctUV.offset (m_rctBoundUV.left, m_rctBoundUV.top);
  229. m_ppxlcBoundY = (PixelC*) m_puciY->pixels () + iOffsetY;
  230. m_ppxlcBoundU = (PixelC*) m_puciU->pixels () + iOffsetUV;
  231. m_ppxlcBoundV = (PixelC*) m_puciV->pixels () + iOffsetUV;
  232. if (m_fAUsage != RECTANGLE) {
  233. m_ppxlcBoundBY = (PixelC*) m_puciBY->pixels () + iOffsetY;
  234. m_ppxlcBoundBUV = (PixelC*) m_puciBUV->pixels () + iOffsetUV;
  235. if (m_fAUsage == EIGHT_BIT)
  236. m_ppxlcBoundA = (PixelC*) m_puciA->pixels () + iOffsetY;
  237. }
  238. }
  239. Void CVOPU8YUVBA::setAndExpandBoundRctOnly (const CRct& rctBoundY, Int iExpand)
  240. {
  241. assert (rctBoundY <= m_rctY);
  242. m_rctBoundY = rctBoundY;
  243. m_rctBoundY.expand (iExpand);
  244. m_rctBoundUV = m_rctBoundY.downSampleBy2 ();
  245. }
  246. Void CVOPU8YUVBA::cropOnAlpha ()
  247. {
  248. m_puciBY -> cropOnAlpha ();
  249. m_puciBUV -> cropOnAlpha ();
  250. m_puciY -> where (m_puciBY -> where ());
  251. m_puciU -> where (m_puciBUV -> where ());
  252. m_puciV -> where (m_puciBUV -> where ());
  253. if (m_fAUsage == EIGHT_BIT)
  254. m_puciA -> where (m_puciBY -> where ());
  255. }
  256. Void CVOPU8YUVBA::overlay (const CVOPU8YUVBA& vopc)
  257. {
  258. if (!vopc.valid ()) return;
  259. if (m_puciBY) //sometime rectangular vops dont have by
  260. m_puciBY -> overlay (*vopc.getPlane (BY_PLANE));
  261. if (m_puciBUV)
  262. m_puciBUV -> overlay (*vopc.getPlane (BUV_PLANE));
  263. m_puciY -> overlay (*vopc.getPlane (Y_PLANE));
  264. m_puciU -> overlay (*vopc.getPlane (U_PLANE));
  265. m_puciV -> overlay (*vopc.getPlane (V_PLANE));
  266. if (m_fAUsage == EIGHT_BIT)
  267. m_puciA -> overlay (*vopc.getPlane (A_PLANE));
  268. }
  269. Void CVOPU8YUVBA::overlay (const CVOPU8YUVBA& vopc, const CRct& rctY)
  270. {
  271. if (!vopc.valid ()) return;
  272. if (!rctY.valid ()) return;
  273. CRct rctUV = rctY.downSampleBy2 ();
  274. m_puciBY -> overlay (*vopc.getPlane (BY_PLANE), rctY);
  275. m_puciBUV -> overlay (*vopc.getPlane (BUV_PLANE), rctUV);
  276. m_puciY -> overlay (*vopc.getPlane (Y_PLANE), rctY);
  277. m_puciU -> overlay (*vopc.getPlane (U_PLANE), rctUV);
  278. m_puciV -> overlay (*vopc.getPlane (V_PLANE), rctUV);
  279. if (m_fAUsage == EIGHT_BIT)
  280. m_puciA -> overlay (*vopc.getPlane (A_PLANE), rctY);
  281. }
  282. own CVOPU8YUVBA* CVOPU8YUVBA::downsampleForSpatialScalability () const
  283. {
  284. //only handle CIF->QCIF for RECTANGULAR VOP
  285. assert (m_fAUsage == RECTANGLE);
  286. //CRct rctDown = whereY ();
  287. assert (whereY().left == 0 && whereY().top == 0);
  288. CVOPU8YUVBA* pvopfRet = new CVOPU8YUVBA (m_fAUsage);
  289. assert (pvopfRet != NULL);
  290. pvopfRet -> m_puciY = m_puciY->downsampleForSpatialScalability ();
  291. pvopfRet -> m_puciU = m_puciU->downsampleForSpatialScalability ();
  292. pvopfRet -> m_puciV = m_puciV->downsampleForSpatialScalability ();
  293. pvopfRet -> m_puciBY = new CU8Image (pvopfRet->whereY (), opaqueValue);
  294. pvopfRet -> m_puciBUV = new CU8Image (pvopfRet->whereUV (), opaqueValue);
  295. return pvopfRet;
  296. }
  297. //wchen: maybe these upsampling functions should be in sys; do it later
  298. own CVOPU8YUVBA* CVOPU8YUVBA::upsampleForSpatialScalability (Int iVerticalSamplingFactorM,
  299.  Int iVerticalSamplingFactorN,
  300.  Int iHorizontalSamplingFactorM,
  301.  Int iHorizontalSamplingFactorN,
  302.  Int iExpandYRefFrame,
  303.  Int iExpandUVRefFrame) const
  304. {
  305. //only handle QCIF->CIF for RECTANGULAR VOP
  306. //assert (m_fAUsage == RECTANGLE);
  307. CVOPU8YUVBA* pvopfRet = new CVOPU8YUVBA (m_fAUsage);
  308. assert (pvopfRet != NULL);
  309. pvopfRet -> m_puciY = m_puciY->upsampleForSpatialScalability (iVerticalSamplingFactorM, iVerticalSamplingFactorN, iHorizontalSamplingFactorM, 
  310.   iHorizontalSamplingFactorN, 1, iExpandYRefFrame);
  311. pvopfRet -> m_puciU = m_puciU->upsampleForSpatialScalability (iVerticalSamplingFactorM, iVerticalSamplingFactorN, iHorizontalSamplingFactorM, 
  312.   iHorizontalSamplingFactorN, 2, iExpandYRefFrame);
  313. pvopfRet -> m_puciV = m_puciV->upsampleForSpatialScalability (iVerticalSamplingFactorM, iVerticalSamplingFactorN, iHorizontalSamplingFactorM, 
  314.   iHorizontalSamplingFactorN, 2, iExpandYRefFrame);
  315. pvopfRet -> m_puciBY = new CU8Image (pvopfRet->whereY (), opaqueValue);
  316. pvopfRet -> m_puciBUV = new CU8Image (pvopfRet->whereUV (), opaqueValue);
  317. pvopfRet->m_ppxlcY = (PixelC *) pvopfRet->m_puciY->pixels();
  318. pvopfRet->m_ppxlcU = (PixelC *) pvopfRet->m_puciU->pixels();
  319. pvopfRet->m_ppxlcV = (PixelC *) pvopfRet->m_puciV->pixels();
  320. pvopfRet->m_rctY   = pvopfRet->m_puciY->where();
  321. pvopfRet->m_rctUV  = pvopfRet->m_puciU->where();
  322. pvopfRet->m_rctBoundY.expand(-iExpandYRefFrame, -iExpandYRefFrame,-iExpandYRefFrame,-iExpandYRefFrame);
  323. pvopfRet->m_rctBoundUV.expand(-iExpandUVRefFrame,-iExpandUVRefFrame,-iExpandUVRefFrame,-iExpandUVRefFrame);
  324. pvopfRet->m_ppxlcBoundY=pvopfRet->m_ppxlcY+16+16*pvopfRet->m_rctY.width;
  325. pvopfRet->m_ppxlcBoundU=pvopfRet->m_ppxlcU +8 +8*pvopfRet->m_rctUV.width;
  326. pvopfRet->m_ppxlcBoundY=pvopfRet->m_ppxlcV +8 +8*pvopfRet->m_rctUV.width;
  327. return pvopfRet;
  328. }
  329. own Double* CVOPU8YUVBA::mse (const CVOPU8YUVBA& vopf) const
  330. {
  331. assert (whereY () == vopf.whereY () && whereUV () == vopf.whereUV ());
  332. Double* rgdblMeanSquareError = new Double [4]; // mean square
  333. CU8Image* puciBOr = new CU8Image (*m_puciBY);
  334. puciBOr -> CU8Image_or (*vopf.getPlane (BY_PLANE));
  335. CU8Image* puciExp0 = new CU8Image (*m_puciY, puciBOr -> where ());
  336. CU8Image* puciExp1 = new CU8Image (*vopf.getPlane (Y_PLANE), puciBOr -> where ());
  337. rgdblMeanSquareError [0] = puciExp1 -> mse (*puciExp0, *puciBOr);
  338. delete puciExp0;
  339. delete puciExp1;
  340. if (fAUsage () == EIGHT_BIT) {
  341. puciExp0 = new CU8Image (*m_puciA, puciBOr -> where ());
  342. puciExp1 = new CU8Image (*vopf.getPlane (A_PLANE), puciBOr -> where ());
  343. rgdblMeanSquareError [3] = puciExp1 -> mse (*puciExp0, *puciBOr);
  344. delete puciExp0;
  345. delete puciExp1;
  346. }
  347. delete puciBOr;
  348. puciBOr = new CU8Image (*m_puciBUV);
  349. puciBOr -> CU8Image_or (*vopf.getPlane (BUV_PLANE));
  350. puciExp0 = new CU8Image (*m_puciU, puciBOr -> where ());
  351. puciExp1 = new CU8Image (*vopf.getPlane (U_PLANE), puciBOr -> where ());
  352. rgdblMeanSquareError [1] = puciExp1 -> mse (*puciExp0, *puciBOr);
  353. delete puciExp0;
  354. delete puciExp1;
  355. puciExp0 = new CU8Image (*m_puciV, puciBOr -> where ());
  356. puciExp1 = new CU8Image (*vopf.getPlane (V_PLANE), puciBOr -> where ());
  357. rgdblMeanSquareError [2] = puciExp1 -> mse (*puciExp0, *puciBOr);
  358. delete puciExp0;
  359. delete puciExp1;
  360. delete puciBOr;
  361. return rgdblMeanSquareError;
  362. }
  363. own Double* CVOPU8YUVBA::snr (const CVOPU8YUVBA& vopf) const
  364. {
  365. assert (whereY () == vopf.whereY () && whereUV () == vopf.whereUV ());
  366. Double* psnr = new Double [4]; // mean square
  367. CU8Image* puciBOr = new CU8Image (*m_puciBY);
  368. puciBOr -> CU8Image_or (*vopf.getPlane (BY_PLANE));
  369. CU8Image* puciExp0 = new CU8Image (*m_puciY, puciBOr -> where ());
  370. CU8Image* puciExp1 = new CU8Image (*vopf.getPlane (Y_PLANE), puciBOr -> where ());
  371. psnr [0] = puciExp1 -> snr (*puciExp0, *puciBOr);
  372. delete puciExp0;
  373. delete puciExp1;
  374. if (fAUsage () == EIGHT_BIT) {
  375. puciExp0 = new CU8Image (*m_puciA, puciBOr -> where ());
  376. puciExp1 = new CU8Image (*vopf.getPlane (A_PLANE), puciBOr -> where ());
  377. psnr [3] = puciExp1 -> snr (*puciExp0, *puciBOr);
  378. delete puciExp0;
  379. delete puciExp1;
  380. }
  381. delete puciBOr;
  382. puciBOr = new CU8Image (*m_puciBUV);
  383. puciBOr -> CU8Image_or (*vopf.getPlane (BUV_PLANE));
  384. puciExp0 = new CU8Image (*m_puciU, puciBOr -> where ());
  385. puciExp1 = new CU8Image (*vopf.getPlane (U_PLANE), puciBOr -> where ());
  386. psnr [1] = puciExp1 -> snr (*puciExp0, *puciBOr);
  387. delete puciExp0;
  388. delete puciExp1;
  389. puciExp0 = new CU8Image (*m_puciV, puciBOr -> where ());
  390. puciExp1 = new CU8Image (*vopf.getPlane (V_PLANE), puciBOr -> where ());
  391. psnr [2] = puciExp1 -> snr (*puciExp0, *puciBOr);
  392. delete puciExp0;
  393. delete puciExp1;
  394. delete puciBOr;
  395. return psnr;
  396. }
  397. const CU8Image* CVOPU8YUVBA::getPlane (PlaneType plnType) const
  398. {
  399. if (plnType == Y_PLANE) return m_puciY;
  400. else if (plnType == U_PLANE) return m_puciU;
  401. else if (plnType == V_PLANE) return m_puciV;
  402. else if (plnType == BY_PLANE) return m_puciBY;
  403. else if (plnType == BUV_PLANE) return m_puciBUV;
  404. else if (plnType == A_PLANE) return m_puciA;
  405. else return NULL;
  406. }
  407. Void CVOPU8YUVBA::dump (FILE* pfFile) const
  408. {
  409. fwrite (m_ppxlcY, m_rctY .area(), 1, pfFile);
  410. fwrite (m_ppxlcU, m_rctUV.area(), 1, pfFile);
  411. fwrite (m_ppxlcV, m_rctUV.area(), 1, pfFile);
  412. }
  413. Void CVOPU8YUVBA::dump (const Char* pchFileName) const
  414. {
  415. FILE* pfOut = fopen (pchFileName, "wb");
  416. dump (pfOut);
  417. fclose (pfOut);
  418. }
  419. Void CVOPU8YUVBA::vdlDump (const Char* pchFileName, const CRct& rct) const
  420. {
  421. CRct rctROI = (!rct.valid ()) ? m_rctY : rct;
  422. assert (rctROI <= m_rctY);
  423. CVideoObjectPlane vop (rctROI, opaquePixel);
  424. Int offset = (rctROI == m_rctY)? 0 : m_rctY.width - rct.width;
  425. CU8Image* puciZoomedU = m_puciU -> zoomup (2, 2);
  426. CU8Image* puciZoomedV = m_puciV -> zoomup (2, 2);
  427. PixelC* ppxlucY = (PixelC*) m_puciY -> pixels ();
  428. PixelC* ppxlucU = (PixelC*) puciZoomedU -> pixels ();
  429. PixelC* ppxlucV = (PixelC*) puciZoomedV -> pixels ();
  430. PixelC* ppxlucA = NULL;
  431. if (m_fAUsage == EIGHT_BIT)
  432. ppxlucA = (PixelC*) m_puciA -> pixels ();
  433. else if (m_fAUsage == ONE_BIT)
  434. ppxlucA = (PixelC*) m_puciBY -> pixels ();
  435. CPixel* ppxl = (CPixel*) vop.pixels ();
  436. for (CoordI y = rctROI.top; y < rctROI.bottom; y++) {
  437. for (CoordI x = rctROI.left; x < rctROI.right; x++, ppxlucY++, ppxlucU++, ppxlucV++, ppxlucA++) {
  438. Double var = 1.164 * (*ppxlucY - 16);
  439. Int r = (Int) ((Double) (var + 1.596 * (*ppxlucV - 128)) + .5);
  440. Int g = (Int) ((Double) (var - 0.813 * (*ppxlucV - 128) - 0.391 * (*ppxlucU - 128)) + .5);
  441. Int b = (Int) ((Double) (var + 2.018 * (*ppxlucU - 128)) + .5);
  442. Int a = (m_fAUsage == RECTANGLE)? opaqueValue : *ppxlucA;
  443. ppxl -> pxlU.rgb.r = (U8) checkrange (r, 0, 255);
  444. ppxl -> pxlU.rgb.g = (U8) checkrange (g, 0, 255);
  445. ppxl -> pxlU.rgb.b = (U8) checkrange (b, 0, 255);
  446. ppxl -> pxlU.rgb.a = (U8) checkrange (a, 0, 255);
  447. ppxl++;
  448. }
  449. ppxlucY += offset; ppxlucU += offset; ppxlucV += offset; ppxlucA += offset;
  450. }
  451. delete puciZoomedU;
  452. delete puciZoomedV;
  453. vop.vdlDump (pchFileName);
  454. }
  455. Void CVOPU8YUVBA::addBYPlain ()
  456. {
  457. m_puciBY = new CU8Image (m_rctY, 255); //initialize so that outside VOP is transp
  458. assert (m_puciBY != NULL);
  459. m_puciBUV = new CU8Image (m_rctUV, 255); //initialize so that outside VOP is transp
  460. assert (m_puciBUV != NULL);
  461. m_ppxlcBY = (PixelC*) m_puciBY->pixels ();
  462. m_ppxlcBUV = (PixelC*) m_puciBUV->pixels ();
  463. if (m_fAUsage == EIGHT_BIT) {
  464. m_puciA = new CU8Image (m_rctY, 255); //initialize so that outside VOP is transp
  465. assert (m_puciA != NULL);
  466. m_ppxlcA = (PixelC*) m_puciA->pixels ();
  467. }
  468. }
  469. Void CVOPU8YUVBA::addBYPlain (const CRct& rct, const CRct& rctUV)
  470. {
  471. CU8Image* puciTemp = new CU8Image ( rct, MPEG4_OPAQUE );
  472. //m_puciBY = new CU8Image (m_rctY, 255); //initialize so that outside VOP is transp
  473. m_puciBY = new CU8Image (m_rctY, MPEG4_TRANSPARENT); //initialize so that outside VOP is transp
  474. m_puciBY->CU8Image_or( *puciTemp ); // for background composition, mask of whole image is generated here
  475. assert (m_puciBY != NULL);
  476. CU8Image* puciTempUV = new CU8Image ( rctUV, MPEG4_OPAQUE );
  477. //m_puciBUV = new CU8Image (m_rctUV, 255); //initialize so that outside VOP is transp
  478. m_puciBUV = new CU8Image (m_rctUV, MPEG4_TRANSPARENT); //initialize so that outside VOP is transp
  479. m_puciBUV->CU8Image_or( *puciTempUV ); // for background composition, mask of whole image is generated here
  480. assert (m_puciBUV != NULL);
  481. m_ppxlcBY = (PixelC*) m_puciBY->pixels ();
  482. m_ppxlcBUV = (PixelC*) m_puciBUV->pixels ();
  483. if (m_fAUsage == EIGHT_BIT) {
  484. //m_puciA = new CU8Image (m_rctY, 255); //initialize so that outside VOP is transp
  485. m_puciA = new CU8Image (m_rctY, MPEG4_TRANSPARENT); //initialize so that outside VOP is transp
  486. m_puciA->CU8Image_or( *puciTemp );
  487. assert (m_puciA != NULL);
  488. m_ppxlcA = (PixelC*) m_puciA->pixels ();
  489. }
  490. }