Skip to content

Commit 528a97b

Browse files
committed
auto-generate output filename when not specified
1 parent c7ade38 commit 528a97b

1 file changed

Lines changed: 35 additions & 3 deletions

File tree

apps/avifenc.c

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -188,15 +188,17 @@ typedef struct avifEncodedByteSizes
188188

189189
static void syntaxShort(void)
190190
{
191-
printf("Syntax: avifenc [options] -q quality input.[jpg|jpeg|png|y4m] output.avif\n");
191+
printf("Syntax: avifenc [options] -q quality input.[jpg|jpeg|png|y4m] [output.avif]\n");
192192
printf("where quality is between %d (worst quality) and %d (lossless).\n", AVIF_QUALITY_WORST, AVIF_QUALITY_LOSSLESS);
193-
printf("Typical value is 60-80.\n\n");
193+
printf("Typical value is 60-80.\n");
194+
printf("If output.avif is not specified, it is derived from the input filename with a .avif extension.\n\n");
194195
printf("Try -h for an exhaustive list of options.\n");
195196
}
196197

197198
static void syntaxLong(void)
198199
{
199-
printf("Syntax: avifenc [options] input.[jpg|jpeg|png|y4m] output.avif\n");
200+
printf("Syntax: avifenc [options] input.[jpg|jpeg|png|y4m] [output.avif]\n");
201+
printf("If output.avif is not specified, it is derived from the input filename with a .avif extension.\n");
200202
printf("Standard options:\n");
201203
printf(" -h,--help : Show syntax help (this page)\n");
202204
printf(" -V,--version : Show the version number\n");
@@ -1381,6 +1383,7 @@ int main(int argc, char * argv[])
13811383
}
13821384

13831385
const char * outputFilename = NULL;
1386+
char * generatedOutputFilename = NULL;
13841387

13851388
avifInput input;
13861389
memset(&input, 0, sizeof(input));
@@ -2079,6 +2082,34 @@ int main(int argc, char * argv[])
20792082
goto cleanup;
20802083
}
20812084

2085+
if (!outputFilename && input.filesCount == 1 && input.files[0].filename != AVIF_FILENAME_STDIN) {
2086+
// Auto-derive output filename by replacing the input file extension with .avif.
2087+
const char * inputFilename = input.files[0].filename;
2088+
const char * lastSlash = strrchr(inputFilename, '/');
2089+
#if defined(_WIN32)
2090+
const char * lastBackslash = strrchr(inputFilename, '\\');
2091+
if (lastBackslash && (!lastSlash || lastBackslash > lastSlash)) {
2092+
lastSlash = lastBackslash;
2093+
}
2094+
#endif
2095+
const char * filenamePart = lastSlash ? lastSlash + 1 : inputFilename;
2096+
const char * lastDot = strrchr(filenamePart, '.');
2097+
size_t prefixLen = lastDot ? (size_t)(lastDot - inputFilename) : strlen(inputFilename);
2098+
generatedOutputFilename = malloc(prefixLen + 6); // ".avif" + null terminator
2099+
if (!generatedOutputFilename) {
2100+
fprintf(stderr, "ERROR: memory allocation failure\n");
2101+
goto cleanup;
2102+
}
2103+
memcpy(generatedOutputFilename, inputFilename, prefixLen);
2104+
memcpy(generatedOutputFilename + prefixLen, ".avif", 6);
2105+
if (!strcmp(generatedOutputFilename, inputFilename)) {
2106+
fprintf(stderr, "ERROR: auto-generated output filename is the same as the input filename: %s\n", inputFilename);
2107+
fprintf(stderr, "Please specify a different output filename with -o.\n");
2108+
goto cleanup;
2109+
}
2110+
outputFilename = generatedOutputFilename;
2111+
}
2112+
20822113
if (!outputFilename) {
20832114
fprintf(stderr, "ERROR: no output specified\n");
20842115
goto cleanup;
@@ -2658,6 +2689,7 @@ int main(int argc, char * argv[])
26582689
avifRWDataFree(&exifOverride);
26592690
avifRWDataFree(&xmpOverride);
26602691
avifRWDataFree(&iccOverride);
2692+
free(generatedOutputFilename);
26612693
avifCodecSpecificOptionsFree(&pendingSettings.codecSpecificOptions);
26622694
while (input.cacheCount) {
26632695
--input.cacheCount;

0 commit comments

Comments
 (0)