strcodec.c 37 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252
  1. //*@@@+++@@@@******************************************************************
  2. //
  3. // Copyright © Microsoft Corp.
  4. // All rights reserved.
  5. //
  6. // Redistribution and use in source and binary forms, with or without
  7. // modification, are permitted provided that the following conditions are met:
  8. //
  9. // • Redistributions of source code must retain the above copyright notice,
  10. // this list of conditions and the following disclaimer.
  11. // • Redistributions in binary form must reproduce the above copyright notice,
  12. // this list of conditions and the following disclaimer in the documentation
  13. // and/or other materials provided with the distribution.
  14. //
  15. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  16. // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  17. // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  18. // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
  19. // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  20. // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  21. // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  22. // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  23. // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  24. // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  25. // POSSIBILITY OF SUCH DAMAGE.
  26. //
  27. //*@@@---@@@@******************************************************************
  28. #include "strcodec.h"
  29. #include "perfTimer.h"
  30. #ifdef MEM_TRACE
  31. #define TRACE_MALLOC 1
  32. #define TRACE_NEW 0
  33. #define TRACE_HEAP 0
  34. #include "memtrace.h"
  35. #endif
  36. //================================================================
  37. // Quantization index tables
  38. //================================================================
  39. const int blkOffset[16] = {0, 64, 16, 80, 128, 192, 144, 208, 32, 96, 48, 112, 160, 224, 176, 240};
  40. const int blkOffsetUV[4] = {0, 32, 16, 48};
  41. const int blkOffsetUV_422[8] = {0, 64, 16, 80, 32, 96, 48, 112};
  42. const int dctIndex[3][16] = { /** permutation matrix tailored to the transform, nothing to do with ZZS **/
  43. {0,5,1,6, 10,12,8,14, 2,4,3,7, 9,13,11,15}, //AC 444
  44. {0,5,1,6, 10,12,8,14, 2,4,3,7, 9,13,11,15}, //AC 420
  45. {0,128,64,208, 32,240,48,224, 16,192,80,144, 112,176,96,160 }, //DC 444
  46. };
  47. //================================================================
  48. // Color conversion index table
  49. //================================================================
  50. const U8 idxCC[16][16] =
  51. {
  52. {0x00, 0x01, 0x05, 0x04, 0x40, 0x41, 0x45, 0x44, 0x80, 0x81, 0x85, 0x84, 0xc0, 0xc1, 0xc5, 0xc4, },
  53. {0x02, 0x03, 0x07, 0x06, 0x42, 0x43, 0x47, 0x46, 0x82, 0x83, 0x87, 0x86, 0xc2, 0xc3, 0xc7, 0xc6, },
  54. {0x0a, 0x0b, 0x0f, 0x0e, 0x4a, 0x4b, 0x4f, 0x4e, 0x8a, 0x8b, 0x8f, 0x8e, 0xca, 0xcb, 0xcf, 0xce, },
  55. {0x08, 0x09, 0x0d, 0x0c, 0x48, 0x49, 0x4d, 0x4c, 0x88, 0x89, 0x8d, 0x8c, 0xc8, 0xc9, 0xcd, 0xcc, },
  56. {0x10, 0x11, 0x15, 0x14, 0x50, 0x51, 0x55, 0x54, 0x90, 0x91, 0x95, 0x94, 0xd0, 0xd1, 0xd5, 0xd4, },
  57. {0x12, 0x13, 0x17, 0x16, 0x52, 0x53, 0x57, 0x56, 0x92, 0x93, 0x97, 0x96, 0xd2, 0xd3, 0xd7, 0xd6, },
  58. {0x1a, 0x1b, 0x1f, 0x1e, 0x5a, 0x5b, 0x5f, 0x5e, 0x9a, 0x9b, 0x9f, 0x9e, 0xda, 0xdb, 0xdf, 0xde, },
  59. {0x18, 0x19, 0x1d, 0x1c, 0x58, 0x59, 0x5d, 0x5c, 0x98, 0x99, 0x9d, 0x9c, 0xd8, 0xd9, 0xdd, 0xdc, },
  60. {0x20, 0x21, 0x25, 0x24, 0x60, 0x61, 0x65, 0x64, 0xa0, 0xa1, 0xa5, 0xa4, 0xe0, 0xe1, 0xe5, 0xe4, },
  61. {0x22, 0x23, 0x27, 0x26, 0x62, 0x63, 0x67, 0x66, 0xa2, 0xa3, 0xa7, 0xa6, 0xe2, 0xe3, 0xe7, 0xe6, },
  62. {0x2a, 0x2b, 0x2f, 0x2e, 0x6a, 0x6b, 0x6f, 0x6e, 0xaa, 0xab, 0xaf, 0xae, 0xea, 0xeb, 0xef, 0xee, },
  63. {0x28, 0x29, 0x2d, 0x2c, 0x68, 0x69, 0x6d, 0x6c, 0xa8, 0xa9, 0xad, 0xac, 0xe8, 0xe9, 0xed, 0xec, },
  64. {0x30, 0x31, 0x35, 0x34, 0x70, 0x71, 0x75, 0x74, 0xb0, 0xb1, 0xb5, 0xb4, 0xf0, 0xf1, 0xf5, 0xf4, },
  65. {0x32, 0x33, 0x37, 0x36, 0x72, 0x73, 0x77, 0x76, 0xb2, 0xb3, 0xb7, 0xb6, 0xf2, 0xf3, 0xf7, 0xf6, },
  66. {0x3a, 0x3b, 0x3f, 0x3e, 0x7a, 0x7b, 0x7f, 0x7e, 0xba, 0xbb, 0xbf, 0xbe, 0xfa, 0xfb, 0xff, 0xfe, },
  67. {0x38, 0x39, 0x3d, 0x3c, 0x78, 0x79, 0x7d, 0x7c, 0xb8, 0xb9, 0xbd, 0xbc, 0xf8, 0xf9, 0xfd, 0xfc, },
  68. };
  69. const U8 idxCC_420[8][8] =
  70. {
  71. {0x00, 0x01, 0x05, 0x04, 0x20, 0x21, 0x25, 0x24, },
  72. {0x02, 0x03, 0x07, 0x06, 0x22, 0x23, 0x27, 0x26, },
  73. {0x0a, 0x0b, 0x0f, 0x0e, 0x2a, 0x2b, 0x2f, 0x2e, },
  74. {0x08, 0x09, 0x0d, 0x0c, 0x28, 0x29, 0x2d, 0x2c, },
  75. {0x10, 0x11, 0x15, 0x14, 0x30, 0x31, 0x35, 0x34, },
  76. {0x12, 0x13, 0x17, 0x16, 0x32, 0x33, 0x37, 0x36, },
  77. {0x1a, 0x1b, 0x1f, 0x1e, 0x3a, 0x3b, 0x3f, 0x3e, },
  78. {0x18, 0x19, 0x1d, 0x1c, 0x38, 0x39, 0x3d, 0x3c, },
  79. };
  80. /*************************************************************************
  81. gGDISignature
  82. *************************************************************************/
  83. const Char gGDISignature[] = {'W', 'M', 'P', 'H', 'O', 'T', 'O', '\0'};
  84. // check if enough memory allocated for the image buffer
  85. Int checkImageBuffer(CWMImageStrCodec * pSC, size_t cWidth, size_t cRows)
  86. {
  87. const BITDEPTH_BITS bd = pSC->WMISCP.bYUVData ?
  88. BD_32S : pSC->WMII.bdBitDepth;
  89. const COLORFORMAT cf = pSC->WMISCP.bYUVData ?
  90. pSC->m_param.cfColorFormat : pSC->WMII.cfColorFormat;
  91. size_t cBytes;
  92. Bool bLessThan64Bit = sizeof(void *) < 8;
  93. if(cf == YUV_420)
  94. cRows = (cRows + 1) / 2;
  95. if(cRows > pSC->WMIBI.cLine)
  96. return ICERR_ERROR;
  97. if(cf == YUV_422 || cf == YUV_420)
  98. cWidth = (cWidth + 1) / 2;
  99. if (bLessThan64Bit && (cWidth >> ((sizeof(size_t) * 8 - 5)))) {
  100. /** potential overflow - 32 bit pointers insufficient to address cache **/
  101. /** this uses 2 macroblock row constraint, which is tighter than ensuring rollover doesn't occur below **/
  102. return ICERR_ERROR;
  103. }
  104. cBytes = pSC->WMISCP.bYUVData ? cWidth * sizeof(PixelI) *
  105. (cf == YUV_420 ? 6 : (cf == YUV_422 ? 4 : (cf == YUV_444 ? 3 : 1))) :
  106. (bd == BD_1 ? (pSC->WMII.cBitsPerUnit * cWidth + 7) / 8 : (pSC->WMII.cBitsPerUnit + 7) / 8 * cWidth);
  107. return (cBytes > pSC->WMIBI.cbStride ? ICERR_ERROR : ICERR_OK);
  108. }
  109. Void writeQPIndex(BitIOInfo * pIO, U8 uiIndex, U32 cBits)
  110. {
  111. if(uiIndex == 0)
  112. putBit16(pIO, 1, 1); // default QP
  113. else{
  114. putBit16(pIO, 0, 1); // non default QP
  115. putBit16(pIO, uiIndex - 1, cBits);
  116. }
  117. }
  118. U8 readQPIndex(BitIOInfo * pIO, U32 cBits)
  119. {
  120. if(getBit16(pIO, 1))
  121. return 0; // default QP
  122. return (U8) getBit16(pIO, cBits) + 1;
  123. }
  124. Void getTilePos(CWMImageStrCodec* pSC, size_t mbX, size_t mbY)
  125. {
  126. if(mbX == 0){ // left image boundary
  127. pSC->cTileColumn = 0;
  128. }
  129. else if(pSC->cTileColumn < pSC->WMISCP.cNumOfSliceMinus1V && mbX == pSC->WMISCP.uiTileX[pSC->cTileColumn + 1]){ // left tile boundary
  130. pSC->cTileColumn ++;
  131. }
  132. if(mbY == 0){ // top image boundary
  133. pSC->cTileRow = 0;
  134. }
  135. else if(pSC->cTileRow < pSC->WMISCP.cNumOfSliceMinus1H && mbY == pSC->WMISCP.uiTileY[pSC->cTileRow + 1]){ // top tile boundary
  136. pSC->cTileRow ++;
  137. }
  138. pSC->m_bCtxLeft = (mbX == pSC->WMISCP.uiTileX[pSC->cTileColumn]);
  139. pSC->m_bCtxTop = (mbY == pSC->WMISCP.uiTileY[pSC->cTileRow]);
  140. pSC->m_bResetContext = pSC->m_bResetRGITotals = (((mbX - pSC->WMISCP.uiTileX[pSC->cTileColumn]) & 0xf) == 0);
  141. if(pSC->cTileColumn == pSC->WMISCP.cNumOfSliceMinus1V){ // last tile column
  142. if(mbX + 1 == pSC->cmbWidth)
  143. pSC->m_bResetContext = TRUE;
  144. }
  145. else if(mbX + 1 == pSC->WMISCP.uiTileX[pSC->cTileColumn + 1])
  146. pSC->m_bResetContext = TRUE;
  147. }
  148. //================================================================
  149. // utility functions for 2 macro block rows
  150. //================================================================
  151. Void initMRPtr(CWMImageStrCodec* pSC)
  152. {
  153. size_t j, jend = (pSC->m_pNextSC != NULL);
  154. for (j = 0; j <= jend; j++) {
  155. memcpy (pSC->p0MBbuffer, pSC->a0MBbuffer, sizeof (pSC->p0MBbuffer));
  156. memcpy (pSC->p1MBbuffer, pSC->a1MBbuffer, sizeof (pSC->p1MBbuffer));
  157. pSC = pSC->m_pNextSC;
  158. }
  159. }
  160. Void advanceMRPtr(CWMImageStrCodec* pSC)
  161. {
  162. const COLORFORMAT cf = pSC->m_param.cfColorFormat;
  163. const int cpChroma = cblkChromas[cf] * 16;
  164. size_t i, j, jend = (pSC->m_pNextSC != NULL);
  165. assert(pSC->m_bSecondary == FALSE);
  166. for (j = 0; j <= jend; j++) {
  167. int cpStride = 16 * 16;
  168. for (i = 0; i < pSC->m_param.cNumChannels; i++) {
  169. pSC->pPlane[i] = pSC->p0MBbuffer[i];
  170. pSC->p0MBbuffer[i] += cpStride;
  171. pSC->p1MBbuffer[i] += cpStride;
  172. cpStride = cpChroma;
  173. }
  174. pSC = pSC->m_pNextSC;
  175. }
  176. }
  177. /* advance to next MB row */
  178. Void advanceOneMBRow(CWMImageStrCodec *pSC)
  179. {
  180. size_t i, j, jend = (pSC->m_pNextSC != NULL);
  181. CWMIPredInfo *pPredInfo;
  182. for (j = 0; j <= jend; j++) {
  183. for(i = 0; i < pSC->m_param.cNumChannels; i ++){ // swap current row and previous row
  184. pPredInfo = pSC->PredInfo[i];
  185. pSC->PredInfo[i] = pSC->PredInfoPrevRow[i];
  186. pSC->PredInfoPrevRow[i] = pPredInfo;
  187. }
  188. pSC = pSC->m_pNextSC;
  189. }
  190. }
  191. Void swapMRPtr(CWMImageStrCodec* pSC)
  192. {
  193. PixelI *pTemp[MAX_CHANNELS];
  194. size_t j, jend = (pSC->m_pNextSC != NULL);
  195. for (j = 0; j <= jend; j++) {
  196. memcpy (pTemp, pSC->a0MBbuffer, sizeof (pSC->a0MBbuffer));
  197. memcpy (pSC->a0MBbuffer, pSC->a1MBbuffer, sizeof (pSC->a0MBbuffer));
  198. memcpy (pSC->a1MBbuffer, pTemp, sizeof (pSC->a0MBbuffer));
  199. pSC = pSC->m_pNextSC;
  200. }
  201. }
  202. //================================================================
  203. // Empty function to fill slot
  204. //================================================================
  205. Int IDPEmpty(CWMImageStrCodec* pSC)
  206. {
  207. UNREFERENCED_PARAMETER( pSC );
  208. return ICERR_OK;
  209. }
  210. ERR WMPAlloc(void** ppv, size_t cb)
  211. {
  212. *ppv = calloc(1, cb);
  213. return *ppv ? WMP_errSuccess : WMP_errOutOfMemory;
  214. }
  215. ERR WMPFree(void** ppv)
  216. {
  217. if (*ppv)
  218. {
  219. free(*ppv);
  220. *ppv = NULL;
  221. }
  222. return WMP_errSuccess;
  223. }
  224. //================================================================
  225. // Streaming I/O functions
  226. //================================================================
  227. ERR CreateWS_File(struct WMPStream** ppWS, const char* szFilename, const char* szMode)
  228. {
  229. ERR err = WMP_errSuccess;
  230. struct WMPStream* pWS = NULL;
  231. Call(WMPAlloc((void** )ppWS, sizeof(**ppWS)));
  232. pWS = *ppWS;
  233. pWS->Close = CloseWS_File;
  234. pWS->EOS = EOSWS_File;
  235. pWS->Read = ReadWS_File;
  236. pWS->Write = WriteWS_File;
  237. //pWS->GetLine = GetLineWS_File;
  238. pWS->SetPos = SetPosWS_File;
  239. pWS->GetPos = GetPosWS_File;
  240. #ifdef WIN32
  241. FailIf(0 != fopen_s(&pWS->state.file.pFile, szFilename, szMode), WMP_errFileIO);
  242. #else
  243. pWS->state.file.pFile = fopen(szFilename, szMode);
  244. FailIf(NULL == pWS->state.file.pFile, WMP_errFileIO);
  245. #endif
  246. Cleanup:
  247. return err;
  248. }
  249. ERR CloseWS_File(struct WMPStream** ppWS)
  250. {
  251. ERR err = WMP_errSuccess;
  252. struct WMPStream* pWS = *ppWS;
  253. fclose(pWS->state.file.pFile);
  254. Call(WMPFree((void**)ppWS));
  255. Cleanup:
  256. return err;
  257. }
  258. Bool EOSWS_File(struct WMPStream* pWS)
  259. {
  260. return feof(pWS->state.file.pFile);
  261. }
  262. ERR ReadWS_File(struct WMPStream* pWS, void* pv, size_t cb)
  263. {
  264. // ERR err = WMP_errSuccess;
  265. return (fread(pv, cb, 1, pWS->state.file.pFile) == 1) ? WMP_errSuccess : WMP_errFileIO;
  266. }
  267. ERR WriteWS_File(struct WMPStream* pWS, const void* pv, size_t cb)
  268. {
  269. ERR err = WMP_errSuccess;
  270. if(0 != cb)
  271. {
  272. FailIf(1 != fwrite(pv, cb, 1, pWS->state.file.pFile), WMP_errFileIO);
  273. }
  274. Cleanup:
  275. return err;
  276. }
  277. ERR SetPosWS_File(struct WMPStream* pWS, size_t offPos)
  278. {
  279. ERR err = WMP_errSuccess;
  280. FailIf(0 != fseek(pWS->state.file.pFile, (long)offPos, SEEK_SET), WMP_errFileIO);
  281. Cleanup:
  282. return err;
  283. }
  284. ERR GetPosWS_File(struct WMPStream* pWS, size_t* poffPos)
  285. {
  286. ERR err = WMP_errSuccess;
  287. long lOff = 0;
  288. FailIf(-1 == (lOff = ftell(pWS->state.file.pFile)), WMP_errFileIO);
  289. *poffPos = (size_t)lOff;
  290. Cleanup:
  291. return err;
  292. }
  293. //----------------------------------------------------------------
  294. ERR CreateWS_Memory(struct WMPStream** ppWS, void* pv, size_t cb)
  295. {
  296. ERR err = WMP_errSuccess;
  297. struct WMPStream* pWS = NULL;
  298. Call(WMPAlloc((void** )ppWS, sizeof(**ppWS)));
  299. pWS = *ppWS;
  300. pWS->state.buf.pbBuf = pv;
  301. pWS->state.buf.cbBuf = cb;
  302. pWS->state.buf.cbCur = 0;
  303. pWS->Close = CloseWS_Memory;
  304. pWS->EOS = EOSWS_Memory;
  305. pWS->Read = ReadWS_Memory;
  306. pWS->Write = WriteWS_Memory;
  307. pWS->SetPos = SetPosWS_Memory;
  308. pWS->GetPos = GetPosWS_Memory;
  309. Cleanup:
  310. return err;
  311. }
  312. ERR CloseWS_Memory(struct WMPStream** ppWS)
  313. {
  314. ERR err = WMP_errSuccess;
  315. Call(WMPFree((void**)ppWS));
  316. Cleanup:
  317. return err;
  318. }
  319. Bool EOSWS_Memory(struct WMPStream* pWS)
  320. {
  321. return pWS->state.buf.cbBuf <= pWS->state.buf.cbCur;
  322. }
  323. ERR ReadWS_Memory(struct WMPStream* pWS, void* pv, size_t cb)
  324. {
  325. ERR err = WMP_errSuccess;
  326. // FailIf(pWS->state.buf.cbBuf < pWS->state.buf.cbCur, WMP_errBufferOverflow);
  327. if(pWS->state.buf.cbBuf < pWS->state.buf.cbCur)
  328. return err;
  329. FailIf(pWS->state.buf.cbCur + cb < pWS->state.buf.cbCur, WMP_errBufferOverflow);
  330. if (pWS->state.buf.cbBuf < pWS->state.buf.cbCur + cb)
  331. {
  332. cb = pWS->state.buf.cbBuf - pWS->state.buf.cbCur;
  333. }
  334. memcpy(pv, pWS->state.buf.pbBuf + pWS->state.buf.cbCur, cb);
  335. pWS->state.buf.cbCur += cb;
  336. Cleanup:
  337. return err;
  338. }
  339. ERR WriteWS_Memory(struct WMPStream* pWS, const void* pv, size_t cb)
  340. {
  341. ERR err = WMP_errSuccess;
  342. FailIf(pWS->state.buf.cbCur + cb < pWS->state.buf.cbCur, WMP_errBufferOverflow);
  343. FailIf(pWS->state.buf.cbBuf < pWS->state.buf.cbCur + cb, WMP_errBufferOverflow);
  344. memcpy(pWS->state.buf.pbBuf + pWS->state.buf.cbCur, pv, cb);
  345. pWS->state.buf.cbCur += cb;
  346. Cleanup:
  347. return err;
  348. }
  349. ERR SetPosWS_Memory(struct WMPStream* pWS, size_t offPos)
  350. {
  351. ERR err = WMP_errSuccess;
  352. //While the following condition is possibly useful, failure occurs
  353. //at the end of a file since packets beyond the end may be accessed
  354. //FailIf(pWS->state.buf.cbBuf < offPos, WMP_errBufferOverflow);
  355. pWS->state.buf.cbCur = offPos;
  356. //Cleanup:
  357. return err;
  358. }
  359. ERR GetPosWS_Memory(struct WMPStream* pWS, size_t* poffPos)
  360. {
  361. *poffPos = pWS->state.buf.cbCur;
  362. return WMP_errSuccess;
  363. }
  364. //=================================================================
  365. // Linked list based WMPStream
  366. // - for indefinite size, multiple stream out
  367. // - reads not supported in this mode
  368. //=================================================================
  369. ERR CreateWS_List(struct WMPStream** ppWS)
  370. {
  371. ERR err = WMP_errSuccess;
  372. struct WMPStream* pWS = NULL;
  373. Call(WMPAlloc((void** )ppWS, sizeof(**ppWS) + PACKETLENGTH + sizeof(void *)));
  374. pWS = *ppWS;
  375. pWS->state.buf.pbBuf = (U8 *)pWS + sizeof(**ppWS) + sizeof(void *); // first buffer points here
  376. memset(pWS->state.buf.pbBuf - sizeof(void *), 0, sizeof(void *));
  377. pWS->state.buf.cbBuf = PACKETLENGTH;
  378. pWS->state.buf.cbCur = 0;
  379. pWS->state.buf.cbBufCount = 0;
  380. pWS->Close = CloseWS_List;
  381. pWS->EOS = NULL; // doesn't get called
  382. pWS->Read = ReadWS_List;
  383. pWS->Write = WriteWS_List;
  384. pWS->SetPos = SetPosWS_List;
  385. pWS->GetPos = GetPosWS_List;
  386. //printf ("create buffer %d: %x\n", pWS->state.buf.cbBufCount, pWS->state.buf.pbBuf);
  387. Cleanup:
  388. return err;
  389. }
  390. ERR CloseWS_List(struct WMPStream** ppWS)
  391. {
  392. ERR err = WMP_errSuccess;
  393. if (ppWS) {
  394. U8 *pBuf = (U8 *)(ppWS[0] + 1); // pointer to buffer
  395. U8 *pNext = (U8 *)(((void **)pBuf)[0]);
  396. while (pNext) {
  397. //struct WMPStream *pWS = ppWS[0];
  398. pBuf = pNext;
  399. pNext = (U8 *)(((void **)(pBuf))[0]);
  400. //printf ("delete buffer %x\n", pBuf);
  401. Call(WMPFree((void**)&pBuf));
  402. }
  403. }
  404. Call(WMPFree((void**)ppWS));
  405. Cleanup:
  406. return err;
  407. }
  408. ERR ReadWS_List(struct WMPStream* pWS, void* pv, size_t cb)
  409. {
  410. ERR err = WMP_errSuccess;
  411. FailIf(pWS->state.buf.cbCur + cb < pWS->state.buf.cbCur, WMP_errBufferOverflow);
  412. if (pWS->state.buf.cbBuf < pWS->state.buf.cbCur + PACKETLENGTH * pWS->state.buf.cbBufCount + cb)
  413. {
  414. cb = pWS->state.buf.cbBuf - pWS->state.buf.cbCur - PACKETLENGTH * pWS->state.buf.cbBufCount;
  415. }
  416. while (cb) {
  417. size_t cl = PACKETLENGTH - pWS->state.buf.cbCur;
  418. if (cl > cb)
  419. cl = cb;
  420. memcpy(pv, pWS->state.buf.pbBuf + pWS->state.buf.cbCur, cl);
  421. pWS->state.buf.cbCur += cl;
  422. pv = (void *)((U8 *)pv + cl);
  423. cb -= cl;
  424. if (pWS->state.buf.cbCur == PACKETLENGTH) {
  425. pWS->state.buf.pbBuf = (U8 *)((void **)(pWS->state.buf.pbBuf - sizeof(void *)))[0] + sizeof(void *);
  426. pWS->state.buf.cbCur = 0;
  427. pWS->state.buf.cbBufCount++;
  428. //printf ("read buffer %d: %x\n", pWS->state.buf.cbBufCount, pWS->state.buf.pbBuf);
  429. }
  430. }
  431. Cleanup:
  432. return err;
  433. }
  434. ERR WriteWS_List(struct WMPStream* pWS, const void* pv, size_t cb)
  435. {
  436. ERR err = WMP_errSuccess;
  437. FailIf(pWS->state.buf.cbCur + cb < pWS->state.buf.cbCur, WMP_errBufferOverflow);
  438. FailIf(pWS->state.buf.cbBuf < pWS->state.buf.cbCur + cb, WMP_errBufferOverflow);
  439. while (cb) {
  440. size_t cl = PACKETLENGTH - pWS->state.buf.cbCur;
  441. if (cl > cb)
  442. cl = cb;
  443. memcpy(pWS->state.buf.pbBuf + pWS->state.buf.cbCur, pv, cl);
  444. pWS->state.buf.cbCur += cl;
  445. pv = (const void *)((U8 *)pv + cl);
  446. cb -= cl;
  447. if (pWS->state.buf.cbCur == PACKETLENGTH) { // allocate next packet in list
  448. U8 *pBuf = NULL;
  449. void **pPtrLoc = (void **)(pWS->state.buf.pbBuf - sizeof(void *));
  450. Call(WMPAlloc((void **)&pBuf, PACKETLENGTH + sizeof(void *)));
  451. pPtrLoc[0] = (void *)pBuf;
  452. pWS->state.buf.pbBuf = pBuf + sizeof(void *);
  453. pWS->state.buf.cbBuf += PACKETLENGTH;
  454. memset(pBuf, 0, sizeof(void *));
  455. pWS->state.buf.cbCur = 0;
  456. pWS->state.buf.cbBufCount++;
  457. //printf ("create buffer %d: %x\n", pWS->state.buf.cbBufCount, pWS->state.buf.pbBuf);
  458. }
  459. }
  460. Cleanup:
  461. return err;
  462. }
  463. ERR SetPosWS_List(struct WMPStream* pWS, size_t offPos)
  464. {
  465. ERR err = WMP_errSuccess;
  466. // get the first buffer
  467. U8 *pBuf = (U8 *)(pWS + 1); // pointer to buffer
  468. pWS->state.buf.cbCur = 0;
  469. pWS->state.buf.cbBufCount = 0;
  470. while (offPos >= PACKETLENGTH && pBuf != NULL) {
  471. pBuf = (U8 *)(((void **)pBuf)[0]);
  472. offPos -= PACKETLENGTH;
  473. pWS->state.buf.cbBufCount++;
  474. }
  475. if (pBuf == NULL)
  476. goto Cleanup;
  477. pWS->state.buf.cbCur = offPos;
  478. pWS->state.buf.pbBuf = pBuf + sizeof(void *);
  479. //printf ("seek buffer %d: %x\n", pWS->state.buf.cbBufCount, pWS->state.buf.pbBuf);
  480. Cleanup:
  481. return err;
  482. }
  483. ERR GetPosWS_List(struct WMPStream* pWS, size_t* poffPos)
  484. {
  485. *poffPos = pWS->state.buf.cbCur + PACKETLENGTH * pWS->state.buf.cbBufCount;
  486. return WMP_errSuccess;
  487. }
  488. //================================================================
  489. // Simple BitIO access functions
  490. //================================================================
  491. // init SimpleBitIO
  492. ERR attach_SB(SimpleBitIO* pSB, struct WMPStream* pWS)
  493. {
  494. pSB->pWS = pWS;
  495. pSB->cbRead = 0;
  496. pSB->bAccumulator = 0;
  497. pSB->cBitLeft = 0;
  498. return WMP_errSuccess;
  499. }
  500. // extract upto 32bit from input stream
  501. U32 getBit32_SB(SimpleBitIO* pSB, U32 cBits)
  502. {
  503. U32 rc = 0;
  504. while (pSB->cBitLeft < cBits)
  505. {
  506. rc <<= pSB->cBitLeft;
  507. rc |= pSB->bAccumulator >> (8 - pSB->cBitLeft);
  508. cBits -= pSB->cBitLeft;
  509. pSB->pWS->Read(pSB->pWS, &pSB->bAccumulator, 1);
  510. pSB->cbRead++;
  511. pSB->cBitLeft = 8;
  512. }
  513. rc <<= cBits;
  514. rc |= pSB->bAccumulator >> (8 - cBits);
  515. pSB->bAccumulator <<= cBits;
  516. pSB->cBitLeft -= cBits;
  517. return rc;
  518. }
  519. // ignore input to byte boundary
  520. Void flushToByte_SB(SimpleBitIO* pSB)
  521. {
  522. pSB->bAccumulator = 0;
  523. pSB->cBitLeft = 0;
  524. }
  525. // return read byte count
  526. U32 getByteRead_SB(SimpleBitIO* pSB)
  527. {
  528. return pSB->cbRead;
  529. }
  530. ERR detach_SB(SimpleBitIO* pSB)
  531. {
  532. assert(0 == pSB->cBitLeft);
  533. pSB->pWS = NULL;
  534. return WMP_errSuccess;
  535. }
  536. //================================================================
  537. // Memory access functions
  538. //================================================================
  539. #if (defined(WIN32) && !defined(UNDER_CE)) || (defined(UNDER_CE) && defined(_ARM_))
  540. // WinCE ARM and Desktop x86
  541. #else
  542. // other platform
  543. #ifdef _BIG__ENDIAN_
  544. #define _byteswap_ulong(x) (x)
  545. #else // _BIG__ENDIAN_
  546. U32 _byteswap_ulong(U32 bits)
  547. {
  548. U32 r = (bits & 0xffu) << 24;
  549. r |= (bits << 8) & 0xff0000u;
  550. r |= ((bits >> 8) & 0xff00u);
  551. r |= ((bits >> 24) & 0xffu);
  552. return r;
  553. }
  554. #endif // _BIG__ENDIAN_
  555. #endif
  556. U32 load4BE(void* pv)
  557. {
  558. #ifdef _BIG__ENDIAN_
  559. return (*(U32*)pv);
  560. #else // _BIG__ENDIAN_
  561. #if defined(_M_IA64) || defined(_ARM_)
  562. U32 v;
  563. v = ((U16 *) pv)[0];
  564. v |= ((U32)((U16 *) pv)[1]) << 16;
  565. return _byteswap_ulong(v);
  566. #else // _M_IA64
  567. return _byteswap_ulong(*(U32*)pv);
  568. #endif // _M_IA64
  569. #endif // _BIG__ENDIAN_
  570. }
  571. #define LOAD16 load4BE
  572. #ifdef _BIG__ENDIAN_
  573. #define WRITESWAP_ENDIAN(a) ((a)>>16)
  574. #else // _BIG__ENDIAN_
  575. #define WRITESWAP_ENDIAN(a) _byteswap_ulong(a)
  576. #endif // _BIG__ENDIAN_
  577. //================================================================
  578. // Bit I/O functions
  579. //================================================================
  580. Int allocateBitIOInfo(CWMImageStrCodec* pSC)
  581. {
  582. U32 cNumBitIO;
  583. SUBBAND sbSubband = pSC->WMISCP.sbSubband;
  584. pSC->cSB = (sbSubband == SB_DC_ONLY ? 1 : (sbSubband == SB_NO_HIGHPASS ? 2 : (sbSubband == SB_NO_FLEXBITS ? 3 : 4)));
  585. // # of additional BitIOs other than pSC->pIOHeader
  586. if (!pSC->m_param.bIndexTable) { // pure streaming mode, no index table, no additional BitIO!
  587. assert (pSC->WMISCP.bfBitstreamFormat == SPATIAL && pSC->WMISCP.cNumOfSliceMinus1H + pSC->WMISCP.cNumOfSliceMinus1V == 0);
  588. cNumBitIO = 0;
  589. }
  590. else if(pSC->WMISCP.bfBitstreamFormat == SPATIAL)
  591. cNumBitIO = pSC->WMISCP.cNumOfSliceMinus1V + 1;
  592. else
  593. cNumBitIO = (pSC->WMISCP.cNumOfSliceMinus1V + 1) * pSC->cSB;
  594. if(cNumBitIO > MAX_TILES * 4)
  595. return ICERR_ERROR;
  596. // allocate additional BitIos
  597. if(cNumBitIO > 0){
  598. U32 i = 0;
  599. size_t cb = sizeof(BitIOInfo) * cNumBitIO + (PACKETLENGTH * 4 - 1) + PACKETLENGTH * 4 * cNumBitIO;
  600. U8* pb = (U8*)malloc(cb);
  601. if (NULL == pb) return ICERR_ERROR;
  602. memset(pb, 0, cb);
  603. pSC->m_ppBitIO = (BitIOInfo**)pb;
  604. pb += sizeof(BitIOInfo) * cNumBitIO;
  605. pb = (U8*)ALIGNUP(pb, PACKETLENGTH * 4) + PACKETLENGTH * 2;
  606. for (i = 0; i < cNumBitIO; ++i){
  607. pSC->m_ppBitIO[i] = (BitIOInfo*)pb;
  608. pb += PACKETLENGTH * 4;
  609. }
  610. // allocate index table
  611. if(cNumBitIO > MAX_TILES * 4 || pSC->WMISCP.cNumOfSliceMinus1H >= MAX_TILES)
  612. return ICERR_ERROR;
  613. pSC->pIndexTable = malloc(cNumBitIO * (pSC->WMISCP.cNumOfSliceMinus1H + 1) * sizeof(size_t));
  614. if(NULL == pSC->pIndexTable) return ICERR_ERROR;
  615. }
  616. pSC->cNumBitIO = cNumBitIO;
  617. return ICERR_OK;
  618. }
  619. Int setBitIOPointers(CWMImageStrCodec* pSC)
  620. {
  621. if(pSC->cNumBitIO > 0){
  622. U32 i;
  623. for(i = 0; i <= pSC->WMISCP.cNumOfSliceMinus1V; i ++){
  624. CCodingContext * pContext = &pSC->m_pCodingContext[i];
  625. if(pSC->WMISCP.bfBitstreamFormat == SPATIAL){
  626. pContext->m_pIODC = pContext->m_pIOLP = pContext->m_pIOAC = pContext->m_pIOFL = pSC->m_ppBitIO[i];
  627. }
  628. else{
  629. U32 j = pSC->cSB;
  630. pContext->m_pIODC = pSC->m_ppBitIO[i * j];
  631. if(j > 1)
  632. pContext->m_pIOLP = pSC->m_ppBitIO[i * j + 1];
  633. if(j > 2)
  634. pContext->m_pIOAC = pSC->m_ppBitIO[i * j + 2];
  635. if(j > 3)
  636. pContext->m_pIOFL = pSC->m_ppBitIO[i * j + 3];
  637. }
  638. }
  639. }
  640. else{ // streamimg mode
  641. CCodingContext * pContext = &pSC->m_pCodingContext[0];
  642. pContext->m_pIODC = pContext->m_pIOLP = pContext->m_pIOAC = pContext->m_pIOFL = pSC->pIOHeader;
  643. }
  644. return ICERR_OK;
  645. }
  646. Int allocateTileInfo(CWMImageStrCodec * pSC)
  647. {
  648. size_t i;
  649. if(pSC->WMISCP.cNumOfSliceMinus1V >= MAX_TILES)
  650. return ICERR_ERROR;
  651. pSC->pTile = (CWMITile *)malloc((pSC->WMISCP.cNumOfSliceMinus1V + 1) * sizeof(CWMITile));
  652. if(pSC->pTile == NULL)
  653. return ICERR_ERROR;
  654. memset(pSC->pTile, 0, (pSC->WMISCP.cNumOfSliceMinus1V + 1) * sizeof(CWMITile));
  655. for(i = 0; i <= pSC->WMISCP.cNumOfSliceMinus1V; i ++)
  656. pSC->pTile[i].cNumQPHP = pSC->pTile[i].cNumQPLP = 1, pSC->pTile[i].cBitsHP = pSC->pTile[i].cBitsLP = 0;
  657. return ICERR_OK;
  658. }
  659. Void freeTileInfo(CWMImageStrCodec * pSC)
  660. {
  661. size_t iTile;
  662. if((pSC->m_param.uQPMode & 1) != 0) // not DC uniform
  663. for(iTile = 0; iTile <= pSC->WMISCP.cNumOfSliceMinus1V; iTile ++)
  664. freeQuantizer(pSC->pTile[iTile].pQuantizerDC);
  665. else
  666. freeQuantizer(pSC->pTile[0].pQuantizerDC);
  667. if(pSC->WMISCP.sbSubband != SB_DC_ONLY)
  668. if((pSC->m_param.uQPMode & 2) != 0) // not LP uniform
  669. for(iTile = 0; iTile <= pSC->WMISCP.cNumOfSliceMinus1V; iTile ++)
  670. freeQuantizer(pSC->pTile[iTile].pQuantizerLP);
  671. else
  672. freeQuantizer(pSC->pTile[0].pQuantizerLP);
  673. if(pSC->WMISCP.sbSubband != SB_DC_ONLY && pSC->WMISCP.sbSubband != SB_NO_HIGHPASS)
  674. if((pSC->m_param.uQPMode & 4) != 0) // not HP uniform
  675. for(iTile = 0; iTile <= pSC->WMISCP.cNumOfSliceMinus1V; iTile ++)
  676. freeQuantizer(pSC->pTile[iTile].pQuantizerHP);
  677. else
  678. freeQuantizer(pSC->pTile[0].pQuantizerHP);
  679. if(pSC->pTile != NULL)
  680. free(pSC->pTile);
  681. }
  682. Int allocateQuantizer(CWMIQuantizer * pQuantizer[MAX_CHANNELS], size_t cChannel, size_t cQP)
  683. {
  684. size_t iCh;
  685. if(cQP > 16 || cChannel > MAX_CHANNELS)
  686. return ICERR_ERROR;
  687. pQuantizer[0] = (CWMIQuantizer *)malloc(cQP * sizeof(CWMIQuantizer) * cChannel);
  688. if(pQuantizer[0] == NULL)
  689. return ICERR_ERROR;
  690. for(iCh = 1; iCh < cChannel; iCh ++)
  691. pQuantizer[iCh] = pQuantizer[iCh - 1] + cQP;
  692. return ICERR_OK;
  693. }
  694. Void freeQuantizer(CWMIQuantizer * pQuantizer[MAX_CHANNELS])
  695. {
  696. if(pQuantizer[0] != NULL)
  697. free(pQuantizer[0]);
  698. }
  699. Void formatQuantizer(CWMIQuantizer * pQuantizer[MAX_CHANNELS], U8 cChMode, size_t cCh, size_t iPos, Bool bShiftedUV,
  700. Bool bScaledArith)
  701. {
  702. size_t iCh;
  703. for(iCh = 0; iCh < cCh; iCh ++){
  704. if(iCh > 0)
  705. if(cChMode == 0) // uniform
  706. pQuantizer[iCh][iPos] = pQuantizer[0][iPos];
  707. else if(cChMode == 1) // mixed
  708. pQuantizer[iCh][iPos] = pQuantizer[1][iPos];
  709. remapQP(pQuantizer[iCh] + iPos, (iCh > 0 && bShiftedUV == TRUE) ? SHIFTZERO - 1 : SHIFTZERO, bScaledArith);
  710. }
  711. }
  712. Void setUniformQuantizer(CWMImageStrCodec * pSC, size_t sb)
  713. {
  714. size_t iCh, iTile;
  715. for(iCh = 0; iCh < pSC->m_param.cNumChannels; iCh ++)
  716. for(iTile = 1; iTile <= pSC->WMISCP.cNumOfSliceMinus1V; iTile ++)
  717. if(sb == 0) // DC
  718. pSC->pTile[iTile].pQuantizerDC[iCh] = pSC->pTile[0].pQuantizerDC[iCh];
  719. else if(sb == 1) // LP
  720. pSC->pTile[iTile].pQuantizerLP[iCh] = pSC->pTile[0].pQuantizerLP[iCh];
  721. else // HP
  722. pSC->pTile[iTile].pQuantizerHP[iCh] = pSC->pTile[0].pQuantizerHP[iCh];
  723. }
  724. Void useDCQuantizer(CWMImageStrCodec * pSC, size_t iTile)
  725. {
  726. size_t iCh;
  727. for(iCh = 0; iCh < pSC->m_param.cNumChannels; iCh ++)
  728. pSC->pTile[iTile].pQuantizerLP[iCh][0] = *pSC->pTile[iTile].pQuantizerDC[iCh];
  729. }
  730. Void useLPQuantizer(CWMImageStrCodec * pSC, size_t cQP, size_t iTile)
  731. {
  732. size_t iCh, iQP;
  733. for(iCh = 0; iCh < pSC->m_param.cNumChannels; iCh ++)
  734. for(iQP = 0; iQP < cQP; iQP ++)
  735. pSC->pTile[iTile].pQuantizerHP[iCh][iQP] = pSC->pTile[iTile].pQuantizerLP[iCh][iQP];
  736. }
  737. U8 dquantBits(U8 cQP)
  738. {
  739. return (cQP < 2 ? 0 : (cQP < 4 ? 1 : (cQP < 6 ? 2 : (cQP < 10 ? 3 : 4))));
  740. }
  741. #ifndef ARMOPT_BITIO
  742. U32 peekBit16(BitIOInfo* pIO, U32 cBits)
  743. {
  744. PEEKBIT16(pIO, cBits);
  745. }
  746. U32 flushBit16(BitIOInfo* pIO, U32 cBits)
  747. {
  748. FLUSHBIT16(pIO, cBits);
  749. }
  750. U32 getBit16(BitIOInfo* pIO, U32 cBits)
  751. {
  752. U32 uiRet = peekBit16(pIO, cBits);
  753. flushBit16(pIO, cBits);
  754. return uiRet;
  755. }
  756. U32 getBool16(BitIOInfo* pIO)
  757. {
  758. U32 uiRet = peekBit16(pIO, 1);
  759. flushBit16(pIO, 1);
  760. return uiRet;
  761. }
  762. /** this function returns cBits if zero is read, or a signed value if first cBits are not all zero **/
  763. I32 getBit16s(BitIOInfo* pIO, U32 cBits)
  764. {
  765. U32 uiRet = peekBit16(pIO, cBits + 1);
  766. if (uiRet < 2) {
  767. flushBit16(pIO, cBits);
  768. return 0;
  769. }
  770. else {
  771. flushBit16(pIO, cBits + 1);
  772. if (uiRet & 1)
  773. return (-(I32)(uiRet >> 1));
  774. else
  775. return (I32)(uiRet >> 1);
  776. }
  777. }
  778. U32 getBit32(BitIOInfo* pIO, U32 cBits)
  779. {
  780. U32 uiRet = 0;
  781. assert(0 <= (I32)cBits && cBits <= 32);
  782. if (16 < cBits)
  783. {
  784. uiRet = getBit16(pIO, 16);
  785. cBits -= 16;
  786. uiRet <<= cBits;
  787. }
  788. uiRet |= getBit16(pIO, cBits);
  789. return uiRet;
  790. }
  791. U32 flushToByte(BitIOInfo* pIO)
  792. {
  793. return flushBit16(pIO, (16 - pIO->cBitsUsed) & 7);
  794. }
  795. #endif // ARMOPT_BITIO
  796. //----------------------------------------------------------------
  797. Void putBit16z(BitIOInfo* pIO, U32 uiBits, U32 cBits)
  798. {
  799. assert(cBits <= 16);
  800. assert(0 == uiBits >> cBits);
  801. pIO->uiAccumulator = (pIO->uiAccumulator << cBits) | uiBits;
  802. pIO->cBitsUsed += cBits;
  803. *(U16*)pIO->pbCurrent = (U16)WRITESWAP_ENDIAN(pIO->uiAccumulator << (32 - pIO->cBitsUsed));
  804. pIO->pbCurrent = MASKPTR(pIO->pbCurrent + ((pIO->cBitsUsed >> 3) & 2), pIO->iMask);
  805. pIO->cBitsUsed &= 16 - 1;
  806. }
  807. Void putBit16(BitIOInfo* pIO, U32 uiBits, U32 cBits)
  808. {
  809. assert(cBits <= 16);
  810. uiBits &= ~(-1 << cBits);
  811. putBit16z(pIO, uiBits, cBits);
  812. }
  813. Void putBit32(BitIOInfo* pIO, U32 uiBits, U32 cBits)
  814. {
  815. assert(0 <= (I32)cBits && cBits <= 32);
  816. if (16 < cBits)
  817. {
  818. putBit16(pIO, uiBits >> (cBits - 16), 16);
  819. cBits -= 16;
  820. }
  821. putBit16(pIO, uiBits, cBits);
  822. }
  823. Void fillToByte(BitIOInfo* pIO)
  824. {
  825. putBit16z(pIO, 0, (16 - pIO->cBitsUsed) & 7);
  826. }
  827. //----------------------------------------------------------------
  828. U32 getBit16_S(CWMImageStrCodec* pSC, BitIOInfo* pIO, U32 cBits)
  829. {
  830. U32 rc = getBit16(pIO, cBits);
  831. readIS_L1(pSC, pIO);
  832. return rc;
  833. }
  834. U32 putBit16_S(CWMImageStrCodec* pSC, BitIOInfo* pIO, U32 uiBits, U32 cBits)
  835. {
  836. putBit16(pIO, uiBits, cBits);
  837. writeIS_L1(pSC, pIO);
  838. return 0;
  839. }
  840. //----------------------------------------------------------------
  841. // Query buffered data size held in BitIOInfo
  842. // Write() for Enc, Read() for Dec
  843. //----------------------------------------------------------------
  844. U32 getSizeRead(BitIOInfo* pIO)
  845. {
  846. return (U32)(UINTPTR_T)(pIO->pbStart + PACKETLENGTH * 2 - pIO->pbCurrent) - pIO->cBitsUsed / 8;
  847. }
  848. U32 getSizeWrite(BitIOInfo* pIO)
  849. {
  850. return (U32)(UINTPTR_T)(pIO->pbCurrent + (pIO->pbStart <= pIO->pbCurrent ? 0 : PACKETLENGTH * 2) - pIO->pbStart) + pIO->cBitsUsed / 8;
  851. }
  852. //----------------------------------------------------------------
  853. // Query stream offset from attached BitIO object for dec
  854. //----------------------------------------------------------------
  855. U32 getPosRead(BitIOInfo* pIO)
  856. {
  857. size_t cbCached = (pIO->pbStart + PACKETLENGTH * 2 - pIO->pbCurrent) - pIO->cBitsUsed / 8;
  858. return (U32)(pIO->offRef - cbCached);
  859. }
  860. //================================================================
  861. // Block I/O functions
  862. //================================================================
  863. #ifndef ARMOPT_BITIO
  864. ERR attachISRead(BitIOInfo* pIO, struct WMPStream* pWS, CWMImageStrCodec* pSC)
  865. {
  866. UNREFERENCED_PARAMETER( pSC );
  867. pWS->GetPos(pWS, &pIO->offRef);
  868. pIO->pbStart = (U8*)pIO - PACKETLENGTH * 2;
  869. pIO->pbCurrent = pIO->pbStart;
  870. PERFTIMER_STOP(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf);
  871. pWS->SetPos(pWS, pIO->offRef);
  872. pWS->Read(pWS, pIO->pbStart, PACKETLENGTH * 2);
  873. PERFTIMER_START(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf);
  874. pIO->offRef += PACKETLENGTH * 2;
  875. pIO->uiAccumulator = load4BE(pIO->pbStart);
  876. pIO->cBitsUsed = 0;
  877. pIO->iMask = ~(PACKETLENGTH * 2);
  878. pIO->iMask &= ~1;
  879. pIO->pWS = pWS;
  880. return WMP_errSuccess;
  881. }
  882. ERR readIS(CWMImageStrCodec* pSC, BitIOInfo* pIO)
  883. {
  884. ERR err = WMP_errSuccess;
  885. UNREFERENCED_PARAMETER( pSC );
  886. if (PACKET1(pIO->pbStart, pIO->pbCurrent, PACKETLENGTH))
  887. {
  888. struct WMPStream *pWS = pIO->pWS;
  889. PERFTIMER_STOP(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf);
  890. //Call(0 != pIO->pWS->Read(pIO->pWS, pIO->pbStart, PACKETLENGTH));
  891. // TODO: add error checking code
  892. pWS->SetPos(pWS, pIO->offRef);
  893. pWS->Read(pWS, pIO->pbStart, PACKETLENGTH);
  894. pIO->offRef += PACKETLENGTH;
  895. PERFTIMER_START(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf);
  896. // make shadow copy for first 4B
  897. pIO->uiShadow = *(U32*)pIO->pbStart;
  898. // reposition pbPacket pointer
  899. pIO->pbStart = MASKPTR(pIO->pbStart + PACKETLENGTH, pIO->iMask);
  900. }
  901. //Cleanup:
  902. return err;
  903. }
  904. ERR detachISRead(CWMImageStrCodec* pSC, BitIOInfo* pIO)
  905. {
  906. ERR err = WMP_errSuccess;
  907. struct WMPStream* pWS = pIO->pWS;
  908. size_t cbRemain = 0;
  909. // we can ONLY detach IStream at byte boundary
  910. flushToByte(pIO);
  911. assert(0 == (pIO->cBitsUsed % 8));
  912. Call(readIS_L1(pSC, pIO));
  913. // set stream to right offset, undo buffering
  914. cbRemain = (pIO->pbStart + PACKETLENGTH * 2) - (pIO->pbCurrent + pIO->cBitsUsed / 8);
  915. pWS->SetPos(pWS, pIO->offRef - cbRemain);
  916. pIO->pWS = NULL;
  917. Cleanup:
  918. return err;
  919. }
  920. #endif // ARMOPT_BITIO
  921. //----------------------------------------------------------------
  922. ERR attachISWrite(BitIOInfo* pIO, struct WMPStream* pWS)
  923. {
  924. pWS->GetPos(pWS, &pIO->offRef);
  925. pIO->pbStart = (U8*)pIO - PACKETLENGTH * 2;
  926. pIO->pbCurrent = pIO->pbStart;
  927. pIO->uiAccumulator = 0;
  928. pIO->cBitsUsed = 0;
  929. pIO->iMask = ~(PACKETLENGTH * 2);
  930. pIO->pWS = pWS;
  931. return WMP_errSuccess;
  932. }
  933. // write out packet if we have >=1 packet data filled
  934. ERR writeIS(CWMImageStrCodec* pSC, BitIOInfo* pIO)
  935. {
  936. ERR err = WMP_errSuccess;
  937. UNREFERENCED_PARAMETER( pSC );
  938. if (PACKET1(pIO->pbStart, pIO->pbCurrent, PACKETLENGTH))
  939. {
  940. PERFTIMER_STOP(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf);
  941. err = pIO->pWS->Write(pIO->pWS, pIO->pbStart, PACKETLENGTH);
  942. PERFTIMER_START(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf);
  943. Call(err);
  944. // reposition pbStart pointer
  945. pIO->pbStart = MASKPTR(pIO->pbStart + PACKETLENGTH, pIO->iMask);
  946. }
  947. Cleanup:
  948. return err;
  949. }
  950. // write out partially filled buffer and detach bitIO from IStream
  951. ERR detachISWrite(CWMImageStrCodec* pSC, BitIOInfo* pIO)
  952. {
  953. ERR err = WMP_errSuccess;
  954. // we can ONLY detach IStream at byte boundary
  955. assert(0 == (pIO->cBitsUsed % 8));
  956. Call(writeIS_L1(pSC, pIO));
  957. PERFTIMER_STOP(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf);
  958. err = pIO->pWS->Write(pIO->pWS, pIO->pbStart, pIO->pbCurrent + pIO->cBitsUsed / 8 - pIO->pbStart);
  959. PERFTIMER_START(pSC->m_fMeasurePerf, pSC->m_ptEncDecPerf);
  960. Call(err);
  961. pIO->pWS = NULL;
  962. Cleanup:
  963. return err;
  964. }
  965. //=========================
  966. // Performance Measurement
  967. //=========================
  968. #ifndef DISABLE_PERF_MEASUREMENT
  969. void OutputIndivPerfTimer(struct PERFTIMERSTATE *pPerfTimer,
  970. char *pszTimerName,
  971. char *pszDescription,
  972. float fltMegaPixels)
  973. {
  974. PERFTIMERRESULTS rResults;
  975. Bool fResult;
  976. fResult = FALSE;
  977. printf("%s (%s): ", pszTimerName, pszDescription);
  978. if (pPerfTimer)
  979. {
  980. fResult = PerfTimerGetResults(pPerfTimer, &rResults);
  981. if (fResult)
  982. {
  983. printf("%.3f milliseconds, %.6f MP/sec\n", (float)rResults.iElapsedTime / 1000000,
  984. 1000000000 * fltMegaPixels / rResults.iElapsedTime);
  985. if (rResults.iZeroTimeIntervals > 0)
  986. {
  987. printf(" *** WARNING: %d time intervals were measured as zero. "
  988. "This perf timer has insufficient precision!\n\n",
  989. (int) rResults.iZeroTimeIntervals);
  990. }
  991. }
  992. }
  993. if (FALSE == fResult)
  994. printf("Results not available!\n");
  995. }
  996. void OutputPerfTimerReport(CWMImageStrCodec *pState)
  997. {
  998. float fltMegaPixels;
  999. assert(pState->m_fMeasurePerf);
  1000. printf("***************************************************************************\n");
  1001. printf("* Perf Report\n");
  1002. printf("***************************************************************************\n\n");
  1003. fltMegaPixels = (float)pState->WMII.cWidth * pState->WMII.cHeight / 1000000;
  1004. printf("Image Width = %d, Height = %d, total MegaPixels = %.1f MP\n",
  1005. (int) pState->WMII.cWidth, (int) pState->WMII.cHeight, fltMegaPixels);
  1006. OutputIndivPerfTimer(pState->m_ptEncDecPerf, "m_ptEncDecPerf", "excl I/O", fltMegaPixels);
  1007. OutputIndivPerfTimer(pState->m_ptEndToEndPerf, "m_ptEndToEndPerf", "incl I/O", fltMegaPixels);
  1008. }
  1009. #endif // DISABLE_PERF_MEASUREMENT