ref: a105ad42e036c4b88fe1f728ff9c60cfd7fcd6ca
parent: 56fcd319c56268612ac2406f74d16207935ab730
author: phil9 <[email protected]>
date: Tue Nov 23 02:33:44 EST 2021
handle image with CMAP8 chan properly we were making the assumption that all images had a 32bit depth with an x8r8g8b8 chan which would obviously not work with CMAP8 chan format.
--- a/ifilter.c
+++ b/ifilter.c
@@ -10,51 +10,51 @@
struct Filter
{
const char *name;
- void (*filter)(uchar[3], float);
+ void (*filter)(int *r, int *g, int *b, float);
};
void
-grayscale(uchar p[3], float)
+grayscale(int *r, int *g, int *b, float)
{
- uchar v = 0.2126*p[2] + 0.7152*p[1] + 0.0722*p[0];
- p[0] = p[1] = p[2] = v;
+ uchar v = 0.2126*(*r) + 0.7152*(*g) + 0.0722*(*b);
+ *r = *g = *b = v;
}
void
-sepia(uchar p[3], float)
+sepia(int *r, int *g, int *b, float)
{
- float r, g, b;
+ float fr, fg, fb;
- r = 0.393*p[2] + 0.769*p[1] + 0.189*p[0];
- g = 0.349*p[2] + 0.686*p[1] + 0.168*p[0];
- b = 0.272*p[2] + 0.534*p[1] + 0.131*p[0];
- p[2] = MIN(r, 255);
- p[1] = MIN(g, 255);
- p[0] = MIN(b, 255);
+ fr = 0.393*(*r) + 0.769*(*g) + 0.189*(*b);
+ fg = 0.349*(*r) + 0.686*(*g) + 0.168*(*b);
+ fb = 0.272*(*r) + 0.534*(*g) + 0.131*(*b);
+ *r = MIN(fr, 255);
+ *g = MIN(fg, 255);
+ *b = MIN(fb, 255);
}
void
-invert(uchar p[3], float)
+invert(int *r, int *g, int *b, float)
{
- p[0] = 255 - p[0];
- p[1] = 255 - p[1];
- p[2] = 255 - p[2];
+ *b = 255 - *b;
+ *g = 255 - *g;
+ *r = 255 - *r;
}
void
-shade(uchar p[3], float factor)
+shade(int *r, int *g, int *b, float factor)
{
- p[0] = p[0] * (1 - factor);
- p[1] = p[1] * (1 - factor);
- p[2] = p[2] * (1 - factor);
+ *b = *b * (1 - factor);
+ *g = *g * (1 - factor);
+ *r = *r * (1 - factor);
}
void
-tint(uchar p[3], float factor)
+tint(int *r, int *g, int *b, float factor)
{
- p[0] = p[0] + (255.0 - p[0]) * factor;
- p[1] = p[1] + (255.0 - p[1]) * factor;
- p[2] = p[2] + (255.0 - p[2]) * factor;
+ *b = *b + (255.0 - *b) * factor;
+ *g = *g + (255.0 - *g) * factor;
+ *r = *r + (255.0 - *r) * factor;
}
void
@@ -73,10 +73,47 @@
};
void
+getcolor(int depth, uchar *buf, int *r, int *g, int *b)
+{
+ int c;
+
+ switch(depth){
+ case 8:
+ c = cmap2rgb(*buf);
+ *r = (c >> 8 * 2) & 0xFF;
+ *g = (c >> 8 * 1) & 0xFF;
+ *b = (c >> 8 * 0) & 0xFF;
+ break;
+ case 24:
+ case 32:
+ *r = buf[2];
+ *g = buf[1];
+ *b = buf[0];
+ break;
+ }
+}
+
+void
+setcolor(int depth, uchar *buf, int r, int g, int b)
+{
+ switch(depth){
+ case 8:
+ *buf = rgb2cmap(r, g, b);
+ break;
+ case 32:
+ buf[2] = r;
+ buf[1] = g;
+ buf[0] = b;
+ break;
+ }
+
+}
+
+void
main(int argc, char *argv[])
{
Memimage *i;
- int w, h, p, n;
+ int w, h, p, n, s, r, g, b;
uchar *buf;
Filter *f;
float factor;
@@ -110,16 +147,20 @@
i = readmemimage(0);
if(i==nil)
sysfatal("readmemimage: %r");
+ s = i->depth/8;
w = Dx(i->r);
h = Dy(i->r);
- n = 4*w*h*sizeof(uchar);
+ n = s*w*h*sizeof(uchar);
buf = malloc(n);
if(buf==nil)
sysfatal("malloc: %r");
if(unloadmemimage(i, i->r, buf, n)<0)
sysfatal("unloadmemimage: %r");
- for(p = 0; p < n; p+=4)
- f->filter(buf+p, factor);
+ for(p = 0; p < n; p+=s){
+ getcolor(i->depth, buf+p, &r, &g, &b);
+ f->filter(&r, &g, &b, factor);
+ setcolor(i->depth, buf+p, r, g, b);
+ }
if(loadmemimage(i, i->r, buf, n)<0)
sysfatal("unloadmemimage: %r");
writememimage(1, i);