/* ichika6.c - Don Yang (uguu.org) 11/20/04 */ #include #include #define z return typedef float s; typedef unsigned char W; typedef int _; _ I, C, H, i, K, A, ta, n; W *M, *X, *m, *x, y; s R, G, B, r, g, b, V, v, w, MA, N, a, T, S, U; char *t[] = {"read error", "write error", "invalid image", "out of memory"}, e[64]; FILE *f; _ c() { N = U = r; if( N > g ) N = g; if( U < g ) U = g; if( N > b ) N = b; if( U < b ) U = b; V = v = w = 0; if( N != U ) { N = U - N; V = (r == U) ? ((g - b) / N) : (g == U) ? ((b - r) / N + 2) : ((r - g) / N + 4); w = N / (v = U); } z 0; } _ j(_ k) { if( k < C || k > I - C || !(k % C) || !((k + 1) % C) ) z 1; r = (s)*(X + k * 3) / 255; g = (s)*(X + k * 3 + 1) / 255; b = (s)*(X + k * 3 + 2) / 255; c(); z ((.3 < V && V < .45) || 4.3 < V || V < .1) ? 0 : j(k + K); } _ Q() { z f ? fclose(f) : 0; } _ q() { z puts(t[K]); } _ E(_ k) { if( M[k] - 255 ) { M[k] = 255; if( (k % C) < C - 1 ) E(k + 1); if( (k / C) < H - 1 ) E(k + C); if( k % C ) E(k - 1); if( k / C ) E(k - C); } z 0; } _ P() { x = X - 1; for(i = 0; i < I; i++) { y = *++x; *x = *(x + 2); *(x += 2) = y; } z 0; } _ O() { z fwrite(x, n, 1, f); } _ main(_ D, char **d) { if( D < 3 ) z printf("%s \n", *d); K = C = 0; if( !(f = fopen(*++d, "rb")) ) z q(); X = 0; if( fread(e, 64, 1, f) - 1 ) z q(); K += 2; if( *e == 66 && e[1] == 77 ) { if( *(_*)(e + 28) - 24 ) z q(); C = *(_*)(e + 18); H = *(_*)(e + 22); ta = (4 - ((C * 3) & 3)) & 3; n = 54; } else if( *e == 80 && e[1] == 54 ) { for(i = A = n = 0; i < 63; i++) if( e[i] == 10 ) if( ++A == 3 ) { e[n = ++i] = 0; i = 64; } if( !n || (sscanf(e, "P6\n%d %d\n", &C, &H) - 2) ) z q(); ta = 0; } if( C < 16 || H < 16 ) z q(); K++; if( !(X = (W*)malloc((I = C * H) * 3)) ) z q(); x = X; for(fseek(f, n, i = 0); i < H; i++) { fread(x, C * 3, 1, f); x += C * 3; for(A = 0; A++ < ta; fgetc(f)); } Q(); f = 0; if( *e - 80 ) P(); if( !(m = M = (W*)malloc(I)) ) z q(); x = X; for(A = 0; A < I; A++) { r = (s)*(x++) / 255; g = (s)*(x++) / 255; b = (s)*(x++) / 255; c(); *m = 255; if( 3.6 < V && V < 4.24 ) { S = (w-.65)*(w-.65) + (v-.42)*(v-.42) * 1.29; T = (w-.36)*(w-.36) + (v-.6)*(v-.6) * 1.29; if( S < .6 || T < .6 ) *m = (W)(255 * ((S < .6) ? (S / .6) : (T / .6))); } m++; } for(i = A = K = 0; A < C;) { E(A); E(A + C); E(A + I - C * 2); E(A++ + I - C); } for(; K < H;) { E(K * C); E(K * C + 1); E((K + 1) * C - 2); E(++K * C - 1); } for(m = M; i < I; i++) { if( *m - 255 ) if( (j(i + (K = 1)) ? 1 : j(i + (K = -1)) ? 1 : j(i + (K = C)) ? 1 : j(i + (K = -C)) ? 1 : 0) ) E(i); m++; } x = X; m = M; for(i = 0; i < I; i++) { if( *m - 255 ) { S = (s)*m / 255; T = 1 - S; r = R = (s)*x / 255; g = G = (s)*(x+1) / 255; b = B = (s)*(x+2) / 255; c(); if( (V += 2) >= 6 ) V -= 6; if( (w += .7) > 1 ) w = 1; if( (v += .1) > 1 ) v = 1; K = (_)V; MA = V - (s)K; N = v * (1 - w); U = v * (1 - w * MA); a = v * (1 - w * (1 - MA)); r = (K < 4) ? (K < 2) ? K ? U : v : N : (K > 4) ? v : a; g = (K < 3) ? K ? v : a : K > 3 ? N : U; b = (K < 3) ? (K > 1) ? a : N : (K > 4) ? U : v; r = R * S + r * T; g = R * S + g * T; b = R * S + b * T; *x = (W)(r * 255); x[1] = (W)(g * 255); x[2] = (W)(b * 255); } x += 3; m++; } free(M); if( *e - 80 ) P(); K = 1; if( !(f = fopen(*++d, "wb+")) ) z q(); x = (W*)e; O(); n = C * 3; x = X; for(A = 0; A < H; A++) { O(); for(K = 0; K < ta; K++) fputc(0, f); x += C * 3; } free(X); z Q(); }