Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

727 lines
27 KiB

  1. /* *************************************************************************
  2. ** INTEL Corporation Proprietary Information
  3. **
  4. ** This listing is supplied under the terms of a license
  5. ** agreement with INTEL Corporation and may not be copied
  6. ** nor disclosed except in accordance with the terms of
  7. ** that agreement.
  8. **
  9. ** Copyright (c) 1996 Intel Corporation.
  10. ** All Rights Reserved.
  11. **
  12. ** *************************************************************************
  13. */
  14. ////////////////////////////////////////////////////////////////////////////
  15. // $Author:$
  16. // $Date:$
  17. // $Archive:$
  18. // $Header:$
  19. // $Log:$
  20. ////////////////////////////////////////////////////////////////////////////
  21. //--------------------------------------------------------------------------
  22. //
  23. // d1bvriq.cpp
  24. //
  25. // Description:
  26. // This routine performs run length decoding and inverse quantization
  27. // of transform coefficients for one non-empty block.
  28. //
  29. // Routines:
  30. // VLD_RLD_IQ_Block
  31. //
  32. // Inputs (dwords pushed onto stack by caller):
  33. // lpBlockAction pointer to Block action stream for current blk.
  34. //
  35. // lpSrc The input bitstream.
  36. //
  37. // uBitsInOut Number of bits already read.
  38. //
  39. // pIQ_INDEX Pointer to coefficients and indices.
  40. //
  41. // pN Pointer to number of coefficients read.
  42. //
  43. // Returns:
  44. // 0 on bit stream error, otherwise total number of bits read
  45. // (including number read prior to call).
  46. //
  47. // Note:
  48. // This has not been verfied as layout!!!
  49. // The structure of gTAB_TCOEFF_MAJOR is as follows:
  50. // bits name: description
  51. // ---- ----- -----------
  52. // 25-18 bits: number of bitstream bits used
  53. // 17 last: flag for last coefficient
  54. // 16-9 run: number of preceeding 0 coefficients plus 1
  55. // 8-2 level: absolute value of coefficient
  56. // 1 sign: sign of coefficient
  57. // 0 hit: 1 = major table miss, 0 = major table hit
  58. //
  59. // The structure of gTAB_TCOEFF_MINOR is the same, right shifted by 1 bit.
  60. // A gTAB_TCOEFF_MAJOR value of 00000001h indicates the escape code.
  61. //
  62. //--------------------------------------------------------------------------
  63. //Block level decoding for H.261 decoder
  64. #include "precomp.h"
  65. #define HIGH_FREQ_CUTOFF 6 + 4
  66. // local variable definitions
  67. #define FRAMEPOINTER esp
  68. #define L_BITSUSED FRAMEPOINTER + 0 // 4 byte
  69. #define L_QUANT L_BITSUSED + 4
  70. #define L_RUNCUM L_QUANT + 4
  71. #define L_EVENT L_RUNCUM + 4
  72. #define L_BLOCKTYPE L_EVENT + 4
  73. #define L_COEFFINDEX L_BLOCKTYPE + 4
  74. #define L_INPUTSRC L_COEFFINDEX + 4
  75. #define L_LPACTION L_INPUTSRC + 4
  76. #define L_ecx L_LPACTION + 4
  77. #define L_NUMOFBYTES L_ecx + 4
  78. #define L_NUMOFBITS L_NUMOFBYTES + 4
  79. #ifdef CHECKSUM_MACRO_BLOCK
  80. #define L_SAVEREG L_NUMOFBITS + 4
  81. #define L_SAVEREG2 L_SAVEREG + 4
  82. #define L_CHECKSUM L_SAVEREG2 + 4
  83. #define L_CHECKSUMADDR L_CHECKSUM + 4
  84. #define L_COEFFCOUNT L_CHECKSUMADDR + 4
  85. #define L_COEFFVALUE L_COEFFCOUNT + 4
  86. #else
  87. #define L_COEFFCOUNT L_NUMOFBITS + 4
  88. #define L_COEFFVALUE L_COEFFCOUNT + 4
  89. #endif
  90. #define L_END_OF_FRAME FRAMEPOINTER + 128 // nothing
  91. #define LOCALSIZE ((128+3)&~3) // keep aligned
  92. #define HUFFMAN_ESCAPE 0x5f02 // Huffman escape code
  93. ////////////////////////////////////////////////////////////////
  94. // Decode a none empty block
  95. //
  96. ////////////////////////////////////////////////////////////////
  97. #pragma code_seg("IACODE1")
  98. extern "C" __declspec(naked)
  99. U32 VLD_RLD_IQ_Block(T_BlkAction *lpBlockAction,
  100. U8 *lpSrc,
  101. U32 uBitsread,
  102. U32 *pN,
  103. U32 *pIQ_INDEX)
  104. {
  105. __asm {
  106. push ebp // save callers frame pointer
  107. mov ebp, esp // make parameters accessible
  108. push esi // assumed preserved
  109. push edi
  110. push ebx
  111. xor eax, eax
  112. xor edx, edx
  113. sub esp, LOCALSIZE // reserve local storage
  114. mov esi, lpSrc
  115. #ifdef CHECKSUM_MACRO_BLOCK
  116. mov edi, uCheckSum
  117. ;
  118. mov ecx, [edi]
  119. mov [L_CHECKSUMADDR], edi
  120. ;
  121. mov [L_CHECKSUM], ecx
  122. #endif
  123. // zero out the BLOCKSTORE , 64*2 /32 load, 64*2/4 writes
  124. // it is very likely that the cache has been loaded for
  125. // the stack. Need to find out this later.
  126. mov edi, lpBlockAction //pair with operation above
  127. xor ecx, ecx
  128. mov [L_INPUTSRC], esi
  129. mov eax, uBitsread
  130. mov [L_LPACTION], edi
  131. mov [L_COEFFCOUNT], ecx // zero out coefficient counter
  132. mov [L_COEFFVALUE], ecx // zero out coefficient value
  133. mov [L_NUMOFBYTES], ecx // zero out number of bytes used
  134. mov dl, [edi]T_BlkAction.u8Quant
  135. mov cl, al // init cl to no. of bits used
  136. shl edx, 6 // leave room for val later,
  137. // quant*32 shift by 6 because,
  138. // 5-bits for quant look up &
  139. // it's a word table. Don't need
  140. // to multiply by 2 later
  141. mov [L_BITSUSED], eax // init the counter
  142. mov bl, [edi]T_BlkAction.u8BlkType
  143. mov edi, pIQ_INDEX // Load edi with address of output
  144. // array
  145. mov [L_QUANT], edx // save quant for this block;
  146. mov [L_BLOCKTYPE], ebx // save block type
  147. ;
  148. /////////////////////////////////////////////////////////////////////
  149. // registers:
  150. // eax: 4 bytes input bits
  151. // ebx: block type
  152. // ecx: bits count
  153. // edx: quant*64
  154. // esi: input source
  155. // edi: output array address
  156. // ebp: bits count >>4
  157. mov DWORD PTR [L_RUNCUM], 0ffh // Adjust total run for INTER Blocks
  158. cmp bl, 1 // bl has block type
  159. ja ac_coeff // jump if not INTRA coded
  160. //decode DC first, and invserse quanitzation, 13 clocks
  161. mov ah,[esi]
  162. xor ebx, ebx
  163. mov al,[esi+1]
  164. mov DWORD PTR [L_RUNCUM], ebx
  165. shl eax, cl
  166. ;
  167. and eax, 0ffffh
  168. ;
  169. shr eax, 8
  170. ;
  171. #ifdef CHECKSUM_MACRO_BLOCK
  172. mov [L_SAVEREG], eax // save eax in temp
  173. mov edi, [L_CHECKSUM]
  174. shl eax, 8
  175. and eax, 0000ff00h // just get DC
  176. ;
  177. cmp eax, 0000ff00h // special case when INTRADC==ff, use 80
  178. jne not_255_chk
  179. mov eax, 00008000h
  180. not_255_chk:
  181. add edi, eax // add to DC checksum
  182. ;
  183. mov [L_CHECKSUM], edi // save updated checksum
  184. mov eax, [L_SAVEREG] // restore eax
  185. #endif
  186. shl eax, 3 // INTRADC*8
  187. xor ecx, ecx
  188. cmp eax, 7f8h // take out 11111111 code word.
  189. jne not_255
  190. mov eax, 0400h
  191. not_255:
  192. mov ebx, eax // inversed quantized DC
  193. // save in output array value and index
  194. mov [edi], eax // DC inversed quantized value
  195. mov [edi+4], ecx // index 0
  196. add edi, 8 // increment output address
  197. mov ecx,[L_COEFFCOUNT] // get coefficient counter
  198. mov ebx,[L_BLOCKTYPE]
  199. inc ecx
  200. mov [L_COEFFCOUNT], ecx // save updated coef counter
  201. mov ecx,[L_BITSUSED]
  202. test bl,bl
  203. jz done_dc // jump if only the INTRADC present
  204. add cl, 8 // Add 8 to bits used counter for DC
  205. jmp vld_code // Skip around 1s special case
  206. ac_coeff:
  207. nop
  208. mov ah,[esi]
  209. mov al,[esi+1]
  210. mov dh,[esi+2]
  211. shl eax,16
  212. mov dl,[esi+3]
  213. mov ax, dx
  214. shl eax, cl
  215. mov [L_ecx], ecx
  216. mov edx, eax //save in edx
  217. shr eax, 24 //mask of high order 24 bits
  218. ;
  219. ; // agi
  220. ;
  221. mov bh, gTAB_TCOEFF_tc1a[eax*2] //get the codewords
  222. mov bl, gTAB_TCOEFF_tc1a[eax*2+1] //get the codewords
  223. jmp InFrom1stac
  224. vld_code:
  225. mov ah,[esi]
  226. mov dh,[esi+2]
  227. mov al,[esi+1]
  228. mov dl,[esi+3]
  229. shl eax,16
  230. mov ax, dx
  231. shl eax, cl
  232. mov [L_ecx], ecx
  233. mov edx, eax //save in edx
  234. shr eax, 24 //mask of high order 24 bits
  235. ;
  236. ; // agi
  237. ;
  238. mov bh, gTAB_TCOEFF_tc1[eax*2] //get the codewords
  239. mov bl, gTAB_TCOEFF_tc1[eax*2+1] //get the codewords
  240. InFrom1stac:
  241. mov ax, bx
  242. cmp bx, HUFFMAN_ESCAPE
  243. mov [L_EVENT], eax // 3-bits lenght-1,1-bit if code>8bits,
  244. // 4-bits run,8-bits val
  245. je Handle_Escapes
  246. sar ax, 12 // if 12th bit NOT set, code <= 8-bits
  247. mov [L_NUMOFBITS], ax // save for later the number of bits
  248. js Gt8bits // jump
  249. mov eax, [L_EVENT]
  250. mov ebx, [L_QUANT] //bx:4::8 quant has val
  251. and eax, 0ffh
  252. movsx eax, al //sign extend level
  253. add eax, eax
  254. jns AROUND // if positive jump
  255. neg eax // convert neg to positive
  256. inc eax // increment
  257. #ifdef CHECKSUM_MACRO_BLOCK
  258. /* add in sign to checksum */
  259. mov [L_SAVEREG2], edi // save edi in temp
  260. mov edi, [L_CHECKSUM]
  261. inc edi // add 1 to checksum when sign negative
  262. /* add in level, shift left 8 and add to checksum */
  263. mov [L_SAVEREG], eax // save eax in temp
  264. mov eax, [L_EVENT]
  265. and eax, 0ffh
  266. neg eax
  267. and eax, 0ffh
  268. shl eax, 8 // shift level left 8
  269. add edi, eax // add to level checksum
  270. mov eax, [L_SAVEREG] // restore eax
  271. mov [L_CHECKSUM], edi // save updated checksum
  272. mov edi, [L_SAVEREG2] // restore edi
  273. jmp NEG_AROUND
  274. #endif
  275. AROUND:
  276. #ifdef CHECKSUM_MACRO_BLOCK
  277. /* add in level, shift left 8 and add to checksum */
  278. mov [L_SAVEREG], eax // save eax in temp
  279. mov [L_SAVEREG2], edi // save edi in temp
  280. mov eax, [L_EVENT]
  281. shl eax, 8 // shift level left 8
  282. mov edi, [L_CHECKSUM]
  283. and eax, 0000ff00h // just get level
  284. ;
  285. add edi, eax // add to level checksum
  286. mov eax, [L_SAVEREG] // restore eax
  287. mov [L_CHECKSUM], edi // save updated checksum
  288. mov edi, [L_SAVEREG2] // restore edi
  289. NEG_AROUND:
  290. #endif
  291. mov bx, gTAB_INVERSE_Q[2*eax+ebx] //ebx has the inverse quant
  292. mov eax, [L_EVENT]
  293. shr eax, 8 //leave RUN at al
  294. ;
  295. and eax, 0fh // RUN is just 4-bits
  296. #ifdef CHECKSUM_MACRO_BLOCK
  297. /* add in run, shift left 24 and add to checksum */
  298. mov [L_SAVEREG], eax // save eax in temp
  299. mov [L_SAVEREG2], edi // save edi in temp
  300. shl eax, 24 // shift run left 24
  301. mov edi, [L_CHECKSUM]
  302. add edi, eax // add run to checksum
  303. mov eax, [L_SAVEREG] // restore eax
  304. mov [L_CHECKSUM], edi // save updated checksum
  305. mov edi, [L_SAVEREG2] // restore edi
  306. #endif
  307. mov edx, [L_RUNCUM] // Zig-zag and run length decode
  308. inc al // run+1
  309. add dl, al // dl cumulated run
  310. mov [L_RUNCUM], edx // update the cumulated run ;
  311. mov ecx, gTAB_ZZ_RUN[edx*4]
  312. mov edx, [L_EVENT] // restore run, level to temp
  313. movsx ebx,bx
  314. and edx, 0ffh // get just level
  315. add edx, edx // For EOB level will be zero
  316. jz last_coeff // jump to last_coeff if EOB
  317. // save in output array value and index
  318. mov [edi], ebx // save inversed quantized value
  319. mov [edi+4], ecx // save index
  320. mov ecx,[L_COEFFCOUNT] // get coefficient counter
  321. inc ecx
  322. mov [L_COEFFCOUNT], ecx // save updated coef counter
  323. mov ecx, [L_ecx]
  324. mov eax, [L_NUMOFBITS] // fetch num of bits-1
  325. inc al
  326. add edi, 8 // increment output address
  327. add cl, al //adjust bits used,
  328. mov ebx, [L_NUMOFBYTES] // fetch number of bytes used
  329. test al, al
  330. jz error
  331. cmp cl, 16
  332. jl vld_code //if needs to save ebx, and edx, jump
  333. add esi, 2 //to vld_code to reload
  334. inc ebx // increment number of bytes used
  335. mov [L_NUMOFBYTES], ebx // store updated number of bytes used
  336. ;
  337. sub cl, 16
  338. jmp vld_code
  339. /////////
  340. Gt8bits:
  341. // code > 8-bits
  342. neg ax // -(no of bits -1)
  343. shl edx, 8 // shift of just used 8 bits
  344. add ecx, 8 // Update bit counter by 8
  345. add cx, ax // Update by extra bits
  346. and ebx, 0ffh
  347. dec ecx // dec because desired value is no of
  348. // bits -1
  349. mov [L_ecx], ecx // store
  350. mov cl, 32 // 32
  351. sub cl, al // get just the extra bits
  352. shr edx, cl
  353. add bx, dx
  354. xor ecx, ecx
  355. movzx ebx, bx
  356. shl edx, 3 //do this even if hit major
  357. mov [L_NUMOFBITS], ecx // set num of bits for codes > 8 to 0
  358. // because already updated ecx.
  359. mov ah,gTAB_TCOEFF_tc2[ebx*2]//use minor table with 10 bits
  360. mov al, gTAB_TCOEFF_tc2[ebx*2+1]
  361. mov ebx, [L_QUANT] //bx:4::8 quant has val
  362. mov [L_EVENT], eax
  363. // RLD+ ZZ and Inverse quantization
  364. and eax, 0ffh
  365. movsx eax, al //sign extend level
  366. add eax, eax
  367. jns AROUND1 // if positive jump
  368. neg eax // convert neg to positive
  369. inc eax // increment
  370. #ifdef CHECKSUM_MACRO_BLOCK
  371. /* add in sign to checksum */
  372. mov [L_SAVEREG2], edi // save edi in temp
  373. mov edi, [L_CHECKSUM]
  374. inc edi // add 1 to checksum when sign negative
  375. /* add in level, shift left 8 and add to checksum */
  376. mov [L_SAVEREG], eax // save eax in temp
  377. mov eax, [L_EVENT]
  378. and eax, 0ffh
  379. neg eax
  380. and eax, 0ffh
  381. shl eax, 8 // shift level left 8
  382. add edi, eax // add to level checksum
  383. mov eax, [L_SAVEREG] // restore eax
  384. mov [L_CHECKSUM], edi // save updated checksum
  385. mov edi, [L_SAVEREG2] // restore edi
  386. jmp NEG_AROUND1
  387. #endif
  388. AROUND1:
  389. #ifdef CHECKSUM_MACRO_BLOCK
  390. /* add in level, shift left 8 and add to checksum */
  391. mov [L_SAVEREG], eax // save eax in temp
  392. mov [L_SAVEREG2], edi // save edi in temp
  393. mov eax, [L_EVENT]
  394. shl eax, 8 // shift level left 8
  395. mov edi, [L_CHECKSUM]
  396. and eax, 0000ff00h // just get level
  397. ;
  398. add edi, eax // add to level checksum
  399. mov eax, [L_SAVEREG] // restore eax
  400. mov [L_CHECKSUM], edi // save updated checksum
  401. mov edi, [L_SAVEREG2] // restore edi
  402. NEG_AROUND1:
  403. #endif
  404. mov bx, gTAB_INVERSE_Q[2*eax+ebx] //ebx has the inverse quant
  405. mov eax, [L_EVENT]
  406. shr eax, 8 //leave RUN at al
  407. and eax, 01fh // RUN is just 5-bits
  408. #ifdef CHECKSUM_MACRO_BLOCK
  409. /* add in run, shift left 24 and add to checksum */
  410. mov [L_SAVEREG], eax // save eax in temp
  411. mov [L_SAVEREG2], edi // save edi in temp
  412. shl eax, 24 // shift run left 24
  413. mov edi, [L_CHECKSUM]
  414. add edi, eax // add run to checksum
  415. mov eax, [L_SAVEREG] // restore eax
  416. mov [L_CHECKSUM], edi // save updated checksum
  417. mov edi, [L_SAVEREG2] // restore edi
  418. #endif
  419. mov edx, [L_RUNCUM] //Zig-zag and run length decode
  420. inc al // run+1
  421. add dl, al //dl cumulated run
  422. movsx ebx,bx
  423. mov [L_RUNCUM], edx //update the cumulated run ;
  424. mov ecx, gTAB_ZZ_RUN[edx*4]
  425. mov edx, [L_EVENT] // restore run, level to temp
  426. and edx, 0ffh // get just level
  427. add edx, edx // For EOB level will be zero
  428. jz last_coeff // jump to last_coeff if EOB
  429. // save in output array value and index
  430. mov [edi], ebx // store inversed quantized value
  431. mov [edi+4], ecx // store index
  432. mov ecx,[L_COEFFCOUNT] // get coefficient counter
  433. inc ecx
  434. mov [L_COEFFCOUNT], ecx // save updated coef counter
  435. mov ecx, [L_ecx]
  436. mov eax, [L_NUMOFBITS] // fetch num of bits-1
  437. inc al
  438. add edi, 8 // increment output address
  439. add cl, al //adjust bits used,
  440. mov ebx, [L_NUMOFBYTES] // fetch num of bytes used
  441. test al, al
  442. jz error
  443. cmp cl, 16
  444. jl vld_code //if needs to save ebx, and edx, jump
  445. add esi, 2 //to vld_code to reload
  446. inc ebx // increment number of bytes used
  447. mov [L_NUMOFBYTES], ebx // store updated number of bytes used
  448. ;
  449. sub cl, 16
  450. jmp vld_code
  451. last_coeff: //need to tell it is INTRA or INTER coded
  452. mov ecx, [L_ecx] // restore no of bits used
  453. mov eax, [L_NUMOFBITS] // get no of bits-1
  454. inc al
  455. add cl,al //update bits used count
  456. mov [L_ecx], ecx
  457. #ifdef CHECKSUM_MACRO_BLOCK
  458. mov ecx, [L_CHECKSUM]
  459. mov edi, [L_CHECKSUMADDR]
  460. mov [edi], ecx
  461. #endif
  462. // Add in High Frequency Cutoff check
  463. //
  464. mov eax, [L_RUNCUM] // Total run
  465. mov edx, [L_LPACTION] //pair with operation above
  466. cmp eax, HIGH_FREQ_CUTOFF
  467. jg No_set
  468. mov bl, [edx]T_BlkAction.u8BlkType
  469. or bl, 80h // set hi bit
  470. mov [edx]T_BlkAction.u8BlkType, bl
  471. //
  472. No_set:
  473. mov eax, pN
  474. mov ecx,[L_COEFFCOUNT] // get coefficient counter
  475. mov [eax], ecx // return number of coef
  476. //akk
  477. mov edi,[L_NUMOFBYTES]
  478. mov eax,[L_ecx]
  479. shl edi, 4 // convert bytes used to bits used
  480. add esp,LOCALSIZE // free locals
  481. add eax,edi // add bits used to last few bits used
  482. pop ebx
  483. pop edi
  484. pop esi
  485. pop ebp
  486. ret
  487. error:
  488. #ifdef CHECKSUM_MACRO_BLOCK
  489. mov ecx, [L_CHECKSUM]
  490. mov edi, [L_CHECKSUMADDR]
  491. mov [edi], ecx
  492. #endif
  493. xor eax,eax
  494. add esp,LOCALSIZE // free locals
  495. pop ebx
  496. pop edi
  497. pop esi
  498. pop ebp
  499. ret
  500. //NOTES: 1. the following codes need to be optimized later.
  501. // 2. the codes will be rarely used.
  502. // at this point: eax has 32bits - cl valid bits
  503. // first cl+7 bits
  504. Handle_Escapes: //process escape code separately
  505. add cl, 6 // escape 6-bit code
  506. mov ebx, [L_NUMOFBYTES] // fetch number of bytes used
  507. cmp cl, 16
  508. jl less_16
  509. add esi, 2
  510. sub cl, 16
  511. inc ebx // increment number of bytes used
  512. mov [L_NUMOFBYTES], ebx // store updated number of bytes used
  513. less_16:
  514. mov ah,[esi] // these codes will be further
  515. mov dh,[esi+2]
  516. mov al,[esi+1]
  517. mov dl,[esi+3]
  518. shl eax,16
  519. mov ebx, [L_RUNCUM]
  520. mov ax, dx
  521. inc bl //increae the total run
  522. shl eax, cl
  523. mov edx,eax
  524. shr eax, 32-6 //al has run
  525. #ifdef CHECKSUM_MACRO_BLOCK
  526. /* add in run, shift left 24 and add to checksum */
  527. mov [L_SAVEREG], eax // save eax in temp
  528. mov [L_SAVEREG2], edi // save edi in temp
  529. shl eax, 24 // shift run left 24
  530. mov edi, [L_CHECKSUM]
  531. add edi, eax // add run to checksum
  532. mov eax, [L_SAVEREG] // restore eax
  533. mov [L_CHECKSUM], edi // save updated checksum
  534. mov edi, [L_SAVEREG2] // restore edi
  535. #endif
  536. shl edx, 6 // cl < 6, cl+6 < 16
  537. add al,bl
  538. sar edx, 32-8 //8 bits level, keep the sign
  539. mov [L_RUNCUM], eax
  540. ; // agi
  541. ;
  542. mov ebx, gTAB_ZZ_RUN[eax*4] //run length decode
  543. mov eax, [L_QUANT] //bx:4::8 quant has val
  544. shr eax, 6 //recover quant
  545. mov [L_COEFFINDEX], ebx
  546. #ifdef CHECKSUM_MACRO_BLOCK
  547. /* add in level, shift left 8 and add to checksum */
  548. mov [L_SAVEREG], edx // save edx in temp
  549. mov [L_SAVEREG2], edi // save edi in temp
  550. mov edi, [L_CHECKSUM]
  551. cmp edx, 0 // test level
  552. jns Pos_Level
  553. neg edx
  554. inc edi // add 1 when sign negative
  555. Pos_Level:
  556. shl edx, 8 // shift level left 8
  557. and edx, 0000ff00h // just get level
  558. ;
  559. add edi, edx // add to level checksum
  560. mov edx, [L_SAVEREG] // restore edx
  561. mov [L_CHECKSUM], edi // save updated checksum
  562. mov edi, [L_SAVEREG2] // restore edi
  563. #endif
  564. // new code
  565. test edx, 7fh // test for invalid codes
  566. jz error
  567. imul edx, eax // edx = L*Q
  568. ;
  569. dec eax // Q-1
  570. mov ebx, edx // mask = LQ
  571. sar ebx, 31 // -l if L neq, else 0
  572. or eax, 1 // Q-1 if Even, else Q
  573. xor eax, ebx // -Q[-1] if L neg, else = Q[-1]
  574. add edx, edx // 2*L*Q
  575. sub eax, ebx // -(Q[-1]) if L neg, else = Q[-1]
  576. add edx, eax // 2LQ +- Q[-1]
  577. // now clip to -2048 ... +2047 (12 bits: 0xfffff800 <= res <= 0x000007ff)
  578. cmp edx, -2048
  579. jge skip1
  580. mov edx, -2048
  581. jmp run_zz_q_fixed
  582. skip1:
  583. cmp edx, +2047
  584. jle run_zz_q_fixed
  585. mov edx, +2047
  586. run_zz_q_fixed:
  587. mov ebx, [L_COEFFINDEX]
  588. // save in output array value and index
  589. mov [edi], edx // save inversed quantized value
  590. mov [edi+4], ebx // save index
  591. mov ebx,[L_COEFFCOUNT] // get coefficient counter
  592. inc ebx
  593. mov [L_COEFFCOUNT], ebx // save updated coef counter
  594. add cl, 14
  595. add edi, 8 // increment output address
  596. mov ebx, [L_NUMOFBYTES] // fetch number of bytes used
  597. cmp cl, 16
  598. jl vld_code
  599. add esi, 2
  600. sub cl, 16
  601. inc ebx // increment number of bytes used
  602. mov [L_NUMOFBYTES], ebx // store updated number of bytes used
  603. jmp vld_code
  604. // 18 clocks without cache misses in the inner loop for
  605. // the most frequenctly used events 8/2/95
  606. // the above numbers changed becuase of integration with
  607. // bitstream parsing and IDCT. 8/21/95
  608. done_dc://intra coded block
  609. add ecx, 8
  610. #ifdef CHECKSUM_MACRO_BLOCK
  611. mov ecx, [L_CHECKSUM]
  612. mov edi, [L_CHECKSUMADDR]
  613. mov [edi], ecx
  614. #endif
  615. // Add in High Frequency Cutoff check
  616. //
  617. mov edx, [L_RUNCUM] // Total run
  618. mov eax, lpBlockAction //pair with operation above
  619. cmp edx, HIGH_FREQ_CUTOFF
  620. jg No_set_Intra
  621. mov bl, [eax]T_BlkAction.u8BlkType
  622. or bl, 80h // set hi bit
  623. mov [eax]T_BlkAction.u8BlkType, bl
  624. //
  625. No_set_Intra:
  626. mov eax, pN
  627. mov ebx,[L_COEFFCOUNT] // get coefficient counter
  628. mov [eax], ebx // return number of coef
  629. add esp,LOCALSIZE // free locals
  630. mov eax,ecx
  631. pop ebx
  632. pop edi
  633. pop esi
  634. pop ebp
  635. ret
  636. } //end of asm
  637. } // end of VLD_RLD_IQ_Block
  638. #pragma code_seg()