home *** CD-ROM | disk | FTP | other *** search
/ Amiga ISO Collection / AmigaUtilCD1.iso / CDRom / fotocd11.lha / src / photocdaga / EncodeHAM8.asm < prev    next >
Encoding:
Assembly Source File  |  1995-01-09  |  11.9 KB  |  293 lines

  1. ; PhotoCDAGA utility function written by Günther Röhrich
  2. ; this code is Public Domain and may be used with other programs
  3.  
  4. ;enhanced 9-Jan-1995 by Günther Röhrich:
  5.  
  6. ;when the screen is moved around errors at the left side will be much smaller
  7.  
  8. ; this version is for 68020+ processors only
  9. ; it is is called from C:
  10. ; EncodeHAM8(char *rorig, char *gorig, char *borig, char *yham, int xsize);
  11. ; rorig       = original row (red, 8 bit)
  12. ; gorig       = original row (green, 8 bit)
  13. ; borig       = original row (blue, 8 bit)
  14. ; yham        = row in HAM8 chunky format
  15. ; xsize       = size of row in pixels
  16. ; rstep       = step for red component array
  17. ; gstep       = step for green component array
  18. ; bstep       = step for blue component array
  19.  
  20.  MACHINE MC68020
  21.  
  22. ;NOTE: GCC stores all data as 32 bit at subroutine calls!
  23.  
  24. rorig        EQU 44  
  25. gorig        EQU 48
  26. borig        EQU 52  
  27. yham         EQU 56  ;pointer to actual row (HAM)
  28. xsize        EQU 60  ;number of pixels (x)
  29.  
  30.     
  31.         XREF _Mult_Table  ;address of multiplication table
  32.         XDEF _EncodeHAM8  ;entry point for function
  33.         XREF _ColorCache ;an 256K array
  34.         XREF _ColorTable ;an array with 64 colors
  35.         XREF _rstep
  36.         XREF _gstep
  37.         XREF _bstep
  38.  
  39. *       XDEF _blue_left ;only for debugging purposes
  40. *       XDEF _search_finish ;only for debugging
  41. *       XDEF _MaxError
  42. *       XDEF _MaxErrorPos 
  43. *       XDEF _hit       ;only for debugging
  44. *       XDEF _t1        ;only for debugging        
  45.  
  46.                dseg
  47.  
  48.  cnop 0,4
  49. _blue_left:      dc.b 0  ;this order is better for HAM-encoding
  50. _red_left:       dc.b 0
  51. _green_left:     dc.b 0,0 ;additional dummy-value for faster longword access
  52.  
  53.  cnop 0,2
  54. _offset_orig:   dc.w 0
  55. _offset_ham:    dc.w 0
  56. _CacheOffset    dc.l 0
  57. rcounter        dc.l 0
  58. gcounter        dc.l 0
  59. bcounter        dc.l 0
  60. _colcount       dc.w 2
  61.  
  62.         cseg
  63.  
  64. ;register usage:   D0 = general purpose register
  65. ;                  D1 = contains afterwards the error
  66. ;                  D2 = orig_blue
  67. ;                  D3 = orig_red
  68. ;                  D4 = orig_green
  69. ;                  D5 = color that should be set
  70. ;                  D6 = offset to actual pixel (HAM)
  71. ;                  D7 = offset for color table / (0,1,2) at HAM
  72. ;                  A0 = best color so far (color+1)*3
  73. ;                  A1 = pointer to multiplication table
  74. ;                  A2 = pointer to color table / to _blue_left
  75. ;                  A3 = smallest error that has been reached so far
  76. ;                  A4 = used by the Aztec assembler (small data model)
  77. ;                  A5 = not used
  78. ;                  A6 = pointer to the actual row (HAM)
  79.  
  80.  
  81.  
  82. ;computing the difference of color values is done with signed 8 bit
  83. ;arithmetic 
  84.  
  85. ;the maximum error value is 63^2+63^2+63^2=11907
  86. ;the summation has to be done therefore with 16 bits
  87.  
  88.  
  89. ;Initializing
  90. _EncodeHAM8:    movem.l D2-D7/A2-A3/A5/A6,-(A7)  ;store registers
  91.                 lea     _blue_left,A0      ;load start of left colors
  92.                 lea     _ColorTable,A2
  93.                 move.l  (A2),(A0)          ;initialize left colors
  94.                 moveq.l #0,D6              ;initialize ham offset  
  95.                 move.l  yham(sp),A6                           
  96.                 lea     _Mult_Table,A1
  97.                 lea     255*2(A1),A1              
  98. search_begin:   move.l  rcounter,D7          ;load position
  99.                 move.b  ([rorig,sp],D7.L),D3 ;load original red
  100.                 lsr.b   #2,D3
  101.                 add.l   _rstep,D7            ;add step
  102.                 move.l  D7,rcounter          ;store position
  103.                 move.l  gcounter,D7          ;load position
  104.                 move.b  ([gorig,sp],D7.L),D4 ;load original green
  105.                 lsr.b   #2,D4
  106.                 add.l   _gstep,D7            ;add step
  107.                 move.l  D7,gcounter          ;store position
  108.                 move.l  bcounter,D7          ;load position
  109.                 move.b  ([borig,sp],D7.L),D2 ;load original blue
  110.                 lsr.b   #2,D2
  111.                 add.l   _bstep,D7            ;add step
  112.                 move.l  D7,bcounter          ;store position
  113.                 move.w  #15000,A3          ;dummy-value for minimum error so far
  114.                 lea     _ColorTable,A2
  115.                 moveq.l #0,D7              ;initialize offset for color table
  116.  
  117. ;find out if the new pixel has the same color as the previous one
  118.  
  119.                 lea      _blue_left,A0
  120.                 cmp.b    (A0),D2
  121.                 bne.s    search_cont
  122.                 cmp.b    1(A0),D3
  123.                 bne.s    search_cont
  124.                 cmp.b    2(A0),D4
  125.                 bne.s    search_cont
  126.  
  127. ;the new pixel has the same color, let's do a special encoding
  128.  
  129.                 move.w   _colcount,D7
  130.                 move.b   0(A0,D7.w),D5      
  131.                 subq.w   #1,_colcount
  132.                 bpl.s    ham6_9
  133.                 move.w  #2,_colcount
  134.                 bra.s    ham6_9
  135.  
  136.  
  137. ;First take a look if we have the value already in the cache
  138. search_cont:    moveq.l  #0,D0
  139.                 moveq.l  #0,D1             
  140.                 move.b   D3,D0             ;compute the cache offset
  141.                 lsl.l    #6,D0
  142.                 or.b     D4,D0
  143.                 lsl.l    #6,D0
  144.                 or.b     D2,D0             ;now we have the offset in D0
  145.                 movea.l  _ColorCache,A0    ;load start address of the cache
  146.                 move.b   0(A0,D0.l),D1     ;take the value from the cache
  147.                 bne     _hit               ;jump if we have a cache hit
  148.                 
  149.                 move.l   D0,_CacheOffset   ;store the offset to avoid recomputing it
  150.                 move.l   #3,A0             ;dummy-value for best colornumber so far
  151.                                            ; (3 means color 0)
  152.  
  153. search_start:    bsr      _compute_error
  154.                 cmp.w    D1,A3              ;A3 <= D1 ?
  155.                 bls.s    search4
  156.                 move.w   D1,A3              ;D1 is smaller than A3, store it
  157.                 move.w   D7,A0              ;store color number     
  158.                 tst.w    D1                 ;do we have the correct color ?
  159.                 beq      search5            ;then finish immediately
  160. search4:        cmp.w    #64*3,D7            ;have we reached highest colornum ?
  161.                 bne.s    search_start       ;no, then once again                   
  162.                                         
  163. ;A0 contains now (colornumber+1)*3
  164. ;A3 contains the error for that colornumber
  165.  
  166. _t1:            move.w   A0,D0        
  167.                 movea.l  _ColorCache,A2
  168.                 move.l   _CacheOffset,D1
  169.                 move.b   D0,0(A2,D1.l)      ;store the value in the cache                
  170.                 lea      _blue_left,A2      ;restore A2
  171.  
  172. ;compute the error when using modify mode
  173.  
  174. start_ham6:     move.b   D2,D0              ;load orig_blue
  175.                 moveq.l  #0,D7              ;assume blue should be changed
  176.                 move.b   D2,D5              ;store value to change
  177.                 sub.b    _blue_left,D0      ;D0=D0-_blue_left
  178.                 bpl.s    ham6_1
  179.                 neg.b    D0                 ;make result positive
  180. ham6_1:         move.b   D0,D1              ;store maximum error so far
  181.                 move.b   D3,D0              ;load orig_red
  182.                 sub.b    _red_left,D0       ;D0=D0-_red_left
  183.                 bpl.s    ham6_2
  184.                 neg.b    D0              
  185. ham6_2:         cmp.b    D0,D1              ;check D1-D0
  186.                 bge.s    ham6_3             ;jump if D1>=D0
  187.                 move.b   D0,D1              ;store new maximum error
  188.                 moveq.l  #1,D7              ;assume red should be changed
  189.                 move.b   D3,D5              ;store value to change
  190. ham6_3:         move.b   D4,D0              ;load orig_green
  191.                 sub.b    _green_left,D0     ;D0=D0-_green_left
  192.                 bpl.s    ham6_4
  193.                 neg.b    D0
  194. ham6_4:         cmp.b    D0,D1
  195.                 bge.s    ham6_5
  196.                 move.b   D0,D1              ;store maximum error
  197.                 moveq.l  #2,D7              ;green should be changed
  198.                 move.b   D4,D5              ;store value to change
  199. ham6_5:         lea      _blue_left,A2      
  200.                 move.b   D5,0(A2,D7.W)      ;perform change
  201.  
  202. ham_error:      moveq.l  #0,D1
  203.                 moveq.l  #0,D0
  204.                 move.b   D2,D0              ;load blue_origin
  205.                 sub.b    (A2)+,D0           ;D0 = blue_color - blue_origin
  206.                 ext.w    D0
  207.                 add.w    0(A1,D0.W*2),D1
  208.                 move.b   D3,D0              ;load red_origin
  209.                 sub.b    (A2)+,D0           ;D0 = red_color - red_origin 
  210.                 ext.w    D0
  211.                 add.w    0(A1,D0.W*2),D1
  212.                 move.b   D4,D0              ;load green_origin
  213.                 sub.b    (A2)+,D0           ;D0 = green_color - green_origin
  214.                 ext.w    D0
  215.                 add.w    0(A1,D0.W*2),D1
  216.  
  217.                 cmpa.w   D1,A3              ;check what error is smaller
  218.                 bls.s    _search_finish     ;jump if colortable is better
  219. ham6_9:         add.b    #1,D7              ;needed to get correct code
  220.                 lsl.b    #6,D7              ;HAM8-adjust                               
  221.                 or.b     D5,D7
  222.                 move.b   D7,(A6,D6.W)       ;store code in bitmap
  223.  
  224.                 addq.w   #1,D6              ;increase _offset_ham
  225.                 cmp.l    xsize(sp),D6       ;end of column ?
  226.                 bne      search_begin
  227.                 bra.s    search_end
  228.                 
  229. _search_finish: move.w   A0,D0
  230.                 lea      _ColorTable,A2
  231.                 lea      -3(A2,D0.W),A3     ;load A3 with pointer to colors
  232.                 divu     #3,D0
  233.                 subq.w   #1,D0
  234.                 move.b   D0,0(A6,D6.W)      ;store colornumber in bitmap
  235.                 lea      _blue_left,A2
  236.                 move.l   (A3),(A2)
  237.                 addq.w   #1,D6              ;increase _offset_ham
  238.                 cmp.l    xsize(sp),D6       ;have we reached the end ?
  239.                 bne      search_begin
  240.  
  241. search_end:     movem.l  (A7)+,D2-D7/A2-A3/A5/A6  ;restore registers
  242.                 clr.l    rcounter
  243.                 clr.l    gcounter
  244.                 clr.l    bcounter
  245.                 rts                         ;jump back to caller
  246.                 
  247.  
  248.  
  249. ;we jump here if we have reached error 0 by colortable only
  250. ;and there was not a cache hit
  251. search5:        move.w   A0,D0         
  252.                 movea.l  _ColorCache,A2
  253.                 move.l   _CacheOffset,D1
  254.                 move.b   D0,0(A2,D1.l)      ;store the value in the cache                
  255.                 bra.s    _search_finish
  256.  
  257.  
  258. ;we jump here if we have a cache hit
  259. ;D1 contains the best color number, but we have to compute the error
  260.  
  261. _hit:           subq.w   #3,D1              ;correct color number
  262.                 move.w   D1,D7
  263.                 bsr.s    _compute_error
  264.         move.w   D1,A3              ;D1 is smaller than A3, store it
  265.                 move.w   D7,A0              ;store color number     
  266.                 bra      start_ham6         ;continue with HAM encoding
  267.  
  268.  
  269. ;compute the error
  270.  
  271. _compute_error: moveq.l  #0,D1
  272.                 moveq.l  #0,D0             
  273.                 move.b   D2,D0              ;load blue_origin
  274.                 sub.b    0(A2,D7.W),D0      ;D0 = blue_color - blue_origin
  275.                 ext.w    D0                 ;extend result to word
  276.                 add.w    0(A1,D0.W*2),D1
  277.                 addq.w   #1,D7              ;advance color table offset
  278.                 move.b   D3,D0              ;load red_origin
  279.                 sub.b    0(A2,D7.W),D0      ;D0 = red_color - red_origin
  280.                 ext.w    D0
  281.                 add.w    0(A1,D0.W*2),D1
  282.                 addq.w   #1,D7              ;advance color table offset
  283.                 move.b   D4,D0              ;load green_origin
  284.                 sub.b    0(A2,D7.W),D0      ;D0 = green_color - green_origin
  285.                 ext.w    D0
  286.                 add.w    0(A1,D0.W*2),D1  ;D1 = D1 + D0*D0
  287.                 addq.w   #1,D7              ;advance color table offset
  288.         rts
  289.  
  290.                 
  291.  
  292.  
  293.