home *** CD-ROM | disk | FTP | other *** search
/ ARM Club 3 / TheARMClub_PDCD3.iso / hensa / graphics / randjpeg_1 / source / s / mapchangefsi
Text File  |  1996-01-21  |  6KB  |  188 lines

  1. ; mapchangefsi.s
  2. ; MACHINE:     RISC OS
  3. ; LANGUAGE:    OBJASM assembler
  4. ; AUTHOR:      Cy Booker, cy@cheepnis.demon.co.uk
  5. ; LICENSE:     FreeWare, Copyright (c) Cy Booker 1996
  6. ; PURPOSE:     Given an arbitary 48-bit colour, what is the closest 8-bit colour number?
  7. ;              assuming the default 256 colour palette
  8. ;
  9. ; Note the algorithm used is based on the one inside Acorns' ChangeFSI
  10. ; but modified slightly by me to be faster and more accurate
  11. ;
  12. ; ChangeFSI's algorithm is the same as the one posted to UseNet
  13. ;
  14. ;       Message-ID: <12463@acorn.co.uk>
  15. ;       Date: 30 Jan 92 12:20:23 GMT
  16. ;       From: RWilson@acorn.co.uk
  17. ;       Subject: How to find the closest colour out of the RISC OS 256
  18. ;
  19. ; And so I hereby acknowledge that I'm using their spiffy code
  20. ;
  21. ; in middle we have |intensity-difference| <-- 0x3fff
  22. ; so |i|^2 <= 0x0fff8001
  23. ; and so |d|^2 <= 3.|i|^2 <= 0x2ffe8003
  24. ; so total scale must be < 2^32/(|d|^2) , ie < ~5
  25. ; but this does not leave enough accuracy really, so we shift by a bit
  26. ;
  27. ; the weights we want are:
  28. ;       Red     * 0.212671   * 14 ~=  3 / 4 ~= 0x0.c
  29. ;       Green   * 0.715160   * 14 ~= 10 / 4 ~= 0x2.8
  30. ;       Blue    * 0.072169   * 14 ~=  1 / 4 ~= 0x0.4
  31. ;
  32. ; note we will divide by 4 to ensure total < 2^32
  33. ; (ie 0x3fff*0x3fff*3*14/2 < 2^32)
  34. ;
  35.  
  36.  
  37.         GET     OS:Hdr.os
  38.  
  39. ;
  40.  
  41.         EXPORT  map_scaled_rgb_to_8bpp_colour_number_changefsi
  42.         IMPORT  default_wimp_palette_as_tuples
  43.  
  44.         AREA |ARM$$code|, CODE, READONLY
  45.  
  46.         ROUT
  47.  
  48. ;
  49. ; In    R0 -> structure
  50. ;       R1 = red nominally [0, 0xffff], but clipped as necessary
  51. ;       R2 = green nominally [0, 0xffff], but clipped as necessary
  52. ;       R3 = blue nominally [0, 0xffff], but clipped as necessary
  53. ; Out   R0 <-- palette entry %BGgRbrTt (bits 8-31 are zero)
  54. ;       structure[0] = error in approximating red intensity
  55. ;       structure[1] = error in approximating green intensity
  56. ;       structure[2] = error in approximating blue intensity
  57. ;
  58.  
  59.         ROUT
  60.  
  61. map_scaled_rgb_to_8bpp_colour_number_changefsi
  62.  
  63. str     RN      a1
  64. red     RN      a2
  65. grn     RN      a3
  66. blu     RN      a4
  67. tint    RN      v1
  68. dmin    RN      v2
  69. dist    RN      v3
  70. colour  RN      v4
  71. best    RN      v5
  72. mtint   RN      v6
  73. x       RN      ip
  74. y       RN      lr
  75.  
  76. dr      RN      tint
  77. dg      RN      dmin
  78. db      RN      dist
  79.  
  80. bits    * 16                    ; the inline weighting functions assume bits <= 16
  81.  
  82.         STMFD   sp!, {v1-v6, lr}
  83.         MOV     lr, #1 << bits
  84.         CMP     red, lr                              ; ensure in range [0, 0xffff]
  85.         MOVHS   red, #0
  86.         SUBGE   red, lr, #1
  87.         CMP     grn, lr
  88.         MOVHS   grn, #0
  89.         SUBGE   grn, lr, #1
  90.         CMP     blu, lr
  91.         MOVHS   blu, #0
  92.         SUBGE   blu, lr, #1
  93. ;
  94.         MOV     dmin, #&ffffffff
  95.         MOV     tint, #&30 << 23
  96. 0
  97.         RSB     mtint, tint, #&20 << 23
  98.  
  99.         SUB     y, blu, blu, LSR #4                     ; y ~= blu * 16 / 17
  100.         ADDS    x, mtint, y, LSL #31 - bits
  101.         MOVVSS  x, #&c0 << 23
  102.         MOVMI   x, #0
  103.         AND     x, x, #&c0 << 23                        ; %0Bb0 0000 0000 0000 0000 0000 0000 0000
  104.         ADD     x, x, tint                              ; %0BbT t000 0000 0000 0000 0000 0000 0000
  105.         ADD     colour, x, x, LSR #4                    ; colour = blu << 23
  106.         [ bits > 8
  107.         ADD     x, colour, colour, LSR #8               ; %0BbT tBbT tBbT tBbT t000 0000 0000 0000
  108.         [ bits > 16
  109.         ADD     x, x, x, LSR #16                        ; %0BbT tBbT tBbT tBbT tBbT tBbT tBbT tBbT
  110.         ]
  111.         ]
  112.         SUBS    y, blu, x, LSR #31 - bits               ; bug in changefsi here!
  113.         RSBLT   y, y, #0                                ; speeds up MUL instruction
  114.  
  115.         MUL     dist, y, y                              ; dist = blu * 0x1.0
  116.  
  117.         SUB     y, grn, grn, LSR #4
  118.         ADDS    x, mtint, y, LSL #31 - bits
  119.         MOVVSS  x, #&c0 << 23
  120.         MOVMI   x, #0
  121.         AND     x, x, #&c0 << 23
  122.         ADD     x, tint, x
  123.         ADD     x, x, x, LSR #4
  124.         ORR     colour, colour, x, LSR #8               ; colour |= grn << 15
  125.         [ bits > 8
  126.         ADD     x, x, x, LSR #8
  127.         [ bits > 16
  128.         ADD     x, x, x, LSR #16
  129.         ]
  130.         ]
  131.         SUBS    y, grn, x, LSR #31 - bits
  132.         RSBLT   y, y, #0
  133.  
  134.         MUL     x, y, y
  135.         MOV     x, x, LSL #1
  136.         ADD     dist, x, dist, LSR #2                   ; dist = blu * 0x0.4 + grn * 0x2.0
  137.         ADD     dist, dist, x, LSR #3                   ; dist = blu * 0x0.4 + grn * 0x2.8
  138.  
  139.         SUB     y, red, red, LSR #4
  140.         ADDS    x, mtint, y, LSL #31 - bits
  141.         MOVVSS  x, #&c0 << 23
  142.         MOVMI   x, #0
  143.         AND     x, x, #&c0 << 23
  144.         ADD     x, tint, x
  145.         ADD     x, x, x, LSR #4
  146.         ORR     colour, colour, x, LSR #16              ; colour |= red << 7
  147.         [ bits > 8
  148.         ADD     x, x, x, LSR #8
  149.         [ bits > 16
  150.         ADD     x, x, x, LSR #16
  151.         ]
  152.         ]
  153.         SUBS    y, red, x, LSR #31 - bits
  154.         RSBLT   y, y, #0
  155.  
  156.         MULNE   x, y, y
  157.         ADDNE   dist, dist, x, LSR #2                   ; dist = blu * 0x0.4 + grn * 0x2.8 + red * 0x0.4
  158.         ADDNE   dist, dist, x, LSR #1                   ; dist = blu * 0x0.4 + grn * 0x2.8 + red * 0x0.c
  159.  
  160.         CMP     dist, dmin
  161.         MOVLS   dmin, dist
  162.         MOVLS   best, colour
  163.  
  164.         SUBS    tint, tint, #&10 << 23
  165.         BGE     %BT0
  166.  
  167.         MOVS    x, best, LSR #11
  168.         AND     x, x, #&07                              ; x= %00000rTt
  169.         ORRCS   x, x, #&10                              ; x= %000R0rTt
  170.         MOVS    y, best, LSL #2
  171.         ORRCS   x, x, #&80                              ; x= %B00R0rTt
  172.         ORRMI   x, x, #&08                              ; x= %B00RbrTt
  173.         ANDS    y, best, #&c0 << 15
  174.         ORRNE   x, x, y, LSR #16                        ; y= %BGgRbrTt
  175.  
  176.         LDR     y, =default_wimp_palette_as_tuples
  177.         ADD     y, y, x, LSL #2
  178.         ADD     y, y, x, LSL #3
  179.         LDMIA   y, {dr, dg, db}
  180.         SUB     red, red, dr
  181.         SUB     grn, grn, dg
  182.         SUB     blu, blu, db
  183.         STMIA   str, {red, grn, blu}                    ; store error
  184.         MOV     a1, x
  185.         LDMFD   sp!, {v1-v6, pc}^
  186.  
  187.   END
  188.