2019-11-29 13:18:11 +01:00
|
|
|
/*
|
|
|
|
FIMGOPS
|
|
|
|
*/
|
2019-09-11 07:43:08 +02:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <unistd.h>
|
2021-05-20 09:31:28 +02:00
|
|
|
#include <stdint.h>
|
2019-09-11 07:43:08 +02:00
|
|
|
|
|
|
|
#include "../floatimg.h"
|
|
|
|
|
|
|
|
int verbosity;
|
|
|
|
|
2019-09-11 18:58:39 +02:00
|
|
|
/* --------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
float global_fvalue;
|
|
|
|
|
2019-09-11 07:43:08 +02:00
|
|
|
/* --------------------------------------------------------------------- */
|
|
|
|
#define OP_ADD 1
|
2019-09-11 13:56:38 +02:00
|
|
|
#define OP_SUB 2
|
2019-09-11 18:58:39 +02:00
|
|
|
#define OP_MIX 3
|
2019-09-11 13:56:38 +02:00
|
|
|
#define OP_MUL 4
|
2019-11-20 11:12:16 +01:00
|
|
|
#define OP_MINI 5
|
|
|
|
#define OP_MAXI 6
|
2019-09-11 07:43:08 +02:00
|
|
|
typedef struct {
|
|
|
|
int code;
|
|
|
|
char *op;
|
|
|
|
} Opcode;
|
|
|
|
|
|
|
|
Opcode opcodes[] = {
|
|
|
|
{ OP_ADD, "add" },
|
2019-09-11 13:56:38 +02:00
|
|
|
{ OP_SUB, "sub" },
|
2019-09-11 18:58:39 +02:00
|
|
|
{ OP_MIX, "mix" },
|
2019-09-11 07:43:08 +02:00
|
|
|
{ OP_MUL, "mul" },
|
2019-11-20 11:12:16 +01:00
|
|
|
{ OP_MINI, "mini" },
|
|
|
|
{ OP_MAXI, "maxi" },
|
2019-09-11 07:43:08 +02:00
|
|
|
{ 0, NULL }
|
|
|
|
};
|
|
|
|
static void pr_opcodes(void)
|
|
|
|
{
|
|
|
|
Opcode *optr;
|
|
|
|
puts("operators:");
|
|
|
|
for (optr = opcodes; optr->code; optr++) {
|
2019-09-11 18:58:39 +02:00
|
|
|
printf("\t%-15s %d\n", optr->op, optr->code);
|
2019-09-11 07:43:08 +02:00
|
|
|
}
|
|
|
|
}
|
2019-09-11 13:56:38 +02:00
|
|
|
static int look_opcode(char *txt)
|
2019-09-11 07:43:08 +02:00
|
|
|
{
|
|
|
|
Opcode *optr;
|
|
|
|
|
2019-09-11 13:56:38 +02:00
|
|
|
#if DEBUG_LEVEL
|
|
|
|
fprintf(stderr, ">>> %s ( '%s' )\n", __func__, txt);
|
|
|
|
#endif
|
|
|
|
|
2019-09-11 07:43:08 +02:00
|
|
|
for (optr = opcodes; optr->code; optr++) {
|
|
|
|
if (!strcmp(txt, optr->op)) {
|
2019-09-11 13:56:38 +02:00
|
|
|
// printf("found %s as %d\n", optr->op, optr->code);
|
2019-09-11 07:43:08 +02:00
|
|
|
return optr->code;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
/* --------------------------------------------------------------------- */
|
|
|
|
static void help(int lj)
|
|
|
|
{
|
|
|
|
|
|
|
|
puts("usage:\n\tfimgops [options] A.fimg B.fimg operator D.fimg");
|
2019-09-11 18:58:39 +02:00
|
|
|
puts("options:");
|
2024-05-01 12:28:23 +02:00
|
|
|
puts("\t-a\t\texport absolute value");
|
2021-03-09 11:55:48 +01:00
|
|
|
// puts("\t-g convert output to gray");
|
2021-04-02 19:12:22 +02:00
|
|
|
printf("\t-k N.N\t\tset float value (def=%.3f)\n", global_fvalue);
|
|
|
|
puts("\t-v\t\tincrease verbosity");
|
2019-11-20 11:12:16 +01:00
|
|
|
pr_opcodes();
|
2022-07-06 10:27:55 +02:00
|
|
|
if (verbosity) fimg_print_version(lj);
|
2019-09-11 07:43:08 +02:00
|
|
|
exit(0);
|
|
|
|
}
|
|
|
|
/* --------------------------------------------------------------------- */
|
2019-09-11 13:56:38 +02:00
|
|
|
int exec_operator(FloatImg *A, FloatImg *B, int action, FloatImg *D)
|
|
|
|
{
|
|
|
|
int foo;
|
|
|
|
|
|
|
|
switch (action) {
|
|
|
|
|
|
|
|
case OP_ADD:
|
2020-01-15 11:38:40 +01:00
|
|
|
foo = fimg_add_3(A, B, D); break;
|
2019-09-11 13:56:38 +02:00
|
|
|
case OP_SUB:
|
2020-01-15 11:38:40 +01:00
|
|
|
foo = fimg_sub_3(A, B, D); break;
|
2019-09-11 18:58:39 +02:00
|
|
|
case OP_MIX:
|
2022-03-10 16:59:51 +01:00
|
|
|
if (verbosity) fprintf(stderr, "%s: mix: fvalue is %f\n",
|
2020-02-16 21:28:20 +01:00
|
|
|
__func__, global_fvalue);
|
2019-09-11 18:58:39 +02:00
|
|
|
foo = fimg_interpolate(A, B, D, global_fvalue);
|
|
|
|
break;
|
2019-09-11 13:56:38 +02:00
|
|
|
case OP_MUL:
|
2020-01-15 11:38:40 +01:00
|
|
|
foo = fimg_mul_3(A, B, D); break;
|
2019-11-20 11:12:16 +01:00
|
|
|
case OP_MINI:
|
|
|
|
foo = fimg_maximum(A, B, D); break;
|
|
|
|
case OP_MAXI:
|
|
|
|
foo = fimg_minimum(A, B, D); break;
|
2019-09-11 13:56:38 +02:00
|
|
|
default:
|
2020-02-17 07:40:06 +01:00
|
|
|
fprintf(stderr, "fscking action #%d\n", action);
|
2019-09-11 13:56:38 +02:00
|
|
|
foo = -99; break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return foo;
|
|
|
|
}
|
|
|
|
/* --------------------------------------------------------------------- */
|
2019-09-11 07:43:08 +02:00
|
|
|
int main(int argc, char *argv[])
|
|
|
|
{
|
2019-09-11 13:56:38 +02:00
|
|
|
int foo, opt, action;
|
2024-05-01 12:28:23 +02:00
|
|
|
int absolute = 0;
|
2019-09-11 13:56:38 +02:00
|
|
|
char *operator;
|
|
|
|
FloatImg srcA, srcB, dest;
|
2019-09-11 07:43:08 +02:00
|
|
|
|
2021-04-02 19:12:22 +02:00
|
|
|
global_fvalue = 0.5;
|
|
|
|
|
2024-05-01 12:28:23 +02:00
|
|
|
while ((opt = getopt(argc, argv, "ahk:v")) != -1) {
|
2019-09-11 07:43:08 +02:00
|
|
|
switch(opt) {
|
2024-05-01 12:28:23 +02:00
|
|
|
case 'a': absolute = 1; break;
|
2021-03-09 11:55:48 +01:00
|
|
|
case 'g': break;
|
2019-09-11 07:43:08 +02:00
|
|
|
case 'h': help(0); break;
|
2019-09-11 18:58:39 +02:00
|
|
|
case 'k': global_fvalue = atof(optarg); break;
|
2019-09-11 07:43:08 +02:00
|
|
|
case 'v': verbosity++; break;
|
2023-05-29 09:06:57 +02:00
|
|
|
default: exit(1);
|
2019-09-11 07:43:08 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#if DEBUG_LEVEL
|
|
|
|
fprintf(stderr, "argc %d optind %d\n", argc, optind);
|
|
|
|
for (foo=0; foo<argc; foo++)
|
|
|
|
fprintf(stderr, "%3d %s\n", foo, argv[foo]);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if (4 != argc-optind) {
|
|
|
|
fprintf(stderr, "%s need some arguments...\n", argv[0]);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
2019-09-11 13:56:38 +02:00
|
|
|
operator = argv[optind+2];
|
|
|
|
action = look_opcode(operator);
|
|
|
|
if (action < 0) {
|
|
|
|
fprintf(stderr, "%s : opcode '%s' unknow\n", argv[0], operator);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2019-11-20 11:12:16 +01:00
|
|
|
* load the two source files, and check compatibility
|
2019-09-11 13:56:38 +02:00
|
|
|
*/
|
|
|
|
if ((foo=fimg_create_from_dump(argv[optind], &srcA))) {
|
|
|
|
fprintf(stderr, "read error on '%s' is %d\n", argv[optind], foo);
|
|
|
|
exit(2);
|
|
|
|
}
|
|
|
|
if ((foo=fimg_create_from_dump(argv[optind+1], &srcB))) {
|
|
|
|
fprintf(stderr, "read error on '%s' is %d\n", argv[optind+1], foo);
|
|
|
|
exit(3);
|
|
|
|
}
|
|
|
|
|
2020-02-16 21:28:20 +01:00
|
|
|
if (verbosity > 1) { /* please, debug me */
|
2019-09-11 13:56:38 +02:00
|
|
|
fimg_describe(&srcA, argv[optind]);
|
|
|
|
fimg_describe(&srcB, argv[optind+1]);
|
|
|
|
}
|
|
|
|
|
2020-04-06 20:09:11 +02:00
|
|
|
foo = fimg_images_not_compatible(&srcA, &srcB);
|
2019-09-11 13:56:38 +02:00
|
|
|
if (foo) {
|
|
|
|
fprintf(stderr, "images are not compatibles, %d\n", foo);
|
|
|
|
exit(4);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* we can now create the resultant image, and going coredump...
|
|
|
|
*/
|
|
|
|
foo = fimg_create(&dest, srcA.width, srcA.height, srcA.type);
|
2021-05-01 17:54:42 +02:00
|
|
|
if (foo) {
|
|
|
|
fprintf(stderr, "%s: crash coredump on create fimg\n", argv[0]);
|
|
|
|
#if MUST_ABORT
|
|
|
|
abort();
|
|
|
|
#endif
|
|
|
|
exit(1);
|
|
|
|
}
|
2019-09-11 13:56:38 +02:00
|
|
|
// fimg_describe(&dest, "destination");
|
|
|
|
|
|
|
|
foo = exec_operator(&srcA, &srcB, action, &dest);
|
|
|
|
if (foo) {
|
2019-09-11 18:58:39 +02:00
|
|
|
fprintf(stderr, "operator '%s' exec give us a %d\n",
|
|
|
|
operator, foo);
|
2019-09-11 13:56:38 +02:00
|
|
|
}
|
|
|
|
|
2024-05-01 12:28:23 +02:00
|
|
|
if (absolute) {
|
|
|
|
if (verbosity) fprintf(stderr, "compute abs of %p\n", &dest);
|
|
|
|
fimg_absolute(&dest);
|
|
|
|
}
|
|
|
|
|
2019-09-11 13:56:38 +02:00
|
|
|
foo = fimg_dump_to_file(&dest, argv[optind+3], 0);
|
|
|
|
if (foo) {
|
|
|
|
fprintf(stderr, "dumping datas to file give us a %d\n", foo);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2019-09-11 07:43:08 +02:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
/* --------------------------------------------------------------------- */
|