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.

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