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

流媒体/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-4 Video conforming products. 
  20. This copyright notice must be included in all copies or derivative works. 
  21. Copyright (c) 1996, 1997.
  22. Module Name:
  23.     typeapi.cpp
  24. Abstract:
  25.     Glue for TYPE called from elsewhere
  26. Revision History:
  27. NOTE: CALLER OWNS ALL THE RETURNED POINTERS!!
  28. *************************************************************************/
  29. #include "typeapi.h"
  30. #include <stdlib.h>
  31. #include <math.h>
  32. #ifdef __MFC_
  33. #ifdef _DEBUG
  34. #undef THIS_FILE
  35. static char BASED_CODE THIS_FILE[] = __FILE__;
  36. #endif
  37. #define new DEBUG_NEW    
  38. #endif // __MFC_
  39. // handy functions
  40. Int nint (Double x)  // returns nearest integer to x, analog of FORTRAN NINT
  41. {
  42. return x > 0 ? (Int) (x + .5) : (Int) (x - .5);
  43. }
  44. #ifndef __DOUBLE_PRECISION_
  45. Double checkrange (Double x, Double cMin, Double cMax) // returns cMin if x < cMin, cMax if x > cMax, otherwise x
  46. {
  47. if (x < cMin) return cMin;
  48. if (x > cMax) return cMax;
  49. return x;
  50. }
  51. #endif // __DOUBLE_PRECISION_
  52. U8 checkrangeU8 (U8 x, U8 cMin, U8 cMax) // returns cMin if x < cMin, cMax if x > cMax, otherwise x
  53. {
  54. if (x < cMin) return cMin;
  55. if (x > cMax) return cMax;
  56. return x;
  57. }
  58. // NBIT: add checkrange for U16
  59. unsigned char checkrange (unsigned char x, unsigned char cMin, unsigned char cMax) // returns cMin if x < cMin, cMax if x > cMax, otherwise x
  60. {
  61. if (x < cMin) return cMin;
  62. if (x > cMax) return cMax;
  63. return x;
  64. }
  65. U16 checkrange (U16 x, U16 cMin, U16 cMax) // returns cMin if x < cMin, cMax if x > cMax, otherwise x
  66. {
  67. if (x < cMin) return cMin;
  68. if (x > cMax) return cMax;
  69. return x;
  70. }
  71. Int checkrange (Int x, Int cMin, Int cMax) // returns cMin if x < cMin, cMax if x > cMax, otherwise x
  72. {
  73. if (x < cMin) return cMin;
  74. if (x > cMax) return cMax;
  75. return x;
  76. }
  77. Long checkrange (Long x, Long cMin, Long cMax) // returns cMin if x < cMin, cMax if x > cMax, otherwise x
  78. {
  79. if (x < cMin) return cMin;
  80. if (x > cMax) return cMax;
  81. return x;
  82. }
  83. Float checkrange (Float x, Float cMin, Float cMax) // returns cMin if x < cMin, cMax if x > cMax, otherwise x
  84. {
  85. if (x < cMin) return cMin;
  86. if (x > cMax) return cMax;
  87. return x;
  88. }
  89. Double dist (Double x0, Double y0, Double x1, Double y1) // returns distance between (x0,y0) and (x1,y1)
  90. {
  91. Double dx = x0 - x1;
  92. Double dy = y0 - y1;
  93. return sqrt (dx * dx + dy * dy);
  94. }
  95. // handy numerical functions
  96. Int sad (const CIntImage& fi0, const CIntImage& fi1, const CIntImage& fiMsk)
  97. {
  98. assert (fi0.where () == fi1.where ());
  99. const UInt area = fi0.where ().area ();
  100. const PixelI* ppxlf0 = fi0.pixels ();
  101. const PixelI* ppxlf1 = fi1.pixels ();
  102. const PixelI* ppxlfMsk = fiMsk.pixels ();
  103. Int sadRet = 0;
  104. for (UInt ip = 0; ip < area; ip++, ppxlf0++, ppxlf1++, ppxlfMsk++) {
  105. if (*ppxlfMsk != (PixelI) transpValue)
  106. sadRet += abs (*ppxlf0 - *ppxlf1);
  107. }
  108. return sadRet;
  109. }
  110. Void mse (const CVideoObjectPlane& vop1, const CVideoObjectPlane& vop2, Double dmse [3])
  111. {
  112. assert (vop1.where () == vop2.where ());
  113. Int sqrR = 0, sqrG = 0, sqrB = 0;
  114. const CPixel* ppxlVopThis = vop1.pixels ();
  115. const CPixel* ppxlVopCompare = vop2.pixels ();
  116. UInt area = vop1.where ().area ();
  117. for (UInt i = 0; i < area; i++) {
  118. Int diffR = ppxlVopThis -> pxlU.rgb.r - ppxlVopCompare -> pxlU.rgb.r;
  119. Int diffG = ppxlVopThis -> pxlU.rgb.g - ppxlVopCompare -> pxlU.rgb.g;
  120. Int diffB = ppxlVopThis -> pxlU.rgb.b - ppxlVopCompare -> pxlU.rgb.b;
  121. sqrR += diffR * diffR;
  122. sqrG += diffG * diffG;
  123. sqrB += diffB * diffB;
  124. ppxlVopThis++;
  125. ppxlVopCompare++;
  126. }
  127. dmse [0] = (Double) sqrR / (Double) area;  
  128. dmse [1] = (Double) sqrG / (Double) area;
  129. dmse [2] = (Double) sqrB / (Double) area;
  130. }
  131. Void snr (const CVideoObjectPlane& vop1, const CVideoObjectPlane& vop2, Double dsnr [3])
  132. {
  133. Double msError [3];
  134. mse (vop1, vop2, msError);
  135. for (UInt i = 0; i < 3; i++) {
  136. if (msError [i] == 0.0)
  137. dsnr [i] = 1000.0;
  138. else 
  139. dsnr [i] = (log10 (255 * 255 / msError [i]) * 10.0);
  140. }
  141. }
  142. // CRct
  143. CRct rctFromIndex (UInt indexX, UInt indexY, const CRct& rct, UInt size) // starting from 0
  144. {
  145. assert (rct.width % size == 0 && rct.height () % size == 0);
  146. CoordI left = rct.left + indexX * size;
  147. CoordI right = left + size;
  148. CoordI top = rct.top + indexY * size;
  149. CoordI bottom = top + size;
  150. return CRct (left, top, right, bottom); 
  151. }
  152. CRct rctDivide (const CRct& rctBlk, const CRct& rctVOP, UInt rate) // divide the rctBlk by rate, with refererence to rvtVOP
  153. {
  154. assert (rctBlk <= rctVOP);
  155. CoordI left = (rctBlk.left - rctVOP.left) / rate + rctVOP.left;
  156. CoordI top = (rctBlk.top - rctVOP.top) / rate + rctVOP.top;
  157. CoordI right = left + rctBlk.width / rate;
  158. CoordI bottom = top + rctBlk.height () / rate;
  159. return CRct (left, top, right, bottom);
  160. }
  161. // CVOPIntYUVBA
  162. Void getBlockDataFromMB (const CVOPIntYUVBA* pvopfMB, CIntImage*& pfiBlk, CIntImage*& pfiB, BlockNum blkNum)
  163. {
  164. if (blkNum == ALL_Y_BLOCKS) {
  165. pfiB = new CIntImage (*pvopfMB -> getPlane (BY_PLANE));
  166. pfiBlk = new CIntImage (*pvopfMB -> getPlane (Y_PLANE));
  167. }
  168. else if (blkNum == ALL_A_BLOCKS) {
  169. pfiB = new CIntImage (*pvopfMB -> getPlane (BY_PLANE));
  170. pfiBlk = new CIntImage (*pvopfMB -> getPlane (A_PLANE));
  171. }
  172. else if (blkNum == U_BLOCK || blkNum == V_BLOCK) {
  173. pfiB = new CIntImage (*pvopfMB -> getPlane (BUV_PLANE));
  174. pfiBlk = 
  175. (blkNum == U_BLOCK) ? new CIntImage (*pvopfMB -> getPlane (U_PLANE)) :
  176. new CIntImage (*pvopfMB -> getPlane (V_PLANE));
  177. }
  178. else if ((Int) blkNum >= (Int) Y_BLOCK1 && (Int) blkNum <= (Int) Y_BLOCK4)  {
  179. UInt idx = (blkNum == Y_BLOCK1 || blkNum == Y_BLOCK3) ? 0 : 1;
  180. UInt idy = (blkNum == Y_BLOCK1 || blkNum == Y_BLOCK2) ? 0 : 1;
  181. CRct rct = pvopfMB -> whereY ();
  182. CoordI left = rct.left + idx * BLOCK_SIZE;
  183. CoordI top = rct.top + idy * BLOCK_SIZE;
  184. CRct rctF (left, top, left + BLOCK_SIZE, top + BLOCK_SIZE);
  185. pfiBlk = new CIntImage (*pvopfMB -> getPlane (Y_PLANE), rctF);
  186. pfiB = new CIntImage (*pvopfMB -> getPlane (BY_PLANE), rctF);
  187. }
  188. else { // alpha plane
  189. assert (pvopfMB -> fAUsage () == EIGHT_BIT);
  190. UInt idx = (blkNum == A_BLOCK1 || blkNum == A_BLOCK3) ? 0 : 1;
  191. UInt idy = (blkNum == A_BLOCK1 || blkNum == A_BLOCK2) ? 0 : 1;
  192. CRct rct = pvopfMB -> whereY ();
  193. CoordI left = rct.left + idx * BLOCK_SIZE;
  194. CoordI top = rct.top + idy * BLOCK_SIZE;
  195. CRct rctF (left, top, left + BLOCK_SIZE, top + BLOCK_SIZE);
  196. pfiBlk = new CIntImage (*pvopfMB -> getPlane (A_PLANE), rctF);
  197. pfiB = new CIntImage (*pvopfMB -> getPlane (BY_PLANE), rctF);
  198. }
  199. }
  200. Void getTextureDataFromMB (const CVOPIntYUVBA* pvopfMB, CIntImage*& pfiBlk, BlockNum blkNum)
  201. {
  202. if (blkNum == ALL_Y_BLOCKS) {
  203. pfiBlk = new CIntImage (*pvopfMB -> getPlane (Y_PLANE));
  204. }
  205. else if (blkNum == ALL_A_BLOCKS) {
  206. pfiBlk = new CIntImage (*pvopfMB -> getPlane (A_PLANE));
  207. }
  208. else if (blkNum == U_BLOCK || blkNum == V_BLOCK) {
  209. pfiBlk = 
  210. (blkNum == U_BLOCK) ? new CIntImage (*pvopfMB -> getPlane (U_PLANE)) :
  211. new CIntImage (*pvopfMB -> getPlane (V_PLANE));
  212. }
  213. else if ((Int) blkNum >= (Int) Y_BLOCK1 && (Int) blkNum <= (Int) Y_BLOCK4)  {
  214. UInt idx = (blkNum == Y_BLOCK1 || blkNum == Y_BLOCK3) ? 0 : 1;
  215. UInt idy = (blkNum == Y_BLOCK1 || blkNum == Y_BLOCK2) ? 0 : 1;
  216. CRct rct = pvopfMB -> whereY ();
  217. CoordI left = rct.left + idx * BLOCK_SIZE;
  218. CoordI top = rct.top + idy * BLOCK_SIZE;
  219. CRct rctF (left, top, left + BLOCK_SIZE, top + BLOCK_SIZE);
  220. pfiBlk = new CIntImage (*pvopfMB -> getPlane (Y_PLANE), rctF);
  221. }
  222. else { // alpha plane
  223. assert (pvopfMB -> fAUsage () == EIGHT_BIT);
  224. UInt idx = (blkNum == A_BLOCK1 || blkNum == A_BLOCK3) ? 0 : 1;
  225. UInt idy = (blkNum == A_BLOCK1 || blkNum == A_BLOCK2) ? 0 : 1;
  226. CRct rct = pvopfMB -> whereY ();
  227. CoordI left = rct.left + idx * BLOCK_SIZE;
  228. CoordI top = rct.top + idy * BLOCK_SIZE;
  229. CRct rctF (left, top, left + BLOCK_SIZE, top + BLOCK_SIZE);
  230. pfiBlk = new CIntImage (*pvopfMB -> getPlane (A_PLANE), rctF);
  231. }
  232. }
  233. Void getBinaryDataFromMB (const CVOPIntYUVBA* pvopfMB, CIntImage*& pfiA, BlockNum blkNum)
  234. {
  235. if (blkNum == U_BLOCK || blkNum == V_BLOCK) {
  236. pfiA = new CIntImage (*pvopfMB -> getPlane (BUV_PLANE));
  237. }
  238. else if ((Int) blkNum >= (Int) Y_BLOCK1 && (Int) blkNum <= (Int) Y_BLOCK4)  {
  239. UInt idx = (blkNum == Y_BLOCK1 || blkNum == Y_BLOCK3) ? 0 : 1;
  240. UInt idy = (blkNum == Y_BLOCK1 || blkNum == Y_BLOCK2) ? 0 : 1;
  241. CRct rct = pvopfMB -> whereY ();
  242. CoordI left = rct.left + idx * BLOCK_SIZE;
  243. CoordI top = rct.top + idy * BLOCK_SIZE;
  244. CRct rctF (left, top, left + BLOCK_SIZE, top + BLOCK_SIZE);
  245. pfiA = new CIntImage (*pvopfMB -> getPlane (BY_PLANE), rctF);
  246. }
  247. else { // alpha plane
  248. assert (pvopfMB -> fAUsage () == EIGHT_BIT);
  249. UInt idx = (blkNum == A_BLOCK1 || blkNum == A_BLOCK3) ? 0 : 1;
  250. UInt idy = (blkNum == A_BLOCK1 || blkNum == A_BLOCK2) ? 0 : 1;
  251. CRct rct = pvopfMB -> whereY ();
  252. CoordI left = rct.left + idx * BLOCK_SIZE;
  253. CoordI top = rct.top + idy * BLOCK_SIZE;
  254. CRct rctF (left, top, left + BLOCK_SIZE, top + BLOCK_SIZE);
  255. pfiA = new CIntImage (*pvopfMB -> getPlane (BY_PLANE), rctF);
  256. }
  257. }
  258. CRct fitToMulOfSize (const CRct& rctOrg, UInt size)
  259. {
  260. CRct rct = rctOrg;
  261. Int remW = rct.width % size;
  262. Int right = rct.right;
  263. if (remW != 0) 
  264. right = rct.left + rct.width + size - remW;
  265. Int remH = rct.height () % size;
  266. Int bottom = rct.bottom;
  267. if (remH != 0) 
  268. bottom = rct.top + rct.height () + size - remH;
  269. return CRct (rct.left, rct.top, right, bottom);
  270. }
  271. own CIntImage* fiFitToMulOfSize (const CIntImage* pfi, UInt size, const CSite* pstLeftTop)
  272. {
  273. CRct rctOrig = pfi -> where ();
  274. if (pstLeftTop != NULL) {
  275. rctOrig.left = pstLeftTop->x;
  276. rctOrig.top = pstLeftTop->y;
  277. }
  278. CRct rctExpanded = fitToMulOfSize (rctOrig, size); 
  279. return new CIntImage (*pfi, rctExpanded);
  280. }
  281. own CVOPIntYUVBA* vopfFitToMulOfMBSize (const CVOPIntYUVBA* pvopf, const CSite* pstLeftTop)
  282. {
  283. if (!pvopf -> valid ()) return NULL;
  284. CVOPIntYUVBA* pvopfRet = new CVOPIntYUVBA (pvopf -> fAUsage ());
  285. UInt iPln;
  286. for (iPln = Y_PLANE; iPln <= BUV_PLANE; iPln++) {
  287. if (pvopf -> fAUsage () != EIGHT_BIT) {
  288. if (iPln == A_PLANE)
  289. continue;
  290. }
  291. UInt size;
  292. CSite stOrig;
  293. if (iPln == U_PLANE || iPln == V_PLANE  || iPln == BUV_PLANE) {
  294. size = MB_SIZE >> 1;
  295. if (pstLeftTop != NULL)
  296. stOrig = *pstLeftTop / 2;
  297. else
  298. stOrig = CSite (pvopf -> whereUV ().left, pvopf -> whereUV ().top);
  299. }
  300. else {
  301. size = MB_SIZE;
  302. if (pstLeftTop != NULL)
  303. stOrig = *pstLeftTop;
  304. else
  305. stOrig = CSite (pvopf -> whereY ().left, pvopf -> whereY ().top);
  306. }
  307. CIntImage* pfiNew = fiFitToMulOfSize (pvopf -> getPlane ((PlaneType) iPln), size, &stOrig);
  308. pvopfRet -> setPlane (pfiNew, (PlaneType) iPln);
  309. delete pfiNew;
  310. }
  311. return pvopfRet;
  312. }
  313. own CIntImage* alphaFromCompFile (
  314. const Char* pchSeg, 
  315. UInt ifr, UInt iobj, 
  316. const CRct& rct, 
  317. UInt nszHeader
  318. )
  319. {
  320. CIntImage* pfiRet = new CIntImage (pchSeg, ifr, rct, nszHeader);
  321. PixelI* ppxlf = (PixelI*) pfiRet -> pixels ();
  322. UInt area = pfiRet -> where ().area ();
  323. for (UInt ip = 0; ip < area; ip++, ppxlf++) {
  324. if (*ppxlf == (PixelI) iobj)
  325. *ppxlf = (PixelI) opaqueValue;
  326. else
  327. *ppxlf = (PixelI) transpValue;
  328. }
  329. return pfiRet;
  330. }