home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 5 / FreshFish_July-August1994.bin / bbs / gfx / jpegaga-1.0.lha / jpegAGA-1.0 / EncodeHAM8.asm < prev    next >
Assembly Source File  |  1994-05-28  |  11KB  |  254 lines

  1. ; jpegAGA utility function written by Günther Röhrich
  2. ; this code is Public Domain and may be used with other programs
  3.  
  4. ; this version is for 68020+ processors only
  5. ; it is is called from C:
  6. ; EncodeHAM8(char *rorig, char *gorig, char *borig, char *yham, int xsize);
  7. ; rorig       = original row (red, 8 bit)
  8. ; gorig       = original row (green, 8 bit)
  9. ; borig       = original row (blue, 8 bit)
  10. ; yham        = row in HAM8 chunky format
  11. ; xsize       = size of row in pixels
  12.  
  13.  
  14.  MACHINE MC68020
  15.  
  16. ;NOTE: GCC stores all data as 32 bit at subroutine calls!
  17.  
  18. rorig        EQU 44  
  19. gorig        EQU 48
  20. borig        EQU 52  
  21. yham         EQU 56  ;pointer to actual row (HAM)
  22. xsize        EQU 60  ;number of pixels (x)
  23.  
  24.     
  25.         XREF _Mult_Table  ;address of multiplication table
  26.         XDEF _EncodeHAM8  ;entry point for function
  27.         XREF _ColorCache ;an 256K array
  28.         XREF _ColorTable ;an array with 64 colors
  29.  
  30. *       XDEF _blue_left ;only for debugging purposes
  31. *       XDEF _search_finish ;only for debugging
  32. *       XDEF _MaxError
  33. *       XDEF _MaxErrorPos 
  34. *       XDEF _hit       ;only for debugging
  35. *       XDEF _t1        ;only for debugging        
  36.  
  37.                dseg
  38.  
  39.  cnop 0,4
  40. _blue_left:      dc.b 0  ;this order is better for HAM-encoding
  41. _red_left:       dc.b 0
  42. _green_left:     dc.b 0,0 ;additional dummy-value for faster longword access
  43.  
  44.  cnop 0,2
  45. _offset_orig:   dc.w 0
  46. _offset_ham:    dc.w 0
  47. _CacheOffset    dc.l 0
  48. xcounter        dc.w 0
  49.  
  50.  
  51.         cseg
  52.  
  53. ;register usage:   D0 = general purpose register
  54. ;                  D1 = contains afterwards the error
  55. ;                  D2 = orig_blue
  56. ;                  D3 = orig_red
  57. ;                  D4 = orig_green
  58. ;                  D5 = color that should be set
  59. ;                  D6 = offset to actual pixel (HAM)
  60. ;                  D7 = offset for color table / (0,1,2) at HAM
  61. ;                  A0 = best color so far (color+1)*3
  62. ;                  A1 = pointer to multiplication table
  63. ;                  A2 = pointer to color table / to _blue_left
  64. ;                  A3 = smallest error that has been reached so far
  65. ;                  A4 = used by the Aztec assembler (small data model)
  66. ;                  A5 = not used
  67. ;                  A6 = pointer to the actual row (HAM)
  68.  
  69.  
  70.  
  71. ;computing the difference of color values is done with signed 8 bit
  72. ;arithmetic 
  73.  
  74. ;the maximum error value is 63^2+63^2+63^2=11907
  75. ;the summation has to be done therefore with 16 bits
  76.  
  77.  
  78. ;Initializing
  79. _EncodeHAM8:    movem.l D2-D7/A2-A3/A5/A6,-(A7)  ;store registers
  80.                 lea     _blue_left,A0      ;load start of left colors
  81.                 lea     _ColorTable,A2
  82.                 move.l  (A2),(A0)          ;initialize left colors
  83.                 moveq.l #0,D6              ;initialize ham offset  
  84.                 move.l  yham(sp),A6                           
  85.                 lea     _Mult_Table,A1
  86.                 lea     255*2(A1),A1              
  87. search_begin:   move.w  xcounter,D7
  88.                 move.b  ([rorig,sp],D7.W),D3 ;load original red
  89.                 lsr.b   #2,D3
  90.                 move.b  ([gorig,sp],D7.W),D4 ;load original green
  91.                 lsr.b   #2,D4
  92.                 move.b  ([borig,sp],D7.W),D2 ;load original blue
  93.                 lsr.b   #2,D2
  94.                 addq.w  #1,D7
  95.                 move.w  D7,xcounter
  96.                 move.w  #15000,A3          ;dummy-value for minimum error so far
  97.                 lea     _ColorTable,A2
  98.                 moveq.l #0,D7              ;initialize offset for color table
  99.  
  100. ;First take a look if we have the value already in the cache
  101.         moveq.l  #0,D0
  102.                 moveq.l  #0,D1             
  103.                 move.b   D3,D0             ;compute the cache offset
  104.                 lsl.l    #6,D0
  105.                 or.b     D4,D0
  106.                 lsl.l    #6,D0
  107.                 or.b     D2,D0             ;now we have the offset in D0
  108.                 movea.l  _ColorCache,A0    ;load start address of the cache
  109.                 move.b   0(A0,D0.l),D1     ;take the value from the cache
  110.                 bne     _hit               ;jump if we have a cache hit
  111.                 
  112.                 move.l   D0,_CacheOffset   ;store the offset to avoid recomputing it
  113.                 move.l   #3,A0             ;dummy-value for best colornumber so far
  114.                                            ; (3 means color 0)
  115.  
  116. search_start:    bsr      _compute_error
  117.                 cmp.w    D1,A3              ;A3 <= D1 ?
  118.                 bls.s    search4
  119.                 move.w   D1,A3              ;D1 is smaller than A3, store it
  120.                 move.w   D7,A0              ;store color number     
  121.                 tst.w    D1                 ;do we have the correct color ?
  122.                 beq      search5            ;then finish immediately
  123. search4:        cmp.w    #64*3,D7            ;have we reached highest colornum ?
  124.                 bne.s    search_start       ;no, then once again                   
  125.                                         
  126. ;A0 contains now (colornumber+1)*3
  127. ;A3 contains the error for that colornumber
  128.  
  129. _t1:            move.w   A0,D0        
  130.                 movea.l  _ColorCache,A2
  131.                 move.l   _CacheOffset,D1
  132.                 move.b   D0,0(A2,D1.l)      ;store the value in the cache                
  133.                 lea      _blue_left,A2      ;restore A2
  134.  
  135. ;compute the error when using modify mode
  136.  
  137. start_ham6:     move.b   D2,D0              ;load orig_blue
  138.                 moveq.l  #0,D7              ;assume blue should be changed
  139.                 move.b   D2,D5              ;store value to change
  140.                 sub.b    _blue_left,D0      ;D0=D0-_blue_left
  141.                 bpl.s    ham6_1
  142.                 neg.b    D0                 ;make result positive
  143. ham6_1:         move.b   D0,D1              ;store maximum error so far
  144.                 move.b   D3,D0              ;load orig_red
  145.                 sub.b    _red_left,D0       ;D0=D0-_red_left
  146.                 bpl.s    ham6_2
  147.                 neg.b    D0              
  148. ham6_2:         cmp.b    D0,D1              ;check D1-D0
  149.                 bge.s    ham6_3             ;jump if D1>=D0
  150.                 move.b   D0,D1              ;store new maximum error
  151.                 moveq.l  #1,D7              ;assume red should be changed
  152.                 move.b   D3,D5              ;store value to change
  153. ham6_3:         move.b   D4,D0              ;load orig_green
  154.                 sub.b    _green_left,D0     ;D0=D0-_green_left
  155.                 bpl.s    ham6_4
  156.                 neg.b    D0
  157. ham6_4:         cmp.b    D0,D1
  158.                 bge.s    ham6_5
  159.                 move.b   D0,D1              ;store maximum error
  160.                 moveq.l  #2,D7              ;green should be changed
  161.                 move.b   D4,D5              ;store value to change
  162. ham6_5:         lea      _blue_left,A2      
  163.                 move.b   D5,0(A2,D7.W)      ;perform change
  164.  
  165. ham_error:      moveq.l  #0,D1
  166.                 moveq.l  #0,D0
  167.                 move.b   D2,D0              ;load blue_origin
  168.                 sub.b    (A2)+,D0           ;D0 = blue_color - blue_origin
  169.                 ext.w    D0
  170.                 add.w    0(A1,D0.W*2),D1
  171.                 move.b   D3,D0              ;load red_origin
  172.                 sub.b    (A2)+,D0           ;D0 = red_color - red_origin 
  173.                 ext.w    D0
  174.                 add.w    0(A1,D0.W*2),D1
  175.                 move.b   D4,D0              ;load green_origin
  176.                 sub.b    (A2)+,D0           ;D0 = green_color - green_origin
  177.                 ext.w    D0
  178.                 add.w    0(A1,D0.W*2),D1
  179.  
  180.                 cmpa.w   D1,A3              ;check what error is smaller
  181.                 bls.s    _search_finish     ;jump if colortable is better
  182. ham6_9:         add.b    #1,D7              ;needed to get correct code
  183.                 lsl.b    #6,D7              ;HAM8-adjust                               
  184.                 or.b     D5,D7
  185.                 move.b   D7,(A6,D6.W)       ;store code in bitmap
  186.  
  187.                 addq.w   #1,D6              ;increase _offset_ham
  188.                 cmp.l    xsize(sp),D6       ;end of column ?
  189.                 bne      search_begin
  190.                 bra.s    search_end
  191.                 
  192. _search_finish: move.w   A0,D0
  193.