/*
diff.c
see the difference!
-15.11.2022
+30.11.2022
Copyright (C) 2022 Balthasar SzczepaĆski
struct diff_data
{
ILuint r_a;
- ILuint r_a;
- ILuint r_a;
- ILuint g_b;
- ILuint g_b;
+ ILuint g_a;
+ ILuint b_a;
+ ILuint r_b;
ILuint g_b;
+ ILuint b_b;
ILuint max;
};
+int difference (ILuint n, struct PixelInfo *p, void *data);
+static inline ILuint diff_1ch (ILint64 x, ILint64 y, ILint64 A, ILint64 B, ILint64 F);
+
char DIFF_MISSING_ARGS[] = "Missing parameters.\ndiff inPixA inPixB outPix [RA GA BA [RB GB BB]]\n";
int subtool_diff (int argc, char **argv, int argi, char **err)
CAN_BE_MULTIPLE | CAN_BE_OVER_8BIT | CANNOT_BE_GRAY | NOT_READABLE
};
uint_fast8_t palette_only;
- uint_fast8_t i;
+ ILuint i;
ILubyte new_pal[0x100 * 4];
- ILubyte *pal[3];
- ILuint handle;
int r;
-
if (argc < argi + 3)
{
*err = DIFF_MISSING_ARGS;
return r;
}
- r = load_picture(1, argv[argi], &(info[1]), &(flags[1]));
+ r = load_picture(1, argv[argi+1], &(info[1]), &(flags[1]));
if (r)
{
*err = LOAD_FAILED;
if ((info[0].image_height != info[1].image_height) || (info[0].image_width != info[1].image_width) || (info[0].num_images != info[1].num_images))
{
*err = SIZE_MISMATCH;
- return r;
+ return EINVAL;
}
if ((info[0].image_bpc != info[1].image_bpc) || (!(flags[0] & IS_OVER_8BIT)) || (!(flags[0] & IS_OVER_8BIT)))
flags[2] |= CANNOT_BE_INDEXED;
}
- r = convert_picture(0, &(info[0]), &(flags[0]);
+ r = convert_picture(0, &(info[0]), &(flags[0]));
+ if (r!=0)
{
*err = CONVERT_FAILED;
return EIO;
}
- r = convert_picture(1, &(info[1]), &(flags[1]);
+ r = convert_picture(1, &(info[1]), &(flags[1]));
+ if (r!=0)
{
*err = CONVERT_FAILED;
return EIO;
data.g_b = upscale_value(GB, info[0].image_bpc);
data.b_b = upscale_value(BB, info[0].image_bpc);
}
+ data.max = upscale_value(0xFF, info[0].image_bpc);
- r = build_picture_from_info(2, &(info[0], &(info[2]), &(flags[2]));
+ r = build_picture_from_info(2, &(info[0]), &(info[2]), &(flags[2]));
if (r!=0)
{
*err = CREATE_FAILED;
if (palette_only)
{
+ for (i=0; i<=info[2].num_images; ++i)
+ {
+ set_palette (
+ 2,
+ new_pal,
+ info[0].palette_num_cols * info[1].palette_num_cols * info[0].palette_bpp,
+ info[0].palette_type,
+ i
+ );
+ }
- ilRegisterPal
-
-
+ r = perform_action_palette_mix(
+ id,
+ &difference,
+ flags,
+ &data
+ );
+ if (r)
+ {
+ *err = CONVERT_FAILED;
+ return r;
+ }
+ flags[0] &= ~OK_PALETTE_ONLY;
+ flags[1] &= ~OK_PALETTE_ONLY;
+ flags[2] &= ~OK_PALETTE_ONLY;
+ r = perform_action(
+ 3,
+ id,
+ xyf0, xyf0, xyf0,
+ 0, 0, 0,
+ &palette_mix_index,
+ flags,
+ &data
+ );
+ if (r)
+ {
+ *err = CONVERT_FAILED;
+ return r;
+ }
}
else
{
- for (i=0; i<3; ++i)
+ r = perform_action(
+ 3,
+ id,
+ xyf0, xyf0, xyf0,
+ 0, 0, 0,
+ &difference,
+ flags,
+ &data
+ );
+ if (r)
{
- handle = get_handle(i);
- ilBindImage(handle);
- if (i==2)
- {
- ilRegisterPal(
- new_pal,
- ((flags[0] & HAS_ALPHA)?4:3) * info[0].palette_num_cols * info[1].palette_num_cols,
-
-
-
+ *err = CONVERT_FAILED;
+ return r;
+ }
}
+
+ r = save_picture(2, argv[argi+2], flags[2]);
+ if (r!=0)
+ {
+ *err = SAVE_FAILED;
+ return r;
+ }
+
+ return 0;
+}
+
+int difference (ILuint n, struct PixelInfo *p, void *data)
+{
+ struct diff_data *d;
+ d = data;
+
+ if (n < 3)
+ return EIO;
+
+ p[2].red = diff_1ch(p[0].red, p[1].red, d->r_a, d->r_b, d->max);
+ p[2].green = diff_1ch(p[0].green, p[1].green, d->g_a, d->g_b, d->max);
+ p[2].blue = diff_1ch(p[0].blue, p[1].blue, d->b_a, d->b_b, d->max);
+ if (p[2].flags & EFF_ALPHA)
+ p[2].alpha = (p[0].alpha + p[1].alpha) / 2; /* no better idea */
+
+ return 0;
+}
+
+static inline ILuint diff_1ch (ILint64 x, ILint64 y, ILint64 A, ILint64 B, ILint64 F)
+{
+ ILint64 v;
+
+ if (x == y)
+ return (ILuint) x;
+ else if (x > y)
+ v = y + ((A * (x - y)) / F);
+ else
+ v = x + ((B * (y - x)) / F);
+
+ return (ILuint) v;
+}