/* SPECIALS EFFECTS */ #include #include #include #include "tga_outils.h" /*::------------------------------------------------------------------::*/ #define EFF_4BITS 4 #define EFF_CLASS0 5 #define EFF_DECOMP 6 #define EFF_FLATGRAY 7 #define EFF_GRAY 9 #define EFF_GRAYK 11 #define EFF_MOSAIC 13 #define EFF_MOSAIC0 14 #define EFF_PHMATON 15 /* new 30 avril 2007 */ #define EFF_MIRROR 16 #define EFF_EXTRBIT0 17 /* new 11 mars 2015 */ #define EFF_EXTRBIT1 18 /* new 11 mars 2015 */ #define EFF_NEGATE 20 #define EFF_SEUIL 22 #define EFF_DEGOULE 23 /* new octobre 2015 */ #define EFF_NOISE 27 #define EFF_PIXELX 33 #define EFF_PIXELY 34 /* new 30 mars 2007 */ #define EFF_FIVE 35 /* new 16 dec 2007 */ #define EFF_WARP_0 36 /* new 17 janv 2015 */ #define EFF_ROTULACION 37 /* new 6 juillet 2022 */ #define EFF_RECURSE 40 #define EFF_RGBMSKH 41 #define EFF_RGBMSKV 42 #define EFF_RGBMSK2 43 #define EFF_RGBMSKR 44 #define EFF_BICOLOR0 46 /* new 17 janv 2010 */ #define EFF_BICOLOR1 47 /* new 18 janv 2010 */ #define EFF_BICOLOR2 48 /* new 22 janv 2010 */ #define EFF_ROT4PIX 51 #define EFF_CONT2X2 52 /* new 1 sept 2008 */ #define EFF_CONT2X2G 53 /* new 8 sept 2008 */ #define EFF_SCRATCH 54 #define EFF_SINW0 55 #define EFF_SINW1 56 #define EFF_SWAPCOL 58 #define EFF_SWAPNIBBLE 59 #define EFF_UPDOWN 65 #define EFF_SHIFT_XY 66 /* new 8 mai 2009 */ #define EFF_WATER 72 #define EFF_FUKUNG 75 #define EFF_CLASS1 83 /* new 20 nov 2013 */ #define EFF_GLITCH 87 /* new 13 oct 2014 */ #define EFF_X0 100 #define EFF_X1 101 #define EFF_X2 102 #define EFF_X3 103 #define EFF_X4 104 #define EFF_X5 105 mot_clef mots_clef[] = { { "4bits", EFF_4BITS, "", "and 0xf0" }, { "class0", EFF_CLASS0, "", "experimental" }, { "decomp", EFF_DECOMP, "f", "flag: print colors" }, { "flatgray", EFF_FLATGRAY, "i", "detect flatgray zones" }, { "gray", EFF_GRAY, "", "" }, { "grayk", EFF_GRAYK, "iii", "3 coefs" }, { "mirror", EFF_MIRROR, "", "" }, { "updown", EFF_UPDOWN, "", "upside down" }, { "rotulacion", EFF_ROTULACION, "d", "angle in degree" }, { "extrbits0", EFF_EXTRBIT0, "iii", "shifts for r, g & b" }, { "mosaic", EFF_MOSAIC, "", "?" }, { "mosaic0", EFF_MOSAIC0, "iif", "?" }, { "photomaton", EFF_PHMATON, "", "" }, { "negate", EFF_NEGATE, "", "" }, { "seuil", EFF_SEUIL, "iii", "rgb thresholds" }, { "degoule", EFF_DEGOULE, "ii", "k1 & k2 ? wtf ?" }, { "noise", EFF_NOISE, "i", "0..255" }, { "pixelX", EFF_PIXELX, "", "prototype" }, { "pixelY", EFF_PIXELY, "", "prototype" }, { "efive", EFF_FIVE, "", "got it, code it" }, { "warp0", EFF_WARP_0, "dii", "angle xc yc" }, { "recurse", EFF_RECURSE, "i", "classic and recursif" }, { "rgbmskh", EFF_RGBMSKH, "i", "'par' is a gray level" }, { "rgbmskv", EFF_RGBMSKV, "i", "'par' is a gray level" }, { "rgbmsk2", EFF_RGBMSK2, "i", "'par' is a gray level" }, { "rgbmskr", EFF_RGBMSKR, "i", "'par' is a gray level" }, { "bicolor0", EFF_BICOLOR0, "i", "?" }, { "bicolor1", EFF_BICOLOR1, "ii", "..." }, { "rot4pix", EFF_ROT4PIX, "i", "???" }, { "cont2x2", EFF_CONT2X2, "", "contours 2x2 en auto" }, { "cont2x2g", EFF_CONT2X2G, "", "contours 2x2 sur le gris" }, { "scratch", EFF_SCRATCH, "i", "coredumper :)" }, { "sinwave1", EFF_SINW1, "dddddd", "strange effect" }, { "swapcol", EFF_SWAPCOL, "s", "rg rb bg" }, { "swapnibble", EFF_SWAPNIBBLE, "", "swap all pix nibbles" }, { "shift_xy", EFF_SHIFT_XY, "ii", "les deux offsets" }, { "water", EFF_WATER, "i", "'par' is water distance" }, /* { "fukung", EFF_FUKUNG, "i", "OMG ! WTF ?" }, */ { "class1", EFF_CLASS1, "iiii", "R G B diameter" }, { "glitch", EFF_GLITCH, "si", "type nbre" }, { "x0", EFF_X0, "iii", "3 thresholds for r, g, b" }, { "x1", EFF_X1, "", "xor other componant" }, { "x2", EFF_X2, "iii", "trigonometry" }, { "x3", EFF_X3, "iis", "" }, { "x4", EFF_X4, "i", "essai Aug 2008" }, { "x5", EFF_X5, "iii", "essai Sept 2008" }, { NULL, 0, NULL, NULL } }; /*::------------------------------------------------------------------::*/ void usage(int flag) { fprintf(stderr, "*** tga_effects v 0.1.58 [%s] %s\n", TGA_OUTILS_VERSION, TGA_OUTILS_COPYLEFT); fprintf(stderr, "\nUsage:\n"); fprintf(stderr, "\ttga_effects EFF [p1] ... [p8]\n"); if (flag) { Image_print_version(0); liste_mots_clefs(mots_clef, 42); } else { fprintf(stderr, "\ttry 'tga_effects list' for a list.\n"); } exit(5); } /*::------------------------------------------------------------------::*/ /* fonction codee a la rache le 8 septembre 2008. * a passer un jour ou l'autre dans la libimage */ int contours_du_gris(Image_Desc *src, Image_Desc *dst) { Image_Desc *tmp; int foo; #if DEBUG_LEVEL fprintf(stderr, ">>> %s ( %p %p )\n", src, dst); #endif tmp = Image_clone(src, 1); foo = Image_to_gray(src, tmp, 0); #if DEBUG_LEVEL fprintf(stderr, "to_gray %d\n", foo); #endif foo = Image_seuil_RGB(tmp, tmp, 64, 128, 192); fprintf(stderr, "%s: seuil rgb -> %d\n", __func__, foo); Image_2x2_contours_0(tmp); Image_copy(tmp, dst); Image_DeAllocate(tmp); free(tmp); return 42; } /*::------------------------------------------------------------------::*/ static int do_classif_1(Image_Desc *img, int kr, int kg, int kb, int diam) { int foo; Une_Classe_Sph classes[2]; int r, g, b; Image_Rect zone; #if DEBUG_LEVEL fprintf(stderr, "%s ( %p %d %d %d %d )\n", __func__, img, kr, kg, kb, diam); #endif zone.x = zone.y = 0; zone.w = img->width; zone.h = img->height; foo = Image_stats_zone_0(img, &zone, &r, &g, &b, NULL, NULL, NULL); #if DEBUG_LEVEL fprintf(stderr, "%s, stats -> %d %d %d\n", __func__, r, g, b); #endif classes[0].rc = r; classes[0].gc = g; classes[0].bc = b; classes[0].rad = 30; classes[0].r = classes[0].g = 50; classes[0].b = 200; classes[1].rc = kr; classes[1].gc = kg; classes[1].bc = kb; classes[1].rad = diam; classes[1].r = classes[1].g = 250; classes[1].b = 20; if (must_be_verbose()) { Image_display_classes(classes, 2, "umpf", 0); } foo = Image_classif_1(img, img, classes, 2, 0); fprintf(stderr, "classif 1 -> %d\n", foo); return FUNC_IS_BETA; } /*::------------------------------------------------------------------::*/ /* new 13 OCT 2014 - comburant: Kellegen 8.0 50cl */ static int do_glitch(Image_Desc *src, Image_Desc *dst, char *type, int nbre) { int foo; #if DEBUG_LEVEL fprintf(stderr, "%s :\n\t%p %p %s %d\n", __func__, src, dst, type, nbre); #endif foo = Image_Glitch_simple(src, dst, nbre); fprintf(stderr, "glitch (%s) simple -> %d\n", type, foo); return 0; } /*::------------------------------------------------------------------::*/ /* * argv[1] source.tga * argv[2] type de l'effet * argv[3] destination.tga */ #define FIRST_PARAM 4 int main(int argc, char *argv[]) { Image_Desc *src, *dst; int foo; int commande, nbargs, idx; double angle; int xc, yc; /* * USE GETOPT HERE */ dump_command_line(argc, argv, 0); if (argc==2 && !strcmp(argv[1], "-?")) usage(0); if (argc==2 && !strcmp(argv[1], "list")) usage(1); if (argc < 4) usage(0); srand(getpid()); /* recherche du type d'effet demande */ idx = cherche_mot_clef(argv[2], mots_clef, &commande, &nbargs); if (idx < 0) { fprintf(stderr, "tga_effects: mot-clef '%s' inconnu...\n", argv[2]); exit (5); } if ( (argc-nbargs) != FIRST_PARAM ) { fprintf(stderr, "%s: bad number of parameters\n", argv[0]); exit(5); } /* analyse des parametres */ foo = parse_parametres(argc, argv, mots_clef[idx].ptypes, FIRST_PARAM); if ((src = Image_TGA_alloc_load(argv[1]))==NULL) { fprintf(stderr, "tga_effect: can't load image %s\n", argv[1]); exit(5); } if ( (dst=Image_clone(src, 1)) == NULL ) { fprintf(stderr, "tga_effect: can't clone %p\n", src); exit(1); } /* XXX ne serait-il pas de bon ton d'effacer l'image de destination ? */ switch (commande) { case EFF_4BITS: foo = Image_col4bits_and(src, dst); break; case EFF_CLASS0: foo = Image_classif_0(src, dst); break; case EFF_DECOMP: foo = Image_decompose(src, dst, GFP(0)); break; case EFF_FLATGRAY: foo = Image_detect_flat_gray(src, dst, GIP(0), 0); break; case EFF_GRAY: foo = Image_to_gray(src, dst, 0); break; case EFF_GRAYK: foo = Image_to_gray_k(src, dst, GIP(0), GIP(1), GIP(2), 0); break; case EFF_MIRROR: foo = Image_mirror(src, dst, 0); break; case EFF_ROTULACION: /* new 6 juillet 2022 */ angle = GDP(0); fprintf(stderr, "%s: angle rotulacion = %f\n", __FILE__, angle); foo = Image_center_rotate(src, dst, angle); break; case EFF_EXTRBIT0: foo = Image_extrbits_0(src, dst, GIP(0), GIP(1), GIP(2)); break; case EFF_MOSAIC: foo = Image_mosaic_simple(src, dst); break; case EFF_MOSAIC0: /* explanation of the parameters, please */ foo = Image_mosaic_0(src, dst, GIP(0), GIP(1), GFP(2)); break; case EFF_PHMATON: foo = Image_photomaton_0(src, dst); break; case EFF_NEGATE: foo = Image_negate(src, dst); break; case EFF_SEUIL: foo = Image_seuil_RGB(src, dst, GIP(0), GIP(1), GIP(2)); break; case EFF_DEGOULE: foo = Image_degouline_0(src, dst, GIP(0), GIP(1)); #if DEBUG_LEVEL fprintf(stderr, "Degouline ---> %d\n", foo); #endif break; case EFF_NOISE: foo = Image_noise(src, dst, GIP(0)); break; case EFF_PIXELX: /* fprintf(stderr, "Experimental : pixel X !\n"); */ foo = Image_pixeliz_X(src, dst); break; case EFF_PIXELY: /* fprintf(stderr, "Experimental : pixel Y!\n"); */ foo = Image_pixeliz_Y(src, dst); break; case EFF_FIVE: /* XXX */ foo = Image_effect_x_5(src, dst, 0, 0, 0); break; case EFF_WARP_0: angle = 33.5; xc = GIP(1); yc = GIP(2); foo = Image_warp_essai_0(src, dst, angle, xc, yc); #if DEBUG_LEVEL fprintf(stderr, "warp0 %f %d %d > %d\n", angle, xc, yc, foo); #endif break; case EFF_RECURSE: #if DEBUG_LEVEL fprintf(stderr, "RECURSE EXPERIMENTAL !\n"); #endif foo = Image_call_recursion_0(src, dst, GIP(0)); break; case EFF_RGBMSKH: foo = Image_rgbmask_H(src, dst, GIP(0)); break; case EFF_RGBMSKV: foo = Image_rgbmask_V(src, dst, GIP(0)); break; case EFF_RGBMSK2: foo = Image_rgbmask_2(src, dst, GIP(0)); break; case EFF_RGBMSKR: foo = Image_rgbmask_R(src, dst, GIP(0)); break; case EFF_BICOLOR0: foo = Image_BiColor_0(src, dst, GIP(0)); break; case EFF_BICOLOR1: foo = Image_BiColor_1(src, dst, GIP(0), GIP(1)); break; case EFF_ROT4PIX: foo = Image_2x2_rot4pix(src, dst, GIP(0)); break; case EFF_CONT2X2: Image_AutoSeuilRGB(src, dst); foo = Image_2x2_contours_0(dst); break; case EFF_CONT2X2G: foo = contours_du_gris(src, dst); break; case EFF_SCRATCH: foo = Image_scratch(src, dst, GIP(0)); break; case EFF_SWAPCOL: Image_copy(src, dst); foo = Image_swap_colors(dst, GSP(0)); break; case EFF_SWAPNIBBLE: foo = Image_swap_nibbles(src, dst); break; case EFF_UPDOWN: foo = Image_upside_down(src, dst, 0); break; case EFF_SHIFT_XY: foo = Image_shift_xy(src, dst, GIP(0), GIP(1)); break; case EFF_WATER: foo = Image_water(src, dst, GIP(0)); break; case EFF_CLASS1: /* XXX not very trustable */ foo = do_classif_1(dst, GIP(0), GIP(1), GIP(2), GIP(3)); break; /* new 13 october 2014 */ case EFF_GLITCH: foo = do_glitch(src, dst, GSP(0), GIP(1)); fprintf(stderr, "do glitch -> %d\n", 0); break; case EFF_X0: foo = Image_effect_x_0(src, dst, GIP(0), GIP(1), GIP(2)); break; case EFF_X1: foo = Image_effect_x_1(src, dst); break; case EFF_X2: #if DEBUG_LEVEL fprintf(stderr, "\teff X2 badly implemented :)\n"); #endif foo = Image_effect_x_2(src, dst, 12, 12, 0); break; case EFF_X3: #if DEBUG_LEVEL fprintf(stderr, "\teff X3 badly implemented :)\n"); #endif foo = Image_effect_x_3(src, dst, GIP(0), GIP(1), GSP(2)); break; case EFF_X4: foo = Image_effect_x_4(src, dst, GIP(0)); break; case EFF_X5: #if DEBUG_LEVEL fprintf(stderr, "\teff X5 badly implemented :)\n"); #endif foo = Image_effect_x_5(src, dst, GIP(0), GIP(1), GIP(2)); break; default: fprintf(stderr, "%s invalid command %d, plopped out\n", argv[0], commande); foo = 666; break; } if (foo) { fprintf(stderr, "%s: return code is %d\n", __FILE__, foo); Image_print_error(argv[0], foo); } foo = Image_TGA_save(argv[3], dst, 0); if (foo) { fprintf(stderr, "%s: error %d saving '%s'\n", __FILE__, foo, argv[3]); Image_print_error(argv[0], foo); } return 0; } /*::------------------------------------------------------------------::*/