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