sistema_progs

Programas para customizar o meu entorno de traballo nos meus equipos persoais
Log | Files | Refs

colorglass.bash (11253B)


      1 # bash
      2 
      3 bleopt/declare -v colorglass_gamma 0
      4 bleopt/declare -v colorglass_contrast 0
      5 bleopt/declare -v colorglass_rotate 0
      6 bleopt/declare -v colorglass_saturation 0
      7 bleopt/declare -v colorglass_brightness 0
      8 bleopt/declare -v colorglass_alpha 255
      9 bleopt/declare -v colorglass_color 0x8888FF
     10 #bleopt/declare -v colorglass_color   0xFF8888
     11 
     12 function bleopt/check:colorglass_gamma {
     13   if ! ((value=value,value>-100)); then
     14     ble/util/print "bleopt colorglass_gamma: invalid value '$value'" >&2
     15     return 1
     16   fi
     17   ble/color/g2sgr/.clear-cache
     18   _ble_contrib_colorglass_gamma=()
     19   return 0
     20 }
     21 function bleopt/check:colorglass_contrast {
     22   if ! ((value=value,-100<=value&&value<=100)); then
     23     ble/util/print "bleopt colorglass_contrast: invalid value '$value'" >&2
     24     return 1
     25   fi
     26   ble/color/g2sgr/.clear-cache
     27   _ble_contrib_colorglass_contrast=()
     28   return 0
     29 }
     30 function bleopt/check:colorglass_rotate {
     31   ((value=value%360,value<0&&(value+=360)))
     32   ble/color/g2sgr/.clear-cache
     33   return 0
     34 }
     35 function bleopt/check:colorglass_saturation {
     36   if ! ((value=value,-100<=value&&value<=100)); then
     37     ble/util/print "bleopt colorglass_saturation: invalid value '$value'" >&2
     38     return 1
     39   fi
     40   ble/color/g2sgr/.clear-cache
     41   return 0
     42 }
     43 function bleopt/check:colorglass_brightness {
     44   if ! ((value=value,-100<=value&&value<=100)); then
     45     ble/util/print "bleopt colorglass_brightness: invalid value '$value'" >&2
     46     return 1
     47   fi
     48   ble/color/g2sgr/.clear-cache
     49   return 0
     50 }
     51 function bleopt/check:colorglass_color {
     52   ble/color/g2sgr/.clear-cache
     53   return 0
     54 }
     55 function bleopt/check:colorglass_alpha { ble/color/g2sgr/.clear-cache; return 0; }
     56 
     57 bleopt -I colorglass_@
     58 
     59 _ble_contrib_colorglass_gamma=()
     60 function ble/contrib/colorglass/.gamma {
     61   local x=$1
     62   ret=${_ble_contrib_colorglass_gamma[x]-}
     63   [[ $ret ]] && return 0
     64   local g=$(((100+bleopt_colorglass_gamma)*_ble_fixed_unit/100))
     65   ble/fixed-point#pow "$((x*_ble_fixed_unit/255))" "$g"
     66   ble/fixed-point#round "$((ret*255))"
     67   ((ret=ret/_ble_fixed_unit,ret<0?(ret=0):(ret>255&&(ret=255))))
     68   _ble_contrib_colorglass_gamma[x]=$ret
     69 }
     70 
     71 _ble_contrib_colorglass_contrast=()
     72 function ble/contrib/colorglass/.contrast {
     73   local x=$1
     74   ret=${_ble_contrib_colorglass_contrast[x]-}
     75   [[ $ret ]] && return 0
     76 
     77   local c=$bleopt_colorglass_contrast
     78   if ((c==-100)); then
     79     ((ret=x==0?-_ble_fixed_unit:(x==255?_ble_fixed_unit:0)))
     80   else
     81     if ((c>0)); then
     82       ((c=_ble_fixed_unit-c*_ble_fixed_unit/100))
     83     else
     84       ((c=_ble_fixed_unit*_ble_fixed_unit/(_ble_fixed_unit+c*_ble_fixed_unit/100)))
     85     fi
     86     ble/fixed-point#pow "$((2*x*_ble_fixed_unit/255-_ble_fixed_unit))" "$c"
     87   fi
     88   ble/fixed-point#round "$(((ret+_ble_fixed_unit)*255/2))"
     89   ((ret=ret/_ble_fixed_unit,ret<0?(ret=0):(ret>255&&(ret=255))))
     90   _ble_contrib_colorglass_contrast[x]=$ret
     91 }
     92 
     93 ## @fn ble/contrib/colorglass.filter
     94 ##   @var[ref] ccode
     95 function ble/contrib/colorglass.filter {
     96   # 24bit color
     97   local R= G= B= dirty=
     98   if ((ccode<16)); then
     99     if ((ccode==7)); then
    100       ((R=G=B=0xAA))
    101     elif ((ccode==8)); then
    102       ((R=G=B=0x55))
    103     else
    104       local L=$((ccode>=8?0xFF:0x80))
    105       ((R=(ccode&1)?L:0))
    106       ((G=(ccode&2)?L:0))
    107       ((B=(ccode&4)?L:0))
    108     fi
    109   elif ((ccode<256)); then
    110     local index_colors=$_ble_color_index_colors_default
    111     [[ $bleopt_term_index_colors == auto ]] || ((index_colors=bleopt_term_index_colors))
    112     if ((index_colors==88)); then
    113       # xterm-88color (16+4x4x4+8grey)
    114       if ((ccode>=80)); then
    115         ((R=G=B=46+25*(ccode-80)))
    116       else
    117         local k
    118         ((k=(ccode-16)/16 ,R=k?81+k*58:0))
    119         ((k=(ccode-16)/4%4,G=k?81+k*58:0))
    120         ((k=(ccode-16)%4  ,B=k?81+k*58:0))
    121       fi
    122     else
    123       # xterm-256color (16+6x6x6+24grey)
    124       if ((ccode>=232)); then
    125         ((R=G=B=8+10*(ccode-232)))
    126       else
    127         local k
    128         ((k=(ccode-16)/36 ,R=k?55+k*40:0))
    129         ((k=(ccode-16)/6%6,G=k?55+k*40:0))
    130         ((k=(ccode-16)%6  ,B=k?55+k*40:0))
    131       fi
    132     fi
    133   elif ((0x1000000<=ccode&&ccode<=0x1FFFFFF)); then
    134     ((R=0xFF&ccode>>16))
    135     ((G=0xFF&ccode>>8))
    136     ((B=0xFF&ccode))
    137   fi
    138 
    139   local rot=$((bleopt_colorglass_rotate))
    140   local sat=$((bleopt_colorglass_saturation))
    141   local bright=$((bleopt_colorglass_brightness))
    142   if ((rot||sat||bright)); then
    143     dirty=1
    144     local Min x y h
    145     case $((R<=B?(R<=G?0:1):(G<=B?1:2))) in
    146     (0) Min=$R x=$((G-Min)) y=$((B-Min)) h=1200 ;;
    147     (1) Min=$G x=$((B-Min)) y=$((R-Min)) h=2400 ;;
    148     (2) Min=$B x=$((R-Min)) y=$((G-Min)) h=0 ;;
    149     esac
    150     local Range=$((x>y?x:y))
    151     if ((Range)); then
    152       if ((x>y)); then
    153         ((h+=y*600/x))
    154       else
    155         ((h+=1200-x*600/y))
    156       fi
    157     fi
    158     ((h=(h+rot*10)%3600))
    159 
    160     if ((bright)); then
    161       ((bright=_ble_fixed_unit*bright/100))
    162       if ((bright<0)); then
    163         ((bright=_ble_fixed_unit+bright))
    164         ((Min=Min*bright/_ble_fixed_unit))
    165         ((Range=Range*bright/_ble_fixed_unit))
    166       else
    167         ((bright=_ble_fixed_unit-bright))
    168         ((Min=255-(255-Min)*bright/_ble_fixed_unit))
    169         ((Range=Range*bright/_ble_fixed_unit))
    170       fi
    171     fi
    172 
    173     if ((sat)); then
    174       ((sat=_ble_fixed_unit*sat/100))
    175       if ((sat<0)); then
    176         ((sat=-sat))
    177         ((Min+=Range*sat/(2*_ble_fixed_unit)))
    178         ((Range=Range*(_ble_fixed_unit-sat)/_ble_fixed_unit))
    179       else
    180         local delta=$(((255-Range)*sat/_ble_fixed_unit)) Max
    181         ((Max=Min+Range+delta/2,Max>255&&(Max=255)))
    182         ((Min-=delta/2,Min<0&&(Min=0)))
    183         ((Range=Max-Min))
    184       fi
    185     fi
    186 
    187     local h1 h2 x=$Min y=$Min z=$Min
    188     ((h1=h%1200,h2=1200-h1,
    189       x+=Range*(h2<600?h2:600)/600,
    190       y+=Range*(h1<600?h1:600)/600))
    191     case $((h/1200)) in
    192     (0) R=$x G=$y B=$z ;;
    193     (1) R=$z G=$x B=$y ;;
    194     (2) R=$y G=$z B=$x ;;
    195     esac
    196   fi
    197 
    198   local alpha=$((bleopt_colorglass_alpha))
    199   if ((alpha!=255)); then
    200     dirty=1
    201     local min max ofac
    202     if ((R<G)); then
    203       ((min=R<B?R:B,max=G>B?G:B))
    204     else
    205       ((min=G<B?G:B,max=R>B?R:B))
    206     fi
    207     ((ofac=max<255-min?max:255-min))
    208     ((ofac=ofac*2<255?ofac*2:255))
    209     ((alpha=alpha*ofac/255))
    210     if ((alpha)); then
    211       local c1=$((bleopt_colorglass_color))
    212       local r1=$((0xFF&c1>>16))
    213       local g1=$((0xFF&c1>>8))
    214       local b1=$((0xFF&c1))
    215       ((R=r1+(R-r1)*alpha/255))
    216       ((G=g1+(G-g1)*alpha/255))
    217       ((B=b1+(B-b1)*alpha/255))
    218     fi
    219   fi
    220 
    221   if ((bleopt_colorglass_contrast)); then
    222     dirty=1
    223     local ret
    224     ble/contrib/colorglass/.contrast "$R"; R=$ret
    225     ble/contrib/colorglass/.contrast "$G"; G=$ret
    226     ble/contrib/colorglass/.contrast "$B"; B=$ret
    227   fi
    228 
    229   if ((bleopt_colorglass_gamma)); then
    230     dirty=1
    231     local ret
    232     ble/contrib/colorglass/.gamma "$R"; R=$ret
    233     ble/contrib/colorglass/.gamma "$G"; G=$ret
    234     ble/contrib/colorglass/.gamma "$B"; B=$ret
    235   fi
    236 
    237   ((dirty)) && ((ccode=0x1000000|R<<16|G<<8|B))
    238   return 0
    239 }
    240 _ble_color_color2sgr_filter=ble/contrib/colorglass.filter
    241 
    242 _ble_fixed_unit=0x10000
    243 _ble_fixed_e=$((0x2b7e1))
    244 _ble_fixed_ln2=$((0xb172))
    245 _ble_fixed_log2=$((0x4d10))
    246 
    247 function ble/fixed-point#tostr {
    248   ret=$1
    249   ((ret=(ret*1000000+5)/(_ble_fixed_unit*10)))
    250   ret=0000$ret
    251   ret=${ret::${#ret}-5}.${ret:${#ret}-5}
    252   ble/string#match "$ret" '^0+' &&
    253     ret=${ret:${#BASH_REMATCH}}
    254   ret=${ret/#./0.}
    255 }
    256 
    257 function ble/fixed-point#round {
    258   local x=$1
    259   ((ret=(x+_ble_fixed_unit/2)/_ble_fixed_unit*_ble_fixed_unit))
    260 }
    261 
    262 function ble/fixed-point#mul {
    263   if (($#)); then
    264     ret=$1; shift
    265     local a
    266     for a; do ((ret=ret*a/_ble_fixed_unit)); done
    267   else
    268     ret=$_ble_fixed_unit
    269   fi
    270 }
    271 
    272 _ble_fixed_sqrt=()
    273 function ble/fixed-point#sqrt {
    274   local x=$1
    275   if ((x<=0)); then
    276     ret=0
    277   elif [[ ${_ble_fixed_sqrt[x]} ]]; then
    278     ret=${_ble_fixed_sqrt[x]}
    279   else
    280     local y=$x c=0 dy
    281     while ((c++<=16&&(dy=(x*_ble_fixed_unit-y*y)/(2*y)))); do
    282       ((y+=dy))
    283     done
    284 
    285     # 微修正
    286     local res=$((x*_ble_fixed_unit-y*y))
    287     if ((res<0)); then
    288       while ((res+y<=0)); do
    289         ((res+=2*y---1))
    290       done
    291     elif ((res>0)); then
    292       while ((0<res-y)); do
    293         ((res-=2*y+++1))
    294       done
    295     fi
    296 
    297     ret=$y
    298     _ble_fixed_sqrt[x]=$ret
    299   fi
    300 }
    301 
    302 function ble/fixed-point#pow {
    303   local x=$1 y=$2 out=$_ble_fixed_unit sgn=1
    304   if ((x==0)); then
    305     ret=0
    306     return 0
    307   elif ((x<0)); then
    308     ((x=-x,sgn=-1))
    309   fi
    310 
    311   if ((x!=_ble_fixed_unit)); then
    312     local p xx fac
    313     if ((p=y/_ble_fixed_unit)); then
    314       xx=$x fac=()
    315       while ((p&1)) && ble/array#push fac "$xx"; ((p>>=1)); do
    316         ((xx=xx*xx/_ble_fixed_unit))
    317       done
    318       ((x>_ble_fixed_unit)) && ble/array#reverse fac
    319       ble/fixed-point#mul "${fac[@]}"
    320       ((out=out*ret/_ble_fixed_unit))
    321     fi
    322 
    323     if ((p=y&0xFFFF)); then
    324       xx=$x fac=()
    325       while
    326         ble/fixed-point#sqrt "$xx"
    327         xx=$ret
    328         (((p<<=1)&_ble_fixed_unit)) && ble/array#push fac "$xx"
    329         ((p&0xFFFF))
    330       do :; done
    331       ((x<_ble_fixed_unit)) && ble/array#reverse fac
    332       ble/fixed-point#mul "${fac[@]}"
    333       ((out=out*ret/_ble_fixed_unit))
    334     fi
    335   fi
    336   ((ret=out*sgn))
    337 }
    338 function ble/fixed-point#exp {
    339   ble/fixed-point#pow "$_ble_fixed_e" "$1"
    340 }
    341 
    342 function ble/fixed-point#lb {
    343   local x=$1
    344   ((x<0&&(x=-x)))
    345   if ((x==0)); then
    346     ((ret=-32*_ble_fixed_unit))
    347   elif ((x==_ble_fixed_unit)); then
    348     ret=0
    349   else
    350     local p=0
    351     if ((x>=_ble_fixed_unit)); then
    352       while ((x>=256*_ble_fixed_unit)); do ((p+=8,x>>=8)); done
    353       while ((x>=8*_ble_fixed_unit)); do ((p+=3,x>>=3)); done
    354       while ((x>=2*_ble_fixed_unit)); do ((p+=1,x>>=1)); done
    355     else
    356       while ((x<256)); do ((p-=8,x<<=8)); done
    357       while ((x<_ble_fixed_unit/8)); do ((p-=3,x<<=3)); done
    358       while ((x<_ble_fixed_unit)); do ((p--,x<<=1)); done
    359     fi
    360     local out=$((p*_ble_fixed_unit))
    361 
    362     local bit=$_ble_fixed_unit l
    363     ((ret=2*_ble_fixed_unit))
    364     for l in {1..8}; do
    365       ((bit/=2))
    366       ble/fixed-point#sqrt "$ret"
    367       ((x>=ret)) && ((x=x*_ble_fixed_unit/ret,out+=bit))
    368     done
    369     ((x-=_ble_fixed_unit))
    370     ((out+=(_ble_fixed_unit-x/2)*x/_ble_fixed_unit*_ble_fixed_unit/_ble_fixed_ln2))
    371     ret=$out
    372   fi
    373 }
    374 function ble/fixed-point#ln {
    375   ble/fixed-point#lb "$1"
    376   ((ret=ret*_ble_fixed_ln2/_ble_fixed_unit))
    377 }
    378 function ble/fixed-point#log {
    379   ble/fixed-point#lb "$1"
    380   ((ret=ret*_ble_fixed_log2/_ble_fixed_unit))
    381 }
    382 
    383 # --- test codes ---
    384 
    385 # ble/fixed-point#lb "$((e=2718281828*_ble_fixed_unit/1000000000))"
    386 # printf "lb e = %x\n" "$ret"
    387 # ble/fixed-point#tostr "$((_ble_fixed_unit*_ble_fixed_unit/ret))"
    388 # echo "ln 2 = $ret"
    389 # ble/fixed-point#log "$((2*_ble_fixed_unit))"
    390 # ble/fixed-point#tostr "$ret"
    391 # echo "$ret"
    392 
    393 # ble/fixed-point#sqrt $((0x0100))
    394 # time for a in {0..256}; do
    395 #   ble/fixed-point#sqrt "$((a*_ble_fixed_unit/256))"
    396 #   sqrt[a]=$ret
    397 #   # ble/fixed-point#tostr "$((ret*ret*256/_ble_fixed_unit))"
    398 #   # printf "$a -> %x -> $ret\n" "$sqrt"
    399 # done
    400 # ble/fixed-point#pow $((2*_ble_fixed_unit)) $((3*_ble_fixed_unit))
    401 # ble/fixed-point#tostr "$ret"
    402 # echo "$ret"
    403 # ble/fixed-point#pow $((2*_ble_fixed_unit)) $((_ble_fixed_unit/2))
    404 # ble/fixed-point#tostr "$ret"
    405 # echo "$ret"
    406 
    407 # for x in {0..256}; do
    408 #   for y in {0..256}; do
    409 #     ble/fixed-point#pow "$((x*256))" "$((y*256))"
    410 #     ble/fixed-point#tostr "$ret"
    411 #     echo "$x $y $ret"
    412 #   done
    413 #   echo
    414 # done | awk 'NF == 3 {print $1,$2,$3,($1/256)^($2/256);next}{print}' > colorglass.pow.txt