-
Notifications
You must be signed in to change notification settings - Fork 13
Expand file tree
/
Copy pathmodify.R
More file actions
144 lines (134 loc) · 4.95 KB
/
modify.R
File metadata and controls
144 lines (134 loc) · 4.95 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
#' Modify colour space channels in hex-encoded colour strings
#'
#' This set of functions allows you to modify colours as given by strings,
#' whithout first decoding them. For large vectors of colour values this should
#' provide a considerable speedup.
#'
#' @param colour A character string giving colours, either as hexadecimal
#' strings or accepted colour names.
#' @param channel The channel to modify or extract as a single letter, or
#' `'alpha'` for the alpha channel.
#' @param value The value to modify with
#' @param space The colour space the channel pertains to. Allowed values are:
#' `"cmy"`, `"cmyk"`, `"hsl"`, `"hsb"`, `"hsv"`, `"lab"` (CIE L*ab), `"hunterlab"`
#' (Hunter Lab), `"oklab"` , `"lch"` (CIE Lch(ab) / polarLAB), `"luv"`,
#' `"rgb"` (sRGB), `"xyz"`, `"yxy"` (CIE xyY), `"hcl"` (CIE Lch(uv) / polarLuv),
#' or `"oklch"` (Polar form of oklab)
#' @param white The white reference of the channel colour space. Will only have
#' an effect for relative colour spaces such as Lab and luv. Any value accepted
#' by [as_white_ref()] allowed.
#' @param na_value A valid colour string or `NA` to use when `colour` contains
#' `NA` elements. The general approach in farver is to carry `NA` values over,
#' but if you want to mimick [col2rgb()] you should set
#' `na_value = 'transparent'`, i.e. treat `NA` as transparent white.
#'
#' @return A character vector of the same length as `colour` (or a numeric
#' vector in the case of `get_channel()`)
#'
#' @family encoding and decoding functions
#'
#' @rdname manip_channel
#' @name manip_channel
#'
#' @examples
#' spectrum <- rainbow(10)
#'
#' # set a specific channel
#' set_channel(spectrum, 'r', c(10, 50))
#' set_channel(spectrum, 'l', 50, space = 'lab')
#' set_channel(spectrum, 'alpha', c(0.5, 1))
#'
#' # Add value to channel
#' add_to_channel(spectrum, 'r', c(10, 50))
#' add_to_channel(spectrum, 'l', 50, space = 'lab')
#'
#' # Multiply a channel
#' multiply_channel(spectrum, 'r', c(10, 50))
#' multiply_channel(spectrum, 'l', 50, space = 'lab')
#'
#' # set a lower bound on a channel
#' raise_channel(spectrum, 'r', c(10, 50))
#' raise_channel(spectrum, 'l', 20, space = 'lab')
#'
#' # set an upper bound on a channel
#' cap_channel(spectrum, 'r', c(100, 50))
#' cap_channel(spectrum, 'l', 20, space = 'lab')
#'
NULL
#' @rdname manip_channel
#' @export
set_channel <- function(colour, channel, value, space = 'rgb', white = 'D65', na_value = NA) {
if (space != 'rgb') {
white <- as_white_ref(white)
}
encode_channel_c(colour, channel, value, space, 1L, white, na_value)
}
#' @rdname manip_channel
#' @export
add_to_channel <- function(colour, channel, value, space = 'rgb', white = 'D65', na_value = NA) {
if (space != 'rgb') {
white <- as_white_ref(white)
}
encode_channel_c(colour, channel, value, space, 2L, white, na_value)
}
#' @rdname manip_channel
#' @export
multiply_channel <- function(colour, channel, value, space = 'rgb', white = 'D65', na_value = NA) {
if (space != 'rgb') {
white <- as_white_ref(white)
}
encode_channel_c(colour, channel, value, space, 3L, white, na_value)
}
#' @rdname manip_channel
#' @export
raise_channel <- function(colour, channel, value, space = 'rgb', white = 'D65', na_value = NA) {
if (space != 'rgb') {
white <- as_white_ref(white)
}
encode_channel_c(colour, channel, value, space, 4L, white, na_value)
}
#' @rdname manip_channel
#' @export
cap_channel <- function(colour, channel, value, space = 'rgb', white = 'D65', na_value = NA) {
if (space != 'rgb') {
white <- as_white_ref(white)
}
encode_channel_c(colour, channel, value, space, 5L, white, na_value)
}
#' @rdname manip_channel
#' @export
get_channel <- function(colour, channel, space = 'rgb', white = 'D65', na_value = NA) {
if (space != 'rgb') {
white <- as_white_ref(white)
}
decode_channel_c(colour, channel, space, white, na_value)
}
encode_channel_c <- function(colour, channel, value, space, op, white, na_value) {
if (length(colour) == 0) {
return(colour)
}
if (length(value) == 0) {
stop("`value` must not be empty", call. = FALSE)
}
if (length(value) != 1) value <- rep_len(value, length(colour))
if (channel == 'alpha') {
channel <- 0L
space <- 0L
} else {
space <- colourspace_match(space)
channel <- colour_channel_index[[space]][channel]
if (is.na(channel)) stop('Invalid channel for this colourspace', call. = FALSE)
}
.Call(`farver_encode_channel_c`, as_colour_code(colour), as.integer(channel), value, as.integer(space), as.integer(op), white, as.character(na_value))
}
decode_channel_c <- function(colour, channel, space, white, na_value) {
if (channel == 'alpha') {
channel <- 0L
space <- 0L
} else {
space <- colourspace_match(space)
channel <- colour_channel_index[[space]][channel]
if (is.na(channel)) stop('Invalid channel for this colourspace', call. = FALSE)
}
.Call(`farver_decode_channel_c`, as_colour_code(colour), as.integer(channel), as.integer(space), white, as.character(na_value))
}