/*
nofading.c
The tool to remove fading from an image
-06.11.2022
+29.11.2022
Copyright (C) 2015, 2022 Balthasar Szczepański
*/
#include <stdint.h>
+#include <getopt.h>
#include <inttypes.h>
#include <errno.h>
+#include <unistd.h>
#include "core.h"
#include "nofading.h"
-char NOFADING_MISSING_ARGS[] = "Missing parameters.\nnofading inPix outPix [a] [framesize]\n";
+#define UPDATE_RANGE(val, low, high) \
+{ \
+ if ((val) < (low)) \
+ (low) = (val); \
+ if ((val) > (high)) \
+ (high) = (val); \
+}
+
+char NOFADING_MISSING_ARGS[] = "Missing parameters.\nnofading [-a -c -f] inPix outPix [framesize]\n";
-int nofading (int argc, char **argv, char **err)
+struct nofading_data
{
uint_fast8_t individual_channels;
+ uint_fast8_t individual_frames;
+ uint_fast8_t enhance_alpha;
+ ILuint red_low;
+ ILuint red_high;
+ ILuint green_low;
+ ILuint green_high;
+ ILuint blue_low;
+ ILuint blue_high;
+ ILuint alpha_low;
+ ILuint alpha_high;
+ ILuint max;
+};
+
+ILuint enhance_fading_1ch (ILuint val, ILuint low, ILuint high, ILuint max);
+int find_fading_range (ILuint n, struct PixelInfo *p, void *data);
+int enhance_fading (ILuint n, struct PixelInfo *p, void *data);
+
+int subtool_nofading (int argc, char **argv, int argi, char **err)
+{
uint_fast16_t frame_t = 0;
uint_fast16_t frame_b = 0;
uint_fast16_t frame_l = 0;
uint_fast16_t frame_r = 0;
- uint_fast8_t palette_only = 0;
+ ILint x0 = 0;
+ ILint y0 = 0;
+ ILint width = 0;
+ ILint height = 0;
+ ILint frames;
+ ILint loops;
+ ILint f;
+
+ struct nofading_data data;
+ struct IL_full_info info;
+
+ struct option long_options[] = {
+ {"enhance-alpha", no_argument, NULL, 'a'},
+ {"no-alpha", no_argument, NULL, 'n'},
+ {"individual-channels", no_argument, NULL, 'c'},
+ {"individual-frames", no_argument, NULL, 'f'},
+ {"help", no_argument, NULL, 'h'},
+ {0, 0, 0, 0}
+ };
+ char short_options[] = "acfh";
+
+ int opt;
int r;
- if (argc<2)
+ FLAG_TYPE flags = CAN_BE_MULTIPLE | CAN_BE_OVER_8BIT;
+
+ data.individual_channels = 0;
+ data.individual_frames = 0;
+ data.enhance_alpha = 0;
+
+ optind = argi;
+ while ((opt = getopt_long(argc, argv, short_options, long_options, NULL)) != -1)
{
- *err = NOFADING_MISSING_ARGS;
- return EINVAL;
+ switch (opt)
+ {
+ case 'a':
+ data.enhance_alpha = 1;
+ break;
+ case 'n':
+ flags |= CANNOT_HAVE_ALPHA;
+ break;
+ case 'c':
+ data.individual_channels = 1;
+ break;
+ case 'f':
+ data.individual_frames = 1;
+ flags |= IN_WINDOW;
+ break;
+ case 'h':
+ /* help */
+ break;
+ }
}
- if (argc>=3)
+
+ if (argc < optind + 2)
{
- if(argv[2][0]=='a' || argv[3][0]=='A')
- individual_channels = 1;
+ *err = NOFADING_MISSING_ARGS;
+ return EINVAL;
}
- if (argc>=7)
+ if (argc >= optind + 6)
{
- sscanf(argv[3], "%"SCNuFAST16, &frame_t);
- sscanf(argv[4], "%"SCNuFAST16, &frame_b);
- sscanf(argv[5], "%"SCNuFAST16, &frame_l);
- sscanf(argv[6], "%"SCNuFAST16, &frame_r);
+ sscanf(argv[optind+2], "%"SCNuFAST16, &frame_t);
+ sscanf(argv[optind+3], "%"SCNuFAST16, &frame_b);
+ sscanf(argv[optind+4], "%"SCNuFAST16, &frame_l);
+ sscanf(argv[optind+5], "%"SCNuFAST16, &frame_r);
}
- else if (argc>=5)
+ else if (argc >= optind + 4)
{
- sscanf(argv[3], "%"SCNuFAST16, &frame_t);
+ sscanf(argv[optind+2], "%"SCNuFAST16, &frame_t);
frame_b = frame_t;
- sscanf(argv[4], "%"SCNuFAST16, &frame_l);
+ sscanf(argv[optind+3], "%"SCNuFAST16, &frame_l);
frame_r = frame_l;
}
- else if (argc>=4)
+ else if (argc >= optind + 3)
{
- sscanf(argv[3], "%"SCNuFAST16, &frame_t);
+ sscanf(argv[optind+2], "%"SCNuFAST16, &frame_t);
frame_b = frame_t;
frame_l = frame_t;
frame_r = frame_t;
}
if ((frame_t==0) && (frame_b==0) && (frame_l==0) && (frame_r==0))
- palette_only = OK_PALETTE_ONLY;
+ flags |= OK_PALETTE_ONLY;
+ else
+ flags |= CANNOT_BE_INDEXED | IN_WINDOW;
- r = create_pictures(1);
+ r = reserve_pictures(1);
if (r)
{
*err = CREATE_FAILED;
return r;
}
- r = load_picture(0, argv[0], CAN_BE_MULTIPLE);
+ r = load_picture(0, argv[optind], &info, &flags);
if (r)
{
*err = LOAD_FAILED;
return r;
}
- r = action_1picture (
- 0,
- 0,0,0,0,
- &action,
- CAN_BE_MULTIPLE,
- NULL
- );
+ if (data.individual_frames)
+ {
+ loops = info.num_images+1;
+ frames = 1;
+ }
+ else
+ {
+ loops = 1;
+ frames = info.num_images+1;
+ }
+
+ for (f=0; f<loops; ++f)
+ {
+ data.red_low = 0xFFFFFFFF;
+ data.green_low = 0xFFFFFFFF;
+ data.blue_low = 0xFFFFFFFF;
+ data.alpha_low = 0xFFFFFFFF;
+ data.red_high = 0x00000000;
+ data.green_high= 0x00000000;
+ data.blue_high = 0x00000000;
+ data.alpha_high= 0x00000000;
+
+ get_info(0, &info, f);
+ data.max = upscale_value(0xFF,info.image_bpc);
+ if (f==0)
+ {
+ if (flags & IN_WINDOW)
+ {
+ x0 = frame_l;
+ y0 = frame_t;
+ width = info.image_width - frame_l - frame_r;
+ height = info.image_height - frame_t - frame_b;
+ }
+ }
+
+ r = perform_action_1picture (
+ 0,
+ x0, y0, f, width, height, frames,
+ &find_fading_range,
+ flags | NOT_WRITABLE,
+ &data
+ );
+ if (r)
+ {
+ *err = CONVERT_FAILED;
+ return r;
+ }
+ r = perform_action_1picture (
+ 0,
+ x0, y0, f, width, height, frames,
+ &enhance_fading,
+ flags,
+ &data
+ );
+ }
+
+ r = save_picture (0, argv[optind+1], flags);
+ if (r)
+ {
+ *err = SAVE_FAILED;
+ return r;
+ }
return 0;
}
-/*
-
-#define INPIX_MUSTARD 1
-#define OUTPIX_MUSTARD 2
-
-#define ARGUMENT_MUSTARD 4
-
-#define ANIMATED_MUSTARD 6
-#define FAIL 900
-#define OK 0
-
-#define CR newdata[4*(i+inX*j)+0]
-#define CG newdata[4*(i+inX*j)+1]
-#define CB newdata[4*(i+inX*j)+2]
-
-#define RA ((long)(*ra))
-#define RB ((long)(*rb))
-#define GA ((long)(*ga))
-#define GB ((long)(*gb))
-#define BA ((long)(*ba))
-#define BB ((long)(*bb))
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <IL/il.h>
-
-void mustard(int mustard);
-
-ILubyte enhance(ILubyte x, long r, long s, long t);
-int main (int argc, const char *argv[]);
-
-ILuint pix;
-ILboolean q=true;
-ILboolean pixOpen=false;
-ILboolean allchannels=false;
-
-ILubyte enhance(ILubyte x, long A, long B)
-{
- if(A==B)
- return x;
- long y=(((long)x)-A)*255/(B-A);
- return (ILubyte)((y>255)?255:((y<0)?0:y));
-}
-
-int main (int argc, const char *argv[])
+int find_fading_range (ILuint n, struct PixelInfo *p, void *data)
{
- ILubyte rav, rbv, gav, gbv, bav, bbv;
- ILubyte *ra, *rb, *ga, *gb, *ba, *bb;
- ILuint inX, inY, frame;
- ILubyte *newdata;
+ struct nofading_data *d;
- if(argc<3)
- mustard(ARGUMENT_MUSTARD);
- if (argc>=4)
- {
- sscanf(argv[3],"%u",&frame);
- }
- else
- frame=0;
- if (argc>=5)
+ d = data;
+
+ if (p->flags & EFF_GRAY)
{
- if (argv[4][0]=='q' || argv[4][0]=='Q')
- q=false;
+ UPDATE_RANGE(p->value, d->green_low, d->green_high);
}
- if (argc>=6)
+ else if (d->individual_channels)
{
- if (argv[5][0]=='a' || argv[5][0]=='A')
- allchannels=true;
+ UPDATE_RANGE(p->red, d->red_low, d->red_high);
+ UPDATE_RANGE(p->green, d->green_low, d->green_high);
+ UPDATE_RANGE(p->blue, d->blue_low, d->blue_high);
}
-
- ra=&rav;
- rb=&rbv;
- if(allchannels)
+ else
{
- ga=&gav;
- gb=&gbv;
- ba=&bav;
- bb=&bbv;
+ UPDATE_RANGE(p->red, d->green_low, d->green_high);
+ UPDATE_RANGE(p->green, d->green_low, d->green_high);
+ UPDATE_RANGE(p->blue, d->green_low, d->green_high);
}
- else
+ if ((p->flags & EFF_ALPHA) && (d->enhance_alpha))
{
- ga=&rav;
- gb=&rbv;
- ba=&rav;
- bb=&rbv;
+ UPDATE_RANGE(p->alpha, d->alpha_low, d->alpha_high);
}
- ilInit();
- if(!ilEnable(IL_ORIGIN_SET))mustard(FAIL);
- if(!ilEnable(IL_FILE_OVERWRITE))mustard(FAIL);
- ilClearColour(255,255,0,0);
- ilGenImages(1, &pix);
- pixOpen=true;
- ilBindImage(pix);
- if(!ilLoadImage(argv[1]))mustard(INPIX_MUSTARD);
- if(!ilConvertImage(IL_RGBA,IL_UNSIGNED_BYTE))mustard(INPIX_MUSTARD);
+ return 0;
+}
+
+ILuint enhance_fading_1ch (ILuint val, ILuint low, ILuint high, ILuint max)
+{
+ ILint64 y;
- inX=ilGetInteger(IL_IMAGE_WIDTH);
- inY=ilGetInteger(IL_IMAGE_HEIGHT);
- if(ilGetInteger(IL_NUM_IMAGES)>1)
- mustard(ANIMATED_MUSTARD);
+ if (low == high)
+ return val;
- newdata=ilGetData();
+ y = (((ILint64)val) - low) * max / (high - low);
+ return (ILuint)((y>max)?max:((y<0)?0:y));
+}
+
+int enhance_fading (ILuint n, struct PixelInfo *p, void *data)
+{
+ struct nofading_data *d;
- *ra=255;
- *ga=255;
- *ba=255;
- *rb=0;
- *gb=0;
- *bb=0;
+ d = data;
- for(unsigned long i=frame;i<inX-frame;++i)
+ if (p->flags & EFF_GRAY)
+ p->value = enhance_fading_1ch(p->value, d->green_low, d->green_high, d->max);
+ else if (d->individual_channels)
{
- for(unsigned long j=frame;j<inY-frame;++j)
- {
- if(CR<*ra)
- *ra=CR;
- if(CR>*rb)
- *rb=CR;
- if(CG<*ga)
- *ga=CG;
- if(CG>*gb)
- *gb=CG;
- if(CB<*ba)
- *ba=CB;
- if(CB>*bb)
- *bb=CB;
- }
+ p->red = enhance_fading_1ch(p->red , d->red_low, d->red_high, d->max);
+ p->green = enhance_fading_1ch(p->green, d->green_low, d->green_high, d->max);
+ p->blue = enhance_fading_1ch(p->blue , d->blue_low, d->blue_high, d->max);
}
-
- for(unsigned long i=frame;i<inX-frame;++i)
+ else
{
- for(unsigned long j=frame;j<inY-frame;++j)
- {
-
- CR=enhance(CR,RA,RB);
- CG=enhance(CG,GA,GB);
- CB=enhance(CB,BA,BB);
- }
+ p->red = enhance_fading_1ch(p->red , d->green_low, d->green_high, d->max);
+ p->green = enhance_fading_1ch(p->green, d->green_low, d->green_high, d->max);
+ p->blue = enhance_fading_1ch(p->blue , d->green_low, d->green_high, d->max);
}
- if(!ilSave(IL_PNG,argv[2]))mustard(OUTPIX_MUSTARD);
- // no mustard
- mustard(0);
-}
+ if ((p->flags & EFF_ALPHA) && (d->enhance_alpha))
+ p->alpha = enhance_fading_1ch(p->alpha, d->alpha_low, d->alpha_high, d->max);
-void mustard(int mustard)
-{
- switch(mustard)
- {
- case 0:
- if(q) printf("ENHANCED!\n");break;
- case ARGUMENT_MUSTARD:
- if(q) printf("nofadig inPix outPix [framesize] [q] [a]\n");break;
- case INPIX_MUSTARD:
- if(q) printf("inPIX mustard.\n");break;
- case OUTPIX_MUSTARD:
- if(q) printf("outPIX mustard.\n");break;
- case ANIMATED_MUSTARD:
- if(q) printf("Animation is mustard.\n");break;
- default:
- if (q) printf("Ch*rpin* mustard mustaard!\n");
- }
- if(pixOpen)
- ilDeleteImages(1, &pix);
- exit(mustard);
+ return 0;
}
-*/