Source code of Windows XP (NT5)
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.

504 lines
12 KiB

  1. page ,132
  2. ;-----------------------------Module-Header-----------------------------;
  3. ; Module Name: RLEA.ASM - helper routines for RLE stuff
  4. ;
  5. ; Created: Thu 27-Jun-1991
  6. ; Author: Todd Laney [ToddLa]
  7. ;
  8. ; Copyright (c) 1991 Microsoft Corporation
  9. ;
  10. ; Exported Functions: none
  11. ;
  12. ; Public Functions: DecodeRle386
  13. ;
  14. ; Public Data: none
  15. ;
  16. ; General Description:
  17. ;
  18. ; Restrictions:
  19. ;
  20. ; History:
  21. ; Thu 15-Aug-1991 13:45:58 -by- Todd Laney [ToddLa]
  22. ; Created.
  23. ;
  24. ;-----------------------------------------------------------------------;
  25. .xlist
  26. include cmacros.inc
  27. include windows.inc
  28. .list
  29. RLE_ESCAPE equ 0
  30. RLE_EOL equ 0
  31. RLE_EOF equ 1
  32. RLE_JMP equ 2
  33. ; The following structure should be used to access high and low
  34. ; words of a DWORD. This means that "word ptr foo[2]" -> "foo.hi".
  35. LONG struc
  36. lo dw ?
  37. hi dw ?
  38. LONG ends
  39. FARPOINTER struc
  40. off dw ?
  41. sel dw ?
  42. FARPOINTER ends
  43. wptr equ <word ptr>
  44. bptr equ <byte ptr>
  45. min_ax macro REG
  46. sub ax,REG
  47. cwd
  48. and ax,dx
  49. add ax,REG
  50. endm
  51. max_ax macro REG
  52. sub ax,REG
  53. cwd
  54. not dx
  55. and ax,dx
  56. add ax,REG
  57. endm
  58. ; Manually perform "push" dword register instruction to remove warning
  59. PUSHD macro reg
  60. db 66h
  61. push reg
  62. endm
  63. ; Manually perform "pop" dword register instruction to remove warning
  64. POPD macro reg
  65. db 66h
  66. pop reg
  67. endm
  68. ; -------------------------------------------------------
  69. ; DATA SEGMENT DECLARATIONS
  70. ; -------------------------------------------------------
  71. sBegin Data
  72. sEnd Data
  73. ; -------------------------------------------------------
  74. ; CODE SEGMENT DECLARATIONS
  75. ; -------------------------------------------------------
  76. ifndef SEGNAME
  77. SEGNAME equ <_TEXT>
  78. endif
  79. createSeg %SEGNAME, CodeSeg, word, public, CODE
  80. sBegin CodeSeg
  81. assumes cs,CodeSeg
  82. assumes ds,nothing
  83. assumes es,nothing
  84. ;---------------------------Macro---------------------------------------;
  85. ; NOP32 - 32 bit NOP
  86. ;
  87. ; put after all string instructions that use esi or edi to fix a wierd
  88. ; 386 stepping bug
  89. ;
  90. ;-----------------------------------------------------------------------;
  91. NOP32 macro
  92. db 67h
  93. nop
  94. endm
  95. ;---------------------------Macro---------------------------------------;
  96. ; ReadRLE
  97. ;
  98. ; read a WORD from rle data
  99. ;
  100. ; Entry:
  101. ; DS:ESI --> rle data
  102. ; Returns:
  103. ; AX - word at DS:[ESI]
  104. ; DS:ESI advanced
  105. ; History:
  106. ; Wed 04-Jan-1990 13:45:58 -by- Todd Laney [ToddLa]
  107. ; Created.
  108. ;-----------------------------------------------------------------------;
  109. ReadRLE macro
  110. if 0 ; lets work on the wierd 386 step
  111. lods wptr ds:[esi]
  112. else
  113. mov ax, wptr ds:[esi]
  114. add esi,2
  115. endif
  116. endm
  117. ;---------------------------Public-Routine------------------------------;
  118. ; DecodeRle386
  119. ;
  120. ; copy a rle bitmap to a DIB
  121. ;
  122. ; Entry:
  123. ; pBits - pointer to rle bits
  124. ; Returns:
  125. ; none
  126. ; Error Returns:
  127. ; None
  128. ; Registers Preserved:
  129. ; BP,DS,SI,DI
  130. ; Registers Destroyed:
  131. ; AX,BX,CX,DX,FLAGS
  132. ; Calls:
  133. ; INT 10h
  134. ; History:
  135. ;
  136. ; Wed 04-Jan-1990 13:45:58 -by- Todd Laney [ToddLa]
  137. ; Created.
  138. ;-----------------------------------------------------------------------;
  139. assumes ds,nothing
  140. assumes es,nothing
  141. cProc DecodeRle386, <NEAR, PASCAL, PUBLIC>, <ds>
  142. ParmD lpbi
  143. ParmD pDest
  144. ParmD pBits
  145. cBegin
  146. .386
  147. PUSHD di ; push edi
  148. PUSHD si ; push esi
  149. xor edi,edi
  150. xor esi,esi
  151. xor eax,eax
  152. xor ecx,ecx
  153. lds si,lpbi
  154. mov ax,wptr [si].biWidth
  155. add ax,3
  156. and ax,not 3
  157. movzx ebx,ax ; ebx is next_scan
  158. les di,pDest
  159. lds si,pBits
  160. assumes ds,nothing
  161. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  162. ; Start of RLE decoding
  163. ;
  164. ; DS:SI --> RLE bits
  165. ; ES:DI --> screen output (points to start of scan)
  166. ;
  167. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  168. align 4
  169. RleBltStart:
  170. mov edx,edi ; save start of scan
  171. align 4
  172. RleBltAlign:
  173. inc esi ; !!! re-align source
  174. and si,not 1
  175. align 4
  176. RleBltNext:
  177. ReadRLE ; al=count ah=color
  178. or al,al ; is it a escape?
  179. jz short RleBltEscape
  180. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  181. ; We have found a encoded run (al != 0)
  182. ;
  183. ; al - run length
  184. ; ah - run color
  185. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  186. RleBltEncodedRun:
  187. mov cl,al
  188. mov al,ah
  189. shr cx,1
  190. rep stos wptr es:[edi]
  191. NOP32
  192. jnc short RleBltNext
  193. stos bptr es:[edi]
  194. NOP32
  195. jmp short RleBltNext
  196. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  197. ; We have found a RLE escape code (al=0)
  198. ; Possibilities are:
  199. ; . End of Line - ah = 0
  200. ; . End of RLE - ah = 1
  201. ; . Delta - ah = 2
  202. ; . Unencoded run - ah = 3 or more
  203. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  204. align 4
  205. RleBltEscape:
  206. cmp ah,al
  207. je short RleBltEOL
  208. inc al
  209. cmp ah,al
  210. je short RleBltEOF
  211. inc al
  212. cmp ah,al
  213. je short RleBltDelta
  214. errn$ RleBltUnencodedRun
  215. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  216. ; We have found a un-encoded run (ah >= 3)
  217. ;
  218. ; ah is pixel count
  219. ; DS:SI --> pixels
  220. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  221. RleBltUnencodedRun:
  222. mov cl,ah
  223. shr cx,1
  224. rep movs wptr es:[edi], wptr ds:[esi]
  225. NOP32
  226. jnc short RleBltAlign
  227. movs bptr es:[edi], bptr ds:[esi]
  228. NOP32
  229. jmp short RleBltAlign
  230. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  231. ; We have found a delta jump, the next two bytes contain the jump values
  232. ; note the the jump values are unsigned bytes, x first then y
  233. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  234. align 4
  235. RleBltDelta:
  236. ReadRLE ; al = deltaX, ah = deltaY
  237. or ah,ah
  238. jnz short RleBltDeltaXY
  239. RleBltDeltaX:
  240. add edi,eax
  241. jmp short RleBltNext
  242. align 4
  243. RleBltDeltaXY:
  244. add edi,ebx
  245. add edx,ebx
  246. dec ah
  247. jnz RleBltDeltaXY
  248. add edi,eax
  249. jmp short RleBltNext
  250. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  251. ; We have found a end of line marker, point ES:DI to the begining of the
  252. ; next scan
  253. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  254. RleBltEOL:
  255. mov edi,edx ; go back to start of scan
  256. add edi,ebx ; advance to next scan
  257. jmp short RleBltStart ; go get some more
  258. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  259. ; We have found a end of rle marker, clean up and exit.
  260. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  261. RleBltEOF:
  262. errn$ RleBltExit
  263. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  264. RleBltExit:
  265. POPD si ; pop esi
  266. POPD di ; pop edi
  267. .286
  268. cEnd
  269. ;---------------------------Macro---------------------------------------;
  270. ; ReadRle286
  271. ;
  272. ; read a WORD from rle data
  273. ;
  274. ; Entry:
  275. ; DS:SI --> rle data
  276. ; Returns:
  277. ; AX - word at DS:[SI]
  278. ; DS:SI advanced
  279. ; History:
  280. ; Wed 04-Jan-1990 13:45:58 -by- Todd Laney [ToddLa]
  281. ; Created.
  282. ;-----------------------------------------------------------------------;
  283. ReadRle286 macro
  284. lods wptr ds:[si]
  285. endm
  286. ;---------------------------Public-Routine------------------------------;
  287. ; DecodeRle286
  288. ;
  289. ; copy a rle bitmap to a DIB
  290. ;
  291. ; Entry:
  292. ; pBits - pointer to rle bits
  293. ; Returns:
  294. ; none
  295. ; Error Returns:
  296. ; None
  297. ; Registers Preserved:
  298. ; BP,DS,SI,DI
  299. ; Registers Destroyed:
  300. ; AX,BX,CX,DX,FLAGS
  301. ; Calls:
  302. ; INT 10h
  303. ; History:
  304. ;
  305. ; Wed 04-Jan-1990 13:45:58 -by- Todd Laney [ToddLa]
  306. ; Created.
  307. ;-----------------------------------------------------------------------;
  308. assumes ds,nothing
  309. assumes es,nothing
  310. cProc DecodeRle286, <NEAR, PASCAL, PUBLIC>, <ds>
  311. ParmD lpbi
  312. ParmD pDest
  313. ParmD pBits
  314. cBegin
  315. push di
  316. push si
  317. xor di,di
  318. xor si,si
  319. xor ax,ax
  320. xor cx,cx
  321. lds si,lpbi
  322. mov ax,wptr [si].biWidth
  323. add ax,3
  324. and ax,not 3
  325. mov bx,ax ; bx is next_scan
  326. les di,pDest
  327. lds si,pBits
  328. assumes ds,nothing
  329. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  330. ; Start of RLE decoding
  331. ;
  332. ; DS:SI --> RLE bits
  333. ; ES:DI --> screen output (points to start of scan)
  334. ;
  335. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  336. Rle286Start:
  337. mov dx,di ; save start of scan
  338. Rle286Next:
  339. ReadRLE286 ; al=count ah=color
  340. or al,al ; is it a escape?
  341. jz Rle286Escape
  342. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  343. ; We have found a encoded run (al != 0)
  344. ;
  345. ; al - run length
  346. ; ah - run color
  347. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  348. Rle286EncodedRun:
  349. mov cl,al
  350. mov al,ah
  351. shr cx,1
  352. rep stos wptr es:[di]
  353. adc cl,cl
  354. rep stos bptr es:[di]
  355. jmp short Rle286Next
  356. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  357. ; We have found a RLE escape code (al=0)
  358. ; Possibilities are:
  359. ; . End of Line - ah = 0
  360. ; . End of RLE - ah = 1
  361. ; . Delta - ah = 2
  362. ; . Unencoded run - ah = 3 or more
  363. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  364. Rle286Escape:
  365. cmp ah,al
  366. je Rle286EOL
  367. inc al
  368. cmp ah,al
  369. je Rle286EOF
  370. inc al
  371. cmp ah,al
  372. je Rle286Delta
  373. errn$ Rle286UnencodedRun
  374. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  375. ; We have found a un-encoded run (ah >= 3)
  376. ;
  377. ; ah is pixel count
  378. ; DS:SI --> pixels
  379. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  380. Rle286UnencodedRun:
  381. mov cl,ah
  382. shr cx,1
  383. rep movs wptr es:[di], wptr ds:[si]
  384. adc cl,cl
  385. rep movs bptr es:[di], bptr ds:[si]
  386. inc si ; !!! re-align source
  387. and si,not 1
  388. jmp short Rle286Next
  389. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  390. ; We have found a delta jump, the next two bytes contain the jump values
  391. ; note the the jump values are unsigned bytes, x first then y
  392. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  393. Rle286Delta:
  394. ReadRLE286 ; al = deltaX, ah = deltaY
  395. or ah,ah
  396. jnz Rle286DeltaXY
  397. Rle286DeltaX:
  398. add di,ax
  399. jmp short Rle286Next
  400. Rle286DeltaXY:
  401. add di,bx
  402. add dx,bx
  403. dec ah
  404. jnz Rle286DeltaXY
  405. add di,ax
  406. jmp short Rle286Next
  407. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  408. ; We have found a end of line marker, point ES:DI to the begining of the
  409. ; next scan
  410. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  411. Rle286EOL:
  412. mov di,dx ; go back to start of scan
  413. add di,bx ; advance to next scan
  414. jmp short Rle286Start ; go get some more
  415. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  416. ; We have found a end of rle marker, clean up and exit.
  417. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  418. Rle286EOF:
  419. errn$ Rle286Exit
  420. ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
  421. Rle286Exit:
  422. pop si
  423. pop di
  424. cEnd
  425. sEnd
  426. sEnd
  427. end