Skip to content

Commit

Permalink
Add parameters to customize libimagequant behaviour.
Browse files Browse the repository at this point in the history
  • Loading branch information
cubicibo committed Oct 3, 2023
1 parent 1f025eb commit b8309e9
Show file tree
Hide file tree
Showing 4 changed files with 149 additions and 72 deletions.
23 changes: 20 additions & 3 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ The following optional arguments are available:
| ``-q`` | Sets and enable image quantization with N colors. |
| ``--quantize`` | Choices: value in [0; 255]. |
| | Default: ``0`` (Disabled, PNGs are 32-bit RGBA) |
| | Notes: Do not use if the BDNXML is generated for SUPer.|
| | **Notes: Do not use if target is SUPer.** |
| | This must be enabled if target software is Scenarist BD|
+--------------------+--------------------------------------------------------+
| ``-a`` | Sets an additional font directory for custom fonts not |
Expand All @@ -53,7 +53,7 @@ The following optional arguments are available:
| ``-s`` | Sets the event split across 2 graphics behaviour. |
| ``--split`` | 0: Disabled, 1: Normal, 2: Strong, 3: Very aggressive. |
| | Default: ``0`` (Disabled) |
| | Note: Do not use if the BDNXML is generated for SUPer. |
| | **Note: Do not use if target is SUPer.** |
+--------------------+--------------------------------------------------------+
| ``-m`` | Sets the vertical and opt. horizontal margins to split |
| ``--splitmargin`` | Format: ``VxH`` (V=y difference, H=x difference). |
Expand Down Expand Up @@ -95,7 +95,7 @@ The following optional arguments are available:
| ``--render-height``| Defaults to output height if not specified. Some ass |
| | tags may not render properly if the value is improper. |
+--------------------+--------------------------------------------------------+
| ``-g`` | Flag to enable libass hinting. |
| ``-g`` | Flag to enable libass soft hinting. |
| ``--hinting`` | |
+--------------------+--------------------------------------------------------+
| ``-x`` | Sets the ASS storage width. I.e the pre-anamorphic |
Expand All @@ -104,3 +104,20 @@ The following optional arguments are available:
| ``-y`` | Sets the ASS storage height. Last resort option for |
| ``--height-store`` | ASS with complex transforms with unusual video height. |
+--------------------+--------------------------------------------------------+

Below are parameters to tune libimagequant (LIQ). Those shall only be used along ``--quantize`` (``-q``). Only long parameters names are available.

+--------------------+--------------------------------------------------------+
| Option | Effect |
+====================+========================================================+
| ``--liq-speed`` | LIQ speed. Lower value are slower but higher quality. |
| | Choices: value within [1; 10] incl. Default: ``4`` |
+--------------------+--------------------------------------------------------+
| ``--liq-quality`` | Quantization quality. Values < 100 can be visually |
| | lossless and will compress way better as PGS. |
| | Default: ``100`` but 90~97 is recommended in general. |
+--------------------+--------------------------------------------------------+
| ``--liq-dither`` | Dithering level, value must be within [0; 1.0] incl. |
| | Default: ``1.0``. Disable: ``0``. LIQ dithering is soft|
| | so default or ``0.5`` is perfect in general. |
+--------------------+--------------------------------------------------------+
102 changes: 71 additions & 31 deletions ass2bdnxml.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ vfmt_t vfmts[] = {
{NULL, 0, 0}
};

#define OPT_LIQ_SPEED 1000
#define OPT_LIQ_DITHER 1001
#define OPT_LIQ_MAXQUAL 1002

