diff options
author | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-09-07 13:14:59 +0300 |
---|---|---|
committer | Jaakko Keränen <jaakko.keranen@iki.fi> | 2021-09-07 13:14:59 +0300 |
commit | ab893836d09a178460b9e64e76e42c89836e5721 (patch) | |
tree | 4f802d963792fb8692dad8d61a0010b12d1210a8 /src/media.c | |
parent | c3e5a0c2d4168515804dc0823c93d0522982108c (diff) |
Added image colorization preference
Option to colorize images to grayscale, text color, or preformatted color.
Diffstat (limited to 'src/media.c')
-rw-r--r-- | src/media.c | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/src/media.c b/src/media.c index 5240ab5d..e47c5278 100644 --- a/src/media.c +++ b/src/media.c | |||
@@ -87,6 +87,40 @@ void deinit_GmImage(iGmImage *d) { | |||
87 | deinit_GmMediaProps_(&d->props); | 87 | deinit_GmMediaProps_(&d->props); |
88 | } | 88 | } |
89 | 89 | ||
90 | static void applyImageStyle_(enum iImageStyle style, iInt2 size, uint8_t *imgData) { | ||
91 | if (style == original_ImageStyle) { | ||
92 | return; | ||
93 | } | ||
94 | iColor colorize = (iColor){ 255, 255, 255, 255}; | ||
95 | float brighten = 0.0f; | ||
96 | if (style != grayscale_ImageStyle) { | ||
97 | colorize = get_Color(style == textColorized_ImageStyle ? tmParagraph_ColorId | ||
98 | : tmPreformatted_ColorId); | ||
99 | /* Maximize contrast. */ | ||
100 | const int colMax = iMax(iMax(colorize.r, colorize.g), colorize.b); | ||
101 | if (colMax >= 8) { | ||
102 | colorize.r = colorize.r * 255 / colMax; | ||
103 | colorize.g = colorize.g * 255 / colMax; | ||
104 | colorize.b = colorize.b * 255 / colMax; | ||
105 | } | ||
106 | else { | ||
107 | colorize = (iColor){ 255, 255, 255, 255}; | ||
108 | } | ||
109 | // printf("colorize:%d %d %d\n", colorize.r, colorize.g, colorize.b); | ||
110 | // brighten = iClamp(1.0f - (colorize.r + colorize.g + colorize.b) / 600.0f, 0.0f, 0.5f); /* compensate loss of light */ | ||
111 | // printf("bright:%f\n", brighten); | ||
112 | } | ||
113 | uint8_t *pos = imgData; | ||
114 | size_t numPixels = size.x * size.y; | ||
115 | while (numPixels-- > 0) { | ||
116 | iHSLColor hsl = hsl_Color((iColor){ pos[0], pos[1], pos[2], 255 }); | ||
117 | pos[0] = powf((colorize.r * hsl.lum) / 255.0f, 1.0f - brighten) * 255; | ||
118 | pos[1] = powf((colorize.g * hsl.lum) / 255.0f, 1.0f - brighten) * 255; | ||
119 | pos[2] = powf((colorize.b * hsl.lum) / 255.0f, 1.0f - brighten) * 255; | ||
120 | pos += 4; | ||
121 | } | ||
122 | } | ||
123 | |||
90 | void makeTexture_GmImage(iGmImage *d) { | 124 | void makeTexture_GmImage(iGmImage *d) { |
91 | iBlock *data = &d->partialData; | 125 | iBlock *data = &d->partialData; |
92 | d->numBytes = size_Block(data); | 126 | d->numBytes = size_Block(data); |
@@ -105,6 +139,7 @@ void makeTexture_GmImage(iGmImage *d) { | |||
105 | d->texture = NULL; | 139 | d->texture = NULL; |
106 | } | 140 | } |
107 | else { | 141 | else { |
142 | applyImageStyle_(prefs_App()->imageStyle, d->size, imgData); | ||
108 | /* TODO: Save some memory by checking if the alpha channel is actually in use. */ | 143 | /* TODO: Save some memory by checking if the alpha channel is actually in use. */ |
109 | iWindow *window = get_Window(); | 144 | iWindow *window = get_Window(); |
110 | iInt2 texSize = d->size; | 145 | iInt2 texSize = d->size; |