libtthimage/Tools/tga_effects.c

458 lines
12 KiB
C
Raw Normal View History

2022-06-27 08:53:59 +02:00
/*
SPECIALS EFFECTS
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#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 */
2022-07-07 12:52:00 +02:00
#define EFF_ROTULACION 37 /* new 6 juillet 2022 */
2022-06-27 08:53:59 +02:00
#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, "", "" },
2022-07-07 12:52:00 +02:00
{ "updown", EFF_UPDOWN, "", "upside down" },
{ "rotulacion", EFF_ROTULACION, "d", "angle in degree" },
2022-06-27 08:53:59 +02:00
{ "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 ?" },
2022-07-07 12:52:00 +02:00
{ "noise", EFF_NOISE, "i", "0..255" },
2022-06-27 08:53:59 +02:00
{ "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)
{
2022-07-07 12:52:00 +02:00
fprintf(stderr, "*** tga_effects v 0.1.58 [%s] %s\n",
2022-06-27 08:53:59 +02:00
TGA_OUTILS_VERSION, TGA_OUTILS_COPYLEFT);
fprintf(stderr, "\nUsage:\n");
fprintf(stderr, "\ttga_effects <src.tga> EFF <dst.tga> [p1] ... [p8]\n");
2022-07-07 12:52:00 +02:00
if (flag) {
2022-06-27 08:53:59 +02:00
Image_print_version(0);
liste_mots_clefs(mots_clef, 42);
}
2022-07-07 12:52:00 +02:00
else {
2022-06-27 08:53:59 +02:00
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;
2023-09-22 14:15:52 +02:00
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( %p %p )\n", src, dst);
#endif
2022-06-27 08:53:59 +02:00
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);
2023-09-22 14:15:52 +02:00
fprintf(stderr, "%s: seuil rgb -> %d\n", __func__, foo);
2022-06-27 08:53:59 +02:00
Image_2x2_contours_0(tmp);
Image_copy(tmp, dst);
2023-09-22 14:15:52 +02:00
Image_DeAllocate(tmp); free(tmp);
2022-06-27 08:53:59 +02:00
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);
2023-09-22 14:15:52 +02:00
fprintf(stderr, "glitch (%s) simple -> %d\n", type, foo);
2022-06-27 08:53:59 +02:00
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)
{
2022-07-07 12:52:00 +02:00
fprintf(stderr, "tga_effects: mot-clef '%s' inconnu...\n", argv[2]);
2022-06-27 08:53:59 +02:00
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;
2022-07-07 12:52:00 +02:00
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;
2022-06-27 08:53:59 +02:00
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:
2022-07-11 06:14:45 +02:00
/* fprintf(stderr, "Experimental : pixel X !\n"); */
2022-06-27 08:53:59 +02:00
foo = Image_pixeliz_X(src, dst);
break;
case EFF_PIXELY:
2022-07-11 06:14:45 +02:00
/* fprintf(stderr, "Experimental : pixel Y!\n"); */
2022-06-27 08:53:59 +02:00
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);
2022-07-07 12:52:00 +02:00
#if DEBUG_LEVEL
fprintf(stderr, "warp0 %f %d %d > %d\n", angle, xc, yc, foo);
#endif
2022-06-27 08:53:59 +02:00
break;
case EFF_RECURSE:
2022-06-30 15:50:35 +02:00
#if DEBUG_LEVEL
2022-06-27 08:53:59 +02:00
fprintf(stderr, "RECURSE EXPERIMENTAL !\n");
2022-06-30 15:50:35 +02:00
#endif
2022-06-27 08:53:59 +02:00
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;
}
2022-08-23 12:10:16 +02:00
if (foo) {
fprintf(stderr, "%s: return code is %d\n", __FILE__, foo);
Image_print_error(argv[0], foo);
}
2022-06-27 08:53:59 +02:00
foo = Image_TGA_save(argv[3], dst, 0);
2022-08-23 12:10:16 +02:00
if (foo) {
fprintf(stderr, "%s: error %d saving '%s'\n", __FILE__, foo, argv[3]);
Image_print_error(argv[0], foo);
}
2022-06-27 08:53:59 +02:00
return 0;
}
/*::------------------------------------------------------------------::*/