static void die_usage(const char *name)
{
printf("usage: %s <subtitle file> [options]\n", name);
Expand Down Expand Up @@ -209,12 +213,15 @@ int main(int argc, char *argv[])
vfmt_t *vfmt = NULL;
eventlist_t *evlist;

uint8_t liq_params = 0;
uint8_t copy_name = 0;
uint8_t negative_offset = 0;
uint8_t offset_vals[4];
memset(offset_vals, 0, sizeof(offset_vals));

opts_t args;
liqopts_t liqargs = {.dither=1.0f, .speed=4, .max_quality=100};

memset(&args, 0, sizeof(args));

if (argc < 2) {
Expand All @@ -226,7 +233,7 @@ int main(int argc, char *argv[])
{"hinting", no_argument, 0, 'g'},
{"negative", no_argument, 0, 'z'},
{"rleopt", no_argument, 0, 'r'},
{"copyname", no_argument, 0, 'c'},
{"copyname", no_argument, 0, 'c'},
{"split", required_argument, 0, 's'},
{"splitmargin", required_argument, 0, 'm'},
{"trackname", required_argument, 0, 't'},
Expand All @@ -241,52 +248,57 @@ int main(int argc, char *argv[])
{"fontdir", required_argument, 0, 'a'},
{"offset", required_argument, 0, 'o'},
{"quantize", required_argument, 0, 'q'},
{"liq-dither", required_argument, 0, OPT_LIQ_DITHER},
{"liq-quality", required_argument, 0, OPT_LIQ_MAXQUAL},
{"liq-speed", required_argument, 0, OPT_LIQ_SPEED},
{0, 0, 0, 0}
};

while (1) {
int opt_index = 0;
int c = getopt_long(argc, argv, "czdgrt:l:v:f:w:h:x:y:p:a:o:q:s:m:", longopts, &opt_index);
int c = getopt_long(argc, argv, "czdgjrt:l:v:f:w:h:x:y:p:a:o:q:s:m:k:", longopts, &opt_index);

if (c == -1)
break;

switch (c) {
case 'p':
args.par = strtod(optarg, NULL);
if (args.par < 0.1 || args.par > 10) {
printf("Unusual PAR, aborting.\n");
exit(1);
}
if (args.par > 0)
args.par = 1./args.par;
break;
case 't':
track_name = optarg;
case 'a':
args.fontdir = optarg;
break;
case 'c':
copy_name = 1;
break;
case 'l':
language = optarg;
break;
case 'v':
video_format = optarg;
break;
case 'f':
frame_rate = optarg;
break;
case 'd':
args.dvd_mode = 1;
break;
case 'z':
negative_offset = 1;
break;
case 'r':
args.rle_optimise = 1;
break;
case 'g':
args.hinting = 1;
break;
case 'r':
args.rle_optimise = 1;
case 't':
track_name = optarg;
break;
case 'l':
language = optarg;
break;
case 'v':
video_format = optarg;
break;
case 'f':
frame_rate = optarg;
break;
case 'p':
args.par = strtod(optarg, NULL);
if (args.par < 0.1 || args.par > 10) {
printf("Unusual PAR, aborting.\n");
exit(1);
}
args.par = 1./args.par;
break;
case 's':
args.split = (uint8_t)strtol(optarg, NULL, 10);
Expand Down Expand Up @@ -332,12 +344,34 @@ int main(int argc, char *argv[])
case 'q':
args.quantize = (uint16_t)strtol(optarg, NULL, 10);
if (args.quantize > 255) {
printf("Colours must be within [0; 255] (default: 0, no quantization, output are 32-bit RGBA PNGs).\n");
printf("Colours must be within [0; 255] incl. (default: 0, no quantization, output are 32-bit RGBA PNGs).\n");
exit(1);
}
args.quantize += (args.quantize == 1);
break;
case 'a':
args.fontdir = optarg;
case OPT_LIQ_SPEED:
liqargs.speed = (uint8_t)strtol(optarg, NULL, 10);
if (liqargs.speed == 0 || liqargs.speed > 10) {
printf("Invalid libimagequant speed setting. Must be within [1; 10] incl. Default: 4.\n");
exit(1);
}
liq_params |= 1;
break;
case OPT_LIQ_MAXQUAL:
liqargs.max_quality = (uint8_t)strtol(optarg, NULL, 10);
if (liqargs.max_quality == 0 || liqargs.max_quality > 100) {
printf("Invalid libimagequant max quality setting. Must be within [1; 100] incl. Default: 100.\n");
exit(1);
}
liq_params |= 1;
break;
case OPT_LIQ_DITHER:
liqargs.dither = (float)strtod(optarg, NULL);
if (liqargs.dither > 1.0f || liqargs.dither < 0.0f) {
printf("Dithering level must be within [0.0; 1.0] incl. Default: 1 (enabled, maximum).\n");
exit(1);
}
liq_params |= 1;
break;
default:
die_usage(argv[0]);
Expand Down Expand Up @@ -434,11 +468,17 @@ int main(int argc, char *argv[])
if (negative_offset)
args.offset *= -1;

//RLE optimise discard palette entry zero, we have 254 usable colors.
if (args.rle_optimise && args.quantize == 255)
args.quantize -= 1;
if (args.quantize) {
//RLE optimise discard palette entry zero, we have 254 usable colors.
if (args.rle_optimise && args.quantize == 255)
args.quantize -= 1;
liqargs.max_quality = MAX(0, MIN(100, liqargs.max_quality));
} else if (liq_params) {
printf("Set up libimagequant parameters but not using --quantize.\n");
exit(1);
}

evlist = render_subs(subfile, frate, &args);
evlist = render_subs(subfile, frate, &args, &liqargs);

write_xml(evlist, vfmt, frate, bdnfile, track_name, language, &args);

Expand Down
20 changes: 15 additions & 5 deletions common.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
#include <stdint.h>

#define MAX(a,b) ((a) > (b) ? (a) : (b))
#define MIN(a,b) ((a) > (b) ? (b) : (a))

typedef struct BoundingBox_s {
int x1;
int x2;
Expand Down Expand Up @@ -38,11 +41,18 @@ typedef struct opts_s {
int storage_h;
uint16_t quantize;
uint16_t splitmargin[2];
uint8_t dvd_mode;
uint8_t hinting;
uint8_t split;
uint8_t rle_optimise;
uint8_t dvd_mode : 1;
uint8_t hinting : 1;
uint8_t split : 1;
uint8_t rle_optimise : 1;
uint8_t _pad : 4;
const char *fontdir;
} opts_t;

eventlist_t *render_subs(char *subfile, frate_t *frate, opts_t *args);
typedef struct liqopts_s {
float dither;
uint8_t speed;
uint8_t max_quality;
} liqopts_t;

eventlist_t *render_subs(char *subfile, frate_t *frate, opts_t *args, liqopts_t *liqargs);

0 comments on commit b8309e9

Please sign in to comment.