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

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. /*************************************************************************
  2. This software module was originally developed by 
  3. Simon Winder (swinder@microsoft.com), Microsoft Corporation
  4. in the course of development of the MPEG-4 Video (ISO/IEC 14496-2). 
  5. This software module is an implementation of a part of one or more MPEG-4 Video tools 
  6. as specified by the MPEG-4 Video. 
  7. ISO/IEC gives users of the MPEG-4 Video free license to this software module or modifications 
  8. thereof for use in hardware or software products claiming conformance to the MPEG-4 Video. 
  9. Those intending to use this software module in hardware or software products are advised that
  10. its use may infringe existing patents. The original developer of this software module and his/her
  11. company, the subsequent editors and their companies, and ISO/IEC have no liability for use of
  12. this software module or modifications thereof in an implementation. Copyright is not released
  13. for non MPEG-4 Video conforming products. Microsoft retains full right to use the code for
  14. his/her own purpose, assign or donate the code to a third party and to inhibit third parties
  15. from using the code for non MPEG-4 Video conforming products. This copyright notice must be
  16. included in all copies or derivative works. 
  17. Copyright (c) 1996, 1997.
  18. *************************************************************************/
  19. #include <stdio.h>
  20. #include <stdlib.h>
  21. #include <string.h>
  22. #include <ctype.h>
  23. #include "paramset.h"
  24. #ifdef __MFC_
  25. #ifdef _DEBUG
  26. #undef THIS_FILE
  27. static char BASED_CODE THIS_FILE[] = __FILE__;
  28. #endif
  29. #define new DEBUG_NEW    
  30. #endif // __MFC_
  31. ////////////////////////////////////////////////////////////////////////
  32. // CxParamSet
  33. ////////////////////////////////////////////////////////////////////////
  34. CxParamSet::CxParamSet()
  35. : m_pCurrentEnum(NULL), m_pCreateListTail(NULL)
  36. {
  37. Int i;
  38. for(i=0; i<PAR_HASHSIZE; i++)
  39. m_rgpHashList[i] = NULL;
  40. }
  41. CxParamSet::~CxParamSet()
  42. {
  43. DeleteAll();
  44. }
  45. Int CxParamSet::GetParam(const char *pchName, Int iIndex, TxParamValue *ptValueRtn)
  46. {
  47. if(pchName==NULL)
  48. return ERES_PARAMS;
  49. if(iIndex<-1)
  50. iIndex = -1;
  51. Int iHash;
  52. TxParamEntry *pEntry = FindHashEntry(pchName, iIndex, &iHash);
  53. if(pEntry==NULL)
  54. return ERES_NOOBJ;
  55. if(ptValueRtn!=NULL)
  56. *ptValueRtn = pEntry->tValue;
  57. return ERES_OK;
  58. }
  59. Int CxParamSet::SetParam(const char *pchName, Int iIndex, const TxParamValue *ptValue)
  60. {
  61. if(pchName==NULL || ptValue==NULL)
  62. return ERES_PARAMS;
  63. if(ptValue->tType==PS_STRING && ptValue->pchData==NULL)
  64. return ERES_PARAMS;
  65. if(ptValue->tType==PS_ARRAY && ptValue->pdData==NULL)
  66. return ERES_PARAMS;
  67. if(iIndex<-1)
  68. iIndex = -1;
  69. Int iHash;
  70. TxParamEntry *pEntry = FindHashEntry(pchName, iIndex, &iHash);
  71. if(pEntry==NULL)
  72. {
  73. // validate new name
  74. Int i, iL;
  75. iL = strlen(pchName);
  76. for(i=0; i<iL; i++)
  77. if(isspace(pchName[i]) || pchName[i]=='/' || pchName[i]=='['
  78. || pchName[i]=='=')
  79. return ERES_PARAMS;
  80. // create new entry at iHash
  81. pEntry = new TxParamEntry;
  82. if(pEntry==NULL)
  83. return ERES_MEMORY;
  84. pEntry->pchName = new char [strlen(pchName) + 1];
  85. if(pEntry->pchName==NULL)
  86. {
  87. delete pEntry;
  88. return ERES_MEMORY;
  89. }
  90. strcpy(pEntry->pchName, pchName);
  91. pEntry->iIndex = iIndex;
  92. // copy data
  93. pEntry->tValue = *ptValue;
  94. if(pEntry->tValue.tType==PS_STRING)
  95. {
  96. pEntry->tValue.pchData = new char [strlen(ptValue->pchData) + 1];
  97. if(pEntry->tValue.pchData==NULL)
  98. {
  99. delete pEntry->pchName;
  100. delete pEntry;
  101. return ERES_MEMORY;
  102. }
  103. strcpy(pEntry->tValue.pchData, ptValue->pchData);
  104. }
  105. else if(pEntry->tValue.tType==PS_ARRAY)
  106. {
  107. pEntry->tValue.pdData = new Double [pEntry->tValue.iSize + 1]; // add one in case size is zero
  108. if(pEntry->tValue.pdData==NULL)
  109. {
  110. delete pEntry->pchName;
  111. delete pEntry;
  112. return ERES_MEMORY;
  113. }
  114. memcpy(pEntry->tValue.pdData, ptValue->pdData, pEntry->tValue.iSize * sizeof(Double));
  115. }
  116. // add to hash list at head
  117. pEntry->pNextHash = m_rgpHashList[iHash];
  118. pEntry->pPrevHash = NULL;
  119. m_rgpHashList[iHash] = pEntry;
  120. if(pEntry->pNextHash)
  121. pEntry->pNextHash->pPrevHash = pEntry;
  122. // add to create list at tail
  123. pEntry->pPrevCreate = m_pCreateListTail;
  124. pEntry->pNextCreate = NULL;
  125. m_pCreateListTail = pEntry;
  126. if(pEntry->pPrevCreate)
  127. pEntry->pPrevCreate->pNextCreate = pEntry;
  128. }
  129. else // already exists
  130. {
  131. // make copy of string or array if necessary
  132. char *pchTmp = NULL;
  133. Double *pdTmp = NULL;
  134. if(ptValue->tType==PS_STRING)
  135. {
  136. pchTmp = new char [strlen(ptValue->pchData) + 1];
  137. if(pchTmp==NULL)
  138. return ERES_MEMORY;
  139. strcpy(pchTmp, ptValue->pchData);
  140. }
  141. else if(pEntry->tValue.tType==PS_ARRAY)
  142. {
  143. pdTmp = new Double [ptValue->iSize + 1];
  144. if(pdTmp==NULL)
  145. return ERES_MEMORY;
  146. memcpy(pdTmp, ptValue->pdData, ptValue->iSize * sizeof(Double));
  147. }
  148. // delete old string or array if present
  149. if(pEntry->tValue.tType==PS_STRING)
  150. delete pEntry->tValue.pchData;
  151. else if(pEntry->tValue.tType==PS_ARRAY)
  152. delete pEntry->tValue.pdData;
  153. // copy data
  154. pEntry->tValue = *ptValue;
  155. // assign string or array pointer
  156. if(ptValue->tType==PS_STRING)
  157. pEntry->tValue.pchData = pchTmp;
  158. else if(ptValue->tType==PS_ARRAY)
  159. pEntry->tValue.pdData = pdTmp;
  160. }
  161. return ERES_OK;
  162. }
  163. Int CxParamSet::DeleteParam(const char *pchName, Int iIndex)
  164. {
  165. if(pchName==NULL)
  166. return ERES_PARAMS;
  167. if(iIndex<-1)
  168. iIndex = -1;
  169. Int iHash;
  170. TxParamEntry *pEntry = FindHashEntry(pchName, iIndex, &iHash);
  171. if(pEntry==NULL)
  172. return ERES_NOOBJ;
  173. if(pEntry==m_pCurrentEnum)
  174. m_pCurrentEnum = pEntry->pNextCreate;
  175. DeleteHashEntry(pEntry, iHash);
  176. return ERES_OK;
  177. }
  178. void CxParamSet::StartEnum()
  179. {
  180. // set current enum to head of create list
  181. if(m_pCreateListTail==NULL)
  182. return;
  183. m_pCurrentEnum = m_pCreateListTail;
  184. while(m_pCurrentEnum->pPrevCreate)
  185. m_pCurrentEnum = m_pCurrentEnum->pPrevCreate;
  186. }
  187. Bool CxParamSet::NextEnum(char **ppchNameRtn, Int *piIndexRtn, TxParamValue *ptValueRtn)
  188. {
  189. if(m_pCurrentEnum==NULL)
  190. return FALSE;
  191. if(ppchNameRtn)
  192. *ppchNameRtn = m_pCurrentEnum->pchName;
  193. if(piIndexRtn)
  194. *piIndexRtn = m_pCurrentEnum->iIndex;
  195. if(ptValueRtn)
  196. *ptValueRtn = m_pCurrentEnum->tValue;
  197. m_pCurrentEnum = m_pCurrentEnum->pNextCreate;
  198. return TRUE;
  199. }
  200. void CxParamSet::DeleteAll()
  201. {
  202. Int i;
  203. for(i=0; i<PAR_HASHSIZE; i++)
  204. {
  205. TxParamEntry *pEntry;
  206. while((pEntry = m_rgpHashList[i])!=NULL)
  207. DeleteHashEntry(pEntry, i);
  208. }
  209. m_pCurrentEnum = NULL;
  210. }
  211. void CxParamSet::DeleteHashEntry(TxParamEntry *pEntry, Int iHash)
  212. {
  213. // unlink from hash chain
  214. if(pEntry->pPrevHash)
  215. pEntry->pPrevHash->pNextHash = pEntry->pNextHash;
  216. else
  217. m_rgpHashList[iHash] = pEntry->pNextHash;
  218. if(pEntry->pNextHash)
  219. pEntry->pNextHash->pPrevHash = pEntry->pPrevHash;
  220. // unlink from create chain
  221. if(pEntry->pPrevCreate)
  222. pEntry->pPrevCreate->pNextCreate = pEntry->pNextCreate;
  223. if(pEntry->pNextCreate)
  224. pEntry->pNextCreate->pPrevCreate = pEntry->pPrevCreate;
  225. else
  226. m_pCreateListTail = pEntry->pPrevCreate;
  227. // delete
  228. if(pEntry->tValue.tType==PS_STRING)
  229. delete pEntry->tValue.pchData;
  230. else if(pEntry->tValue.tType==PS_ARRAY)
  231. delete pEntry->tValue.pdData;
  232. delete pEntry->pchName;
  233. delete pEntry;
  234. }
  235. TxParamEntry *CxParamSet::FindHashEntry(const char *pchName, Int iIndex, Int *piHashRtn)
  236. {
  237. const char *pchPtr;
  238. Int iHash = (iIndex + 2) % PAR_HASHSIZE;
  239. for(pchPtr = pchName; *pchPtr!=''; pchPtr++)
  240. iHash = (iHash * 17 + *pchPtr) % PAR_HASHSIZE;
  241. *piHashRtn = iHash;
  242. TxParamEntry *pEntry = m_rgpHashList[iHash];
  243. for(; pEntry!=NULL; pEntry = pEntry->pNextHash)
  244. if(iIndex==pEntry->iIndex && strcmp(pchName, pEntry->pchName)==0)
  245. break;
  246. return pEntry;
  247. }
  248. Int CxParamSet::GetC()
  249. {
  250. Int ch = getc(m_fp);
  251. if(ch=='n')
  252. (*m_piErrLine)++;
  253. return ch;
  254. }
  255. void CxParamSet::UnGetC(Int ch)
  256. {
  257. ungetc(ch, m_fp);
  258. if(ch=='n')
  259. (*m_piErrLine)--;
  260. }
  261. Int CxParamSet::GetToken(char *pchBuf)
  262. {
  263. SkipSpace();
  264. Int ch = GetC();
  265. if(ch==EOF)
  266. return ERES_EOF;
  267. if(ch=='/')
  268. {
  269. SkipComment();
  270. ch = GetC();
  271. if(ch==EOF)
  272. return ERES_EOF;
  273. }
  274. if(ch=='[' || ch==']' || ch=='=' || ch=='{' || ch=='}' || ch==','
  275. || ch=='"')
  276. {
  277. pchBuf[0] = (char)ch;
  278. pchBuf[1] = '';
  279. return ERES_OK;
  280. }
  281. pchBuf[0] = (char)ch;
  282. Int i;
  283. for(i=1;i<TOKEN_SIZE - 1;i++)
  284. {
  285. ch = GetC();
  286. if(ch==EOF)
  287. {
  288. pchBuf[i] = '';
  289. return ERES_EOF;
  290. }
  291. if(isspace(ch) || ch=='[' || ch==']' || ch=='=' || ch=='{'
  292. || ch=='}' || ch==',' || ch=='"')
  293. {
  294. pchBuf[i] = '';
  295. UnGetC(ch);
  296. return ERES_OK;
  297. }
  298. if(ch=='/' && SkipComment()!=ERES_NOOBJ)
  299. {
  300. pchBuf[i] = '';
  301. return ERES_OK;
  302. }
  303. pchBuf[i] = (char)ch;
  304. }
  305. pchBuf[i] = '';
  306. return ERES_OK;
  307. }
  308. Int CxParamSet::SkipSpace()
  309. {
  310. Int ch;
  311. do {
  312. ch = GetC();
  313. if(ch==EOF)
  314. return ERES_EOF;
  315. } while(isspace(ch));
  316. UnGetC(ch);
  317. return ERES_OK;
  318. }
  319. Int CxParamSet::SkipComment()
  320. {
  321. // assumes we already read a '/'
  322. // space is skipped at end
  323. Int ch;
  324. do {
  325. ch = GetC();
  326. if(ch==EOF)
  327. return ERES_EOF;
  328. if(ch!='/' && ch!='*')
  329. {
  330. UnGetC(ch);
  331. return ERES_NOOBJ;
  332. }
  333. if(ch=='/')
  334. {
  335. do {
  336. ch = GetC();
  337. if(ch==EOF)
  338. return ERES_EOF;
  339. } while(ch!='n');
  340. }
  341. else if(ch=='*')
  342. {
  343. Int iState = 0;
  344. do {
  345. ch = GetC();
  346. if(ch==EOF)
  347. return ERES_EOF;
  348. if(iState==0 && ch=='*')
  349. iState = 1;
  350. else if(iState==1)
  351. {
  352. if(ch=='/')
  353. iState = 2;
  354. else if(ch!='*')
  355. iState = 0;
  356. }
  357. } while(iState!=2);
  358. }
  359. if(SkipSpace()==ERES_EOF)
  360. return ERES_EOF;
  361. ch = GetC();
  362. if(ch==EOF)
  363. return ERES_EOF;
  364. } while(ch=='/');
  365. UnGetC(ch);
  366. return ERES_OK;
  367. }
  368. Int CxParamSet::ReadValue(char *pchBuf, TxParamValue *ptVal)
  369. {
  370. if(pchBuf[0]=='"')
  371. {
  372. // string value
  373. Int i, ch;
  374. for(i=0; i<TOKEN_SIZE - 2; i++)
  375. {
  376. ch = GetC();
  377. if(ch=='"')
  378. {
  379. pchBuf[i] = '';
  380. //printf(""%s"n", pchBuf);
  381. SetPVString(*ptVal, pchBuf);
  382. return ERES_OK;
  383. }
  384. if(ch==EOF)
  385. return ERES_FORMAT;
  386. pchBuf[i] = (char)ch;
  387. }
  388. return ERES_FORMAT;
  389. }
  390. else
  391. {
  392. char *pchEnd;
  393. Double dVal = strtod(pchBuf, &pchEnd);
  394. if(*pchEnd != '')
  395. return ERES_FORMAT;
  396. //printf("%gn", dVal);
  397. SetPVDouble(*ptVal, dVal);
  398. return ERES_OK;
  399. }
  400. }
  401. Int CxParamSet::Load(FILE *fp, Int *piErrLine)
  402. {
  403. char pchBuf[TOKEN_SIZE], pchName[TOKEN_SIZE];
  404. Int iInd;
  405. TxParamValue tVal;
  406. m_piErrLine = piErrLine;
  407. m_fp = fp;
  408. *m_piErrLine = 1;
  409. while(!(GetToken(pchBuf)==ERES_EOF))
  410. {
  411. strcpy(pchName, pchBuf);
  412. if(GetToken(pchBuf)==ERES_EOF)
  413. goto close_on_format;
  414. if(pchBuf[0]=='[')
  415. {
  416. if(GetToken(pchBuf)==ERES_EOF)
  417. goto close_on_format;
  418. char *pchEnd;
  419. iInd = strtol(pchBuf, &pchEnd, 10);
  420. if(*pchEnd != '')
  421. goto close_on_format;
  422. if(GetToken(pchBuf)==ERES_EOF)
  423. goto close_on_format;
  424. if(pchBuf[0]!=']')
  425. goto close_on_format;
  426. if(GetToken(pchBuf)==ERES_EOF)
  427. goto close_on_format;
  428. }
  429. else
  430. iInd = -1;
  431. if(pchBuf[0]!='=')
  432. goto close_on_format;
  433. if(GetToken(pchBuf)==ERES_EOF)
  434. goto close_on_format;
  435. if(pchBuf[0]=='{')
  436. {
  437. Int iCount = 0;
  438. Double rgdTemp[256];
  439. do {
  440. //printf("%s[%d] = (%d)", pchName, iInd, iCount);
  441. if(GetToken(pchBuf)==ERES_EOF)
  442. goto close_on_format;
  443. if(pchBuf[0]=='}')
  444. break;
  445. Int er = ReadValue(pchBuf, &tVal);
  446. if(er==ERES_OK)
  447. {
  448. if(tVal.tType==PS_DOUBLE)
  449. rgdTemp[iCount] = tVal.dData;
  450. else
  451. rgdTemp[iCount] = 0.0;
  452. }
  453. else
  454. return er;
  455. if(iCount<255)
  456. iCount++;
  457. if(GetToken(pchBuf)==ERES_EOF)
  458. goto close_on_format;
  459. } while(pchBuf[0]==',');
  460. if(pchBuf[0]!='}')
  461. goto close_on_format;
  462. SetPVArray(tVal, rgdTemp, iCount);
  463. Int er = SetParam(pchName, iInd, &tVal);
  464. if(er!=ERES_OK)
  465. return er;
  466. }
  467. else
  468. {
  469. //printf("%s[%d] = ", pchName, iInd);
  470. TxParamValue tVal;
  471. Int er = ReadValue(pchBuf, &tVal);
  472. if(er==ERES_OK)
  473. er = SetParam(pchName, iInd, &tVal);
  474. if(er!=ERES_OK)
  475. return er;
  476. }
  477. }
  478. return ERES_OK;
  479. close_on_format:
  480. return ERES_FORMAT;
  481. }
  482. Int CxParamSet::GetDouble(char *pchName, Int iIndex, Double *pdValue)
  483. {
  484. TxParamValue v;
  485. Int er = GetParam(pchName, iIndex, &v);
  486. if(er==ERES_OK)
  487. {
  488. if(v.tType==PS_DOUBLE)
  489. *pdValue = v.dData;
  490. else
  491. return ERES_PARAMS;
  492. }
  493. return er;
  494. }
  495. Int CxParamSet::GetString(char *pchName, Int iIndex, char **ppchVal)
  496. {
  497. TxParamValue v;
  498. Int er = GetParam(pchName, iIndex, &v);
  499. if(er==ERES_OK)
  500. {
  501. if(v.tType==PS_STRING)
  502. {
  503. char *pchBuf = new char [strlen(v.pchData)+1];
  504. if(pchBuf==NULL)
  505. return ERES_MEMORY;
  506. strcpy(pchBuf, v.pchData);
  507. *ppchVal = pchBuf;
  508. }
  509. else
  510. return ERES_PARAMS;
  511. }
  512. return er;
  513. }
  514. Int CxParamSet::GetArray(char *pchName, Int iIndex, Double **ppdVal, Int *piSize)
  515. {
  516. TxParamValue v;
  517. Int er = GetParam(pchName, iIndex, &v);
  518. if(er==ERES_OK)
  519. {
  520. if(v.tType==PS_ARRAY)
  521. {
  522. Double *pdBuf = NULL;
  523. if(v.iSize>0)
  524. {
  525. pdBuf = new Double [v.iSize];
  526. if(pdBuf==NULL)
  527. return ERES_MEMORY;
  528. memcpy(pdBuf, v.pdData, v.iSize * sizeof(Double));
  529. }
  530. *ppdVal = pdBuf;
  531. *piSize = v.iSize;
  532. }
  533. else
  534. return ERES_PARAMS;
  535. }
  536. return er;
  537. }
  538. void CxParamSet::Dump(FILE *fp)
  539. {
  540. StartEnum();
  541. char *pchName;
  542. int iInd, iCount;
  543. TxParamValue tVal;
  544. iCount = 0;
  545. while(NextEnum(&pchName, &iInd, &tVal))
  546. {
  547. iCount++;
  548. if(iInd<0)
  549. fprintf(fp, "%s = ", pchName);
  550. else
  551. fprintf(fp, "%s[%d] = ", pchName, iInd);
  552. if(tVal.tType==PS_DOUBLE)
  553. fprintf(fp, "%g", tVal.dData);
  554. else if(tVal.tType==PS_STRING)
  555. fprintf(fp, ""%s"", tVal.pchData);
  556. else
  557. {
  558. fprintf(fp, "{");
  559. int i;
  560. for(i = 0; i<tVal.iSize; i++)
  561. {
  562. fprintf(fp, "%g", tVal.pdData[i]);
  563. if(i+1<tVal.iSize)
  564. fprintf(fp, ", ");
  565. }
  566. fprintf(fp, "}");
  567. }
  568. fprintf(fp, "n");
  569. }
  570. fprintf(fp,"n// Total: %d parameters.nn", iCount);
  571. }