(spec: string)
| 315 | * to 8-bit). Returns null on parse failure. |
| 316 | */ |
| 317 | export function parseOscColor(spec: string): Color | null { |
| 318 | const hex = spec.match(/^#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i) |
| 319 | if (hex) { |
| 320 | return { |
| 321 | type: 'rgb', |
| 322 | r: parseInt(hex[1]!, 16), |
| 323 | g: parseInt(hex[2]!, 16), |
| 324 | b: parseInt(hex[3]!, 16), |
| 325 | } |
| 326 | } |
| 327 | const rgb = spec.match( |
| 328 | /^rgb:([0-9a-f]{1,4})\/([0-9a-f]{1,4})\/([0-9a-f]{1,4})$/i, |
| 329 | ) |
| 330 | if (rgb) { |
| 331 | // XParseColor: N hex digits → value / (16^N - 1), scale to 0-255 |
| 332 | const scale = (s: string) => |
| 333 | Math.round((parseInt(s, 16) / (16 ** s.length - 1)) * 255) |
| 334 | return { |
| 335 | type: 'rgb', |
| 336 | r: scale(rgb[1]!), |
| 337 | g: scale(rgb[2]!), |
| 338 | b: scale(rgb[3]!), |
| 339 | } |
| 340 | } |
| 341 | return null |
| 342 | } |
| 343 | |
| 344 | /** |
| 345 | * Parse OSC 21337 payload: `key=value;key=value;...` with `\;` and `\\` |
no test coverage detected