home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 3 / PDCD_3.iso / utilities / utilsd / dithering / TestDither (.txt) < prev   
Encoding:
RISC OS BBC BASIC V Source  |  1994-02-08  |  14.4 KB  |  425 lines

  1.  >TestDither
  2.  : Cy Booker
  3.  : 86 Church View
  4.  : Main Road
  5.  : Crockenhill
  6.  : Swanley
  7.  : Kent
  8.  : BR8 8 JW
  9.  run this in a 16 colour Wimp mode with default palette
  10.  the bottom half uses an accurate 2x2 dither algorithm
  11.  the top half uses ColourTrans
  12.  if change parameters to xdither_rgb then works in any mode/palette (upto 8bpp)
  13.  the suprising fact is that for 4bpp it looks as though we have changed
  14.  the working resolution from 0..255 to 0..65536 (extra 2.4 decimal places)
  15.  only doubles the "resolution"
  16.  all sub-routines conform to
  17.      parameters in R0, R1, R2, ...
  18.      returns in R0, R1, R2, ... [F0, F1, F2, ...]
  19.      corrupts R0-R3, ip, lr
  20.      preserves R4-R9, sl, gb, sp
  21.      if name has `x' prefix then
  22.              PSR_V set on SWI error, PSR_NZC undefined
  23.              PSR_V clear if OK,  PRS_NZC preserved
  24.      else if name has `v' prefix then
  25.              PSR_Z is state of R0, PSR_NCV preserved
  26.      else PSR_NZCV preserved
  27. $+ " ["+ 
  28. )+ "]"
  29.   sp = 13
  30.   lr = 14
  31. !3  gb = 12                       :
  32.  not APCS !!!
  33. "3  ip = 11                       :
  34.  not APCS !!!
  35.   PSR_V = &10000000
  36.   L% = 10240
  37.  code% L% : L% += code%
  38.  pass%= %1000 
  39.  %1010 
  40.     O% = 0 : P% = code%
  41.     [OPT pass%
  42.         
  43. udivide_255
  44.         
  45. udivide_3
  46.         
  47. udivmod
  48.         
  49. xdither_rgb
  50. .(        
  51. convert_paletteentry_to_rgb
  52. /(        
  53. convert_rgb_to_paletteentry
  54. 0E.Palette                        ; standard 16-colour wimp palette
  55.         EQUD    &FFFFFF00
  56.         EQUD    &DDDDDD00
  57.         EQUD    &BBBBBB00
  58.         EQUD    &99999900
  59.         EQUD    &77777700
  60.         EQUD    &55555500
  61.         EQUD    &33333300
  62.         EQUD    &00000000
  63.         EQUD    &99440000
  64.         EQUD    &00EEEE00
  65.         EQUD    &00CC0000
  66.         EQUD    &0000DD00
  67.         EQUD    &BBEEEE00
  68.         EQUD    &00885500
  69.         EQUD    &00BBFF00
  70.         EQUD    &FFBB0000
  71. .xdither
  72.         STMFD   (sp)!, {lr}
  73.         MOV     R3, #20
  74.         ADR     R4, Palette
  75.         MOV     R5, #4
  76.         BL      xdither_rgb
  77.         LDMvsFD (sp)!, {pc}
  78. H"        STMFD   (sp)!, {R0-R3}
  79. I"        STMFD   (sp)!, {R0-R3}
  80.         MOV     R0, #1 << 5
  81.         MOV     R1, sp
  82. L#        SWI     "XOS_SetColour"
  83. M"        ADD     sp, sp, #4*4*2
  84.         LDMFD   (sp)!, {pc}
  85. O        ]
  86.  pass%
  87.  s(2), e(2), c(2)
  88.   s() = 0.03, 0.80, 0.42
  89.   e() = 0.94, 0.05, 0.79
  90.  i%= 0 
  91.     s(i%) = 
  92.     e(i%) = 1 - (
  93. (1) < 0.7
  94. X        
  95.   nstep = 512
  96.  i= 0 
  97.  1.00 
  98.  1/nstep
  99.     c() = e()-s()
  100.     c() = i*c()
  101.     c() = c() + s()
  102.     A% = c(0)*&10000 + 0.5
  103.     B% = c(1)*&10000 + 0.5
  104.     C% = c(2)*&10000 + 0.5
  105.  xdither
  106. c(    
  107.  i*1024, 0, 1024/nstep, 512
  108.     A% = c(0)*&ff + 0.5
  109.     B% = c(1)*&ff + 0.5
  110.     C% = c(2)*&ff + 0.5
  111. gD    
  112.  "ColourTrans_SetGCOL", (A%<<8)+(B%<<16)+(C%<<24),,,&100,0
  113. h,    
  114.  i*1024, 512, 1024/nstep, 512  
  115.   *ScreenSave <d>.Tmp.screen
  116. link(a$):
  117. udivide_3
  118. [OPT pass%
  119. qS; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  120. r*; Calculates round(n/3) extremely fast
  121. ; In    R0 = n
  122. ; Out   R0 = round(n 
  123. .udivide_3
  124. x'        MOV     R2, R0, LSR #32 - 2
  125. y&        ADDS    R1, R0, R0, LSL #2
  126. zD        ADDcs   R2, R2, #1              ; R2.R1 = R0 * &00000005
  127. {'        ADD     R2, R2, R2, LSL #16
  128. |'        ADDS    R3, R1, R1, LSL #16
  129. }D        ADC     R2, R2, R1, LSR #32 - 16; R2.R3 = R0 * &00050005
  130. ~&        ADD     R2, R2, R2, LSL #8
  131. &        ADDS    R1, R3, R3, LSL #8
  132. D        ADC     R2, R2, R3, LSR #32 - 8 ; R2.R1 = R0 * &05050505
  133. &        ADD     R2, R2, R2, LSL #4
  134. &        ADDS    R3, R1, R1, LSL #4
  135. D        ADC     R0, R2, R1, LSR #32 - 4 ; R0.R3 = R0 * &55555555
  136. 6        ADDmi   R0, R0, #1              ; round up
  137.         MOVS    pc, lr
  138.     ]:= 0
  139. udivide_255
  140. [OPT pass%
  141. S; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  142. ,; Calculates round(n/255) extremely fast
  143. ; In    R0 = n
  144. ; Out   R0 = round(n 
  145.  255)
  146. .udivide_255
  147. '        MOV     R2, R0, LSR #32 - 8
  148. &        ADDS    R1, R0, R0, LSL #8
  149. D        ADDcs   R2, R2, #1              ; R2.R1 = R0 * &00000101
  150. '        ADD     R2, R2, R2, LSL #16
  151. '        ADDS    R3, R1, R1, LSL #16
  152. D        ADC     R0, R2, R1, LSR #32 - 16; R0.R3 = R0 * &01010101
  153. 6        ADDmi   R0, R0, #1              ; round up
  154.         MOVS    pc, lr
  155.     ]:= 0
  156. udivmod
  157. [OPT pass%
  158. R;~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
  159. ; In    R0 = unsigned
  160. #;       R1 = unsigned, non-zero
  161. 4; Out   R0 = R0 / R1 (rounded down towards zero)
  162. ;       R1 = R0 
  163. 6; Note  if R1 = 0 then get stuck in infinite loop!
  164. .udivmod
  165.         
  166. divrem(2, 0, 1, 3)
  167.         MOV     R1, R0
  168.         MOV     R0, R2
  169.         MOVS    pc, lr
  170.     ]:= 0
  171. xdither_rgb
  172.  L_TopLeft, L_BottomRight, L_TopRight, L_Mode, L_BPP
  173.  loop
  174.  first 3 words are accumulator (ie tl, tl+br, tl+br+tr)
  175.   L_TopLeft     = 3 << 2
  176.   L_BottomRight = 4 << 2
  177.   L_TopRight    = 5 << 2
  178. 7  L_Mode        = 6 << 2                :
  179.  implicit
  180. 7  L_BPP         = 7 << 2                :
  181.  implicit
  182. link("convert_paletteentry_to_rgb,convert_rgb_to_paletteentry,udivide_3")
  183. [OPT pass%
  184. S; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  185. R; Calculate a 2x2 dither pattern for an rgb given a mode and a palette pointer
  186. M; This routine needed since cant change palette when redirected output to
  187. ; sprite
  188. .; The algorithm based on colourtrans's, ie
  189. ;  tl = closest
  190. O;  br = 2.actual - tl              = actual - (tl - actual) = actual - diff
  191.  ;  tr = 2.actual - (tl+br)/2
  192. %;  bl = 2.actual - (tl+br+tr) / 3
  193. ; In    R0 = &000r.rrrr
  194. ;       R1 = &000g.gggg
  195. ;       R2 = &000b.bbbb
  196. ;       R3 = mode
  197. /;       R4 = pointer to colourtrans palette
  198. +;       R5 = bpp for mode {2, 4, 8, 16}
  199. 8; Out   R0 = top row of screen bytes (word expanded)
  200. ;;       R1 = bottom row of screen bytes (word expanded)
  201. ;       R2 = R0
  202. ;       R3 = R1
  203. .xdither_rgb
  204. :        STMFD   (sp)!, {R0, R1, R2, R3, R5, R6-R9, lr}
  205. J        LDMIA   (sp)!, {R6, R7, R8}             ; R6/R7/R8= rgb wanted
  206. #        SUB     sp, sp, #L_Mode
  207. /        BL      convert_rgb_to_paletteentry
  208. %        LDR     R1, [sp, #L_Mode]
  209.         MOV     R2, R4
  210. <        SWI     "XColourTrans_ReturnColourNumberForMode"
  211. $        Bvs     error_dither_rgb
  212. (        STR     R0, [sp, #L_TopLeft]
  213.         ;
  214. (        LDR     R0, [R4, R0, LSL #2]
  215. /        BL      convert_paletteentry_to_rgb
  216. B        STMIA   sp, {R0, R1, R2}                ; Stack tl rgb
  217. A        
  218. aux_dithers_rgb                       ; br = 2x - tl
  219. ,        STR     R0, [sp, #L_BottomRight]
  220.         ;
  221. (        LDR     R0, [R4, R0, LSL #2]
  222. /        BL      convert_paletteentry_to_rgb
  223. $        LDMIA   sp, {R3, ip, lr}
  224.         ADD     R0, R0, R3
  225.         ADD     R1, R1, ip
  226.         ADD     R2, R2, lr
  227. E        STMIA   sp, {R0, R1, R2}                ; Stack tl+br rgb
  228. "        MOVS    R0, R0, ASR #1
  229. K        ADDcs   R0, R0, #1                      ; ensure lsb is correct
  230. "        MOVS    R1, R1, ASR #1
  231.         ADDcs   R1, R1, #1
  232. "        MOVS    R2, R2, ASR #1
  233.         ADDcs   R2, R2, #1
  234. J        
  235. aux_dithers_rgb                       ; tr = 2x - (tl + br)/2
  236. )        STR     R0, [sp, #L_TopRight]
  237.         ;
  238. (        LDR     R0, [R4, R0, LSL #2]
  239. /        BL      convert_paletteentry_to_rgb
  240. $        LDMIA   sp, {R3, ip, lr}
  241. H        ADD     R5, R0, R3                      ; R5 = red(tl+br+tr)
  242. J        ADD     R9, R1, ip                      ; R9 = green(tl+br+tr)
  243. 4        ADD     R0, R2, lr                      
  244. Q        BL      udivide_3                       ; this ensures lsb is correct
  245. N        STR     R0, [sp, #8]                    ; stack blue(tl+br+tr) / 3
  246.         MOV     R0, R9 
  247.         BL      udivide_3
  248. O        STR     R0, [sp, #4]                    ; stack green(tl+br+tr) / 3
  249.         MOV     R0, R5
  250.         BL      udivide_3
  251.          LDMIB   sp, {R1, R2}
  252. K        
  253. aux_dithers_rgb                       ; bl = 2x - (tl+br+tr)/3
  254. $        LDR     R5, [sp, #L_BPP]
  255. ,        LDR     R2, [sp, #L_BottomRight]
  256. )        LDR     R3, [sp, #L_TopRight]
  257. (        LDR     R4, [sp, #L_TopLeft]
  258. C        
  259. R     R1, R2, R0, LSL R5              ; R1= bottom row
  260. @        
  261. R     R0, R3, R4, LSL R5              ; R0= top row
  262. .loop   ADD     R5, R5, R5
  263.         CMP     R5, #16
  264. K        
  265. Rls   R0, R0, R0, LSL R5              ; Expand into full words
  266. %        
  267. Rls   R1, R1, R1, LSL R5
  268.         Blo     loop
  269.         MOV     R2, R0
  270.         MOV     R3, R1
  271.     A        CMP     pc, #0                          ; clear psr_v
  272. .error_dither_rgb
  273. '        ADD     sp, sp, #L_Mode + 4
  274. &        LDMFD   (sp)!, {R5-R9, pc}
  275.     ]:= 0
  276. aux_dithers_rgb
  277. [OPT pass%
  278. H        RSB     R0, R0, R6, LSL #1              ; red = 2*x - f(red)
  279. &        RSB     R1, R1, R7, LSL #1
  280. &        RSB     R2, R2, R8, LSL #1
  281. H        CMP     R0, #&10000                     ; check for overflow
  282. D        MOVhi   R0, #0                          ; and underflow!
  283.         MOVgt   R0, #&10000
  284.         CMP     R1, #&10000
  285.         MOVhi   R1, #0
  286.         MOVgt   R1, #&10000
  287.         CMP     R2, #&10000
  288.         MOVhi   R2, #0
  289.         MOVgt   R2, #&10000
  290. /        BL      convert_rgb_to_paletteentry
  291. %        LDR     R1, [sp, #L_Mode]
  292.         MOV     R2, R4
  293.  <        SWI     "XColourTrans_ReturnColourNumberForMode"
  294. !$        Bvs     error_dither_rgb
  295. "    ]:= 0
  296. xconvert_cmyk_to_rgb
  297. [OPT pass%
  298. &R; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  299. ; In    R0 = &000c.cccc
  300. ;       R1 = &000y.yyyy
  301. ;       R2 = &000m.mmmm
  302. ;       R3 = &000k.kkkk
  303. ; Out   R0 = &000r.rrrr
  304. ;       R1 = &000g.gggg
  305. ;       R2 = &000b.bbbb
  306. .xconvert_cmyk_to_rgb
  307. 13        SWI     "XColourTrans_ConvertCMYKToRGB"
  308.         MOV     pc, lr
  309. 3    ]:= 0
  310. xconvert_hsv_to_rgb
  311. [OPT pass%
  312. 7R; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  313. 91; In    R0 = &0hhh.hhhh (or -1 if achromatic)
  314. ;       R1 = &000s.ssss
  315. ;       R2 = &000v.vvvv
  316. ; Out   R0 = &000r.rrrr
  317. ;       R1 = &000g.gggg
  318. ;       R2 = &000b.bbbb
  319. .xconvert_hsv_to_rgb
  320. AP        CMN     R0, #+1                         ; Achromatic ? [clear PSR_V]
  321.         MOVeq   R0, R2
  322.         MOVeq   R1, R2
  323. D2        SWIne   "XColourTrans_ConvertHSVToRGB"
  324.         MOV     pc, lr
  325. F    ]:= 0
  326. convert_paletteentry_to_rgb
  327. link("udivide_255")
  328. [OPT pass%
  329. KR; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  330. ; In    R0 = &bbggrr??
  331. ; Out   R0 = &000r.rrrr
  332. ;       R1 = &000g.gggg
  333. ;       R2 = &000b.bbbb
  334. R .convert_paletteentry_to_rgb
  335. S&        STMFD   (sp)!, {R4-R5, lr}
  336.         MOV     R4, R0
  337. U"        MOV     R5, #&00ff0000
  338. V=        
  339.      R0, R5, R4, LSR #8              ; &00bb0000
  340. W@        BL      udivide_255                     ; &000b.bbbb
  341.         STMFD   (sp)!, {R0}
  342. Y=        
  343.      R0, R5, R4                      ; &00gg0000
  344. Z@        BL      udivide_255                     ; &000g.gggg
  345.         STMFD   (sp)!, {R0}
  346. \=        
  347.      R0, R5, R4, LSL #8              ; &00rr0000
  348. ]@        BL      udivide_255                     ; &000r.rrrr
  349. ^.        LDMFD   (sp)!, {R1-R2, R4-R5, pc}^
  350. _    ]:= 0
  351. xconvert_rgb_to_cmyk
  352. [OPT pass%
  353. cR; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  354. ; In    R0 = &000r.rrrr
  355. ;       R1 = &000g.gggg
  356. ;       R2 = &000b.bbbb
  357. ; Out   R0 = &000c.cccc
  358. ;       R1 = &000y.yyyy
  359. ;       R2 = &000m.mmmm
  360. ;       R3 = &000k.kkkk
  361. .xconvert_rgb_to_cmyk
  362. n3        SWI     "XColourTrans_ConvertRGBToCMYK"
  363.         MOV     pc, lr
  364. p    ]:= 0
  365. xconvert_rgb_to_hsv
  366. [OPT pass%
  367. tR; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  368. ; In    R0 = &000r.rrrr
  369. ;       R1 = &000g.gggg
  370. ;       R2 = &000b.bbbb
  371. y>; Out   R0 = &0hhh.hhhh  (or -1 if achromatic, ie r==g==b)
  372. ;       R1 = &000s.ssss
  373. ;       R2 = &000v.vvvv
  374. .xconvert_rgb_to_hsv
  375.         CMP     R0, R1
  376. @        CMPeq   R1, R2                          ; Achromatic
  377. K        MVNeq   R0, #
  378. (-1)                    ; So undefined (sentinel)
  379.         MOVeq   R1, #0
  380. 2        SWIne   "XColourTrans_ConvertRGBToHSV"
  381.         MOV     pc, lr
  382.     ]:= 0
  383. convert_rgb_to_paletteentry
  384. [OPT pass%
  385. R; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  386. ; In    R0 = &000r.rrrr
  387. ;       R1 = &000g.gggg
  388. ;       R2 = &000b.bbbb
  389. ; Out   R0 = &bbggrr00
  390.  .convert_rgb_to_paletteentry
  391. I        RSB     R2, R2, R2, LSL #8              ; R2= blue * &ff.0000
  392. #        MOVS    R2, R2, LSR #16
  393. C        ADDcs   R2, R2, #1                      ; R2= &000000bb
  394. J        RSB     R1, R1, R1, LSL #8              ; R1= green * &ff.0000
  395. #        MOVS    R1, R1, LSR #16
  396. C        ADC     R1, R1, R2, LSL #8              ; R1= &0000bbgg
  397. H        RSB     R0, R0, R0, LSL #8              ; R0= red * &ff.0000
  398. #        MOVS    R0, R0, LSR #16
  399. C        ADC     R0, R0, R1, LSL #8              ; R0= &00bbggrr
  400. "        MOV     R0, R0, LSL #8
  401.         MOVS    pc, lr
  402.     ]:= 0
  403.  **********************************************************
  404.  ***   Macro DIVREM - rc := ra DIV rb; ra := ra REM rb  ***
  405.  ***   rb preserved, rtemp corrupt                      ***
  406.  ***   Now up to 37% faster                             ***
  407.  **********************************************************
  408.  from Acorn AAsm header file 'macros'
  409. divrem(rc%, ra%, rb%, rtemp%)
  410.  loop
  411. [OPT pass%
  412.         MOV     rtemp%, rb%
  413. '        CMP     rtemp%, ra%, LSR #1
  414. *.loop   MOVls   rtemp%, rtemp%, LSL #1
  415. '        CMPls   rtemp%, ra%, LSR #1
  416.         Bls     loop
  417.         MOV     rc%, #0
  418. .loop   CMP     ra%, rtemp%
  419. $        SUBcs   ra%, ra%, rtemp%
  420. !        ADC     rc%, rc%, rc%
  421. *        MOV     rtemp%, rtemp%, LSR #1
  422.         CMP     rtemp%, rb%
  423.         Bcs     loop
  424.     ]:= 0
  425.