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.

570 lines
20 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. ;// $Header: S:\h26x\src\dec\cxm12242.asv
  16. ;//
  17. ;// $Log: S:\h26x\src\dec\cxm12242.asv $
  18. ;//
  19. ;// Rev 1.4 01 Apr 1997 12:53:18 BNICKERS
  20. ;// Fix bugs # 153 and 156 -- wrong color when U is small; right edge flickeri
  21. ;//
  22. ;// Rev 1.3 11 Mar 1997 13:49:36 JMCVEIGH
  23. ;// Same ARC bug fix (#94) as was done in cxm12162.asm. Without
  24. ;// this, zoom by 2 and ARC causes black lines in output (every 12th).
  25. ;//
  26. ;// Rev 1.2 06 Sep 1996 16:08:14 BNICKERS
  27. ;// Re-written to filter new points.
  28. ;//
  29. ;-------------------------------------------------------------------------
  30. ;
  31. ; +---------- Color convertor.
  32. ; |+--------- For both H261 and H263.
  33. ; ||+-------- Version for Intel Microprocessors with MMX Technology
  34. ; |||++------ Convert from YUV12.
  35. ; |||||++---- Convert to RGB24.
  36. ; |||||||+--- Zoom by two.
  37. ; ||||||||
  38. ; cxm12242 -- This function performs zoom-by-2 YUV12-to-RGB24 color conversion
  39. ; for H26x. It is tuned for best performance on Intel
  40. ; Microprocessors with MMX Technology. It handles the format in
  41. ; which B is the low order field, then G, then R. This version
  42. ; adds new rows and columns by averaging them with the originals
  43. ; to either side.
  44. ;
  45. ; The YUV12 input is planar, 8 bits per pel. The Y plane may have
  46. ; a pitch of up to 768. It may have a width less than or equal
  47. ; to the pitch. It must be QWORD aligned. Pitch and Width must
  48. ; be a multiple of eight. Height may be any amount, but must be
  49. ; a multiple of two. The U and V planes may have a different
  50. ; pitch than the Y plane, subject to the same limitations.
  51. ;
  52. ; The color convertor is non-destructive; the input Y, U, and V
  53. ; planes will not be clobbered.
  54. OPTION PROLOGUE:None
  55. OPTION EPILOGUE:ReturnAndRelieveEpilogueMacro
  56. .xlist
  57. include iammx.inc
  58. include memmodel.inc
  59. .list
  60. MMXCCDATA SEGMENT PAGE
  61. ALIGN 16
  62. Luma0040002000200000 LABEL DWORD
  63. REPEAT 16
  64. DD 0, 0
  65. ENDM
  66. CNT = 0
  67. REPEAT 219
  68. DW 0
  69. DW (CNT*04A7FH)/00200H
  70. DW (CNT*04A7FH)/00200H
  71. DW (CNT*04A7FH)/00100H
  72. CNT = CNT + 1
  73. ENDM
  74. REPEAT 21
  75. DW 00000H
  76. DW 01FFFH
  77. DW 01FFFH
  78. DW 03FFFH
  79. ENDM
  80. Luma0020004000000020 LABEL DWORD
  81. REPEAT 16
  82. DD 0, 0
  83. ENDM
  84. CNT = 0
  85. REPEAT 219
  86. DW (CNT*04A7FH)/00200H
  87. DW 0
  88. DW (CNT*04A7FH)/00100H
  89. DW (CNT*04A7FH)/00200H
  90. CNT = CNT + 1
  91. ENDM
  92. REPEAT 21
  93. DW 01FFFH
  94. DW 00000H
  95. DW 03FFFH
  96. DW 01FFFH
  97. ENDM
  98. UContribToBandG LABEL DWORD
  99. DW -(-128*0C83H)/00040H
  100. DW 08000H
  101. DW -(-127*0C83H)/00040H
  102. DW 08000H
  103. CNT = -126
  104. REPEAT 253
  105. DW -(CNT*00C83H)/00040H
  106. DW (CNT*0408BH)/00040H
  107. CNT = CNT + 1
  108. ENDM
  109. DW (127*0C83H)/00040H
  110. DW 07FFFH
  111. VContribToRandG LABEL DWORD
  112. CNT = -128
  113. REPEAT 256
  114. DW -(CNT*01A04H)/00040H
  115. DW (CNT*03312H)/00040H
  116. CNT = CNT + 1
  117. ENDM
  118. C0001000001000001 DD 001000001H, 000010000H
  119. C0200020002000200 DD 002000200H, 002000200H
  120. C0000000001000000 DD 001000000H, 000000000H
  121. C000000FF00000000 DD 000000000H, 0000000FFH
  122. C0000010000010000 DD 000010000H, 000000100H
  123. MMXCCDATA ENDS
  124. .CODE
  125. ASSUME ds : FLAT
  126. ASSUME es : FLAT
  127. ASSUME fs : FLAT
  128. ASSUME gs : FLAT
  129. ASSUME ss : FLAT
  130. ; void FAR ASM_CALLTYPE YUV12ToRGB24ZoomBy2 (U8 * YPlane,
  131. ; U8 * VPlane,
  132. ; U8 * UPlane,
  133. ; UN FrameWidth,
  134. ; UN FrameHeight,
  135. ; UN YPitch,
  136. ; UN VPitch,
  137. ; UN AspectAdjustmentCount,
  138. ; U8 * ColorConvertedFrame,
  139. ; U32 DCIOffset,
  140. ; U32 CCOffsetToLine0,
  141. ; IN CCOPitch,
  142. ; IN CCType)
  143. ;
  144. ; CCOffsetToLine0 is relative to ColorConvertedFrame.
  145. ;
  146. ; due to the need for the ebp reg, these parameter declarations aren't used,
  147. ; they are here so the assembler knows how many bytes to relieve from the stack
  148. PUBLIC MMX_YUV12ToRGB24ZoomBy2
  149. MMX_YUV12ToRGB24ZoomBy2 proc DIST LANG AYPlane: DWORD,
  150. AVPlane: DWORD,
  151. AUPlane: DWORD,
  152. AFrameWidth: DWORD,
  153. AFrameHeight: DWORD,
  154. AYPitch: DWORD,
  155. AVPitch: DWORD,
  156. AAspectAdjustmentCnt: DWORD,
  157. AColorConvertedFrame: DWORD,
  158. ADCIOffset: DWORD,
  159. ACCOffsetToLine0: DWORD,
  160. ACCOPitch: DWORD,
  161. ACCType: DWORD
  162. MAXWIDTH = 768
  163. LocalFrameSize = MAXWIDTH*20+64
  164. RegisterStorageSize = 16
  165. ; Arguments:
  166. YPlane_arg = RegisterStorageSize + 4
  167. VPlane_arg = RegisterStorageSize + 8
  168. UPlane_arg = RegisterStorageSize + 12
  169. FrameWidth_arg = RegisterStorageSize + 16
  170. FrameHeight = RegisterStorageSize + 20
  171. YPitch_arg = RegisterStorageSize + 24
  172. ChromaPitch_arg = RegisterStorageSize + 28
  173. AspectAdjustmentCount_arg = RegisterStorageSize + 32
  174. ColorConvertedFrame = RegisterStorageSize + 36
  175. DCIOffset = RegisterStorageSize + 40
  176. CCOffsetToLine0 = RegisterStorageSize + 44
  177. CCOPitch_arg = RegisterStorageSize + 48
  178. CCType = RegisterStorageSize + 52
  179. EndOfArgList = RegisterStorageSize + 56
  180. ; Locals (on local stack frame)
  181. CCOCursor EQU [esp+ 0]
  182. CCOPitch EQU [esp+ 4]
  183. YCursor EQU [esp+ 8]
  184. YLimit EQU [esp+ 12]
  185. YPitch EQU [esp+ 16]
  186. UCursor EQU [esp+ 20]
  187. DistanceFromUToV EQU [esp+ 24]
  188. ChromaPitch EQU [esp+ 28]
  189. AspectCount EQU [esp+ 32]
  190. AspectAdjustmentCount EQU [esp+ 36]
  191. StartIndexOfYLine EQU [esp+ 40]
  192. StashESP EQU [esp+ 44]
  193. FiltLine0 EQU [esp+ 64] ; Must be 32 byte aligned.
  194. FiltLine1 EQU [esp+ 72]
  195. FiltLine2 EQU [esp+ 80]
  196. FiltLine3 EQU [esp+ 88]
  197. HFiltLinePrev EQU [esp+ 96]
  198. push esi
  199. push edi
  200. push ebp
  201. push ebx
  202. mov edi,esp
  203. and esp,0FFFFF000H
  204. sub esp,4096
  205. mov eax,[esp]
  206. sub esp,4096
  207. mov eax,[esp]
  208. sub esp,4096
  209. mov eax,[esp]
  210. sub esp,LocalFrameSize-12288
  211. mov eax,[esp]
  212. mov eax,768
  213. sub eax,[edi+FrameWidth_arg]
  214. imul eax,20
  215. mov StartIndexOfYLine,eax
  216. mov eax,[edi+YPlane_arg]
  217. mov YCursor,eax
  218. mov ebx,[edi+YPitch_arg]
  219. mov YPitch,ebx
  220. mov ecx,[edi+FrameHeight]
  221. imul ebx,ecx
  222. add eax,ebx
  223. mov YLimit,eax
  224. mov eax,[edi+UPlane_arg]
  225. mov ebx,[edi+VPlane_arg]
  226. mov UCursor,eax
  227. sub ebx,eax
  228. mov DistanceFromUToV,ebx
  229. mov eax,[edi+ColorConvertedFrame]
  230. add eax,[edi+DCIOffset]
  231. add eax,[edi+CCOffsetToLine0]
  232. mov CCOCursor,eax
  233. mov eax,[edi+ChromaPitch_arg]
  234. mov ChromaPitch,eax
  235. mov eax,[edi+CCOPitch_arg]
  236. mov CCOPitch,eax
  237. mov eax,[edi+AspectAdjustmentCount_arg]
  238. mov AspectAdjustmentCount,eax
  239. mov AspectCount,eax
  240. mov StashESP,edi
  241. mov esi,YCursor
  242. mov ebp,YPitch
  243. mov edi,StartIndexOfYLine
  244. xor eax,eax
  245. lea edx,[esi+ebp*2]
  246. xor ebx,ebx
  247. mov YCursor,edx
  248. mov bl,[esi+ebp*1] ; Get Y10 (a of line L3; for left edge).
  249. mov al,[esi] ; Get Y00 (A of line L2; for left edge).
  250. movq mm1,Luma0020004000000020[ebx*8] ; L1:< 32a 64a 0 32a >
  251. mov bl,[esi+ebp*1+2] ; Get c.
  252. movq mm0,Luma0020004000000020[eax*8] ; L0:< 32A 64A 0 32A >
  253. mov al,[esi+2] ; Get C.
  254. ; esi -- Cursor over input line of Y.
  255. ; edi -- Index to lines of filtered Y. Quit when MAXWIDTH*20.
  256. ; ebp -- Pitch from one line of Y to the next.
  257. ; al, bl -- Y pels
  258. ; mm0 -- For line 0, contribution of pel to left of two pels under cursor now.
  259. ; mm1 -- For line 1, contribution of pel to left of two pels under cursor now.
  260. ; mm2-mm6 -- Scratch.
  261. Next2PelsOfFirst2LumaLines:
  262. movq mm3,Luma0020004000000020[ebx*8] ; L1:< 32c 64c 0 32c >
  263. psrlq mm1,32 ; L1:< 0 0 32a 64a >
  264. movq mm2,Luma0020004000000020[eax*8] ; L0:< 32C 64C 0 32C >
  265. punpckldq mm1,mm3 ; L1:< 0 32c 32a 64a >
  266. xor ebx,ebx
  267. xor eax,eax
  268. mov bl,[esi+ebp*1+1] ; Get b.
  269. psrlq mm0,32 ; L0:< 0 0 32A 64A >
  270. mov al,[esi+1] ; Get B.
  271. add edi,40 ; Inc filtered luma temp stg idx.
  272. paddw mm1,Luma0040002000200000[ebx*8] ; L1:< 64b 32b+32c 32a+32b 64a >
  273. punpckldq mm0,mm2 ; L0:< 0 32C 32A 64A >
  274. paddw mm0,Luma0040002000200000[eax*8] ; L0:< 64B 32B+32C 32A+32B 64A >
  275. movq HFiltLinePrev[edi-40],mm1 ; Save L1 as next iters LPrev.
  276. paddw mm1,mm0 ; L0+L1
  277. paddw mm0,mm0 ; 2L0
  278. add esi,2 ; Increment input index.
  279. movq FiltLine3[edi-40],mm1 ; Save filtered line L0+L1.
  280. movq mm1,mm3 ; Next iters a.
  281. movq FiltLine2[edi-40],mm0 ; Save filtered line 2L0.
  282. movq mm0,mm2 ; Next iters A.
  283. mov bl,[esi+ebp*1+2] ; Get c.
  284. cmp edi,MAXWIDTH*20-40 ; Done yet.
  285. mov al,[esi+2] ; Get C.
  286. jl Next2PelsOfFirst2LumaLines
  287. xor ebx,ebx
  288. xor ecx,ecx
  289. mov bl,[esi+ebp*1+1] ; Get c.
  290. cmp edi,MAXWIDTH*20 ; Done yet.
  291. mov al,[esi+1] ; Get C.
  292. jl Next2PelsOfFirst2LumaLines
  293. mov ebp,DistanceFromUToV
  294. lea eax,FiltLine2
  295. mov esi,UCursor
  296. mov edx,StartIndexOfYLine
  297. jmp DoOutputLine
  298. Last2OutputLines:
  299. mov ebp,DistanceFromUToV
  300. lea esi,[edi+40]
  301. ja Done
  302. ; edi -- Index to lines of filtered Y. Quit when MAXWIDTH*20.
  303. ; mm0-mm6 -- Scratch.
  304. movq mm0,HFiltLinePrev[edi] ; Fetch horizontally filtered line LP.
  305. paddw mm0,mm0 ; 2LP
  306. Next2PelsOfLast2LumaLines:
  307. movq FiltLine3[edi],mm0 ; Save horz and vert filt line 2LP.
  308. movq FiltLine2[edi],mm0 ; Save horz and vert filt line 2LP.
  309. movq mm0,HFiltLinePrev[edi+40]; Fetch horizontally filtered line LP.
  310. add edi,40
  311. paddw mm0,mm0 ; 2LP
  312. cmp edi,MAXWIDTH*20 ; Done yet.
  313. jne Next2PelsOfLast2LumaLines
  314. lea eax,FiltLine2
  315. mov edx,StartIndexOfYLine
  316. mov esi,UCursor
  317. jmp DoOutputLine
  318. Next4OutputLines:
  319. mov esi,YCursor
  320. mov ebp,YPitch
  321. mov edi,StartIndexOfYLine
  322. mov ecx,YLimit
  323. lea edx,[esi+ebp*2]
  324. xor eax,eax
  325. mov YCursor,edx
  326. xor ebx,ebx
  327. mov al,[esi] ; Get Y00 (A of line L2; for left edge).
  328. cmp esi,ecx
  329. mov bl,[esi+ebp*1] ; Get Y10 (a of line L3; for left edge).
  330. jae Last2OutputLines
  331. movq mm1,Luma0020004000000020[ebx*8] ; L1:< 32a 64a 0 32a >
  332. mov bl,[esi+ebp*1+2] ; Get c.
  333. movq mm0,Luma0020004000000020[eax*8] ; L0:< 32A 64A 0 32A >
  334. mov al,[esi+2] ; Get C.
  335. ; esi -- Cursor over input line of Y.
  336. ; edi -- Index to lines of filtered Y. Quit when MAXWIDTH*20.
  337. ; ebp -- Pitch from one line of Y to the next.
  338. ; al, bl -- Y pels
  339. ; mm0 -- For line 0, contribution of pel to left of two pels under cursor now.
  340. ; mm1 -- For line 1, contribution of pel to left of two pels under cursor now.
  341. ; mm2-mm6 -- Scratch.
  342. Next2PelsOf2LumaLines:
  343. movq mm3,Luma0020004000000020[ebx*8] ; L1:< 32c 64c 0 32c >
  344. psrlq mm1,32 ; L1:< 0 0 32a 64a >
  345. movq mm2,Luma0020004000000020[eax*8] ; L0:< 32C 64C 0 32C >
  346. punpckldq mm1,mm3 ; L1:< 0 32c 32a 64a >
  347. movq mm4,HFiltLinePrev[edi] ; LP
  348. psrlq mm0,32 ; L0:< 0 0 32A 64A >
  349. xor ebx,ebx
  350. xor eax,eax
  351. mov bl,[esi+ebp*1+1] ; Get b.
  352. movq mm5,mm4 ; LP
  353. mov al,[esi+1] ; Get B.
  354. add esi,2 ; Increment input index.
  355. paddw mm1,Luma0040002000200000[ebx*8] ; L1:< 64b 32b+32c 32a+32b 64a >
  356. punpckldq mm0,mm2 ; L0:< 0 32C 32A 64A >
  357. paddw mm0,Luma0040002000200000[eax*8] ; L0:< 64B 32B+32C 32A+32B 64A >
  358. paddw mm5,mm5 ; 2LP
  359. movq HFiltLinePrev[edi],mm1 ; Save L1 as next iters LPrev.
  360. paddw mm4,mm0 ; LP+L0
  361. movq FiltLine0[edi],mm5 ; Save 2LP
  362. paddw mm1,mm0 ; L0+L1
  363. movq FiltLine1[edi],mm4 ; Save LP+L0
  364. paddw mm0,mm0 ; 2L0
  365. movq FiltLine3[edi],mm1 ; Save L0+L1
  366. movq mm1,mm3 ; Next iters a.
  367. movq FiltLine2[edi],mm0 ; Save 2L0
  368. movq mm0,mm2 ; Next iters A.
  369. add edi,40 ; Inc filtered luma temp stg idx.
  370. mov bl,[esi+ebp*1+2] ; Get c.
  371. cmp edi,MAXWIDTH*20-40 ; Done yet.
  372. mov al,[esi+2] ; Get C.
  373. jl Next2PelsOf2LumaLines
  374. xor ebx,ebx
  375. xor ecx,ecx
  376. mov bl,[esi+ebp*1+1] ; Get c.
  377. cmp edi,MAXWIDTH*20 ; Done yet.
  378. mov al,[esi+1] ; Get C.
  379. jl Next2PelsOf2LumaLines
  380. mov ebp,DistanceFromUToV
  381. mov esi,UCursor
  382. lea eax,FiltLine0
  383. mov edx,StartIndexOfYLine
  384. DoOutputLine:
  385. mov edi,CCOCursor
  386. mov ecx,AspectCount
  387. dec ecx ; If count is non-zero, we keep the line.
  388. mov ebx,CCOPitch
  389. mov AspectCount,ecx
  390. je SkipOutputLine
  391. add ebx,edi
  392. xor ecx,ecx
  393. mov cl,[esi]
  394. add eax,MAXWIDTH*20
  395. movq mm7,C0001000001000001
  396. pcmpeqw mm6,mm6
  397. movdt mm0,UContribToBandG[ecx*4] ; < 0 0 Bu Gu >
  398. psllw mm6,15 ; Four words of -32768
  399. mov cl,[esi+ebp*1]
  400. sub edx,MAXWIDTH*20
  401. pxor mm3,mm3
  402. movq mm5,mm7
  403. mov CCOCursor,ebx
  404. jmp StartDoOutputLine
  405. ; ebp -- Distance from U to V
  406. ; esi -- Cursor over U
  407. ; edi -- Cursor over output
  408. ; edx -- Index over Y storage area
  409. ; eax -- Base address of Y line
  410. ; mm6 -- Four words of -32768, to clamp at floor.
  411. ; mm7 -- <0x0100 0x0000 0x0100 0x0001>
  412. DoNext4OutputPels:
  413. movdf [edi-4],mm4 ; Store <R3 G3 B3 R2>
  414. movq mm5,mm7 ; < 0100 0000 0100 0001 >
  415. StartDoOutputLine:
  416. movdt mm2,VContribToRandG[ecx*4] ; < 0 0 Rv Gv >
  417. punpcklwd mm0,mm0 ; < Bu Bu Gu Gu >
  418. movq mm1,mm0 ; < junk junk Gu Gu >
  419. punpcklwd mm2,mm2 ; < Rv Rv Gv Gv >
  420. paddw mm1,mm2 ; < junk junk Guv Guv >
  421. punpckhdq mm0,mm0 ; < Bu Bu Bu Bu >
  422. paddsw mm0,[eax+edx] ; < B2 B3 B1 B0 > w/ ceiling clamped.
  423. punpckldq mm1,mm1 ; < Guv Guv Guv Guv >
  424. paddsw mm1,[eax+edx] ; < G2 G3 G1 G0 > w/ ceiling clamped.
  425. punpckhdq mm2,mm2 ; < Rv Rv Rv Rv >
  426. paddsw mm2,[eax+edx] ; < R2 R3 R1 R0 > w/ ceiling clamped.
  427. paddsw mm0,mm6 ; B with floor clamped.
  428. psubsw mm0,mm6 ; B back in range.
  429. paddsw mm1,mm6 ; G with floor clamped.
  430. psubsw mm1,mm6 ; G back in range.
  431. paddsw mm2,mm6 ; R with floor clamped.
  432. psubsw mm2,mm6 ; R back in range.
  433. psrlw mm0,7 ; < 0 B2 0 B3 0 B1 0 B0 >
  434. pmulhw mm1,C0200020002000200 ; < 0 G2 0 G3 0 G1 0 G0 >
  435. punpckhwd mm3,mm0 ; < -- -- -- -- 0 B3 -- -- >
  436. pmaddwd mm3,C0000000001000000 ; < -- -- -- -- 0 0 B3 0 >
  437. psrlw mm2,7 ; < 0 R2 0 R3 0 R1 0 R0 >
  438. pmullw mm5,mm2 ; < -- -- 0 0 R1 0 0 R0 >
  439. punpckhdq mm2,mm2 ; < -- -- 0 R3 0 R2 -- -- >
  440. pmullw mm0,mm7 ; < 0 B2 0 0 B1 0 0 B0 >
  441. movq mm4,mm1 ; < -- -- -- G3 -- -- -- -- >
  442. pand mm4,C000000FF00000000 ; < -- -- 0 G3 0 0 -- -- >
  443. pmullw mm1,mm7 ; < 0 G2 0 0 G1 0 0 G0 >
  444. pmullw mm2,C0000010000010000 ; < -- -- R3 0 0 R2 -- -- >
  445. psllq mm5,16 ; < 0 0 R1 0 0 R0 0 0 >
  446. xor ecx,ecx
  447. por mm5,mm0 ; < 0 B2 R1 0 B1 R0 0 B0 >
  448. mov cl,[esi+1] ; Fetch next U.
  449. psllq mm1,8 ; < G2 0 0 G1 0 0 G0 0 >
  450. por mm4,mm2 ; < -- -- R3 G3 0 R2 -- -- >
  451. por mm5,mm1 ; < G2 B2 R1 G1 B1 R0 G0 B0 >
  452. inc esi ; Advance input cursor
  453. psrlq mm4,16 ; < -- -- -- -- R3 G3 0 R2 >
  454. movdf [edi],mm5 ; Store < B1 R0 G0 B0 >
  455. psrlq mm5,32 ; < -- -- -- -- G2 B2 R1 G1 >
  456. movdt mm0,UContribToBandG[ecx*4] ; < 0 0 Bu Gv > next iter.
  457. por mm4,mm3 ; < -- -- -- -- R3 G3 B3 R2 >
  458. movdf [edi+4],mm5 ; Store < G2 B2 R1 G1 >
  459. ;
  460. add edi,12 ; Advance output cursor.
  461. add edx,40 ; Increment Y index.
  462. mov cl,[esi+ebp*1] ; Fetch next V.
  463. jne DoNext4OutputPels
  464. movdf [edi-4],mm4 ; Store <R3 G3 B3 R2>
  465. PrepareForNextOutputLine:
  466. mov edx,StartIndexOfYLine
  467. add eax,8-MAXWIDTH*20 ; Advance to next filtered line of Y.
  468. mov esi,UCursor
  469. test al,8 ; Jump if just did line 0 or 2.
  470. mov ebx,ChromaPitch
  471. jne DoOutputLine
  472. add esi,ebx ; Advance to next chroma line.
  473. test al,16 ; Jump if about to do line 2.
  474. mov UCursor,esi
  475. jne DoOutputLine
  476. sub esi,ebx ; Done with 4 lines. Restore UCursor.
  477. mov UCursor,esi
  478. jmp Next4OutputLines
  479. SkipOutputLine:
  480. mov ecx,AspectAdjustmentCount
  481. add eax,MAXWIDTH*20
  482. mov AspectCount,ecx
  483. jmp PrepareForNextOutputLine
  484. Done:
  485. mov esp,StashESP
  486. pop ebx
  487. pop ebp
  488. pop edi
  489. pop esi
  490. rturn
  491. MMX_YUV12ToRGB24ZoomBy2 endp
  492. END